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

62 lines
1.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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):
```ts
// 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)`
```ts
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)