No description
Find a file
Ulysse Gen fc2db98697 Init
Co-authored-by: Ulysse Gen <ulysse1704@gmail.com>
Co-committed-by: Ulysse Gen <ulysse1704@gmail.com>
2025-10-28 01:44:31 +01:00
docs Init 2025-10-28 01:44:31 +01:00
src Init 2025-10-28 01:44:31 +01:00
.dockerignore Init 2025-10-22 01:27:09 +02:00
.env.example Init 2025-10-28 01:44:31 +01:00
.gitignore Init 2025-10-28 01:44:31 +01:00
ControllerDecorator.md Init 2025-10-28 01:44:31 +01:00
package.json Init 2025-10-28 01:44:31 +01:00
README.md Init 2025-10-22 02:56:47 +02:00
tsconfig.json Init 2025-10-28 01:44:31 +01:00

Base Backend

🚀 Overview

Base Backend is a production-ready Express.js API server designed to power modern web applications. It leverages TypeScript for type safety and includes enterprise-grade features like authentication, database integration, and comprehensive logging.

Module Architecture

This project follows a modular architecture pattern with clear separation of concerns and dependency injection.

Module Structure

Each module in the codebase follows a standard structure:

@{ModuleType}Module/
├── ModuleType.ts          # Main module aggregation file
├── Application/           # Business logic and services
│   └── {Feature}/
│       ├── Services/     # Business logic
│       └── Interfaces/   # Contracts and DTOs
├── Domain/               # Core domain entities
│   └── {Feature}/
│       ├── Entities/     # Domain entities
│       └── Events/       # Domain events
├── Infrastructure/        # External dependencies
│   └── {Feature}/
│       ├── Repositories/ # Data access
│       └── Config/       # Infrastructure config
└── Presentation/          # External interfaces
    └── {Feature}/
        ├── Controllers/  # HTTP controllers
        ├── Routes/       # Route definitions
        └── Middleware/   # HTTP middleware

Current Modules

  • @ConfigModule: Handles configuration management and environment variables
  • @CoreModule: Provides core application functionality (health checks, etc.)

Module Communication

Modules communicate using dependency injection and event-driven patterns:

  1. Service Injection: Modules can inject services from other modules
  2. Event System: Modules can publish and subscribe to events
  3. Interface Contracts: Communication happens through well-defined interfaces

Dependency Injection Rules

Allowed:

  • Injecting services from other modules
  • Publishing and subscribing to events
  • Using interfaces and types

Not Allowed:

  • Direct module-to-module dependencies
  • Accessing repositories from other modules
  • Bypassing service layer for data access
  • Direct database access from other modules

Configuration Management

The ConfigModule provides comprehensive environment variable management:

Basic Usage

import { ReadEnv, MustReadEnv, Config } from '@ConfigModule';

// Read with default value
const port = ReadEnvNumber('PORT', 3000);
const nodeEnv = ReadEnv('NODE_ENV', 'development');

// Read required variables (throws if not set)
const databaseUrl = MustReadEnv('DATABASE_URL', 'default-url-here');
const jwtSecret = MustReadEnv('JWT_SECRET', 'default-secret-here');

// Use the Config helper
const config = Config.get(3000);
console.log(config.port, config.nodeEnv);

Available Functions

Function Description Throws Error
ReadEnv(key, default) Read string with default No
MustReadEnv(key, default) Read required string Yes (if not set or equals default)
ReadEnvNumber(key, default) Read number with default Yes (if not a number)
MustReadEnvNumber(key) Read required number Yes (if not set or not a number)
ReadEnvBoolean(key, default) Read boolean with default No
MustReadEnvBoolean(key) Read required boolean Yes (if not set or not boolean)

Environment Variables

Create a .env file in the project root:

# Application Configuration
PORT=3000
NODE_ENV=development
ENVIRONMENT=development
IS_PRODUCTION=false
IS_DEVELOPMENT=true

# Required Configuration (set these properly)
DATABASE_URL=your-actual-database-url-here
JWT_SECRET=your-actual-jwt-secret-here

TypeScript Path Mapping

The project uses path aliases for cleaner imports:

// Instead of:
import { HealthController } from '../../@CoreModule/Presentation/Health/Controllers/HealthController';

// Use:
import { HealthController } from '@CoreModule/Presentation/Health/Controllers/HealthController';

// Or import the main module:
import { CoreModule } from '@CoreModule';

🛠️ Technology Stack

Express.js | Fast, unopinionated web framework | 4.18+ | 📝 TypeScript | Type-safe JavaScript with strict mode | 5.0+ | Zod | Schema validation with first-class TypeScript support | 3.22+ | 🗃️ TypeORM | Object-relational mapping (ORM) for TypeScript | 0.3+ | 🎯 Kysely | Type-safe SQL query builder | 0.26+ | 🔐 JWT | JSON Web Token authentication | 9.0+ | 📊 Winston | Structured logging | 3.11+ | 🧪 Jest | Testing framework | 29.7+ | 🏗️ ESLint & Prettier | Code quality and formatting | Latest |


