orquestador/specs/DOMAIN_MODEL.md

95 lines
6.1 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.

# Modelo de dominio y puertos (T04)
El dominio utiliza Java 21 y no depende de Spring, serializadores, HTTP, JDBC ni
JPA. Sus records son snapshots inmutables, no entidades administradas ni cuerpos
REST. Las escrituras y los bloqueos pertenecen a servicios de aplicación futuros.
| Paquete | Modelos y responsabilidades |
|---|---|
| shared/domain | Identidades UUID distintas por recurso, Actor confiable, JSON inmutable, ErrorCode y DomainException |
| flow/domain | DSL FlowDefinition, estados/eventos, transiciones, rutas fijas o por decisión, tareas, schemas, FlowVersion y ValidationReport |
| decision/domain | AST cerrado de condiciones/valores, reglas ordenadas, política explícita UNIQUE/FIRST, contexto y resultado |
| action/domain | Configuración por capacidad, reintentos acotados, contexto, resultado y metadatos de catálogo confiable |
| request/domain | RequestInstance fijada a FlowId y RequestType con activación opcional |
| execution/domain | Estado técnico, ejecución aceptada, lease/fencing y checkpoint de acción |
| */application/port | DecisionEvaluator, ActionHandler y FlowDefinitionValidator |
| flow/api | ValidationReportResponse y conversión explícita desde dominio al contrato REST |
## Invariantes y representación
- Los estados y eventos de negocio son claves configurables, no enums Java por
proceso. Los enums representan únicamente conceptos técnicos cerrados.
- FlowDefinition representa el DSL; FlowVersion agrega identidad, estado de
publicación, revisión, checksum y fechas. RequestInstance conserva solo FlowId,
sin duplicar la versión. RETIRED es ejecutable para instancias existentes y no
asignable a nuevas solicitudes.
- List.copyOf y Map.copyOf/Set.copyOf impiden cambios por alias. Los hijos JSON
también son inmutables: objetos, listas, strings, BigDecimal, boolean y null
explícito. Lookup.Missing no es un valor JSON; no se confunde con NullValue.
- Los números se construyen con BigDecimal, sin coerción implícita desde strings.
La comparación numérica, resolución de pointers y límites de evaluación son T05.
- Condiciones, acciones y rutas son variantes selladas. EXISTS recibe un path;
NOT un operando; AND/OR conservan orden y requieren al menos dos argumentos.
Una transición tiene ruta fija o decisión/destinos, nunca ambas.
- Los paths de lectura se restringen a request.data, event.data, results y actor.
Updates.target es relativo a request.data; /id significa data.id y no request.id.
La detección de destinos solapados y la validación de datos corresponden a T06.
- Actor solo se construirá desde identidad verificada. No incluye JWT ni secretos
y no se toma del evento. EvaluationContext no expone servicios externos.
- Optional representa campos ausentes del modelo interno; los adapters deben
omitirlos o traducirlos según el contrato, no serializar el dominio directamente.
Versiones de contrato/perfil y schemas pueden faltar en borradores; T06 debe
resolverlos y fijarlos al publicar. SchemaVersion desconocida se diagnostica
en validación, no se interpreta como otra versión del proceso.
- ActionCapability procede del catálogo confiable. Su clasificación de efectos
y schemas no forman parte de ActionDefinition editable. NO_OP solo es para
simulación; T06 debe impedir publicarlo y T11 controlar su ejecución.
- ActionResult.Completed admite resultados negativos normalizados del negocio.
TechnicalFailure expresa fallo técnico TRANSIENT, PERMANENT o UNKNOWN_EFFECT.
La elegibilidad de reintento también requiere revisar efectos y checkpoints;
el record no autoriza por sí solo un reintento.
- ExecutionStatus.RECONCILIATION_REQUIRED sigue activo; SUCCEEDED/FAILED liberan
la exclusión. RUNNING exige lease y otros estados no lo admiten. SUCCEEDED
exige resultado, aunque el resultado conserve el estado anterior del negocio.
- Los hashes usan 64 caracteres hexadecimales en minúsculas, como SQL y API.
Los contadores no son negativos y los checkpoints exitosos exigen resultado y
fecha final. El worker debe verificar tokens y tiempos de PostgreSQL en T10.
## Errores y adaptadores
ErrorCode mantiene códigos de máquina independientes de HTTP. DomainException
expone solo el código, sin incorporar entradas ni respuestas crudas del proveedor.
Los adaptadores API resolverán status, correlationId y mensajes permitidos.
DecisionResult.Failure solo acepta EVALUATION_ERROR o AMBIGUOUS_DECISION; un
fallo nunca se representa mediante la ruta default.
ValidationReport contiene incidencias con JSON Pointer, código y severidad.
ValidationReportResponse convierte solo errores al arreglo errors del contrato;
las advertencias internas no invalidan el flujo ni agregan campos no publicados.
El DTO se comprueba contra api.schema.json. No hay endpoint nuevo en T04.
No hay anotaciones JPA ni entidades persistentes disfrazadas de records de dominio.
Los futuros adapters de persistencia deberán mapear explícitamente sus entidades
hacia estos snapshots; tampoco deben devolver entidades por REST.
## Alcance verificado
DomainModelTest cubre inmutabilidad, AST, pointers, ausencia/null, clasificación de
resultados, versiones, leases/checkpoints, reintentos y errores. DomainBoundaryTest
comprueba el DTO contra el esquema real. DomainArchitectureTest recompila todos
los archivos domain y application/port con classpath vacío y solo java.base;
además prohíbe referencias java.net/java.sql. Así detecta dependencias accidentales
de infraestructura, API, Spring/JPA o clientes HTTP.
No hay implementaciones ficticias de los puertos ni llamadas a proveedores.
T05 implementará el evaluador; T06 el validador/publicación; T11 los handlers.
Los constructors garantizan integridad local del objeto; no sustituyen validación
del DSL, autorización, transacciones, canonicalización ni A01–A20.
## Evaluación implementada en T05
PureDecisionEvaluator implementa el puerto de decisiones. ConditionEvaluator,
JsonPointerResolver, AstLimits y IntervalOverlapAnalyzer son componentes puros.
Ver [semántica y límites](DECISION_EVALUATOR.md). T06/T11 conservan la implementación
del validador y handlers; no se añadió ninguna llamada HTTP ni persistencia.