orquestador/contracts/openapi.yaml

1479 lines
52 KiB
YAML

openapi: 3.1.0
jsonSchemaDialect: https://json-schema.org/draft/2020-12/schema
info:
title: Orquestador NMP
version: 1.0.0
description: Contrato objetivo del MVP. Solicitudes, eventos, ejecuciones, conciliación, tareas e historial implementados hasta T15; simulación administrativa implementada en T16. JWT y autorización por
recurso obligatorios. Campos opcionales ausentes se omiten; no se usa null salvo en datos configurables.
servers:
- url: /api/v1
security:
- bearerAuth: []
tags:
- name: Requests
- name: Administration
paths:
/requests:
post:
operationId: createRequest
summary: Crear solicitud y fijar flujo activo
description: 'Owner y businessScope se derivan del JWT autorizado. Idempotencia durable por actor/scope: repetición
idéntica retorna la respuesta original de creación (201, Location y ETag originales), incluso si cambió el flujo activo o avanzó la solicitud; otro hash retorna 409. GET devuelve el estado actual. data se valida con initialDataSchema y
dataSchema del flujo. Máximo de datos 256 KiB. No se aceptan estado, propietario o resultados de proveedor
como autoridad del cliente. Tipo inexistente retorna 404; tipo deshabilitado, sin flujo publicado activo o cambiado durante la asignación retorna 409 INVALID_FLOW_STATE. Un 409 por cambio concurrente permite reintentar la misma clave, que no queda reservada.'
tags:
- Requests
parameters:
- $ref: '#/components/parameters/IdempotencyKey'
responses:
'201':
description: Crear solicitud y fijar flujo activo
content:
application/json:
schema:
$ref: ../schemas/api.schema.json#/$defs/RequestView
example:
id: 00000000-0000-0000-0000-000000000123
typeKey: CREDITO
flow:
id: 00000000-0000-0000-0000-000000000456
flowKey: SCORING_DEMO
version: 1
currentState: BURO_PENDIENTE
data:
clienteId: CLI-DEMO
consentimientoId: CONS-DEMO
revision: 7
createdAt: '2026-10-26T17:20:00Z'
updatedAt: '2026-10-26T17:20:00Z'
headers:
ETag:
description: Revisión fuerte, entre comillas, por ejemplo "7".
schema:
type: string
pattern: ^"[0-9]+"$
Location:
description: URI del recurso creado o ejecución aceptada.
schema:
type: string
format: uri-reference
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'409':
$ref: '#/components/responses/Conflict'
'413':
$ref: '#/components/responses/PayloadTooLarge'
'422':
$ref: '#/components/responses/UnprocessableEntity'
'503':
$ref: '#/components/responses/Unavailable'
requestBody:
required: true
content:
application/json:
schema:
$ref: ../schemas/api.schema.json#/$defs/CreateRequest
example:
typeKey: CREDITO
data:
clienteId: CLI-DEMO
consentimientoId: CONS-DEMO
/requests/{id}:
get:
operationId: getRequest
summary: Consultar solicitud autorizada
description: Consultar solicitud autorizada
tags:
- Requests
parameters:
- $ref: '#/components/parameters/Id'
responses:
'200':
description: Consultar solicitud autorizada
content:
application/json:
schema:
$ref: ../schemas/api.schema.json#/$defs/RequestView
example:
id: 00000000-0000-0000-0000-000000000123
typeKey: CREDITO
flow:
id: 00000000-0000-0000-0000-000000000456
flowKey: SCORING_DEMO
version: 1
currentState: BURO_PENDIENTE
data:
clienteId: CLI-DEMO
consentimientoId: CONS-DEMO
revision: 7
createdAt: '2026-10-26T17:20:00Z'
updatedAt: '2026-10-26T17:20:00Z'
headers:
ETag:
description: Revisión fuerte, entre comillas, por ejemplo "7".
schema:
type: string
pattern: ^"[0-9]+"$
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'503':
$ref: '#/components/responses/Unavailable'
/requests/{id}/available-events:
get:
operationId: availableEvents
summary: Consultar tareas y eventos permitidos
description: 'Orientativo: el POST revalida roles y guardias. Con ejecución activa, events vacío y blockedByExecutionId
presente. Sólo se exponen causas de bloqueo no sensibles. Filtra por propietario, ámbito y roles; usa la versión fijada incluso retirada. Guardias dependientes de event.data se difieren al POST. Cache-Control no-store, sin ETag; revision sirve para If-Match del evento.'
tags:
- Requests
parameters:
- $ref: '#/components/parameters/Id'
responses:
'200':
description: Consultar tareas y eventos permitidos
content:
application/json:
schema:
$ref: ../schemas/api.schema.json#/$defs/AvailableEvents
example:
requestId: 00000000-0000-0000-0000-000000000123
revision: 8
events: []
blocked: []
blockedByExecutionId: 00000000-0000-0000-0000-000000000789
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'503':
$ref: '#/components/responses/Unavailable'
/requests/{id}/events:
post:
operationId: acceptEvent
summary: Aceptar un evento durable
description: 'Una transición por evento; sin HTTP externo en la transacción de aceptación. El hash incluye
evento, datos y revisión esperada canónicos. Primero comprobar acceso e idempotencia y después revisión;
un replay idéntico devuelve el mismo executionId/status actual incluso si cambió revision. Nueva clave mientras
existe ejecución activa: REQUEST_BUSY (se comprueba revisión antes de busy). Validar data con schema del evento. Reintentar conservando If-Match original. 202 no equivale a éxito de negocio; GET de ejecución permite seguimiento; el worker se habilita explícitamente con WORKER_ENABLED.'
tags:
- Requests
parameters:
- $ref: '#/components/parameters/Id'
- $ref: '#/components/parameters/IdempotencyKey'
- $ref: '#/components/parameters/IfMatch'
responses:
'202':
description: Aceptar un evento durable
content:
application/json:
schema:
$ref: ../schemas/api.schema.json#/$defs/AcceptedEvent
example:
executionId: 00000000-0000-0000-0000-000000000789
requestId: 00000000-0000-0000-0000-000000000123
status: PENDING
headers:
Location:
description: URI del recurso creado o ejecución aceptada.
schema:
type: string
format: uri-reference
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'409':
$ref: '#/components/responses/Conflict'
'412':
$ref: '#/components/responses/PreconditionFailed'
'413':
$ref: '#/components/responses/PayloadTooLarge'
'422':
$ref: '#/components/responses/UnprocessableEntity'
'428':
$ref: '#/components/responses/PreconditionRequired'
'503':
$ref: '#/components/responses/Unavailable'
requestBody:
required: true
content:
application/json:
schema:
$ref: ../schemas/api.schema.json#/$defs/EventCommand
example:
event: REGISTRAR_LICENCIA
data:
documentId: 00000000-0000-0000-0000-000000000789
/executions/{id}:
get:
operationId: getExecution
summary: Consultar ejecución autorizada
description: Verificar acceso a la solicitud asociada. SUCCEEDED es éxito técnico y puede contener resultado
de negocio desfavorable; los fallos asíncronos se consultan aquí. El cliente hace polling con backoff y
después actualiza solicitud/ETag.
tags:
- Requests
parameters:
- $ref: '#/components/parameters/Id'
responses:
'200':
description: Consultar ejecución autorizada
content:
application/json:
schema:
$ref: ../schemas/api.schema.json#/$defs/ExecutionView
example:
id: 00000000-0000-0000-0000-000000000789
requestId: 00000000-0000-0000-0000-000000000123
event: ASIGNAR_CLIENTE
status: SUCCEEDED
result:
outcome: CLIENTE_NO_ENCONTRADO
fromState: CREADA
toState: CREADA
reasonCodes:
- NO_MATCH
createdAt: '2026-10-26T17:20:00Z'
updatedAt: '2026-10-26T17:20:00Z'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'503':
$ref: '#/components/responses/Unavailable'
/requests/{id}/history:
get:
operationId: getHistory
summary: Consultar auditoría paginada y filtrada
description: Orden ascendente (createdAt,id), cursor opaco asociado a solicitud y filtros. Máximo 100. Omitir
nextCursor al terminar. from inclusivo y to exclusivo, UTC Z. Propietario y ámbito obligatorios, sin bypass administrativo. Detail se proyecta por lista permitida (IDs de reglas/acciones, razones y códigos); no entrega evidencia ni resultados completos. Cache-Control no-store. Cursor representa posición, no autorización; no promete snapshot entre páginas concurrentes.
tags:
- Requests
parameters:
- $ref: '#/components/parameters/Id'
- $ref: '#/components/parameters/Cursor'
- $ref: '#/components/parameters/Limit'
- name: kind
in: query
schema:
type: string
pattern: ^[A-Za-z][A-Za-z0-9_.-]{0,99}$
- name: executionId
in: query
schema:
type: string
format: uuid
- name: from
in: query
schema:
type: string
format: date-time
pattern: Z$
- name: to
in: query
schema:
type: string
format: date-time
pattern: Z$
responses:
'200':
description: Consultar auditoría paginada y filtrada
content:
application/json:
schema:
$ref: ../schemas/api.schema.json#/$defs/HistoryPage
example:
items:
- id: 00000000-0000-0000-0000-000000000789
requestId: 00000000-0000-0000-0000-000000000123
kind: EVENT_ACCEPTED
actorSubject: analista-demo
flowId: 00000000-0000-0000-0000-000000000456
fromState: CREADA
detail:
transitionId: asignar-cliente
createdAt: '2026-10-26T17:20:00Z'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'503':
$ref: '#/components/responses/Unavailable'
/admin/flows:
post:
operationId: createDraft
summary: Crear borrador
description: Clave/versión únicas. Cuerpo máximo 1 MiB. El borrador puede tener errores semánticos que se
reportarán al validar; siempre debe cumplir el schema estructural.
tags:
- Administration
parameters: []
responses:
'201':
description: Crear borrador
content:
application/json:
schema:
$ref: ../schemas/api.schema.json#/$defs/FlowView
example:
id: 00000000-0000-0000-0000-000000000456
status: DRAFT
revision: 0
definition:
schemaVersion: 1
flowKey: SCORING_DEMO
version: 1
initialState: BURO_PENDIENTE
dataSchema:
type: object
properties:
clienteId:
type: string
consentimientoId:
type: string
validaciones:
type: object
required:
- clienteId
- consentimientoId
additionalProperties: false
states:
- key: BURO_PENDIENTE
terminal: false
- key: PASO_N
terminal: true
- key: PASO_M
terminal: true
- key: REVISION_MANUAL
terminal: true
events:
- key: VALIDAR_BURO
inputSchema:
type: object
additionalProperties: false
transitions:
- id: consultar-buro
from: BURO_PENDIENTE
event: VALIDAR_BURO
allowedRoles:
- ANALISTA
actions:
- id: buro
type: INVOKE_INTEGRATION
integrationKey: BURO_CONSULTA
contractVersion: '1'
inputs:
clienteId:
path: /request/data/clienteId
consentimientoId:
path: /request/data/consentimientoId
resultKey: buro
decision: RUTA_SCORING
destinations:
N: PASO_N
M: PASO_M
MANUAL: REVISION_MANUAL
updates:
- target: /validaciones/buro
value:
path: /results/buro
decisions:
- id: RUTA_SCORING
hitPolicy: UNIQUE
rules:
- id: alto
when:
op: GT
left:
path: /results/buro/score
right:
literal: 70
output: N
- id: medio
when:
op: AND
args:
- op: GT
left:
path: /results/buro/score
right:
literal: 60
- op: LTE
left:
path: /results/buro/score
right:
literal: 70
output: M
defaultOutput: MANUAL
tasks: []
createdAt: '2026-10-26T17:20:00Z'
createdBy: editor-demo
headers:
ETag:
description: Revisión fuerte, entre comillas, por ejemplo "7".
schema:
type: string
pattern: ^"[0-9]+"$
Location:
description: URI del recurso creado o ejecución aceptada.
schema:
type: string
format: uri-reference
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'409':
$ref: '#/components/responses/Conflict'
'413':
$ref: '#/components/responses/PayloadTooLarge'
'422':
$ref: '#/components/responses/UnprocessableEntity'
'503':
$ref: '#/components/responses/Unavailable'
x-required-roles:
- FLOW_EDITOR
requestBody:
required: true
content:
application/json:
schema:
$ref: ../schemas/flow-definition.schema.json
example:
schemaVersion: 1
flowKey: SCORING_DEMO
version: 1
initialState: BURO_PENDIENTE
dataSchema:
type: object
properties:
clienteId:
type: string
consentimientoId:
type: string
validaciones:
type: object
required:
- clienteId
- consentimientoId
additionalProperties: false
states:
- key: BURO_PENDIENTE
terminal: false
- key: PASO_N
terminal: true
- key: PASO_M
terminal: true
- key: REVISION_MANUAL
terminal: true
events:
- key: VALIDAR_BURO
inputSchema:
type: object
additionalProperties: false
transitions:
- id: consultar-buro
from: BURO_PENDIENTE
event: VALIDAR_BURO
allowedRoles:
- ANALISTA
actions:
- id: buro
type: INVOKE_INTEGRATION
integrationKey: BURO_CONSULTA
contractVersion: '1'
inputs:
clienteId:
path: /request/data/clienteId
consentimientoId:
path: /request/data/consentimientoId
resultKey: buro
decision: RUTA_SCORING
destinations:
N: PASO_N
M: PASO_M
MANUAL: REVISION_MANUAL
updates:
- target: /validaciones/buro
value:
path: /results/buro
decisions:
- id: RUTA_SCORING
hitPolicy: UNIQUE
rules:
- id: alto
when:
op: GT
left:
path: /results/buro/score
right:
literal: 70
output: N
- id: medio
when:
op: AND
args:
- op: GT
left:
path: /results/buro/score
right:
literal: 60
- op: LTE
left:
path: /results/buro/score
right:
literal: 70
output: M
defaultOutput: MANUAL
tasks: []
/admin/flows/{id}:
put:
operationId: updateDraft
summary: Reemplazar definición de borrador
description: Sólo DRAFT. flowKey/version no cambian; crear otra versión para cambiar identidad. Publicados/retirados
son inmutables. Máximo 1 MiB.
tags:
- Administration
parameters:
- $ref: '#/components/parameters/Id'
- $ref: '#/components/parameters/IfMatch'
responses:
'200':
description: Reemplazar definición de borrador
content:
application/json:
schema:
$ref: ../schemas/api.schema.json#/$defs/FlowView
example:
id: 00000000-0000-0000-0000-000000000456
status: DRAFT
revision: 0
definition:
schemaVersion: 1
flowKey: SCORING_DEMO
version: 1
initialState: BURO_PENDIENTE
dataSchema:
type: object
properties:
clienteId:
type: string
consentimientoId:
type: string
validaciones:
type: object
required:
- clienteId
- consentimientoId
additionalProperties: false
states:
- key: BURO_PENDIENTE
terminal: false
- key: PASO_N
terminal: true
- key: PASO_M
terminal: true
- key: REVISION_MANUAL
terminal: true
events:
- key: VALIDAR_BURO
inputSchema:
type: object
additionalProperties: false
transitions:
- id: consultar-buro
from: BURO_PENDIENTE
event: VALIDAR_BURO
allowedRoles:
- ANALISTA
actions:
- id: buro
type: INVOKE_INTEGRATION
integrationKey: BURO_CONSULTA
contractVersion: '1'
inputs:
clienteId:
path: /request/data/clienteId
consentimientoId:
path: /request/data/consentimientoId
resultKey: buro
decision: RUTA_SCORING
destinations:
N: PASO_N
M: PASO_M
MANUAL: REVISION_MANUAL
updates:
- target: /validaciones/buro
value:
path: /results/buro
decisions:
- id: RUTA_SCORING
hitPolicy: UNIQUE
rules:
- id: alto
when:
op: GT
left:
path: /results/buro/score
right:
literal: 70
output: N
- id: medio
when:
op: AND
args:
- op: GT
left:
path: /results/buro/score
right:
literal: 60
- op: LTE
left:
path: /results/buro/score
right:
literal: 70
output: M
defaultOutput: MANUAL
tasks: []
createdAt: '2026-10-26T17:20:00Z'
createdBy: editor-demo
headers:
ETag:
description: Revisión fuerte, entre comillas, por ejemplo "7".
schema:
type: string
pattern: ^"[0-9]+"$
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'409':
$ref: '#/components/responses/Conflict'
'412':
$ref: '#/components/responses/PreconditionFailed'
'413':
$ref: '#/components/responses/PayloadTooLarge'
'422':
$ref: '#/components/responses/UnprocessableEntity'
'428':
$ref: '#/components/responses/PreconditionRequired'
'503':
$ref: '#/components/responses/Unavailable'
x-required-roles:
- FLOW_EDITOR
requestBody:
required: true
content:
application/json:
schema:
$ref: ../schemas/flow-definition.schema.json
example:
schemaVersion: 1
flowKey: SCORING_DEMO
version: 1
initialState: BURO_PENDIENTE
dataSchema:
type: object
properties:
clienteId:
type: string
consentimientoId:
type: string
validaciones:
type: object
required:
- clienteId
- consentimientoId
additionalProperties: false
states:
- key: BURO_PENDIENTE
terminal: false
- key: PASO_N
terminal: true
- key: PASO_M
terminal: true
- key: REVISION_MANUAL
terminal: true
events:
- key: VALIDAR_BURO
inputSchema:
type: object
additionalProperties: false
transitions:
- id: consultar-buro
from: BURO_PENDIENTE
event: VALIDAR_BURO
allowedRoles:
- ANALISTA
actions:
- id: buro
type: INVOKE_INTEGRATION
integrationKey: BURO_CONSULTA
contractVersion: '1'
inputs:
clienteId:
path: /request/data/clienteId
consentimientoId:
path: /request/data/consentimientoId
resultKey: buro
decision: RUTA_SCORING
destinations:
N: PASO_N
M: PASO_M
MANUAL: REVISION_MANUAL
updates:
- target: /validaciones/buro
value:
path: /results/buro
decisions:
- id: RUTA_SCORING
hitPolicy: UNIQUE
rules:
- id: alto
when:
op: GT
left:
path: /results/buro/score
right:
literal: 70
output: N
- id: medio
when:
op: AND
args:
- op: GT
left:
path: /results/buro/score
right:
literal: 60
- op: LTE
left:
path: /results/buro/score
right:
literal: 70
output: M
defaultOutput: MANUAL
tasks: []
/admin/flows/{id}/validate:
post:
operationId: validateFlow
summary: Validar configuración sin publicarla
description: Errores semánticos devuelven 200 con valid=false y JSON Pointers. Sin invocar proveedores. Incluye
grafo, catálogos, límites de AST y mappings.
tags:
- Administration
parameters:
- $ref: '#/components/parameters/Id'
responses:
'200':
description: Validar configuración sin publicarla
content:
application/json:
schema:
$ref: ../schemas/api.schema.json#/$defs/ValidationReport
example:
valid: false
errors:
- pointer: /transitions/0/to
code: UNKNOWN_STATE
message: Estado destino inexistente.
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'503':
$ref: '#/components/responses/Unavailable'
x-required-roles:
- FLOW_EDITOR
- FLOW_PUBLISHER
/admin/flows/{id}/simulate:
post:
operationId: simulateFlow
summary: Simular evaluación pura
description: Sin HTTP ni efectos persistentes. requestData/actor/results son fixtures administrativos, nunca
comandos de negocio. Evaluar guardia/decisión/updates con resultados suministrados; rechazo de tipos y ambigüedad
como problem 422. Body máximo 1 MiB; requestData/event.data/cada resultado máximo 256 KiB. results usa exactamente los resultKey externos de la transición. NO_OP sólo permitido en simulación, toma output de la definición sin fixture externo. Cache-Control no-store. Actor de fixture no sustituye JWT FLOW_EDITOR ni ámbito administrativo.
tags:
- Administration
parameters:
- $ref: '#/components/parameters/Id'
responses:
'200':
description: Simular evaluación pura
content:
application/json:
schema:
$ref: ../schemas/api.schema.json#/$defs/SimulationResult
example:
transitionId: consultar-buro
outcome: N
toState: PASO_N
data:
clienteId: CLI-DEMO
consentimientoId: CONS-DEMO
validaciones:
buro:
score: 71
consultationId: SIM-001
matchedRuleIds:
- alto
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'409':
$ref: '#/components/responses/Conflict'
'413':
$ref: '#/components/responses/PayloadTooLarge'
'422':
$ref: '#/components/responses/UnprocessableEntity'
'503':
$ref: '#/components/responses/Unavailable'
x-required-roles:
- FLOW_EDITOR
requestBody:
required: true
content:
application/json:
schema:
$ref: ../schemas/api.schema.json#/$defs/SimulationInput
example:
state: BURO_PENDIENTE
requestData:
clienteId: CLI-DEMO
consentimientoId: CONS-DEMO
event:
event: VALIDAR_BURO
data: {}
actor:
subject: analista-demo
roles:
- ANALISTA
businessScope: DEMO
results:
buro:
score: 71
consultationId: SIM-001
/admin/flows/{id}/publish:
post:
operationId: publishFlow
summary: Publicar versión inmutable
description: Valida semántica, resuelve versiones de contratos/perfiles, calcula SHA-256 del JSON canónico
y registra auditoría. Rechaza NO_OP. Debe ser DRAFT.
tags:
- Administration
parameters:
- $ref: '#/components/parameters/Id'
- $ref: '#/components/parameters/IfMatch'
responses:
'200':
description: Publicar versión inmutable
content:
application/json:
schema:
$ref: ../schemas/api.schema.json#/$defs/FlowView
example:
id: 00000000-0000-0000-0000-000000000456
status: PUBLISHED
revision: 1
definition:
schemaVersion: 1
flowKey: SCORING_DEMO
version: 1
initialState: BURO_PENDIENTE
dataSchema:
type: object
properties:
clienteId:
type: string
consentimientoId:
type: string
validaciones:
type: object
required:
- clienteId
- consentimientoId
additionalProperties: false
states:
- key: BURO_PENDIENTE
terminal: false
- key: PASO_N
terminal: true
- key: PASO_M
terminal: true
- key: REVISION_MANUAL
terminal: true
events:
- key: VALIDAR_BURO
inputSchema:
type: object
additionalProperties: false
transitions:
- id: consultar-buro
from: BURO_PENDIENTE
event: VALIDAR_BURO
allowedRoles:
- ANALISTA
actions:
- id: buro
type: INVOKE_INTEGRATION
integrationKey: BURO_CONSULTA
contractVersion: '1'
inputs:
clienteId:
path: /request/data/clienteId
consentimientoId:
path: /request/data/consentimientoId
resultKey: buro
decision: RUTA_SCORING
destinations:
N: PASO_N
M: PASO_M
MANUAL: REVISION_MANUAL
updates:
- target: /validaciones/buro
value:
path: /results/buro
decisions:
- id: RUTA_SCORING
hitPolicy: UNIQUE
rules:
- id: alto
when:
op: GT
left:
path: /results/buro/score
right:
literal: 70
output: N
- id: medio
when:
op: AND
args:
- op: GT
left:
path: /results/buro/score
right:
literal: 60
- op: LTE
left:
path: /results/buro/score
right:
literal: 70
output: M
defaultOutput: MANUAL
tasks: []
createdAt: '2026-10-26T17:20:00Z'
createdBy: editor-demo
checksum: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
publishedAt: '2026-10-26T17:20:00Z'
headers:
ETag:
description: Revisión fuerte, entre comillas, por ejemplo "7".
schema:
type: string
pattern: ^"[0-9]+"$
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'409':
$ref: '#/components/responses/Conflict'
'412':
$ref: '#/components/responses/PreconditionFailed'
'422':
$ref: '#/components/responses/UnprocessableEntity'
'428':
$ref: '#/components/responses/PreconditionRequired'
'503':
$ref: '#/components/responses/Unavailable'
x-required-roles:
- FLOW_PUBLISHER
/admin/request-types/{key}/active-flow:
put:
operationId: activateFlow
summary: Activar flujo de un tipo existente
description: If-Match corresponde al tipo, no al flujo. Sólo versión PUBLISHED. Tipos se provisionan mediante
migración/configuración administrativa; tipo inexistente retorna 404. Activación y retiro se serializan.
Nuevas solicitudes fijan esta versión; existentes no migran.
tags:
- Administration
parameters:
- $ref: '#/components/parameters/TypeKey'
- $ref: '#/components/parameters/IfMatch'
responses:
'200':
description: Activar flujo de un tipo existente
content:
application/json:
schema:
$ref: ../schemas/api.schema.json#/$defs/RequestTypeView
example:
typeKey: CREDITO
activeFlowId: 00000000-0000-0000-0000-000000000456
enabled: true
revision: 1
headers:
ETag:
description: Revisión fuerte, entre comillas, por ejemplo "7".
schema:
type: string
pattern: ^"[0-9]+"$
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'409':
$ref: '#/components/responses/Conflict'
'412':
$ref: '#/components/responses/PreconditionFailed'
'413':
$ref: '#/components/responses/PayloadTooLarge'
'422':
$ref: '#/components/responses/UnprocessableEntity'
'428':
$ref: '#/components/responses/PreconditionRequired'
'503':
$ref: '#/components/responses/Unavailable'
x-required-roles:
- FLOW_ADMIN
requestBody:
required: true
content:
application/json:
schema:
$ref: ../schemas/api.schema.json#/$defs/ActivateFlow
example:
flowId: 00000000-0000-0000-0000-000000000456
/admin/flows/{id}/retire:
post:
operationId: retireFlow
summary: Retirar versión para nuevas asignaciones
description: Sólo PUBLISHED a RETIRED. Bloquear asignaciones concurrentes; conservar ejecución de instancias
existentes. No borrar la definición.
tags:
- Administration
parameters:
- $ref: '#/components/parameters/Id'
- $ref: '#/components/parameters/IfMatch'
responses:
'200':
description: Retirar versión para nuevas asignaciones
content:
application/json:
schema:
$ref: ../schemas/api.schema.json#/$defs/FlowView
example:
id: 00000000-0000-0000-0000-000000000456
status: RETIRED
revision: 1
definition:
schemaVersion: 1
flowKey: SCORING_DEMO
version: 1
initialState: BURO_PENDIENTE
dataSchema:
type: object
properties:
clienteId:
type: string
consentimientoId:
type: string
validaciones:
type: object
required:
- clienteId
- consentimientoId
additionalProperties: false
states:
- key: BURO_PENDIENTE
terminal: false
- key: PASO_N
terminal: true
- key: PASO_M
terminal: true
- key: REVISION_MANUAL
terminal: true
events:
- key: VALIDAR_BURO
inputSchema:
type: object
additionalProperties: false
transitions:
- id: consultar-buro
from: BURO_PENDIENTE
event: VALIDAR_BURO
allowedRoles:
- ANALISTA
actions:
- id: buro
type: INVOKE_INTEGRATION
integrationKey: BURO_CONSULTA
contractVersion: '1'
inputs:
clienteId:
path: /request/data/clienteId
consentimientoId:
path: /request/data/consentimientoId
resultKey: buro
decision: RUTA_SCORING
destinations:
N: PASO_N
M: PASO_M
MANUAL: REVISION_MANUAL
updates:
- target: /validaciones/buro
value:
path: /results/buro
decisions:
- id: RUTA_SCORING
hitPolicy: UNIQUE
rules:
- id: alto
when:
op: GT
left:
path: /results/buro/score
right:
literal: 70
output: N
- id: medio
when:
op: AND
args:
- op: GT
left:
path: /results/buro/score
right:
literal: 60
- op: LTE
left:
path: /results/buro/score
right:
literal: 70
output: M
defaultOutput: MANUAL
tasks: []
createdAt: '2026-10-26T17:20:00Z'
createdBy: editor-demo
checksum: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
publishedAt: '2026-10-26T17:20:00Z'
headers:
ETag:
description: Revisión fuerte, entre comillas, por ejemplo "7".
schema:
type: string
pattern: ^"[0-9]+"$
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'409':
$ref: '#/components/responses/Conflict'
'412':
$ref: '#/components/responses/PreconditionFailed'
'428':
$ref: '#/components/responses/PreconditionRequired'
'503':
$ref: '#/components/responses/Unavailable'
x-required-roles:
- FLOW_ADMIN
/admin/executions/{id}/resolve:
post:
operationId: resolveExecution
summary: Conciliar una ejecución incierta
description: Sólo RECONCILIATION_REQUIRED, con acceso por scope. Evidencia referenciada y verificada por operador
autorizado; no admite elegir estado destino. RESUME registra resultados verificados y reencola PENDING;
CLOSE_WITHOUT_TRANSITION registra ausencia/compensación verificada por el operador y cierra FAILED conservando negocio. No consulta automáticamente al proveedor.
Idempotencia durable por ejecución/clave y comando canónico; replay exige el mismo sujeto operador y devuelve la misma resolución.
Auditoría obligatoria.
tags:
- Administration
parameters:
- $ref: '#/components/parameters/Id'
- $ref: '#/components/parameters/IdempotencyKey'
responses:
'200':
description: Conciliar una ejecución incierta
content:
application/json:
schema:
$ref: ../schemas/api.schema.json#/$defs/ReconciliationView
example:
resolutionId: 00000000-0000-0000-0000-000000000456
executionId: 00000000-0000-0000-0000-000000000789
status: PENDING
resolvedAt: '2026-10-26T17:20:00Z'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'409':
$ref: '#/components/responses/Conflict'
'412':
$ref: '#/components/responses/PreconditionFailed'
'413':
$ref: '#/components/responses/PayloadTooLarge'
'422':
$ref: '#/components/responses/UnprocessableEntity'
'503':
$ref: '#/components/responses/Unavailable'
x-required-roles:
- EXECUTION_OPERATOR
requestBody:
required: true
content:
application/json:
schema:
$ref: ../schemas/api.schema.json#/$defs/ReconciliationCommand
example:
mode: RESUME
evidence:
reference: CASE-DEMO-001
reason: Resultado verificado con proveedor.
verifiedActions:
- actionId: buro
result:
score: 71
consultationId: SIM-001
providerReference: SIM-001
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
parameters:
Id:
name: id
in: path
required: true
schema:
type: string
format: uuid
TypeKey:
name: key
in: path
required: true
schema:
type: string
pattern: ^[A-Za-z][A-Za-z0-9_.-]{0,99}$
IfMatch:
name: If-Match
in: header
required: true
description: Una única revisión fuerte entre comillas; no se admite * ni ETag débil.
schema:
type: string
pattern: ^"[0-9]+"$
IdempotencyKey:
name: Idempotency-Key
in: header
required: true
schema:
type: string
minLength: 1
maxLength: 200
pattern: ^[!-~]+$
Cursor:
name: cursor
in: query
required: false
schema:
type: string
minLength: 1
maxLength: 2000
Limit:
name: limit
in: query
required: false
schema:
type: integer
minimum: 1
maximum: 100
default: 50
responses:
BadRequest:
description: Sintaxis o cabeceras inválidas.
content:
application/problem+json:
schema:
$ref: ../schemas/api.schema.json#/$defs/Problem
example:
type: about:blank
title: Sintaxis o cabeceras inválidas.
status: 400
code: BAD_REQUEST
correlationId: demo-correlation-001
Unauthorized:
description: JWT ausente, inválido o vencido.
content:
application/problem+json:
schema:
$ref: ../schemas/api.schema.json#/$defs/Problem
example:
type: about:blank
title: JWT ausente, inválido o vencido.
status: 401
code: UNAUTHORIZED
correlationId: demo-correlation-001
headers:
WWW-Authenticate:
schema:
type: string
description: Challenge Bearer.
Forbidden:
description: Permiso insuficiente.
content:
application/problem+json:
schema:
$ref: ../schemas/api.schema.json#/$defs/Problem
example:
type: about:blank
title: Permiso insuficiente.
status: 403
code: FORBIDDEN
correlationId: demo-correlation-001
NotFound:
description: Recurso inexistente o no visible; se oculta existencia ajena.
content:
application/problem+json:
schema:
$ref: ../schemas/api.schema.json#/$defs/Problem
example:
type: about:blank
title: Recurso inexistente o no visible; se oculta existencia ajena.
status: 404
code: NOT_FOUND
correlationId: demo-correlation-001
Conflict:
description: REQUEST_BUSY, INVALID_EVENT, IDEMPOTENCY_CONFLICT o conflicto de ciclo de vida.
content:
application/problem+json:
schema:
$ref: ../schemas/api.schema.json#/$defs/Problem
example:
type: about:blank
title: REQUEST_BUSY, INVALID_EVENT, IDEMPOTENCY_CONFLICT o conflicto de ciclo de vida.
status: 409
code: REQUEST_BUSY
correlationId: demo-correlation-001
PreconditionFailed:
description: La revisión If-Match no coincide.
content:
application/problem+json:
schema:
$ref: ../schemas/api.schema.json#/$defs/Problem
example:
type: about:blank
title: La revisión If-Match no coincide.
status: 412
code: REVISION_MISMATCH
correlationId: demo-correlation-001
PayloadTooLarge:
description: Se excedió el límite de tamaño.
content:
application/problem+json:
schema:
$ref: ../schemas/api.schema.json#/$defs/Problem
example:
type: about:blank
title: Se excedió el límite de tamaño.
status: 413
code: PAYLOAD_TOO_LARGE
correlationId: demo-correlation-001
UnprocessableEntity:
description: Schema/guardia incumplida o configuración semánticamente inválida.
content:
application/problem+json:
schema:
$ref: ../schemas/api.schema.json#/$defs/Problem
example:
type: about:blank
title: Schema/guardia incumplida o configuración semánticamente inválida.
status: 422
code: VALIDATION_ERROR
correlationId: demo-correlation-001
PreconditionRequired:
description: Falta If-Match.
content:
application/problem+json:
schema:
$ref: ../schemas/api.schema.json#/$defs/Problem
example:
type: about:blank
title: Falta If-Match.
status: 428
code: PRECONDITION_REQUIRED
correlationId: demo-correlation-001
Unavailable:
description: Infraestructura no disponible para aceptar la operación.
content:
application/problem+json:
schema:
$ref: ../schemas/api.schema.json#/$defs/Problem
example:
type: about:blank
title: Infraestructura no disponible para aceptar la operación.
status: 503
code: SERVICE_UNAVAILABLE
correlationId: demo-correlation-001