NestJS-specific implementation of DDD + Hexagonal + CQRS patterns. For the underlying theory (aggregates, domain events, architecture layers), see engineering-toolkit:engineering-foundations. This skill covers the NestJS-specific HOW. Before applying any topic, read its reference file in reference/.
Topics
| Topic |
When to Use |
Reference |
| Error Handling |
Exception filters, domain error -> HTTP mapping |
reference/error-handling.md |
| Config |
Environment variables, config modules, validation |
reference/config.md |
| Auth |
Guards, JWT strategies, RBAC |
reference/auth.md |
| API Design |
Endpoints, DTOs, Swagger, pagination |
reference/api-design.md |
| Code Structure |
Where to place code, resolving circular imports |
reference/code-structure.md |
| Logging |
Structured logging with Pino, correlation IDs |
reference/logging.md |
| Domain Model (NestJS) |
@nestjs/cqrs AggregateRoot, EventPublisher |
reference/nestjs-domain-model.md |
| TypeORM Migrations |
Creating database migrations |
reference/typeorm-migrations.md |
| TypeORM Queries |
Writing queries and transactions |
reference/typeorm-queries.md |
Architecture Overview
+------------------------------------------------------------------+
| PRESENTATION LAYER |
| apps/ (HTTP Controllers, DTOs, Request/Response handling) |
+------------------------------------------------------------------+
| APPLICATION LAYER |
| modules/ (Commands, Queries, Handlers, Events) |
+------------------------------------------------------------------+
| DOMAIN LAYER |
| libs/common/domain/ (Entities, Value Objects, Enums) |
+------------------------------------------------------------------+
| INFRASTRUCTURE LAYER |
| libs/ (Repositories, External APIs, Database, Messaging) |
+------------------------------------------------------------------+
Quick Decision Guide
Writing an endpoint?
-> reference/api-design.md + reference/code-structure.md
Handling errors?
-> reference/error-handling.md
Setting up config/env?
-> reference/config.md
Adding authentication?
-> reference/auth.md
Writing a database query?
-> reference/typeorm-queries.md
Creating a migration?
-> reference/typeorm-migrations.md
Implementing a domain model with events?
-> reference/nestjs-domain-model.md
Adding logging?
-> reference/logging.md
Gotchas
Claude-specific failure modes in NestJS codebases:
- Throwing
HttpException from domain/application layer — Claude defaults to HTTP exceptions everywhere. Domain layer must throw domain-specific exceptions; the exception filter maps them to HTTP responses.
- Using
process.env.X instead of ConfigService — Claude reaches for process.env out of habit. Always inject ConfigService and use .get().
- Putting auth logic in services — Claude tends to add
if (!user.isAdmin) checks inside service methods. Auth belongs in guards; services receive already-validated context.
- Returning entities directly from controllers — Claude skips DTO mapping when "it's the same shape anyway." Always use response DTOs, even if they mirror the entity — the contract must be explicit.
- Circular imports between modules — Claude creates circular dependencies when wiring cross-module services. Use
forwardRef() as last resort; prefer restructuring.
- Logging message-first instead of context-first — Claude writes
logger.log('User created', { userId }) instead of logger.log({ userId }, 'User created'). Pino expects context object first.
- Raw SQL when QueryBuilder suffices — Claude jumps to raw SQL for anything beyond
.find(). Follow the hierarchy: built-in methods > QueryBuilder > raw SQL.
- Forgetting to release QueryRunner — Must always release in a
finally block. Claude sometimes puts release() only in the happy path.
- Importing from other module's internal paths — Use the module's public API (barrel exports), not deep
../other-module/internal/file imports.
Key Rules (Always Apply)
- Domain layer MUST NOT import HTTP exceptions — use domain exceptions, map in filters
- Never access
process.env directly — use ConfigService
- Auth in guards, not in services — domain receives validated user context
- DTOs for all input/output — never expose entities directly
- Relative imports within modules — path aliases across modules
- Context-first logging — structured fields before message string
- Query hierarchy — built-in methods first, query builder second, raw SQL last resort
- Release query runners — always in a
finally block
Source: anpham1925/claude-marketplace — distributed by TomeVault.
1---2name: anpham1925-claude-marketplace-nestjs-stack3description: NestJS-specific implementation of DDD + Hexagonal + CQRS patterns. For the underlying theory (aggregates, domain events, architecture layers), see `engineering-toolkit:engineering-foundations`. This skill covers the NestJS-specific HOW. Before applying any topic, read its reference file in `reference/`.4---56NestJS-specific implementation of DDD + Hexagonal + CQRS patterns. For the underlying theory (aggregates, domain events, architecture layers), see `engineering-toolkit:engineering-foundations`. This skill covers the NestJS-specific HOW. Before applying any topic, read its reference file in `reference/`.78## Topics910| Topic | When to Use | Reference |11|---|---|---|12| **Error Handling** | Exception filters, domain error -> HTTP mapping | `reference/error-handling.md` |13| **Config** | Environment variables, config modules, validation | `reference/config.md` |14| **Auth** | Guards, JWT strategies, RBAC | `reference/auth.md` |15| **API Design** | Endpoints, DTOs, Swagger, pagination | `reference/api-design.md` |16| **Code Structure** | Where to place code, resolving circular imports | `reference/code-structure.md` |17| **Logging** | Structured logging with Pino, correlation IDs | `reference/logging.md` |18| **Domain Model (NestJS)** | @nestjs/cqrs AggregateRoot, EventPublisher | `reference/nestjs-domain-model.md` |19| **TypeORM Migrations** | Creating database migrations | `reference/typeorm-migrations.md` |20| **TypeORM Queries** | Writing queries and transactions | `reference/typeorm-queries.md` |2122## Architecture Overview2324```25+------------------------------------------------------------------+26| PRESENTATION LAYER |27| apps/ (HTTP Controllers, DTOs, Request/Response handling) |28+------------------------------------------------------------------+29| APPLICATION LAYER |30| modules/ (Commands, Queries, Handlers, Events) |31+------------------------------------------------------------------+32| DOMAIN LAYER |33| libs/common/domain/ (Entities, Value Objects, Enums) |34+------------------------------------------------------------------+35| INFRASTRUCTURE LAYER |36| libs/ (Repositories, External APIs, Database, Messaging) |37+------------------------------------------------------------------+38```3940## Quick Decision Guide4142```43Writing an endpoint?44 -> reference/api-design.md + reference/code-structure.md4546Handling errors?47 -> reference/error-handling.md4849Setting up config/env?50 -> reference/config.md5152Adding authentication?53 -> reference/auth.md5455Writing a database query?56 -> reference/typeorm-queries.md5758Creating a migration?59 -> reference/typeorm-migrations.md6061Implementing a domain model with events?62 -> reference/nestjs-domain-model.md6364Adding logging?65 -> reference/logging.md66```6768## Gotchas6970Claude-specific failure modes in NestJS codebases:7172- **Throwing `HttpException` from domain/application layer** — Claude defaults to HTTP exceptions everywhere. Domain layer must throw domain-specific exceptions; the exception filter maps them to HTTP responses.73- **Using `process.env.X` instead of ConfigService** — Claude reaches for `process.env` out of habit. Always inject `ConfigService` and use `.get()`.74- **Putting auth logic in services** — Claude tends to add `if (!user.isAdmin)` checks inside service methods. Auth belongs in guards; services receive already-validated context.75- **Returning entities directly from controllers** — Claude skips DTO mapping when "it's the same shape anyway." Always use response DTOs, even if they mirror the entity — the contract must be explicit.76- **Circular imports between modules** — Claude creates circular dependencies when wiring cross-module services. Use `forwardRef()` as last resort; prefer restructuring.77- **Logging message-first instead of context-first** — Claude writes `logger.log('User created', { userId })` instead of `logger.log({ userId }, 'User created')`. Pino expects context object first.78- **Raw SQL when QueryBuilder suffices** — Claude jumps to raw SQL for anything beyond `.find()`. Follow the hierarchy: built-in methods > QueryBuilder > raw SQL.79- **Forgetting to release QueryRunner** — Must always release in a `finally` block. Claude sometimes puts `release()` only in the happy path.80- **Importing from other module's internal paths** — Use the module's public API (barrel exports), not deep `../other-module/internal/file` imports.8182## Key Rules (Always Apply)8384- **Domain layer MUST NOT import HTTP exceptions** — use domain exceptions, map in filters85- **Never access `process.env` directly** — use ConfigService86- **Auth in guards, not in services** — domain receives validated user context87- **DTOs for all input/output** — never expose entities directly88- **Relative imports within modules** — path aliases across modules89- **Context-first logging** — structured fields before message string90- **Query hierarchy** — built-in methods first, query builder second, raw SQL last resort91- **Release query runners** — always in a `finally` block9293---94> Source: [anpham1925/claude-marketplace](https://github.com/anpham1925/claude-marketplace) — distributed by [TomeVault](https://tomevault.io).95<!-- tomevault:4.0:skill_md:2026-05-22 -->