🎯 Key Features

🔐 Authentication & Security

  • JWT-based authentication with refresh tokens
  • Role-based access control (RBAC)
  • Password hashing with bcrypt
  • CORS configuration
  • Rate limiting middleware
  • Input validation with Zod schemas

🗃️ Database Integration

  • Type-safe database operations with TypeORM
  • Backup query builder with Kysely
  • Database migrations and seeding
  • Connection pooling
  • Transaction support

📡 API Features

  • RESTful API design with OpenAPI documentation
  • Request/response logging with Winston
  • Comprehensive error handling
  • Health check endpoints
  • Environment-based configuration
  • API versioning support

🧪 Development Experience

  • Dockerized development environment
  • Hot reload during development
  • TypeScript strict mode
  • Comprehensive test suite
  • Code formatting with Prettier
  • Linting with ESLint
  • Pre-commit hooks

📋 Project Structure

This project follows Modular Domain-Driven Design (DDD) and Clean Architecture principles with a bounded context approach:

base-backend/
├── 📁 src/
│   ├── 📁 @AuthenticationModule/    # Authentication Bounded Context
│   │   ├── 📁 Domain/             # Core authentication domain logic
│   │   │   ├── 📁 User/           # User Aggregate
│   │   │   │   ├── 📁 Model/
│   │   │   │   │   ├── UserAggregate.ts           # Main aggregate root
│   │   │   │   │   ├── UserEmailValueObject.ts    # Email value object
│   │   │   │   │   ├── UserPasswordValueObject.ts  # Password value object
│   │   │   │   │   └── UserSessionEntity.ts       # Session entity
│   │   │   │   ├── 📁 Errors/
│   │   │   │   │   ├── UserAggregateError.ts       # User domain errors
│   │   │   │   │   ├── AuthenticationError.ts      # Authentication errors
│   │   │   │   │   └── UserEmailError.ts          # Email validation errors
│   │   │   │   ├── 📁 Events/
│   │   │   │   │   ├── UserRegisteredEvent.ts     # User registration event
│   │   │   │   │   ├── UserLoggedInEvent.ts        # User login event
│   │   │   │   │   └── UserLoggedOutEvent.ts      # User logout event
│   │   │   │   └── 📁 Repository/
│   │   │   │       └── IUserRepository.ts         # User repository interface
│   │   │   │
│   │   │   ├── 📁 Token/          # Token Aggregate
│   │   │   │   ├── 📁 Model/
│   │   │   │   │   ├── TokenAggregate.ts           # Token aggregate root
│   │   │   │   │   ├── AccessTokenValueObject.ts   # Access token value object
│   │   │   │   │   └── RefreshTokenValueObject.ts # Refresh token value object
│   │   │   │   ├── 📁 Errors/
│   │   │   │   │   └── TokenAggregateError.ts      # Token domain errors
│   │   │   │   ├── 📁 Events/
│   │   │   │   │   ├── TokenGeneratedEvent.ts      # Token generation event
│   │   │   │   │   └── TokenRefreshedEvent.ts      # Token refresh event
│   │   │   │   └── 📁 Repository/
│   │   │   │       └── ITokenRepository.ts         # Token repository interface
│   │   │   │
│   │   ├── 📁 Application/        # Authentication use cases
│   │   │   ├── 📁 User/
│   │   │   │   ├── 📁 Commands/
│   │   │   │   │   ├── RegisterUserCommand.ts      # Register user command
│   │   │   │   │   ├── LoginUserCommand.ts         # Login user command
│   │   │   │   │   └── LogoutUserCommand.ts        # Logout user command
│   │   │   │   ├── 📁 Queries/
│   │   │   │   │   ├── GetUserQuery.ts             # Get user query
│   │   │   │   │   └── ValidateUserQuery.ts        # Validate user query
│   │   │   │   ├── 📁 Listeners/
│   │   │   │   │   ├── UserRegisteredListener.ts   # User registration listener
│   │   │   │   │   └── UserLoggedInListener.ts      # User login listener
│   │   │   │   └── 📁 Services/
│   │   │   │       ├── AuthenticationService.ts    # Auth service
│   │   │   │       └── AuthenticationEventHandler.ts # Auth event handler
│   │   │   │
│   │   ├── 📁 Infrastructure/     # Authentication implementation
│   │   │   ├── 📁 User/
│   │   │   │   ├── 📁 Repositories/
│   │   │   │   │   ├── UserPostgresRepository.ts   # PostgreSQL implementation
│   │   │   │   │   ├── UserRedisRepository.ts      # Redis implementation
│   │   │   │   │   └── UserSqliteRepository.ts     # SQLite implementation
│   │   │   │   └── 📁 Daos/
│   │   │   │       ├── UserPostgresDao.ts          # PostgreSQL DAO
│   │   │   │       ├── UserRedisDao.ts             # Redis DAO
│   │   │   │       └── UserSqliteDao.ts           # SQLite DAO
│   │   │   │
│   │   │   ├── 📁 Token/
│   │   │   │   ├── 📁 Repositories/
│   │   │   │   │   ├── TokenPostgresRepository.ts  # PostgreSQL implementation
│   │   │   │   │   ├── TokenRedisRepository.ts     # Redis implementation
│   │   │   │   │   └── TokenSqliteRepository.ts    # SQLite implementation
│   │   │   │   └── 📁 Daos/
│   │   │   │       ├── TokenPostgresDao.ts         # PostgreSQL DAO
│   │   │   │       ├── TokenRedisDao.ts            # Redis DAO
│   │   │   │       └── TokenSqliteDao.ts          # SQLite DAO
│   │   │   │
│   │   │   └── 📁 External/
│   │   │       ├── 📁 JWT/
│   │   │       │   ├── JWTService.ts               # JWT service implementation
│   │   │       │   └── JWTValidator.ts             # JWT validator
│   │   │       └── 📁 BCrypt/
│   │   │           ├── PasswordHasher.ts            # Password hashing service
│   │   │           └── PasswordValidator.ts         # Password validation service
│   │   │
│   │   └── 📁 Presentation/      # Authentication API
│   │       ├── 📁 User/
│   │       │   ├── 📁 Controllers/
│   │       │   │   ├── UserHttpController.ts       # User HTTP controller
│   │       │   │   ├── UserController.ts            # User controller
│   │       │   │   └── UserController.ts            # Alternative user controller
│   │       │   └── 📁 Validators/
│   │       │       ├── UserValidator.ts            # User request validator
│   │       │       ├── RegisterUserValidator.ts    # Registration validator
│   │       │       └── LoginUserValidator.ts       # Login validator
│   │       │
│   │       └── 📁 Token/
│   │           ├── 📁 Controllers/
│   │           │   ├── TokenHttpController.ts       # Token HTTP controller
│   │           │   └── TokenController.ts           # Token controller
│   │           └── 📁 Validators/
│   │               ├── TokenValidator.ts            # Token request validator
│   │               └── RefreshTokenValidator.ts    # Refresh token validator
│   │
│   ├── 📁 @AuthorizationModule/   # Authorization Bounded Context
│   │   ├── 📁 Domain/             # Roles, Permissions, Policies
│   │   ├── 📁 Application/        # Permission checking use cases
│   │   ├── 📁 Infrastructure/     # Role management implementation
│   │   └── 📁 Presentation/      # Authorization API endpoints
│   │
│   ├── 📁 @UserModule/           # User Management Bounded Context
│   │   ├── 📁 Domain/             # User profile, settings domain
│   │   ├── 📁 Application/        # User management use cases
│   │   ├── 📁 Infrastructure/     # User storage implementation
│   │   └── 📁 Presentation/      # User CRUD API
│   │
│   └── 📁 @CoreModule/           # Core/Shared Bounded Context
│       ├── 📁 Domain/             # Shared domain entities
│       ├── 📁 Application/        # Shared application services
│       ├── 📁 Infrastructure/     # Database, logging, caching
│       └── 📁 Presentation/      # Shared controllers, middleware
│
│   ├── 📁 @PostgresModule/        # PostgreSQL Infrastructure Module
│   │   ├── 📁 Domain/             # PostgreSQL-specific domain concepts
│   │   │   ├── 📁 Connection/     # Connection aggregates
│   │   │   │   ├── 📁 Model/
│   │   │   │   │   ├── PostgresConnectionAggregate.ts
│   │   │   │   │   ├── ConnectionStringValueObject.ts
│   │   │   │   │   └── DatabaseConfigEntity.ts
│   │   │   │   ├── 📁 Errors/
│   │   │   │   │   ├── ConnectionError.ts
│   │   │   │   │   └── PoolExhaustedError.ts
│   │   │   │   ├── 📁 Events/
│   │   │   │   │   ├── ConnectionEstablishedEvent.ts
│   │   │   │   │   └── ConnectionClosedEvent.ts
│   │   │   │   └── 📁 Repository/
│   │   │   │       └── IPostgresConnectionRepository.ts
│   │   │   ├── 📁 Migration/     # Migration aggregates
│   │   │   │   ├── 📁 Model/
│   │   │   │   │   ├── MigrationAggregate.ts
│   │   │   │   │   ├── MigrationVersionValueObject.ts
│   │   │   │   │   └── MigrationScriptEntity.ts
│   │   │   │   ├── 📁 Errors/
│   │   │   │   │   └── MigrationError.ts
│   │   │   │   ├── 📁 Events/
│   │   │   │   │   ├── MigrationAppliedEvent.ts
│   │   │   │   │   └── MigrationRolledBackEvent.ts
│   │   │   │   └── 📁 Repository/
│   │   │   │       └── IMigrationRepository.ts
│   │   │   └── 📁 Schema/        # Schema aggregates
│   │   │       ├── 📁 Model/
│   │   │       │   ├── SchemaAggregate.ts
│   │   │       │   ├── TableEntity.ts
│   │   │       │   └── IndexEntity.ts
│   │   │       ├── 📁 Errors/
│   │   │       │   └── SchemaError.ts
│   │   │       └── 📁 Events/
│   │   │           ├── SchemaCreatedEvent.ts
│   │   │           └── SchemaUpdatedEvent.ts
│   │   ├── 📁 Application/        # PostgreSQL use cases
│   │   │   ├── 📁 Connection/
│   │   │   │   ├── 📁 Commands/
│   │   │   │   │   ├── CreateConnectionCommand.ts
│   │   │   │   │   ├── TestConnectionCommand.ts
│   │   │   │   │   └── CloseConnectionCommand.ts
│   │   │   │   ├── 📁 Queries/
│   │   │   │   │   ├── GetConnectionStatusQuery.ts
│   │   │   │   │   └── GetConnectionMetricsQuery.ts
│   │   │   │   └── 📁 Services/
│   │   │   │       ├── ConnectionPoolService.ts
│   │   │   │       └── ConnectionHealthService.ts
│   │   │   ├── 📁 Migration/
│   │   │   │   ├── 📁 Commands/
│   │   │   │   │   ├── RunMigrationCommand.ts
│   │   │   │   │   ├── RollbackMigrationCommand.ts
│   │   │   │   │   └── CreateMigrationCommand.ts
│   │   │   │   ├── 📁 Queries/
│   │   │   │   │   ├── GetMigrationStatusQuery.ts
│   │   │   │   │   └── GetMigrationHistoryQuery.ts
│   │   │   │   └── 📁 Services/
│   │   │   │       ├── MigrationService.ts
│   │   │   │       └── SchemaValidationService.ts
│   │   │   └── 📁 Schema/
│   │   │       ├── 📁 Commands/
│   │   │       │   ├── CreateSchemaCommand.ts
│   │   │       │   └── UpdateSchemaCommand.ts
│   │   │       ├── 📁 Queries/
│   │   │       │   ├── GetSchemaInfoQuery.ts
│   │   │       │   └── ValidateSchemaQuery.ts
│   │   │       └── 📁 Services/
│   │   │           ├── SchemaBuilderService.ts
│   │   │           └── SchemaAnalyzerService.ts
│   │   ├── 📁 Infrastructure/     # PostgreSQL implementation
│   │   │   ├── 📁 Connection/
│   │   │   │   ├── 📁 Repositories/
│   │   │   │   │   └── PostgresConnectionRepository.ts
│   │   │   │   └── 📁 Daos/
│   │   │   │       ├── PostgresConnectionDao.ts
│   │   │   │       └── PostgresPoolDao.ts
│   │   │   ├── 📁 Migration/
│   │   │   │   ├── 📁 Repositories/
│   │   │   │   │   └── PostgresMigrationRepository.ts
│   │   │   │   └── 📁 Daos/
│   │   │   │       ├── PostgresMigrationDao.ts
│   │   │   │       └── PostgresSchemaDao.ts
│   │   │   └── 📁 External/
│   │   │       ├── 📁 TypeORM/
│   │   │       │   ├── PostgresTypeORMService.ts
│   │   │       │   └── PostgresTypeORMConfig.ts
│   │   │       ├── 📁 PG/
│   │   │       │   ├── NativePGService.ts
│   │   │       │   └── NativePGConfig.ts
│   │   │       └── 📁 Kysely/
│   │   │           ├── PostgresKyselyService.ts
│   │   │           └── PostgresKyselyConfig.ts
│   │   └── 📁 Presentation/      # PostgreSQL API
│   │       ├── 📁 Controllers/
│   │       │   ├── ConnectionController.ts
│   │       │   ├── MigrationController.ts
│   │       │   └── SchemaController.ts
│   │       └── 📁 Validators/
│   │           ├── ConnectionValidator.ts
│   │           ├── MigrationValidator.ts
│   │           └── SchemaValidator.ts
│   │
│   ├── 📁 @SqliteModule/         # SQLite Infrastructure Module
│   │   ├── 📁 Domain/             # SQLite-specific domain concepts
│   │   │   ├── 📁 Database/        # Database aggregates
│   │   │   │   ├── 📁 Model/
│   │   │   │   │   ├── SQLiteDatabaseAggregate.ts
│   │   │   │   │   ├── DatabasePathValueObject.ts
│   │   │   │   │   └── DatabaseConfigEntity.ts
│   │   │   │   ├── 📁 Errors/
│   │   │   │   │   ├── DatabaseError.ts
│   │   │   │   │   └── DatabaseLockedError.ts
│   │   │   │   ├── 📁 Events/
│   │   │   │   │   ├── DatabaseCreatedEvent.ts
│   │   │   │   │   └── DatabaseBackupEvent.ts
│   │   │   │   └── 📁 Repository/
│   │   │   │       └── ISqliteDatabaseRepository.ts
│   │   │   └── 📁 Query/          # Query aggregates
│   │   │       ├── 📁 Model/
│   │   │       │   ├── SqliteQueryAggregate.ts
│   │   │       │   ├── QueryPlanValueObject.ts
│   │   │       │   └── QueryResultEntity.ts
│   │   │       ├── 📁 Errors/
│   │   │       │   ├── QueryError.ts
│   │   │       │   └── QueryTimeoutError.ts
│   │   │       └── 📁 Events/
│   │   │           ├── QueryExecutedEvent.ts
│   │   │           └── QueryOptimizedEvent.ts
│   │   ├── 📁 Application/        # SQLite use cases
│   │   │   ├── 📁 Database/
│   │   │   │   ├── 📁 Commands/
│   │   │   │   │   ├── CreateDatabaseCommand.ts
│   │   │   │   │   ├── BackupDatabaseCommand.ts
│   │   │   │   │   └── VacuumDatabaseCommand.ts
│   │   │   │   ├── 📁 Queries/
│   │   │   │   │   ├── GetDatabaseInfoQuery.ts
│   │   │   │   │   └── GetDatabaseStatusQuery.ts
│   │   │   │   └── 📁 Services/
│   │   │   │       ├── DatabaseManagementService.ts
│   │   │   │       └── DatabaseBackupService.ts
│   │   │   └── 📁 Query/
│   │   │       ├── 📁 Commands/
│   │   │       │   ├── ExecuteQueryCommand.ts
│   │   │       │   └── OptimizeQueryCommand.ts
│   │   │       ├── 📁 Queries/
│   │   │       │   ├── GetQueryPlanQuery.ts
│   │   │       │   └── GetQueryPerformanceQuery.ts
│   │   │       └── 📁 Services/
│   │   │           ├── QueryOptimizationService.ts
│   │   │           └── QueryAnalysisService.ts
│   │   ├── 📁 Infrastructure/     # SQLite implementation
│   │   │   ├── 📁 Database/
│   │   │   │   ├── 📁 Repositories/
│   │   │   │   │   └── SqliteDatabaseRepository.ts
│   │   │   │   └── 📁 Daos/
│   │   │   │       ├── SqliteDatabaseDao.ts
│   │   │   │       └── SqliteBackupDao.ts
│   │   │   └── 📁 External/
│   │   │       ├── 📁 SQLite3/
│   │   │       │   ├── NativeSQLiteService.ts
│   │   │       │   └── SQLiteConfig.ts
│   │   │       ├── 📁 BetterSQLite/
│   │   │       │   ├── BetterSQLiteService.ts
│   │   │       │   └── BetterSQLiteConfig.ts
│   │   │       └── 📁 Kysely/
│   │   │           ├── SQLiteKyselyService.ts
│   │   │           └── SQLiteKyselyConfig.ts
│   │   └── 📁 Presentation/      # SQLite API
│   │       ├── 📁 Controllers/
│   │       │   ├── DatabaseController.ts
│   │       │   ├── QueryController.ts
│   │       │   └── BackupController.ts
│   │       └── 📁 Validators/
│   │           ├── DatabaseValidator.ts
│   │           ├── QueryValidator.ts
│   │           └── BackupValidator.ts
│   │
│   ├── 📁 @RedisModule/          # Redis Infrastructure Module
│   │   ├── 📁 Domain/             # Redis-specific domain concepts
│   │   │   ├── 📁 Cache/          # Cache aggregates
│   │   │   │   ├── 📁 Model/
│   │   │   │   │   ├── RedisCacheAggregate.ts
│   │   │   │   │   ├── CacheKeyValueObject.ts
│   │   │   │   │   ├── CacheTTLValueObject.ts
│   │   │   │   │   └── CacheEntryEntity.ts
│   │   │   │   ├── 📁 Errors/
│   │   │   │   │   ├── CacheError.ts
│   │   │   │   │   ├── CacheMissError.ts
│   │   │   │   │   └── CacheTimeoutError.ts
│   │   │   │   ├── 📁 Events/
│   │   │   │   │   ├── CacheHitEvent.ts
│   │   │   │   │   ├── CacheMissEvent.ts
│   │   │   │   │   ├── CacheSetEvent.ts
│   │   │   │   │   └── CacheEvictEvent.ts
│   │   │   │   └── 📁 Repository/
│   │   │   │       └── IRedisCacheRepository.ts
│   │   │   ├── 📁 PubSub/         # Pub/Sub aggregates
│   │   │   │   ├── 📁 Model/
│   │   │   │   │   ├── RedisPubSubAggregate.ts
│   │   │   │   │   ├── ChannelValueObject.ts
│   │   │   │   │   ├── MessageEntity.ts
│   │   │   │   │   └── SubscriptionEntity.ts
│   │   │   │   ├── 📁 Errors/
│   │   │   │   │   ├── PubSubError.ts
│   │   │   │   │   └── SubscriptionError.ts
│   │   │   │   ├── 📁 Events/
│   │   │   │   │   ├── MessagePublishedEvent.ts
│   │   │   │   │   ├── MessageReceivedEvent.ts
│   │   │   │   │   └── SubscribedEvent.ts
│   │   │   │   └── 📁 Repository/
│   │   │   │       └── IRedisPubSubRepository.ts
│   │   │   └── 📁 Cluster/        # Cluster aggregates
│   │   │       ├── 📁 Model/
│   │   │       │   ├── RedisClusterAggregate.ts
│   │   │       │   ├── ClusterNodeEntity.ts
│   │   │       │   ├── ClusterSlotValueObject.ts
│   │   │       │   └── ClusterConfigEntity.ts
│   │   │       ├── 📁 Errors/
│   │   │       │   ├── ClusterError.ts
│   │   │       │   └── ClusterNodeError.ts
│   │   │       ├── 📁 Events/
│   │   │       │   ├── ClusterConnectedEvent.ts
│   │   │       │   ├── ClusterFailoverEvent.ts
│   │   │       │   └── ClusterNodeJoinedEvent.ts
│   │   │       └── 📁 Repository/
│   │   │           └── IRedisClusterRepository.ts
│   │   ├── 📁 Application/        # Redis use cases
│   │   │   ├── 📁 Cache/
│   │   │   │   ├── 📁 Commands/
│   │   │   │   │   ├── SetCacheCommand.ts
│   │   │   │   │   ├── GetCacheCommand.ts
│   │   │   │   │   ├── DeleteCacheCommand.ts
│   │   │   │   │   ├── ClearCacheCommand.ts
│   │   │   │   │   └── CacheIncrementCommand.ts
│   │   │   │   ├── 📁 Queries/
│   │   │   │   │   ├── GetCacheInfoQuery.ts
│   │   │   │   │   └── GetCacheStatsQuery.ts
│   │   │   │   └── 📁 Services/
│   │   │   │       ├── CacheManagementService.ts
│   │   │   │       └── CacheEvictionService.ts
│   │   │   ├── 📁 PubSub/
│   │   │   │   ├── 📁 Commands/
│   │   │   │   │   ├── PublishCommand.ts
│   │   │   │   │   ├── SubscribeCommand.ts
│   │   │   │   │   └── UnsubscribeCommand.ts
│   │   │   │   ├── 📁 Queries/
│   │   │   │   │   ├── GetSubscriptionsQuery.ts
│   │   │   │   │   └── GetChannelInfoQuery.ts
│   │   │   │   └── 📁 Services/
│   │   │   │       ├── PubSubService.ts
│   │   │   │       └── MessageHandlerService.ts
│   │   │   └── 📁 Cluster/
│   │   │       ├── 📁 Commands/
│   │   │       │   ├── ConnectClusterCommand.ts
│   │   │       │   ├── AddClusterNodeCommand.ts
│   │   │       │   └── RemoveClusterNodeCommand.ts
│   │   │       ├── 📁 Queries/
│   │   │       │   ├── GetClusterInfoQuery.ts
│   │   │       │   └── GetClusterStatusQuery.ts
│   │   │       └── 📁 Services/
│   │   │           ├── ClusterManagementService.ts
│   │   │           └── ClusterHealthService.ts
│   │   ├── 📁 Infrastructure/     # Redis implementation
│   │   │   ├── 📁 Cache/
│   │   │   │   ├── 📁 Repositories/
│   │   │   │   │   └── RedisCacheRepository.ts
│   │   │   │   └── 📁 Daos/
│   │   │   │       ├── RedisCacheDao.ts
│   │   │   │       └── RedisCacheClusterDao.ts
│   │   │   ├── 📁 PubSub/
│   │   │   │   ├── 📁 Repositories/
│   │   │   │   │   └── RedisPubSubRepository.ts
│   │   │   │   └── 📁 Daos/
│   │   │   │       ├── RedisPubSubDao.ts
│   │   │   │       └── RedisPubSubClusterDao.ts
│   │   │   └── 📁 External/
│   │   │       ├── 📁 ioredis/
│   │   │       │   ├── IoRedisService.ts
│   │   │       │   └── IoRedisConfig.ts
│   │   │       ├── 📁 redis/
│   │   │       │   ├── NodeRedisService.ts
│   │   │       │   └── NodeRedisConfig.ts
│   │   │       └── 📁 upstash/
│   │   │           ├── UpstashRedisService.ts
│   │   │           └── UpstashRedisConfig.ts
│   │   └── 📁 Presentation/      # Redis API
│   │       ├── 📁 Controllers/
│   │       │   ├── CacheController.ts
│   │       │   ├── PubSubController.ts
│   │       │   └── ClusterController.ts
│   │       └── 📁 Validators/
│   │           ├── CacheValidator.ts
│   │           ├── PubSubValidator.ts
│   │           └── ClusterValidator.ts
│
├── 📁 tests/                     # Test files organized by module
│   └── Unknown yet
│
├── 📄 package.json
├── 📄 tsconfig.json              # TypeScript configuration
├── 📄 jest.config.js             # Jest configuration
├── 📄 .env.example               # Environment variables template
├── 📄 .env.dev                   # Environment variables for development
├── 📄 Dockerfile                 # Dockerfile
├── 📄 Dockerfile.dev             # Dockerfile for development
├── 📄 docker-compose.yml         # Docker Compose configuration
├── 📄 docker-compose.dev.yml     # Docker Compose configuration for development
└── 📄 README.md                  # This file

