A production-ready Spring Boot monolith template focused on authentication, role-based authorization, OTP flows, file upload pre-signing, and infrastructure-friendly local development.
- Overview
- Core Features
- Tech Stack
- Project Structure
- Local Development Setup
- API Documentation
- Authentication and Authorization
- Testing
- Build and Packaging
- Contributing
This backend exposes versioned REST APIs under /api/v1/** and includes:
- JWT-based stateless authentication
- OTP verification and resend flows
- Refresh token and logout flow
- Role-based access control (Admin, Employee)
- Pre-signed S3-compatible upload ticket generation
- OpenAPI/Swagger UI documentation
- Test setup using JUnit + Testcontainers + H2
- Stateless Authentication: JWT-based stateless authentication (HS256) with refresh token and logout flows.
- Role-Based Authorization: Fine-grained access control with Admin and Employee scopes.
- OTP Verification: Registration OTP confirmation and resend flows for account verification.
- Flyway Database Migrations: Automatic schema lifecycle management and database migrations.
- Pre-signed S3 Uploads: Endpoint to generate pre-signed upload tickets for S3-compatible storage (e.g., MinIO, RustFS).
- Comprehensive Testing: Unit, Integration, and E2E test suites using JUnit 5, Testcontainers, and MockMvc.
- API Documentation: Interactive OpenAPI/Swagger UI docs exposed at
/docs. - Infrastructure Support: Dev-ready environment using Docker Compose (Postgres, Redis, Mailhog, S3-compatible storage).
- Security & Logging: Correlation ID propagation across filters and aspects, global exception handling, and secure CORS allowlist.
- Java 25 (project target)
- Spring Boot 4.0.4
- Spring Web MVC
- Spring Security OAuth2 Resource Server
- Spring Data JPA
- PostgreSQL
- SpringDoc OpenAPI + Swagger UI
- Spring Cloud AWS S3 Starter
- MapStruct
- Lombok
- Testcontainers + JUnit 5
- Docker + Docker Compose
.
├── src/main/java/com/firomsa/monolith
│ ├── config
│ ├── exception
│ ├── model
│ ├── repository
│ ├── security
│ └── v1
│ ├── controller
│ ├── dto
│ ├── mapper
│ └── service
├── src/main/resources
│ └── application.properties
├── src/test
│ ├── java
│ └── resources/application.properties
├── docker-compose-dev.yaml
├── docker-compose.yaml
├── Dockerfile
└── pom.xml
You can run this project fully inside a VS Code Dev Container.
Steps:
- Install the VS Code Dev Containers extension.
- Open the repository in VS Code.
- Run:
Dev Containers: Reopen in Container. - Wait for the post-create command to finish (
mvn clean install -DskipTests). - Inside the container terminal, continue with the normal setup:
cp example.env .env
docker compose --env-file .env -f docker-compose-dev.yaml up -d
./mvnw spring-boot:run -Dspring-boot.run.profiles=devThis gives you a consistent development environment without needing to install Java/Maven locally.
Install the following tools:
- Java 25 (for local Maven builds)
- Docker + Docker Compose plugin
- Optional: Maven (or use the included Maven wrapper
./mvnw)
- Copy env template:
cp example.env .env- Start local infrastructure:
docker network create monolith_network || true
docker compose --env-file .env -f docker-compose-dev.yaml up -dThis starts:
- PostgreSQL on
5432 - Mailhog SMTP/UI on
1025/8025 - RustFS S3 API/Console on
9000/9001 - SQL Studio on
3030
- Run the application:
./mvnw spring-boot:run -Dspring-boot.run.profiles=devApp runs on:
- API:
http://localhost:8080 - Swagger UI:
http://localhost:8080/docs
Stop all:
docker compose -f docker-compose-dev.yaml downOpenAPI/Swagger is exposed at:
- UI:
GET /docs - Spec:
GET /v3/api-docs
/api/v1/auth/**/docs/v3/api-docs/**- Swagger resource paths
/api/v1/admin/**requiresSCOPE_ADMIN/api/v1/employee/**requiresSCOPE_EMPLOYEE- Any other route requires authentication
Base path: /api/v1/auth
POST /adminsPOST /confirm-otpPOST /resend-otpPOST /loginPOST /refreshPOST /logout
Base path: /api/v1/uploads
POST /presign
Run all tests:
./mvnw testNotes:
- Repository integration tests use Testcontainers PostgreSQL (
postgres:18-alpine). - Test profile also includes H2 config in
src/test/resources/application.properties.
Build jar:
./mvnw clean package -DskipTestsBuilt artifact:
target/monolith-0.0.1-SNAPSHOT.jar- provide environment variables for production configuration (e.g. via
.envfile or orchestration secrets) that match the ones insrc/main/resources/application-prod.properties
Run packaged jar:
java -jar target/monolith-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod- Create a feature branch.
- Make your changes and add tests.
- Run
./mvnw testand ensure green build. - Open a pull request with a concise change summary.