Uecko_ERP/docs/DTOS - GUIA DE ESTILO.md
2025-06-24 20:38:57 +02:00

4.8 KiB

Guía de estilo — DTOs y organización de carpetas

Objetivo: asegurar que todos los equipos usen un vocabulario y una estructura de ficheros idéntica al modelar, versionar y serializar los Data Transfer Objects (DTO).
Esta guía aplica a cualquier API HTTP/JSON implementada en Express + TypeScript que siga DDD, SOLID y CQRS.


1. Estructura de carpetas obligatoria

src/
└─ <bounded-context>/           (ej. billing/)
   └─ api/
      └─ dto/
         ├─ common/            ←  Tipos reutilizables (MoneyDTO, AddressDTO…)
         ├─ request/             ←  Sólo comandos y queries
         │   ├─ *.command.dto.ts
         │   └─ *.query.dto.ts
         │       
         └─ response/            ←  Sólo resultados/vistas
             ├─ *.result.dto.ts
             └─ *.view.dto.ts
                 

Alias TS recomendado: @<context>/dto/*src/<context>/api/dto/*.


2. Convención de nombres

Categoría Sufijo obligatorio Descripción & ejemplos
Comandos (mutaciones) …CommandDTO CreateInvoiceCommandDTO, UpdateInvoiceCommandDTO, DeleteInvoiceCommandDTO, ChangeInvoiceStatusCommandDTO
Queries (lecturas con filtros) …QueryDTO ListInvoicesQueryDTO, GetInvoiceByIdQueryDTO
Resultados (respuesta de comandos) …ResultDTO InvoiceCreationResultDTO, InvoiceDeletionResultDTO
Vistas (respuesta de queries) …ViewDTO InvoiceViewDTO, InvoiceSummaryViewDTO
Tipos comunes …DTO MoneyDTO, PaginationMetaDTO, AddressDTO

Regla de oro: No existe ningún DTO sin sufijo, salvo los tipos comunes dentro de common/.


3. Reglas de contenido

  1. Solo datos planos: números, cadenas, literales, arrays; nada de lógica.
  2. Fechas en ISO-8601 UTC (yyyy-MM-dd'T'HH:mm:ss.SSS'Z').
  3. Enums expuestos como string literal en snake_case o UPPER_SNAKE_CASE; evita números mágicos.
  4. Moneda
    • Siempre con la estructura común:
export interface MoneyDTO {
  amount: number | null;     // unidades mínimas (ej. céntimos)
  scale: number;             // nº de decimales (2 = céntimos)
  currency_code: string;     // ISO-4217 (“EUR”)
}
  • Se importa desde dto/common/money.dto.ts.

4. Guía de mapeo

Dirección Componente responsable Ubicación
DTO → Dominio …CommandMapper / …QueryMapper src/<context>/application/mappers/
Dominio → DTO …ResultMapper / …ViewMapper mismo directorio

Cada mapper implementa una función pública:

interface InvoiceCreationResultMapper {
  toResult(entity: Invoice): InvoiceCreationResultDTO;
}

5. Validación y versiones

  1. Validación de entrada

    • Usa class-validator o Zod en el controller; nunca en el dominio.
    • Convierte a Value Objects una vez que el DTO pasó la validación.
  2. Versionado

    • Añade sufijos de versión en el archivo, no en el nombre de la interfaz:
      invoice.view.v2.dto.tsexport interface InvoiceViewV2DTO { … }
    • Mantén las versiones anteriores durante ≥1 release o hasta que los consumidores migren.

6. Ejemplo completo (creación de factura)

billing/
├─ api/
│  └─ dto/
│     ├─ input/create-invoice.command.dto.ts
│     ├─ output/invoice-creation.result.dto.ts
│     └─ common/money.dto.ts
└─ application/
   └─ mappers/
      └─ invoice-creation.result.mapper.ts
// create-invoice.command.dto.ts
export interface CreateInvoiceCommandDTO {
  customerId: string;
  issueDate: string;
  lines: ReadonlyArray<{
    description: string;
    quantity: number;
    unitPrice: MoneyDTO;
  }>;
}

// invoice-creation.result.dto.ts
export interface InvoiceCreationResultDTO {
  invoiceId: string;
  number: string;
  totalAmount: MoneyDTO;
  createdAt: string;
}

7. Checklist antes de hacer merge

  • Archivo ubicado en la carpeta correcta.
  • Sufijo conforme (CommandDTO, QueryDTO, ResultDTO, ViewDTO).
  • Todos los importes usan MoneyDTO.
  • Tipos opcionales marcados con ? y comentados.
  • Sin lógica, constructores ni métodos.
  • PR incluye al menos un test de mapper (input ⇄ dominio ⇄ output).

8. Tabla resumen

Carpeta Sufijo Ejemplo clásico
dto/input/ CommandDTO DeleteInvoiceCommandDTO
dto/input/ QueryDTO ListInvoicesQueryDTO
dto/output/ ResultDTO InvoiceDeletionResultDTO
dto/output/ ViewDTO InvoiceSummaryViewDTO
dto/common/ DTO MoneyDTO