Module Architecture Pattern

Each module follows Aggregate-Driven DDD with hexagonal architecture principles:

🔒 Module Structure (per Bounded Context)

@ModuleName/
├── 📁 Domain/           # Domain Layer - Business Logic & Rules
│   ├── 📁 Aggregate1/   # Aggregate 1 (e.g., User)
│   │   ├── 📁 Model/     # Domain model components
│   │   │   ├── Aggregate1Aggregate.ts     # Main aggregate root
│   │   │   ├── ValueObject1.ts            # Value objects
│   │   │   ├── ValueObject2.ts            # Value objects
│   │   │   └── Entity1.ts                 # Entities within aggregate
│   │   ├── 📁 Errors/   # Domain-specific errors
│   │   │   ├── Aggregate1Error.ts         # Aggregate errors
│   │   │   └── Aggregate1DomainError.ts  # Domain errors
│   │   ├── 📁 Events/   # Domain events
│   │   │   ├── Aggregate1CreatedEvent.ts  # Domain events
│   │   │   └── Aggregate1UpdatedEvent.ts  # Domain events
│   │   └── 📁 Repository/ # Repository interfaces
│   │       └── IAggregate1Repository.ts   # Repository interface
│   │
│   ├── 📁 Aggregate2/   # Aggregate 2 (e.g., Token)
│   │   ├── 📁 Model/
│   │   ├── 📁 Errors/
│   │   ├── 📁 Events/
│   │   └── 📁 Repository/
│   │
├── 📁 Application/       # Application Layer - Use Cases
│   ├── 📁 Aggregate1/   # Aggregate 1 use cases
│   │   ├── 📁 Commands/  # Commands (CQRS)
│   │   │   ├── CreateAggregate1Command.ts    # Create command
│   │   │   ├── UpdateAggregate1Command.ts    # Update command
│   │   │   └── DeleteAggregate1Command.ts    # Delete command
│   │   ├── 📁 Queries/   # Queries (CQRS)
│   │   │   ├── GetAggregate1Query.ts         # Get query
│   │   │   ├── ListAggregate1Query.ts        # List query
│   │   │   └── SearchAggregate1Query.ts      # Search query
│   │   ├── 📁 Listeners/# Event listeners
│   │   │   ├── Aggregate1CreatedListener.ts # Event listener
│   │   │   └── Aggregate1UpdatedListener.ts # Event listener
│   │   └── 📁 Services/ # Application services
│   │       ├── Aggregate1Service.ts         # Application service
│   │       └── Aggregate1EventHandler.ts    # Event handler
│   │
│   ├── 📁 Aggregate2/   # Aggregate 2 use cases
│   │   ├── 📁 Commands/
│   │   ├── 📁 Queries/
│   │   ├── 📁 Listeners/
│   │   └── 📁 Services/
│   │
├── 📁 Infrastructure/    # Infrastructure Layer - Implementation
│   ├── 📁 Aggregate1/   # Aggregate 1 implementations
│   │   ├── 📁 Repositories/ # Multiple storage implementations
│   │   │   ├── Aggregate1PostgresRepository.ts # PostgreSQL
│   │   │   ├── Aggregate1RedisRepository.ts    # Redis
│   │   │   └── Aggregate1SqliteRepository.ts   # SQLite
│   │   └── 📁 Daos/      # Data Access Objects
│   │       ├── Aggregate1PostgresDao.ts       # PostgreSQL DAO
│   │       ├── Aggregate1RedisDao.ts          # Redis DAO
│   │       └── Aggregate1SqliteDao.ts       # SQLite DAO
│   │
│   ├── 📁 Aggregate2/   # Aggregate 2 implementations
│   │   ├── 📁 Repositories/
│   │   └── 📁 Daos/
│   │
│   └── 📁 External/     # External service implementations
│       ├── 📁 Service1/ # External service 1
│       │   ├── Service1Implementation.ts     # Implementation
│       │   └── Service1Validator.ts         # Validator
│       └── 📁 Service2/ # External service 2
│           ├── Service2Implementation.ts     # Implementation
│           └── Service2Validator.ts         # Validator
│
└── 📁 Presentation/      # Presentation Layer - API
    ├── 📁 Aggregate1/   # Aggregate 1 API endpoints
    │   ├── 📁 Controllers/
    │   │   ├── Aggregate1HttpController.ts   # HTTP controller
    │   │   ├── Aggregate1Controller.ts        # REST controller
    │   │   └── Aggregate1GraphQLController.ts # GraphQL controller
    │   └── 📁 Validators/
    │       ├── Aggregate1Validator.ts         # Request validator
    │       ├── CreateAggregate1Validator.ts   # Create validator
    │       └── UpdateAggregate1Validator.ts   # Update validator
    │
    ├── 📁 Aggregate2/   # Aggregate 2 API endpoints
    │   ├── 📁 Controllers/
    │   └── 📁 Validators/
    │
    └── 📁 Shared/       # Shared presentation components
        ├── 📁 Middleware/ # Module middleware
        ├── 📁 Decorators/ # Custom decorators
        └── 📁 Types/      # Presentation types

