npx skills add ...
npx skills add myatminlu/vector-skills --skill nestjs-dev-guidelines
Production-grade NestJS backend standards for writing, reviewing, and evolving NestJS/Nest-style TypeScript services. Use when a repo has modules, controllers, providers/services, DTOs, guards, pipes, or Nest-oriented boundaries, or when designing NestJS APIs, modules, migrations, auth/RBAC, multi-tenant isolation, DDD layered/hexagonal architecture, ports/adapters, use cases, repository/query patterns, N+1/slow queries, validation, pagination, caching, error handling/exception filters, BullMQ/jobs, webhooks, uploads, decorators, provider scopes, dynamic modules, circular deps, health/readiness/shutdown, observability/logging/tracing, OpenTelemetry, testing, code review, modernization/version/runtime advice, or AI backend patterns like LLM gateways, SSE streaming, usage metering, and quotas. Verify volatile versions/commands/model IDs/APIs against official docs and the repo. Plain Express/Fastify/Hono/Koa without Nest boundaries: cross-cutting guidance only. Not for non-Node backends or pure frontend work.
npx skills add myatminlu/vector-skills --skill nestjs-dev-guidelines
A complete set of production-grade NestJS and Nest-style Node.js backend standards. Apply these rules whenever working on a codebase that already uses NestJS concepts such as modules, controllers, providers/services, DTOs, pipes, and guards, or when the task is explicitly about designing those patterns. Think like a senior backend engineer: consistency over cleverness, explicit over implicit, boundaries over shortcuts.
references/00-execution-discipline.md and the
Non-Negotiables below.references/NN-<topic>.md file. Each is
self-contained: TL;DR, rules, good/bad examples, anti-patterns, and a review checklist.references/29-code-review-checklist.md + the topic
references relevant to the diff.Use this section when the repo is "backend TypeScript" but not obviously a standard NestJS app.
@Module, controllers, providers/services, guards, pipes, DTOs) or when the user is asking
you to design a NestJS solution.class-validator, or a repo-standard structured logger instead of nestjs-pino), follow the
repo rather than rewriting it mid-task.Apply these rules before touching NestJS-specific details. They exist to reduce the usual LLM failure modes: silent assumptions, overbuilt code, broad refactors, and unverified fixes.
35-source-of-truth-freshness.md.Open references/00-execution-discipline.md for the full checklist and examples.
Each rule has a Why so you can reason about edge cases instead of applying it blindly.
04-code-quality.md.class-validator; ValidationPipe is global with whitelist: true, forbidNonWhitelisted: true, transform: true.
Why: DTOs are the one choke point where unknown fields, bad types, and injection payloads
are stopped. Skipping one means you trust the client. See 09-validation.md.whitelist.
Why: IDOR and mass-assignment are the two most common application-level breaches. They only
exist when code assumes "if the token is valid, the payload is fine." See 11, 12.03-module-design.md.id, foreign keys <entity>_id.
Why: each ecosystem has a convention; mixing them creates a lifetime of mapping bugs and
makes ad-hoc SQL painful. Pick the convention of the side that's hardest to change (the DB).
See 13-database-design.md.{ data, meta }; errors return { code, message, details?, traceId }
with the correct HTTP status.
Why: a consistent contract lets clients write one error handler and one pagination handler
that works everywhere, and lets support triage issues by traceId. See 07, 10.meta with pagination info.
Why: an unpaginated list is a latent OOM and a latent DB outage. The right pagination model
depends on UX, consistency requirements, and scale. See 08.20, 11.nestjs-pino with JSON in prod; redact authorization,
cookie, set-cookie, password, token. Correlation ID on every log line.
Why: plain-text logs can't be queried at scale, and one unredacted Authorization header
is a credential leak with a long tail. See 21.23.WHERE tenant_id = ?
or a client-supplied id that was trusted too early. Layered enforcement means a bug in
one layer does not leak data. See 33.Full decision trees live in references/05-thinking-decision-trees.md. Short version:
Where does this file go?
modules/<feature>/core/<name>/common/<kind>/integrations/<provider>/commands/<name>.command.tsevents/<event-name>/Should I create a new module?
utils/.common/ utility.Should I refactor this now?
Should I skip the test?
findById) with no logic? → Skipping is OK; the e2e test
of the controller covers it.Read the full reference file when you need detail. The number prefix is for stable ordering.
| # | File | Rule in one line |
|---|---|---|
| 00 | 00-execution-discipline.md | Think first, verify volatile facts (versions/APIs/model IDs) against docs, keep changes small, edit surgically, define success criteria, verify before claiming done |
| 01 | 01-folder-structure.md | src/{core,common,integrations,modules,events,commands} — one place for each kind of code |
| 02 | 02-naming-conventions.md | camelCase vars, PascalCase classes, snake_case DB, kebab-case.ts files, SCREAMING_SNAKE env |
| 03 | 03-module-design.md | One module per bounded context; @Global() only for true app-wide infra |
| 04 | 04-code-quality.md | SOLID, constructor DI, pure utils, small functions, no any without a reason |
| 05 | 05-thinking-decision-trees.md | How to decide: where to put code, when to refactor, when to skip a test |
| 06 | 06-api-design.md | REST, plural nouns, verbs match semantics, URI versioning /v1/..., idempotency keys |
| 07 | 07-standard-responses.md | Single success returns a plain object; lists return { data, meta }; errors return { code, message, details?, traceId } |
| 08 | 08-pagination-filters-sorting.md | Cursor/keyset for sequential browsing, offset when page numbers/exact totals are real requirements; filter[field]=, sort=-createdAt; whitelist fields |
| 09 | 09-validation.md | class-validator DTOs + global ValidationPipe; Zod for env + runtime JSON parsing |
| 10 | 10-error-handling.md | Hybrid taxonomy: HTTP status + namespaced code + traceId; domain errors extend semantic Nest exceptions; one global filter with host.getType() + headersSent guards, logs via PinoLogger |
| 11 | 11-security.md | Security review routine: OWASP Top 10, transport/CORS, injection/SSRF, password hashing, rate limits, PII/audit, and links to auth/webhooks/uploads |
| 12 | 12-authentication-patterns.md | Session cookie (browsers) or Bearer JWT (mobile/server); hash session/refresh tokens at rest; rotate refresh; use revoked_before; cookie takes precedence and invalid cookies fail closed; auth errors use { code, message } |
| 13 | 13-database-design.md | snake_case, plural tables, FK <entity>_id, indexes on FKs + query paths, deleted_at, UUIDv7 or bigint |
| 14 | 14-database-orm-patterns.md | raw pg / TypeORM / Prisma / Drizzle — side-by-side patterns |
| 15 | 15-migrations.md | Always forward-only in prod; no destructive changes without two-step rollout |
| 16 | 16-cascade-rules.md | ON DELETE CASCADE for owned data; RESTRICT for shared refs; SET NULL for optional |
| 17 | 17-pipelines-interceptors-guards.md | Order: Guard → Interceptor (pre) → Pipe → Handler → Interceptor (post) → Filter |
| 18 | 18-events.md | EventEmitter2 for in-process; outbox pattern when crossing services or queues |
| 19 | 19-background-jobs.md | BullMQ default; idempotent handlers; retries with backoff; DLQ for poison messages |
| 20 | 20-configuration.md | ConfigModule global; Zod schema; fail fast on boot if env invalid |
| 21 | 21-logging.md | nestjs-pino, JSON in prod, redact secrets, correlation ID per request |
| 22 | 22-observability.md | OpenTelemetry traces + metrics; Langfuse/Helicone for LLM traces |
| 23 | 23-testing.md | Unit beside impl (*.spec.ts); e2e in test/; mock at boundaries; real DB for integration |
| 24 | 24-performance.md | Avoid N+1; size the pool; cache selectively; stream large payloads |
| 24a | 24a-caching-patterns.md | Cache deliberately; stable namespaced keys, TTL + invalidation, stampede protection; never the sole authority for auth/quota/billing |
| 25 | 25-documentation-swagger.md | @ApiTags / @ApiOperation / @ApiResponse; DTOs auto-schema via @ApiProperty |
| 26 | 26-ai-product-patterns.md | LLM gateway with provider abstraction, retry, fallback, timeout |
| 27 | 27-ai-streaming-sse.md | SSE endpoints; cancel-aware (abort upstream); heartbeat; typed event vocab; not resumable on reconnect |
| 28 | 28-ai-usage-metering-cost.md | Per-call token + cost rows; aggregate per user/org/model; enforce quotas |
| 29 | 29-code-review-checklist.md | PR review checklist across all rules above |
| 30 | 30-code-review-anti-patterns.md | Catalog of anti-patterns with good-vs-bad snippets |
| 31 | 31-rules-rationale-examples.md | Cross-cut rule + rationale + good/bad examples for quick reference |
| 32 | 32-modern-nestjs-stack.md | Decision checklist for modernizing/starting a NestJS service; bootstrap order, module-system checks; no frozen version matrix |
| 33 | 33-multi-tenancy-patterns.md | Server-derived tenant identity enforced across auth, guard, service, and repository layers; tests prove isolation |
| 34 | 34-health-shutdown.md | Liveness vs readiness; one shutdown coordinator; drain before close; worker processes drain separately |
| 35 | 35-source-of-truth-freshness.md | Durable invariants stay local; volatile APIs/versions/models verified against official docs and the repo |
| 36 | 36-webhooks.md | Verify signature on raw bytes (raw-body config + timingSafeEqual), dedupe on (provider, event_id), ack 2xx after enqueue (incl. unhandled types), re-fetch authoritative state for high-stakes events, resolve tenant from the verified payload |
| 37 | 37-file-uploads.md | Prefer presigned direct-to-bucket uploads (PUT for clients, POST policy for browsers); cap size/MIME at the boundary; sniff magic bytes; opaque tenant-prefixed storage keys; server-compute hash/size/mime; AV scan before exposure; rate-limit upload endpoints |
| 38 | 38-decorators-scopes-dynamic-modules.md | Param decorators only extract from request; default to singleton scope; dynamic modules for configurable infra; forwardRef is a smell |
| 39 | 39-exception-filters.md | One global filter shapes every error to { code, message, details?, traceId }; throw typed HttpException subclasses; never leak internals |
| 40 | 40-ddd-layered-architecture.md | Optional DDD layering in three tiers (classic layers → layered feature modules → hexagonal ports/adapters); dependencies point inward; domain stays framework-free; default six-bucket layout still wins for CRUD |
| 41 | 41-n-plus-one-elimination.md | Prove N+1 by counting queries (never by guessing); six shapes beyond the obvious loop; JOIN vs two-query batch-load vs per-request DataLoader; never SQL LIMIT over a joined collection; lock the fix with a query-count test |
| You are doing... | Open... |
|---|---|
| Starting any implementation or bug fix | 00, 05 |
| Starting a new feature module | 01, 03, 04 |
| Structuring with DDD layers / hexagonal / ports-adapters | 40, 01, 03 |
| Starting or modernizing a service | 32, 34, 20 |
| Designing a new endpoint | 06, 07, 08, 09 |
| Returning errors consistently | 10 |
| Designing DB tables | 13, 14, 15, 16 |
| Adding auth to an endpoint | 11, 12, 17 |
| Adding multi-tenant isolation | 33, 11, 12, 14 |
| Adding a list endpoint | 07, 08, 41 |
| Adding caching | 24, 24a |
| Fixing a slow endpoint, an N+1, or high query counts | 41, 24, 14, 13 |
| Adding a background task | 19, 34 |
| Writing tests | 23 |
| Adding observability | 21, 22 |
| Adding health/readiness/shutdown | 34, 32 |
| Building an LLM feature | 26, 27, 28, 22 |
| Handling webhooks from a third party | 36, 11, 19, 21, 33 |
| Accepting file uploads | 37, 11, 24 |
| Designing custom decorators / scoped providers / dynamic modules | 38, 03, 17 |
| Designing the global exception filter / error wire shape | 39, 07, 10 |
| Giving version/command/model advice | 35 |
| Reviewing a PR | 29, 30, and any topic relevant to the diff |
When the user asks you to review a PR, changes, or a diff:
29-code-review-checklist.md — mark each item pass/fail/NA.04-code-quality.md → Layering / Anti-patterns").30-code-review-anti-patterns.md and quote the
good version.If the project is an AI product backend (LLMs, agents, RAG, vector store, streaming, usage- based billing), also read:
26-ai-product-patterns.md — provider-agnostic LLM gateway, retry/fallback27-ai-streaming-sse.md — SSE endpoint patterns, cancel, heartbeat28-ai-usage-metering-cost.md — token + cost metering, quota enforcement22-observability.md — Langfuse/Helicone for LLM tracingEverything else (auth, DB, error handling, testing) applies identically to AI products — the AI bit is a module, not a framework.