This is an advanced boilerplate project implementing Domain-Driven Design (DDD), Clean Architecture, CQRS (Command Query Responsibility Segregation), Event Sourcing and PostgreSQL with NestJS. It provides a robust foundation for building scalable and maintainable enterprise-level applications with proper separation of concerns and clean dependency direction.
If you want more documentation about NestJS, click here Nest
π Note: This version uses PostgreSQL with TypeORM. If you prefer the MongoDB version with Mongoose, you can find it at the original repository: https://github.com/CollatzConjecture/nestjs-clean-architecture
A quick introduction to clean architecture
- Clean Architecture: Enforces strict separation of concerns with proper dependency direction (Infrastructure β Application β Domain).
- Domain-Driven Design (DDD): Pure business logic encapsulated in Domain Services, accessed through Repository Interfaces.
- CQRS: Segregates read (Queries) and write (Commands) operations for optimized performance and scalability.
- Event Sourcing: Uses an event-driven approach with sagas for orchestrating complex business processes.
- Repository Pattern: Clean interfaces defined in Domain layer, implemented in Infrastructure layer.
- Dependency Inversion: Domain layer depends only on abstractions, never on concrete implementations.
- Domain Layer: Pure business logic, domain entities without framework dependencies, repository interfaces
- Application Layer: Business orchestration, application services, CQRS coordination, framework-agnostic services
- API Layer: HTTP controllers, DTOs, request/response handling, framework-specific HTTP concerns
- Infrastructure Layer: Database implementations, external API calls, concrete repository classes, global services
- JWT Authentication: Implements secure, token-based authentication with refresh token rotation.
- Google OAuth2 Integration: Secure third-party authentication with Google accounts for both web and mobile applications.
- Apple Sign In: Native Sign in with Apple support for iOS and Android clients using Apple ID tokens.
- Web OAuth2: Traditional OAuth2 flow with CSRF protection using state parameters and browser redirects.
- Mobile OAuth2: Direct token exchange for mobile applications using Google ID tokens.
- JWKS-Based Token Validation: Uses remote JSON Web Key Sets (JWKS) for signature verification of Google and Apple ID tokens.
- Role-Based Access Control (RBAC): Complete implementation with protected routes and role-based guards.
- Secure Password Storage: Hashes passwords using
bcrypt
with salt rounds. - Sensitive Data Encryption: Encrypts sensitive fields (e.g., user emails) at rest in the database using AES-256-CBC.
- Blind Indexing: Allows for securely querying encrypted data without decrypting it first.
- CSRF Protection: OAuth flows protected against Cross-Site Request Forgery attacks using state parameters.
- PostgreSQL Integration: Utilizes TypeORM for structured data modeling with a relational database.
- Containerized Environment: Full Docker and Docker Compose setup for development and production.
- Health Checks: Provides application health monitoring endpoints via Terminus.
- Structured Logging: Advanced logging system with business-context awareness and dependency injection.
- Application Metrics: Exposes performance metrics for Prometheus.
- Data Visualization: Comes with a pre-configured Grafana dashboard for visualizing metrics.
- Request Throttling: Built-in rate limiting to prevent abuse and ensure API stability.
- Unit & Integration Tests: A suite of tests for domain, application, and infrastructure layers.
- E2E Tests: End-to-end tests to ensure API functionality from request to response.
- High Test Coverage: Configured to report and maintain high code coverage.
- Mocking: Clear patterns for mocking database and service dependencies.
git clone https://github.com/CollatzConjecture/nestjs-clean-architecture
cd nestjs-clean-architecture
.
βββ doc/
β βββ common.http # Common API requests
β βββ users.http # User-specific API requests
βββ src/
β βββ api/ # API Layer (HTTP Controllers & DTOs)
β β βββ controllers/
β β β βββ *.controller.ts # HTTP endpoints (auth, profile, hello)
β β βββ dto/
β β β βββ auth/ # Authentication DTOs
β β β β βββ *.dto.ts # Login & register DTOs
β β β βββ *.dto.ts # Profile management DTOs
β β βββ api.module.ts # API module configuration
β βββ application/ # Application Layer (Business Orchestration)
β β βββ __test__/
β β β βββ *.spec.ts # Application layer tests
β β βββ auth/
β β β βββ command/ # Auth commands & handlers
β β β β βββ *.command.ts # Create/delete auth user commands
β β β β βββ handler/
β β β β βββ *.handler.ts # Command handlers
β β β βββ events/ # Auth domain events
β β β β βββ *.event.ts # User created/deleted events
β β β βββ sagas/
β β β β βββ *.saga.ts # Registration flow orchestration
β β β βββ decorators/
β β β β βββ *.decorator.ts # Custom decorators (roles)
β β β βββ guards/
β β β β βββ *.guard.ts # Authentication & authorization guards
β β β βββ *.strategy.ts # Auth strategies (JWT, local, Google OAuth)
β β β βββ auth.module.ts # Auth module configuration
β β βββ decorators/
β β β βββ *.decorator.ts # Global decorators (current user)
β β βββ interfaces/
β β β βββ *.interface.ts # Application interfaces
β β βββ interceptors/
β β β βββ *.interceptor.ts # Request logging interceptors
β β βββ middlewere/
β β β βββ *.middleware.ts # HTTP middleware (logging)
β β βββ services/
β β β βββ *.service.ts # Application services (auth, profile, logger)
β β βββ profile/
β β β βββ command/ # Profile commands & handlers
β β β β βββ *.command.ts # Profile commands
β β β β βββ handler/
β β β β βββ *.handler.ts # Command handlers
β β β βββ events/ # Profile domain events
β β β β βββ *.event.ts # Profile events
β β β βββ profile.module.ts # Profile module configuration
β β βββ application.module.ts # Application module aggregator
β βββ domain/ # Domain Layer (Pure Business Logic)
β β βββ __test__/
β β β βββ *.spec.ts # Domain layer tests
β β βββ aggregates/ # Domain aggregates
β β βββ entities/
β β β βββ *.ts # Pure domain entities (Auth, Profile)
β β β βββ enums/ # Domain enums
β β β βββ *.enum.ts # Role enums, etc.
β β βββ interfaces/
β β β βββ repositories/ # Repository contracts defined by domain
β β β βββ *.interface.ts # Repository interfaces
β β βββ services/
β β βββ *.service.ts # Pure business logic services
β βββ infrastructure/ # Infrastructure Layer (External Concerns)
β β βββ database/
β β β βββ database.module.ts # Database configuration
β β β βββ database.providers.ts # Database providers
β β βββ health/
β β β βββ *.check.ts # Health check configurations
β β βββ logger/
β β β βββ logger.module.ts # Global logger module
β β βββ entities/
β β β βββ *.entity.ts # PostgreSQL entities (auth, profile)
β β β βββ index.ts # Entity exports
β β βββ repository/
β β βββ *.repository.ts # Repository implementations
β βββ main.ts # Application entry point
β βββ app.module.ts # Root application module
β βββ constants.ts # Application constants
βββ test/
β βββ *.e2e-spec.ts # End-to-end tests
β βββ jest-e2e.json # E2E test configuration
β βββ setup-e2e.ts # E2E test setup
βββ prometheus/
β βββ prometheus.yml # Prometheus configuration
βββ docker-compose*.yml # Docker Compose configurations (dev, prod)
βββ Dockerfile # Container definition
This project follows a strict 4-layer architecture:
- API Layer (
src/api/
): HTTP controllers, DTOs, and request/response handling - Application Layer (
src/application/
): Business orchestration, CQRS coordination, and application services - Domain Layer (
src/domain/
): Pure business logic, entities, and domain services - Infrastructure Layer (
src/infrastructure/
): Database, external services, and technical implementations
- ApiModule: Aggregates all HTTP controllers and imports ApplicationModule
- ApplicationModule: Central orchestrator that imports and exports feature modules
- AuthModule: Self-contained authentication feature with all its dependencies
- ProfileModule: Self-contained profile management feature with all its dependencies
- LoggerModule: Global infrastructure service for application-wide logging
- Commands: Handle write operations (Create, Update, Delete). Located in
src/application/*/command
. - Queries: Handle read operations (Find, Get). Located in
src/application/*/query
. - Handlers: Process commands and queries separately with proper business-context logging.
- Events: Publish domain events for side effects and inter-module communication.
-
User Registration:
API Controller β Application Service β Domain Service (validation) β RegisterCommand β CreateAuthUser β AuthUserCreated Event β RegistrationSaga β CreateProfile β ProfileCreated
-
Authentication:
API Controller β Application Service β Domain Service (email validation) β LoginCommand β ValidateUser β JWT Token Generation
-
Google OAuth Flow (Web):
/auth/google β Google OAuth β /auth/google/redirect β Domain Service (validation) β FindOrCreateUser β JWT Token Generation
-
Google OAuth Flow (Mobile - iOS):
/auth/google/mobile/ios β ID Token Validation β Domain Service (validation) β FindOrCreateUser β JWT Token Generation
-
Google OAuth Flow (Mobile - Android):
/auth/google/mobile/android β ID Token Validation β Domain Service (validation) β FindOrCreateUser β JWT Token Generation
-
Apple Sign In Flow (Mobile):
/auth/mobile/apple β Apple ID Token Validation via JWKS β Domain Service (validation) β FindOrCreateUser β JWT Token Generation
-
Error Handling:
ProfileCreationFailed Event β RegistrationSaga β DeleteAuthUser (Compensating Transaction)
- Feature Modules: Each feature (Auth, Profile) manages its own dependencies
- Domain Services: Injected via factories to maintain Clean Architecture principles
- Repository Pattern: Interfaces defined in domain, implementations in infrastructure
- Global Services: Logger provided globally via
@Global()
decorator
- Node.js 20+
- Docker and Docker Compose
- PostgreSQL (included in Docker Compose)
- Google OAuth2 credentials (for Google login functionality)
- Apple Sign In credentials (for Apple login functionality)
The project is configured to run seamlessly with Docker. Use the npm scripts from package.json
for convenience.
# Build and start containers in detached mode for development
$ npm run docker:dev
# Build and start containers for production
$ npm run docker:prod
# View logs for the API service
$ npm run docker:logs
# Stop all running containers
$ npm run docker:down
# Restart the development environment
$ npm run docker:restart
- Application: http://localhost:4000
- API Documentation (Swagger): http://localhost:4000/api
- PostgreSQL: localhost:5432
- Prometheus: http://localhost:9090
- Grafana: http://localhost:3000 (admin/admin)
$ npm install
# Development
$ npm run start
# Watch mode (recommended for development)
$ npm run start:dev
# Production mode
$ npm run start:prod
# Debug mode
$ npm run start:debug
# Unit tests
$ npm run test
# E2E tests
$ npm run test:e2e
# Test coverage
$ npm run test:cov
# Watch mode
$ npm run test:watch
POST /auth/register # User registration
POST /auth/login # User login
POST /auth/logout # User logout (Protected)
POST /auth/refresh-token # Token refresh (Protected)
GET /auth/google # Initiate Google OAuth login (Web)
GET /auth/google/oauth2redirect # Google OAuth callback (Web)
POST /auth/google/mobile/ios # Google OAuth login for iOS apps
POST /auth/google/mobile/android # Google OAuth login for Android apps
POST /auth/mobile/apple # Apple Sign In for mobile apps (iOS/Android)
GET /auth/:id # Get user by auth ID (Protected)
DELETE /auth/:id # Delete user by auth ID (Protected)
GET /profile/all # Get all user profiles (Admin only)
GET /profile/admins # Get all admin users (Admin only)
GET /profile/:id # Get user profile by ID
POST /profile # Create a new profile
GET /hello # Health check endpoint
GET /health # Detailed health check
GET /metrics # Prometheus metrics
# Register a new user
curl -X POST http://localhost:4000/auth/register \
-H "Content-Type: application/json" \
-d '{
"name": "John",
"lastname": "Doe",
"age": 30,
"email": "[email protected]",
"password": "securePassword123"
}'
# Login
curl -X POST http://localhost:4000/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"password": "securePassword123"
}'
# Initiate Google login (redirects to Google)
curl -X GET http://localhost:4000/auth/google
# The callback is handled automatically after Google authentication
# Returns JWT token upon successful authentication
iOS Authentication:
# iOS Google login with ID token
curl -X POST http://localhost:4000/auth/google/mobile/ios \
-H "Content-Type: application/json" \
-d '{
"idToken": "GOOGLE_ID_TOKEN_FROM_IOS_APP"
}'
# Returns JWT token upon successful authentication
Android Authentication:
# Android Google login with ID token
curl -X POST http://localhost:4000/auth/google/mobile/android \
-H "Content-Type: application/json" \
-d '{
"idToken": "GOOGLE_ID_TOKEN_FROM_ANDROID_APP"
}'
# Returns JWT token upon successful authentication
# Apple login with ID token
curl -X POST http://localhost:4000/auth/mobile/apple \
-H "Content-Type: application/json" \
-d '{
"platform": "ios",
"idToken": "APPLE_ID_TOKEN_FROM_CLIENT"
}'
# Returns JWT token upon successful authentication
# Access protected route
curl -X GET http://localhost:4000/profile/123 \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
# Admin-only route
curl -X GET http://localhost:4000/profile/all \
-H "Authorization: Bearer YOUR_ADMIN_JWT_TOKEN"
- NestJS - Progressive Node.js framework
- TypeScript - Type-safe JavaScript
- @nestjs/cqrs - CQRS implementation
- @nestjs/event-emitter - Event handling
- @nestjs/jwt - JWT implementation
- @nestjs/passport - Authentication strategies
- @nestjs/throttler - Rate limiting
- bcrypt - Password hashing
- cookie-parser - Cookie handling for OAuth state
- TypeORM - PostgreSQL object relational mapping
- PostgreSQL - Relational database
- @nestjs/terminus - Health checks
- Prometheus - Metrics collection
- Grafana - Metrics visualization
- Authentication Context: User login, registration, tokens, OAuth integration
- Profile Context: User profile management, personal data
- UserAggregate: Manages user lifecycle and events across auth and profile contexts
AuthUserCreatedEvent
: Triggered after successful user creationAuthUserDeletedEvent
: Triggered when user is deleted (compensating action)ProfileCreationFailedEvent
: Triggered when profile creation fails
- RegistrationSaga: Orchestrates user registration process
- Handles profile creation after auth user creation
- Implements compensating transactions for failures
- Supports both traditional and OAuth registration flows
- Business-Context Logging: Logs focus on business events rather than technical execution
- Dependency Injection: Logger service is injected throughout the application
- Consistent Format: All logs include module, method, and timestamp information
- Security Audit Trail: Comprehensive logging of authentication attempts and outcomes
- Database connectivity
- Memory usage
- Disk space
- HTTP request duration
- Request count by endpoint
- Error rates
- Database connection pool
- Authentication success/failure rates
- Application performance metrics
- Database statistics
- Error tracking
- Response time analysis
- Authentication analytics
-
Clone the repository:
git clone https://github.com/CollatzConjecture/nestjs-clean-architecture cd nestjs-clean-architecture
-
Create an environment file:
Create a file named
.env
in the root of the project by copying the example file.cp .env.example .env
-
Generate Secrets:
Your
.env
file requires several secret keys to run securely. Use the following command to generate a cryptographically strong secret:node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
Run this command for each of the following variables in your
.env
file and paste the result:JWT_SECRET
JWT_REFRESH_SECRET
EMAIL_ENCRYPTION_KEY
EMAIL_BLIND_INDEX_SECRET
Do not use the same value for different keys.
-
Configure Google OAuth2 (Optional):
To enable Google login functionality for both web and mobile applications, you'll need to:
a. Go to the Google Cloud Console
b. Create a new project or select an existing one
c. Enable the Google+ API
d. Create OAuth 2.0 credentials:
- Web application type for web OAuth flow
- Android/iOS application type for mobile OAuth flow (if using native mobile apps)
e. For web OAuth, add your redirect URI:
http://localhost:4000/auth/google/oauth2redirect
f. Add the following to your
.env
file:# Web OAuth credentials GOOGLE_CLIENT_ID=your_google_client_id_here GOOGLE_CLIENT_SECRET=your_google_client_secret_here GOOGLE_CALLBACK_URL=http://localhost:4000/auth/google/oauth2redirect # Mobile OAuth credentials (platform-specific) GOOGLE_IOS_CLIENT_ID=your_ios_client_id_here GOOGLE_ANDROID_CLIENT_ID=your_android_client_id_here GOOGLE_MOBILE_CALLBACK_IOS_URL=your_ios_callback_url_here GOOGLE_MOBILE_CALLBACK_ANDROID_URL=your_android_callback_url_here
Note for Mobile Apps:
- iOS: Use Google Sign-In SDK for iOS to obtain ID tokens, then send to
/auth/google/mobile/ios
- Android: Use Google Sign-In SDK for Android to obtain ID tokens, then send to
/auth/google/mobile/android
- The backend validates these ID tokens without requiring client secrets
- Platform-specific client IDs provide additional validation and security
-
Configure Apple Sign In (Optional):
To enable Sign in with Apple for your mobile applications:
a. Sign in to the Apple Developer portal
b. Create an App Identifier that supports Sign in with Apple for each platform bundle ID
c. Generate a Services ID for web/mobile authentication and enable Sign in with Apple
d. Create a private key (p8 file) associated with the Sign in with Apple service
e. Add the following variables to your
.env
file:APPLE_TEAM_ID=your_apple_team_id APPLE_KEY_ID=your_key_id APPLE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----" APPLE_IOS_CLIENT_ID=your_ios_service_id APPLE_ANDROID_CLIENT_ID=your_android_service_id # Optional comma-separated list of additional audience values APPLE_IOS_ADDITIONAL_AUDIENCES= APPLE_ANDROID_ADDITIONAL_AUDIENCES=
f. Provide the corresponding
platform
value (ios
orandroid
) and the Apple ID token from the client when calling/auth/mobile/apple
.
- JWT with Refresh Tokens: Secure token-based authentication with automatic refresh
- Password Security: Bcrypt hashing with configurable salt rounds
- OAuth2 Security:
- Web: CSRF protection using state parameters in OAuth flows
- Mobile: Direct ID token validation for mobile applications
- JWKS Validation: All Google and Apple ID tokens are verified against their official JWKS endpoints before trust
- Apple Sign In: Supports native Sign in with Apple flows for iOS and Android using platform-specific audiences
- Rate Limiting: Configurable throttling on sensitive endpoints
- Encryption at Rest: Sensitive data encrypted using AES-256-CBC
- Blind Indexing: Secure querying of encrypted data
- Input Validation: Comprehensive DTO validation using class-validator
- SQL Injection Prevention: PostgreSQL with TypeORM provides built-in protection
- Automatic Timestamps: All models include
createdAt
andupdatedAt
for audit trails
- Role-Based Authorization: Complete RBAC implementation with guards
- Route Protection: JWT guards on sensitive endpoints
- Admin Controls: Separate endpoints for administrative functions
- Jerry Lucas - Current Maintainer - GitHub
This project is licensed under the MIT License - see the LICENSE file for details.
- Edwin Caminero - Inspiration for this project
- Clean Architecture principles by Robert C. Martin
- Domain-Driven Design concepts by Eric Evans
- CQRS and Event Sourcing patterns
- NestJS framework and community