Key Benefits

Bounded Contexts

  • Each module represents a specific business domain
  • Clear ownership and responsibility boundaries
  • Independent development and deployment

🔗 Cross-Module Communication

  • Domain events for loose coupling
  • Shared kernel for common domain concepts
  • Anti-corruption layers where needed

🎯 Separation of Concerns

  • Domain purity - no framework dependencies
  • Clean interfaces between layers
  • Testable components with clear contracts

📦 Modularity

  • Feature-flag ready modules
  • Independent versioning possible
  • Easy replacement of implementations

🚀 Quick Start

Prerequisites

  • Node.js 22+
  • npm 11+

Installation

# Install dependencies
npm install

# Copy environment variables
cp .env.example .env.dev

# Start development server
npm run dev

Available Scripts

# Development
npm run dev          # Start development server with hot reload
npm run dev:debug    # Start development server with debug mode

# Testing
npm run test         # Run tests
npm run test:coverage # Run tests with coverage report

# Database
npm run migrate      # Run database migrations
npm run seed         # Seed database with initial data
npm run migrate:undo # Rollback last migration

# Build & Production
npm run build        # Build TypeScript files
npm run start        # Start production server
npm run start:debug  # Start production server with debug mode

# Code Quality
npm run lint         # Run ESLint
npm run lint:fix     # Fix ESLint issues
npm run format       # Format code with Prettier

