NestJS CQRS starter kit designed as a clean base for command/query-driven services with event-oriented integrations.
- NestJS monorepo with
apps/apientrypoint - CQRS with sample aggregate, command, query, and event handlers
- JWT auth endpoints (
/auth/login,/auth/refresh,/auth/logout,/auth/me) with RBAC guard/decorator - TypeORM configured for PostgreSQL
- BullMQ configured for Redis
- Dedicated BullMQ queue module and worker processor for project lifecycle jobs
- NATS client configured for event transport (JetStream-ready)
- Transactional outbox publisher with retry policy, DLQ storage, and admin replay endpoints
- TypeORM migration tooling and seed script for repeatable local setup
- Docker Compose for API + Swagger + infra services
- Swagger docs at
/api/docs
apps/
api/
src/
modules/
auth/
health/
projects/
libs/
contracts/
shared/
cp .env.example .env
npm install
docker compose up -d # starts PostgreSQL, Redis, NATS
npm run db:create # creates the nexus_forge database (skip if using Docker Compose Postgres — it creates it automatically)
npm run db:seed
npm run start:devcp .env.example .env
npm install
docker compose up -d
npm run db:seed
npm run start:devThe API runs pending TypeORM migrations automatically at startup when DB_MIGRATIONS_RUN=true (default).
API base URL: http://localhost:3000/api
Swagger: http://localhost:3000/api/docs
docker compose up -d --buildServices:
- API:
http://localhost:3000/api - Built-in Swagger UI (from API):
http://localhost:3000/api/docs - Swagger UI container:
http://localhost:8080(loads spec fromhttp://localhost:3000/api/docs-json)
npm run build
npm run start:prod# lint
npm run lint
# tests
npm test -- --watchman=false
npm run test:e2eHealth check:
curl http://localhost:3000/api/healthSwagger UI: http://localhost:3000/api/docs
scripts/create-db.sh creates the nexus_forge database if it does not already exist. Accepts env overrides:
DB_HOST=localhost DB_PORT=5432 DB_USER=postgres DB_PASSWORD=postgres DB_NAME=nexus_forge npm run db:createDefault values match the Docker Compose Postgres service.
npm run db:migration:run
npm run db:migration:revert
npm run db:migration:show
npm run db:migration:create -- AddUsersTable
npm run db:migration:generate -- SyncProjectIndexesnpm run db:seedOptional overrides:
SEED_PROJECT_ID=00000000-0000-0000-0000-000000000002 \\
SEED_PROJECT_NAME=\"Sandbox Project\" \\
SEED_PROJECT_DESCRIPTION=\"Local seed data\" \\
npm run db:seedDefault seeded auth user:
- email:
admin@nexus.local - password:
ChangeMe123!
# Login
curl -X POST http://localhost:3000/api/auth/login \\
-H "Content-Type: application/json" \\
-d '{"email":"admin@nexus.local","password":"ChangeMe123!"}'
# Refresh
curl -X POST http://localhost:3000/api/auth/refresh \\
-H "Content-Type: application/json" \\
-d '{"refreshToken":"<refresh-token>"}'
# Logout (revoke refresh token)
curl -X POST http://localhost:3000/api/auth/logout \\
-H "Content-Type: application/json" \\
-d '{"refreshToken":"<refresh-token>"}'
# Current user
curl http://localhost:3000/api/auth/me \\
-H "Authorization: Bearer <access-token>"projects module demonstrates:
CreateProjectCommand+ handlerGetProjectByIdQuery+ handlerProjectCreatedEvent+ event handler- Aggregate root (
ProjectAggregate) - Repository port (
ProjectRepository) with TypeORM adapter
