barsa 10c8461661 Implement Zod DTOs for Request Validation and Enhance ESLint Rules
- Introduced Zod DTOs for request validation across multiple controllers, replacing inline validation with structured classes for improved maintainability and clarity.
- Updated ESLint configuration to enforce a rule against importing Zod directly in BFF controllers, promoting the use of shared domain schemas for request validation.
- Removed the SecureErrorMapperService to streamline the security module, as its functionality was deemed unnecessary.
- Enhanced various controllers to utilize the new DTOs, ensuring consistent validation and response handling across the application.
2025-12-26 13:04:15 +09:00

1.8 KiB
Raw Blame History

BFF Validation Standard (2025): DTOs + Global Pipe (Zod)

This repository follows the “big org standard” for NestJS request validation:

  • Schemas live in the shared domain layer (@customer-portal/domain)
  • Controllers use DTOs built from those schemas
  • Validation runs globally via a single app-wide pipe

Standard Pattern

1) Define the schema in @customer-portal/domain

Put request/param/query schemas in the relevant domain modules schema.ts.

Example (conceptual):

// packages/domain/<domain>/schema.ts
import { z } from "zod";

export const exampleRequestSchema = z.object({
  name: z.string().min(1),
});

2) Create a DTO in the controller using createZodDto(schema)

import { createZodDto } from "nestjs-zod";
import { exampleRequestSchema } from "@customer-portal/domain/<domain>";

class ExampleRequestDto extends createZodDto(exampleRequestSchema) {}

Then use ExampleRequestDto in @Body(), @Param(), or @Query().

3) Rely on the global ZodValidationPipe

The BFF registers ZodValidationPipe globally via APP_PIPE in apps/bff/src/app.module.ts.

That means controllers should not import zod or define ad-hoc Zod schemas inline for request validation.


Boundary Validation (Integrations / Mapping)

In addition to request DTO validation, we validate at integration boundaries:

  • Provider raw → domain: validate raw payloads and the mapped domain model using domain schemas.
  • BFF → Portal: use the same domain contracts for stable payload shapes where possible.

Governance / Linting

We enforce this pattern via ESLint:

  • Controllers are expected to import schemas from @customer-portal/domain
  • Controllers should not import zod directly (to prevent drifting schema definitions into the controller layer)