🔧 Configuration

Environment Variables

# Application
NODE_ENV=development          # Environment (development/production/test)
PORT=3001                     # Server port
API_VERSION=v1               # API version
BASE_URL=http://localhost:3000/api # Base URL (your domain for production)

# Database
DB_TYPE=postgres             # Database type (postgres/mysql/sqlite)
DB_HOST=localhost            # Database host
DB_PORT=5432                 # Database port
DB_USERNAME=postgres         # Database username
DB_PASSWORD=password         # Database password
DB_DATABASE=base_backend     # Database name

# JWT
JWT_SECRET=your-secret-key   # JWT secret key
JWT_EXPIRES_IN=7d            # Token expiration
JWT_REFRESH_SECRET=refresh-secret # Refresh token secret
JWT_REFRESH_EXPIRES_IN=30d    # Refresh token expiration

# Security
BCRYPT_ROUNDS=12             # Bcrypt salt rounds
RATE_LIMIT_WINDOW=15         # Rate limit window (minutes)
RATE_LIMIT_MAX=100           # Rate limit max requests

# Logging
LOG_LEVEL=info               # Log level (debug/info/warn/error)
LOG_DIR=logs                 # Log directory

📚 API Documentation

Base URL

  • Development: http://localhost:3001/api/v1
  • Production: https://your-api-domain.com/api/v1

