nestjs-ddd-cli
Version:
CLI for generating NestJS DDD boilerplate code
459 lines (366 loc) โข 16.9 kB
Markdown
# NestJS DDD CLI
๐๏ธ **An opinionated CLI for pragmatic Domain-Driven Design with NestJS**
Stop writing boilerplate. Start building business logic.
Generate production-ready NestJS code following proven DDD/CQRS patterns with consistent structure and immutable architecture principles.
## Installation
**From NPM (Recommended):**
```bash
npm install -g nestjs-ddd-cli
```
**From Source:**
```bash
git clone https://github.com/eshe-huli/nestjs-ddd-cli
cd nestjs-ddd-cli
npm install
npm run build
npm link
```
## Usage
### Generate Complete Scaffolding
Generate all files for a new entity (entity, repository, mapper, use cases, controller, etc.):
```bash
ddd scaffold Product -m inventory
```
### Generate Individual Components
```bash
# Generate a module
ddd generate module user-management
# Generate an entity
ddd generate entity User -m user-management
# Generate a use case
ddd generate usecase CreateUser -m user-management
# Generate a domain service
ddd generate service UserValidation -m user-management
# Generate a domain event
ddd generate event UserCreated -m user-management
# Generate a query handler
ddd generate query GetUser -m user-management
# Generate everything for an entity within existing module
ddd generate all User -m user-management
```
### Options
- `-m, --module <name>`: Specify the module name
- `-p, --path <path>`: Base path for generation (defaults to current directory)
- `--skip-orm`: Skip ORM entity generation
- `--skip-mapper`: Skip mapper generation
- `--skip-repo`: Skip repository generation
- `--with-events`: Include domain events
- `--with-queries`: Include query handlers
## Available Generators
| Generator | Command | Description |
|-----------|---------|-------------|
| **Module** | `ddd generate module <name>` | Creates complete DDD module structure |
| **Entity** | `ddd generate entity <name> -m <module>` | Domain entity with ORM mapping |
| **Use Case** | `ddd generate usecase <name> -m <module>` | CQRS command handler |
| **Domain Service** | `ddd generate service <name> -m <module>` | Domain service for business logic |
| **Domain Event** | `ddd generate event <name> -m <module>` | Domain event for CQRS |
| **Query Handler** | `ddd generate query <name> -m <module>` | CQRS query handler |
| **Complete CRUD** | `ddd scaffold <name> -m <module>` | All files for an entity |
| **All Entity Files** | `ddd generate all <name> -m <module>` | Entity + related files |
## Quick Start
### ๐ **Generate Your First Feature**
```bash
# 1. Create complete scaffolding for a User management feature
ddd scaffold User -m user-management
# 2. Add business logic to the generated files
# 3. Update index.ts exports
# 4. Run migrations
# 5. Import module in app.module.ts
```
**What you get in seconds:**
```
๐ modules/user-management/
โโโ ๐ user-management.module.ts โ
NestJS module configured
โโโ ๐ application/
โ โโโ ๐ controllers/
โ โ โโโ ๐ user.controller.ts โ
REST endpoints (GET, POST, PUT, DELETE)
โ โโโ ๐ domain/
โ โ โโโ ๐ entities/
โ โ โ โโโ ๐ user.entity.ts โ
Domain entity with interfaces
โ โ โโโ ๐ usecases/
โ โ โโโ ๐ create-user.usecase.ts โ
Business logic for creation
โ โ โโโ ๐ update-user.usecase.ts โ
Business logic for updates
โ โ โโโ ๐ delete-user.usecase.ts โ
Business logic for deletion
โ โโโ ๐ dto/
โ โโโ ๐ requests/
โ โ โโโ ๐ create-user.dto.ts โ
Request validation schemas
โ โ โโโ ๐ update-user.dto.ts โ
Update validation schemas
โ โโโ ๐ responses/
โ โโโ ๐ user.response.ts โ
Response data contracts
โโโ ๐ infrastructure/
โโโ ๐ repositories/
โ โโโ ๐ user.repository.ts โ
CRUD operations + custom queries
โโโ ๐ orm-entities/
โ โโโ ๐ user.orm-entity.ts โ
Database schema (TypeORM)
โโโ ๐ mappers/
โโโ ๐ user.mapper.ts โ
Domain โ Database mapping
```
> **๐ From zero to production-ready in under 30 seconds**
## Real-World Examples
### ๐ข **E-commerce Platform**
```bash
# Generate order management
ddd scaffold Order -m orders
# Add payment processing
ddd generate service PaymentProcessor -m orders
ddd generate event OrderPaid -m orders
# Add inventory checking
ddd generate query CheckStock -m inventory
ddd generate service StockValidator -m inventory
```
**Result:** Complete order system with payment processing and inventory management
```
๐ modules/orders/
โโโ ๐ orders.module.ts
โโโ ๐ application/domain/services/
โ โโโ ๐ payment-processor.service.ts ๐ Payment business logic
โโโ ๐ application/domain/events/
โ โโโ ๐ order-paid.event.ts ๐ Order payment event
โโโ ... (all CRUD operations)
๐ modules/inventory/
โโโ ๐ application/queries/
โ โโโ ๐ check-stock.handler.ts ๐ Stock checking query
โโโ ๐ application/domain/services/
โ โโโ ๐ stock-validator.service.ts ๐ Stock validation logic
โโโ ... (all CRUD operations)
```
### ๐ฅ **Healthcare System**
```bash
# Patient management
ddd scaffold Patient -m patients
# Medical records with events
ddd scaffold MedicalRecord -m medical-records
ddd generate event RecordCreated -m medical-records
ddd generate event RecordUpdated -m medical-records
# Appointment scheduling
ddd generate query FindAvailableSlots -m appointments
ddd generate service AppointmentScheduler -m appointments
```
### ๐ **Learning Management System**
```bash
# Course management
ddd scaffold Course -m courses
ddd generate service CourseEnrollment -m courses
ddd generate event StudentEnrolled -m courses
# Progress tracking
ddd generate query GetStudentProgress -m progress
ddd generate service ProgressCalculator -m progress
```
> **๐ฏ Each example follows identical patterns** - Learn once, apply everywhere.
## Philosophy & Principles
This CLI embodies **pragmatic Domain-Driven Design** with unwavering consistency:
### ๐ **Immutable Architecture**
- **"Code once, never touch"** - Each generated component remains unchanged after creation
- **Evolution over modification** - New requirements create new use cases, never modify existing ones
- **Predictable structure** - Every project follows identical patterns, enabling instant developer onboarding
### ๐ฏ **Opinionated by Design**
- **Zero configuration fatigue** - One way to do things, the right way
- **Consistent naming** - PascalCase entities, kebab-case modules, predictable file names
- **Proven patterns** - Battle-tested DDD/CQRS structure from real-world enterprise applications
### ๐ **Developer Experience First**
- **No bikeshedding** - Spend time on business logic, not folder structure debates
- **IDE-friendly** - Barrel exports, clear interfaces, TypeScript-first approach
- **Team consistency** - Every developer generates identical code structure
### ๐๏ธ **Enterprise Ready**
- **Separation of concerns** - Domain logic isolated from infrastructure
- **CQRS compliance** - Commands for writes, queries for reads
- **Testable by default** - Clean interfaces enable easy unit testing
## What Makes This Different?
### ๐จ **Structure That Scales**
Every module follows this **identical, battle-tested structure**:
```
modules/
โโโ [feature-name]/ # ๐ Feature boundary
โโโ [feature-name].module.ts # ๐ง NestJS module wiring
โโโ application/ # ๐ Application layer
โ โโโ commands/ # โ๏ธ CQRS commands (writes)
โ โ โโโ create-[entity].command.ts # โโ Create operations
โ โ โโโ update-[entity].command.ts # โโ Update operations
โ โ โโโ delete-[entity].command.ts # โโ Delete operations
โ โ โโโ index.ts # โโ Barrel exports
โ โโโ controllers/ # ๐ HTTP/GraphQL endpoints
โ โ โโโ [entity].controller.ts # โโ REST API endpoints
โ โ โโโ index.ts # โโ Barrel exports
โ โโโ domain/ # ๐ง Pure business logic
โ โ โโโ entities/ # ๐ฆ Business objects
โ โ โ โโโ [entity].entity.ts # โโ Domain entity
โ โ โ โโโ index.ts # โโ Barrel exports
โ โ โโโ events/ # ๐ฏ Domain events
โ โ โ โโโ [entity]-created.event.ts # โโ Event definitions
โ โ โ โโโ index.ts # โโ Barrel exports
โ โ โโโ services/ # โ๏ธ Domain services
โ โ โ โโโ [entity].service.ts # โโ Business rules
โ โ โ โโโ index.ts # โโ Barrel exports
โ โ โโโ usecases/ # ๐ฌ Use case operations
โ โ โโโ create-[entity].usecase.ts# โโ Create business logic
โ โ โโโ update-[entity].usecase.ts# โโ Update business logic
โ โ โโโ delete-[entity].usecase.ts# โโ Delete business logic
โ โ โโโ index.ts # โโ Barrel exports
โ โโโ dto/ # ๐ Data contracts
โ โ โโโ requests/ # ๐ค Inbound data
โ โ โ โโโ create-[entity].dto.ts # โโ Create request
โ โ โ โโโ update-[entity].dto.ts # โโ Update request
โ โ โ โโโ index.ts # โโ Barrel exports
โ โ โโโ responses/ # ๐ฅ Outbound data
โ โ โ โโโ [entity].response.ts # โโ Entity response
โ โ โ โโโ index.ts # โโ Barrel exports
โ โ โโโ index.ts # โโ Barrel exports
โ โโโ queries/ # ๐ CQRS queries (reads)
โ โโโ get-[entity].handler.ts # โโ Single entity query
โ โโโ list-[entities].handler.ts # โโ Multiple entities query
โ โโโ index.ts # โโ Barrel exports
โโโ infrastructure/ # ๐๏ธ Infrastructure layer
โโโ mappers/ # ๐ Data transformation
โ โโโ [entity].mapper.ts # โโ Domain โ ORM mapping
โ โโโ index.ts # โโ Barrel exports
โโโ orm-entities/ # ๐๏ธ Database schema
โ โโโ [entity].orm-entity.ts # โโ TypeORM entity
โ โโโ index.ts # โโ Barrel exports
โโโ repositories/ # ๐พ Data access
โโโ [entity].repository.ts # โโ Repository implementation
โโโ index.ts # โโ Barrel exports
```
> **๐ฏ Every feature looks identical** - No surprises, no confusion, just consistency.
### ๐ง **Smart Defaults & Conventions**
```bash
# Naming follows strict patterns
ddd generate entity UserProfile # โ user-profile.entity.ts
ddd generate service OrderValidator # โ order-validator.service.ts
ddd generate event PaymentProcessed # โ payment-processed.event.ts
```
**Built-in Intelligence:**
- **๐ Barrel exports** - Automatic `index.ts` files for clean imports
- **๐ TypeScript strict** - Zero `any` types, full type safety
- **๐ DI ready** - Injectable decorators configured
- **๐ Interface first** - Clear contracts between layers
- **๐ Predictable paths** - Same location every time
### ๐ก **Enterprise Patterns**
```typescript
// โ
Commands (writes) - Tell, don't ask
@CommandHandler(CreateUserCommand)
export class CreateUserHandler {
async execute(command: CreateUserCommand): Promise<void> {
// Returns nothing - just does the work
}
}
// โ
Queries (reads) - Ask, don't tell
@QueryHandler(GetUserQuery)
export class GetUserHandler {
async execute(query: GetUserQuery): Promise<UserResponse> {
// Returns data - no side effects
}
}
// โ
Domain Events - Loose coupling
export class UserCreatedEvent implements IEvent {
constructor(public readonly userId: string) {}
}
```
**Battle-tested principles:**
- **Command/Query Separation** - Writes vs reads clearly separated
- **Domain Events** - Decoupled communication between bounded contexts
- **Repository Pattern** - Abstract data access from business logic
- **Clean Architecture** - Dependencies point inward to domain
## After Generation
### ๐ง **Your 5-Minute Setup Checklist:**
```bash
# โ
1. Generated files are ready - Review structure
ls -la modules/your-feature/
# โ
2. Add business properties to entities
# Edit: application/domain/entities/[entity].entity.ts
# Add: name: string; email: string; etc.
# โ
3. Update DTOs with validation rules
# Edit: application/dto/requests/create-[entity].dto.ts
# Add: @IsEmail() email: string; @IsNotEmpty() name: string;
# โ
4. Configure database mappings
# Edit: infrastructure/orm-entities/[entity].orm-entity.ts
# Add: @Column() name: string; @Column() email: string;
# โ
5. Wire up the module
# Edit: app.module.ts
# Add: YourFeatureModule to imports array
```
### ๐ฏ **Focus on Business Value:**
```typescript
// โ
Write business rules in domain services
export class OrderValidator {
validateBusinessRules(order: Order): ValidationResult {
// Your domain logic here - not infrastructure concerns
}
}
// โ
Add complex queries for reporting
@QueryHandler(GetMonthlyRevenueQuery)
export class GetMonthlyRevenueHandler {
async execute(query: GetMonthlyRevenueQuery) {
// Complex business queries - not CRUD
}
}
// โ
Handle domain events for integration
@EventsHandler(OrderCreatedEvent)
export class OrderCreatedHandler {
async handle(event: OrderCreatedEvent) {
// Send emails, update analytics, etc.
}
}
```
> **๐ From scaffolding to production in minutes, not days**
## Why This CLI Exists
### ๐ค **The Problem**
- Endless debates about folder structure
- Inconsistent naming across team members
- Copy-pasting boilerplate between features
- Mixed patterns in the same codebase
- New developers spending weeks learning "our way"
### ๐ฏ **The Solution**
- **One structure** that works for all features
- **Zero configuration** - works out of the box
- **Battle-tested patterns** from real enterprise apps
- **Instant onboarding** - same structure everywhere
- **Focus on business logic** instead of architecture decisions
### ๐ **The Result**
- 10x faster feature development
- Consistent codebase architecture
- Easy code reviews and maintenance
- New developers productive from day one
- No more "where does this file go?" questions
---
## Contributing & Development
### ๐ง **Local Development**
```bash
# Clone and setup
git clone https://github.com/eshe-huli/nestjs-ddd-cli
cd nestjs-ddd-cli
npm install
# Test changes locally
npm run dev -- generate entity Test -m test
# Build for production
npm run build
# Test globally installed version
ddd generate entity Test -m test
```
### ๐งช **Testing Your Changes**
```bash
# Create a test project
mkdir test-project && cd test-project
# Test scaffolding
ddd scaffold Product -m inventory
# Verify structure matches expectations
tree modules/inventory/
# Test individual generators
ddd generate service ProductValidator -m inventory
ddd generate event ProductCreated -m inventory
ddd generate query GetProductsByCategory -m inventory
```
### ๐ **Template Structure**
```
src/templates/
โโโ ๐ entity/ # Domain entity templates
โโโ ๐ service/ # Domain service templates
โโโ ๐ event/ # Domain event templates
โโโ ๐ query/ # Query handler templates
โโโ ๐ usecase/ # Use case templates
โโโ ๐ controller/ # Controller templates
โโโ ๐ repository/ # Repository templates
โโโ ๐ ... (more templates)
```
> **๐ค Pull requests welcome!** Help make DDD development even better.
## License
MIT - Build amazing things ๐