FactuGES_ERP/docs/architecture/dto-guidelines.md

54 lines
2.6 KiB
Markdown
Raw Normal View History

# DTOs y schemas HTTP
> Estado: **NORMATIVO**. Esta guía es la SSOT de contratos HTTP, schemas y naming de DTOs.
## Ubicación y compartición
Los Request DTO se ubican normalmente en:
```text
modules/<module>/src/common/dto/request
```
Los DTOs de response y subcontratos compartidos siguen la estructura `common/dto/response` y `common/dto/shared` cuando corresponda. `common` es deliberadamente importable tanto por backend como por web: el cliente puede usar el RequestDTO para tipar el payload que envía.
Un RequestDTO no pertenece a Infrastructure.
## Zod es la SSOT
Cada contrato nace de un schema Zod y el tipo se infiere de él:
```ts
export const CreateXRequestSchema = z.object({ /* contrato HTTP */ });
export type CreateXRequestDTO = z.infer<typeof CreateXRequestSchema>;
```
No crear interfaces manuales paralelas. Cada endpoint define sus request y response DTOs, salvo subcontratos que sean realmente idénticos y estables.
## Naming
Para body HTTP, usar `<Action><Resource>RequestSchema` y `<Action><Resource>RequestDTO`:
```text
CreateCustomerRequestSchema
CreateProformaRequestSchema
CompleteInitialOnboardingRequestSchema
```
Para params y query se mantiene el rol explícito, por ejemplo `GetCustomerByIdParamsRequestSchema` o `CustomerListQueryRequestSchema`, según la convención local ya establecida. `CommandSchema` no es el nombre general de un body HTTP: un Command es una representación de Application cuando realmente exista.
En output usar nombres que expresen el contrato: `SummarySchema`, `ResourceSchema`, `DetailResponseSchema`, `ListResponseSchema`, `CreatedResponseSchema` o `DeletedResponseSchema`.
## Semántica del contrato
`undefined`, `null`, `""` y `[]` tienen significados diferentes y el schema debe expresarlos. Evitar `.default()` y `.transform()` en DTOs de negocio salvo necesidad justificada; la normalización y la decisión de `Maybe` pertenecen a Application.
Usar schemas semánticos para UUID, fechas, timestamps, porcentajes, importes y cantidades. Los decimales exactos no viajan como `number`; Money, Amount, Percentage y Quantity mantienen el contrato de precisión existente.
## Responses y snapshots
El schema Zod es también la SSOT del contrato de salida. Los snapshot builders se tipan contra el DTO inferido, son deterministas, no implementan lógica de negocio ni acceden a Infrastructure. Pueden convertir Value Objects a primitivas, enums internos a valores de contrato y `Maybe` a `null`.
La ejecución de `validateRequest` y la transición hacia InputMapper se documentan en [Flujo HTTP y entrada a Application](./http-request-flow.md).