Authentication

Most endpoints require authentication. Include the JWT token in the Authorization header:

Authorization: Bearer <your-jwt-token>

Key Endpoints

Authentication

  • POST /auth/login - User login
  • POST /auth/register - User registration
  • POST /auth/refresh - Refresh JWT token
  • POST /auth/logout - User logout

Users

  • GET /users - Get all users
  • GET /users/:id - Get user by ID
  • PUT /users/:id - Update user profile
  • DELETE /users/:id - Delete user

Health Check

  • GET /health - Application health status

🧪 Testing

The project uses Jest for testing with comprehensive test coverage:

# Run all tests
npm test

# Run tests with coverage
npm run test:coverage

# Run specific test file
npm test -- auth.test.ts

Test Structure

Not yet defined

🚀 Deployment

Production Setup

  1. Environment Configuration

    cp .env.example .env
    # Configure production settings
    
  2. Build Application

    npm run build
    
  3. Database Setup

    npm run migrate
    npm run seed
    
  4. Start Production Server

    npm run start
    

Docker Deployment

# Build Docker image
docker build -t base-backend .

Environment Variables for Production

  • Set NODE_ENV=production
  • Use secure JWT secrets
  • Configure production database
  • Set appropriate log levels

🔒 Security Best Practices

  • Input Validation: All inputs validated with Zod schemas
  • SQL Injection Prevention: Parameterized queries with TypeORM
  • XSS Protection: Sanitization middleware
  • Rate Limiting: API endpoint protection
  • CORS: Proper cross-origin configuration
  • Helmet: Security headers middleware
  • Environment Variables: Sensitive data not hardcoded