Skip to main content

NestJS conventions

These are PointNXT rules from AGENTS.md, docs/AI_CONTEXT.md, and the architecture check. They are not a generic NestJS tutorial.

Placement​

src/modules/<area>/<feature>/
feature.module.ts
controllers/
services/
repositories/ when the feature uses them
listeners/
dto/

Areas: identity, commerce, operations, finance, automation.

  • The area module imports the feature. The feature does not import the area module.
  • Controllers do not inject DatabaseService.
  • Do not import Shopify, Amazon, WooCommerce, or Razorpay SDKs from src/modules. Put them in src/integrations.
  • Inventory writes from outside stock go through StockOperationsPort.
  • New Prisma models are classified in tenancy.extension.ts.
  • Order side effects in order command use OutboxWriterService inside the transaction.

HTTP​

  • Default version 1, so paths are /v1/... unless VERSION_NEUTRAL.
  • DTOs use class-validator. The global pipe strips unknown fields and rejects them.
  • @TenantScoped() when the route is tenant data.
  • @RequirePermissions when the route is not for every authenticated user. Omission allows.
  • @AuditLog when the mutation should hit the audit listener.
  • @DocResponse and @ApiOperation so Swagger stays the API reference.

Config​

Add a variable to .env.example, to environment.validation.ts, and to a config factory under src/common/config. Read it with ConfigService.

Tests​

Pair a spec under test/. yarn verify:test-pairs enforces pairing. yarn architecture:check enforces boundaries.

Workers​

Run job bodies inside runWithTenantContext or runWithSystemContext. A Prisma call without that context is not tenant-filtered by the request, because there is no request.