Interfaces y contratos TypeScript
Cómo definir tipos e interfaces nuevos sin fragmentar el modelo de dominio: dónde colocarlos, cómo alinearlos con el orquestador y cuándo usar Zod en los bordes (HTTP, tRPC).
Dónde viven los tipos
| Ubicación | Uso típico |
|---|---|
packages/types | Tipos compartidos entre apps, contratos estables, reexportaciones. Tras cambios: yarn compile en el workspace. |
apps/next/src/types (o equivalente) | Tipos solo del front o capa de presentación cuando no deben ir al paquete compartido. |
src/integrations/contracts/ | Contratos de integración: p. ej. forma del InsuranceAdapter, payloads hacia/desde adaptadores. No mezclar con tipos de UI. |
| Tipos generados (Supabase) | Entidades y filas de BD; no duplicar a mano si el generador ya los produce. |
Regla práctica: si dos módulos (por ejemplo trpc y una route.ts) necesitan el mismo shape de dominio, el tipo sube a packages/types o al contrato compartido que ya use el core.
Contrato del adaptador (InsuranceAdapter)
Los adaptadores de aseguradora implementan el contrato definido en el código (p. ej. integrations/contracts/insurance-adapter.contract.ts — nombre exacto según repo). Al añadir un proveedor:
- Implementar la interfaz completa esperada (emit, manejo de errores coherentes con el orquestador).
- Registrar el slug en
registry.tsen MAYÚSCULAS, alineado con la filaintegrations.slugy consales_integration_slug/post_sales_integration_slugen el paquete.
Detalle de dominio del objeto que viaja: Risk item y Orquestador e integraciones (StandardRiskItem).
Interfaces públicas vs internas
- API Shield / REST: define entrada y salida pensando en clientes externos; usa Zod (o validación equivalente) en el handler y tipos inferidos (
z.infer<typeof schema>). - tRPC: mismos límites —
inputcon Zod enprotectedProcedure/publicProcedure; el tipo inferido es la fuente de verdad para el cliente. - Props de componentes React: interfaces
FooPropsjunto al componente o entypeslocales; no reexportar desde ahí modelos de BD crudos si el componente solo necesita 3 campos — mapear a un DTO de vista.
Nuevas interfaces de dominio
Cuando introduces un concepto nuevo (p. ej. un subestado de emisión o un campo de metadata):
- Comprueba si encaja en metadata JSON existente del risk item o si requiere migración y tipo en
packages/types. - Si solo afecta a un adaptador, puede vivir en el módulo del adaptador siempre que el orquestador siga recibiendo el contrato unificado hacia fuera.
- Documenta el contrato serializado si cruza la API (campos opcionales, nombres estables).
Zod en APIs
Patrón recomendado en rutas y tRPC:
- Un schema Zod por operación (
createXSchema,queryXSchema). - No confiar en
assobre JSON crudo sin validar. - Mensajes de error estables para clientes automatizados (códigos HTTP + cuerpo coherente con el resto de Shield).
Referencias cruzadas
- Estructura base y extensión — dónde encajan los cambios.
- Nuevas rutas Shield — validación y namespaces.
- Integraciones (código) — tabla
integrationsy slugs.