orquestador/specs/EVENTS.md

87 lines
5.2 KiB
Markdown
Raw 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.

# Aceptación durable de eventos — T09
Implementado `POST /api/v1/requests/{id}/events`, habilitado por
`REQUEST_API_ENABLED=true` junto con T08. Requiere JWT válido, propietario y ámbito
coincidentes, `Idempotency-Key` y un `If-Match` fuerte como `"0"`.
```json
{"event":"SUBMIT","data":{}}
```
El evento y sus datos deben corresponder al flujo publicado de la solicitud.
No se aceptan estado, roles, identidad, resultados o transición desde el cliente.
Se aplican los mismos límites de T08: datos canónicos de 256 KiB, cuerpo acotado
a 256 KiB + 4096 bytes y profundidad JSON 64; rechazo de duplicados y UTF-8 inválido.
## Protocolo
1. Verificar acceso; bloquear la solicitud con SELECT FOR UPDATE, filtrando otra
vez propietario/ámbito dentro de la transacción.
2. Buscar la clave por request_id/idempotency_key. Mismo hash y sujeto autorizado:
devolver executionId y estado técnico actual. Hash distinto: 409
IDEMPOTENCY_CONFLICT. El hash SHA-256 incluye evento, datos canónicos y revisión
esperada; cambiar If-Match también cambia el comando.
3. Sin replay, comprobar revisión (412) y ausencia de ejecución activa (409
REQUEST_BUSY). La revisión se comprueba antes de busy, por lo que una carrera
con dos claves y la misma revisión produce un aceptado y otro 412.
4. Leer la definición inmutable fijada por flow_id, sin resolver el activo del tipo.
PUBLISHED y RETIRED pueden ejecutar instancias existentes. Resolver la transición
para estado/evento, exigir uno de allowedRoles (403), validar inputSchema (422)
y evaluar guardia pura con request.data/event.data/actor confiables.
5. Insertar execution PENDING con identidad mínima, evento, transición y estado
origen. Incrementar revisión y updated_at de solicitud, insertar EVENT_ACCEPTED.
Confirmar las tres escrituras en una sola transacción READ COMMITTED.
6. Retornar 202 con Location `/api/v1/executions/{id}` y AcceptedEvent contractual.
accepted_revision guarda la revisión **posterior a aceptar** (If-Match + 1), que
T10 deberá verificar al confirmar trabajo. La solicitud conserva datos y estado
de negocio; T09 no ejecuta acciones, transiciones finales ni HTTP a proveedores.
No se guarda el JWT: actor_snapshot contiene subject, businessScope y roles.
La auditoría registra transición, revisión y correlationId, sin copiar datos del evento.
## Reintentos y errores
El replay se comprueba antes de revisión, busy, transición, roles y guardia actuales.
Devuelve el mismo executionId y status actual, incluso después de avanzar la
solicitud o terminar la ejecución. Exige siempre acceso actual y el sujeto original;
una revocación del rol de transición no vuelve a autorizar efectos, pues el replay
solo consulta la aceptación anterior. No incrementa revisión ni duplica auditoría.
Para reintentar un comando perdido, conservar también el If-Match original.
Un evento nuevo usa otra clave. Mientras haya PENDING, RUNNING, RETRY_WAIT o
RECONCILIATION_REQUIRED no se admite otra ejecución. Las restricciones SQL existentes
son defensa adicional. Un error de persistencia revierte ejecución, revisión y
auditoría; no consume la clave.
Evento no válido en el estado: 409 INVALID_EVENT. Guardia falsa: 422
GUARD_NOT_SATISFIED; ruta ausente/tipo incompatible: 422 EVALUATION_ERROR, no una
condición falsa ni resultado de negocio. Sin If-Match: 428; débil/múltiple/inválido:
400. Recurso ajeno/inexistente: 404; sin autenticación: 401; infraestructura: 503
sin exponer SQL. Revisión agotada en Long.MAX_VALUE no se incrementa y rechaza 409.
## Alcance y verificación
El worker T10 y las integraciones T11 permanecen pendientes. Sin worker, los eventos
aceptados permanecen PENDING. GET /requests/{id} muestra la revisión nueva y la
ejecución activa. La URI Location es la contractual; el endpoint GET /executions/{id}
todavía no está implementado y se completará con el seguimiento de ejecución T10.
No se afirma idempotencia de efectos externos hasta implementar sus protocolos.
EventAcceptanceIT usa PostgreSQL real, login restringido, JWT RSA/JWKS local y HTTP
real. Reutiliza únicamente el fixture de T07/T08 en orquestador_test. Cubre A07–A09
en aceptación: replay/409, carreras simultáneas, schemas y guardias, acceso/roles,
flujo retirado fijado, estados activos y rollback inducido al insertar ejecución,
actualizar revisión e insertar auditoría. Los cambios a SUCCEEDED/RUNNING/etc. son
fixtures SQL explícitos de prueba; no simulan un worker terminado en producción.
Una instancia nueva de adapter recupera el replay desde DB; no se anuncia una prueba
de reinicio del proceso ni procesamiento externo. T16 verificará el recorrido completo.
Comando: `mvnw.cmd clean verify -Pmigration-tests-external` con variables
MIGRATION_TEST_DB_URL/USER/PASSWORD en entorno. Los esquemas/roles temporales propios
se eliminan al terminar. No se modifica orquestador ni se despliega el servicio.
Desde T10 GET /executions/{id} y worker opcional ya están implementados. La sección
anterior de alcance corresponde al cierre de T09. Ver WORKER.md: sin WORKER_ENABLED
los aceptados siguen PENDING; con worker habilitado los flujos sin acciones pueden
concluir y las integraciones no registradas fallan explícitamente, sin mocks.