Skip to main content

Coding Standards

Version: 1.0
Status: Approved
Owner: Platform Engineering
Last Updated: 2026-04-12
References: AGENT.md §1–17 (authoritative), system.md §9


1. Purpose

This document is an executive summary of the platform coding standards. The authoritative, binding source is AGENT.md. All engineers and AI code-generation tools MUST read AGENT.md before writing any code.


2. Non-Negotiable Rules

#RuleSource
1TypeScript everywhere — no .js filesAGENT.md §1.1
2strict: true in all tsconfig.jsonAGENT.md §1.1
3NestJS for all backend microservices — no Express, no raw FastifyAGENT.md §1.2
4@nestjs/platform-fastify used as HTTP adapter internally — never fastify directly in service codeSpec update
5Next.js App Router for all frontendsAGENT.md §1.3
6TailwindCSS + ShadCN UI — no other CSS frameworksAGENT.md §1.3
7Domain layer MUST have zero NestJS / Prisma / NATS importsAGENT.md §4.2
8No shared databases between servicesAGENT.md §5.2
9All APIs follow OpenAPI 3.1 with versioning /v1/...; use @nestjs/swagger decoratorsAGENT.md §6.1
10UUID primary keys everywhereAGENT.md §7.1
11Secrets in Vault / K8s Secrets — never plaintextAGENT.md §11.1
12Conventional commits requiredAGENT.md §16

2a. NestJS Architecture Rules

RuleDetail
Module structureEach microservice MUST have a root AppModule with feature modules (SmsModule, AuthModule, etc.)
GuardsAuthentication and authorisation via NestJS @Injectable() Guards — @UseGuards(JwtAuthGuard) (validates the Kong-forwarded platform JWT) and @UseGuards(ScopeGuard('sms:send')). No IdP-specific guards (e.g. FirebaseAuthGuard) in downstream services — identity is provider-agnostic by design.
InterceptorsCross-cutting concerns (rate limiting, idempotency, logging, tracing) via NestJS Interceptor
PipesInput validation via NestJS ValidationPipe with class-validator DTOs
FiltersGlobal exception filter for consistent error response shape
ProvidersServices, repositories, and publishers registered as NestJS providers with DI
No business logic in controllersControllers MUST delegate to application-layer use cases via injected services
OpenAPI@nestjs/swagger decorators on all controllers and DTOs — @ApiOperation, @ApiResponse, @ApiProperty

3. File & Naming Conventions

EntityConventionExample
Fileskebab-casesms-orchestrator.service.ts
ClassesPascalCaseSmsOrchestratorService
Variables / functionscamelCasesendSmsMessage()
DB tablessnake_casesms_messages
NATS subjects<domain>.<action>.<event>sms.outbound.request
Environment variablesUPPER_SNAKE_CASEDATABASE_URL

4. DDD Folder Structure (per microservice)

/src
/domain
/entities
/value-objects
/services
/events
/repositories ← interfaces only
/application
/use-cases
/dto
/mappers
/infrastructure
/http ← NestJS controllers, guards, interceptors
/nats ← publishers, consumers
/db ← Prisma repository implementations
/config
/tests
/unit
/integration
/contract

5. Testing Requirements (summary)

LayerMinimum coverage
Domain90%
Application80%
Infrastructure60%

Full testing standards: solution_baseline_testing_standards.md


6. Commit Message Format

<type>(<scope>): <description>

Types: feat | fix | chore | docs | refactor | test | perf
Scope: service name or package (e.g. sms-orchestrator, shared-types)

Examples:
feat(sms-orchestrator): add retry pipeline with exponential backoff
fix(api-gateway): correct rate limit header validation
chore(infra): update k8s HPA manifests

7. AI Code Generation Rule

If Cursor, GitHub Copilot, or any AI tool generates code that violates any rule in AGENT.md, the code MUST be regenerated until compliant. AGENT.md overrides all AI suggestions and framework defaults.


8. Assumptions and Open Points

IDAssumption / Open PointOwnerResolution Date
A-001ESLint config (shared-config package) to be published before service scaffolding beginsPlatform EngTBD
A-002Vitest is preferred over Jest; teams must not mix test frameworks within a serviceQA TeamTBD