Ir al contenido
FINORA Academy
SistemaFINORA Plataforma

FINORA Plataforma · Conceptos

Orquestación de procesos con BPMN 2.0

ImplementadoImplementado

El problema: el proceso vive en la cabeza de alguien

Sección titulada «El problema: el proceso vive en la cabeza de alguien»

«Cuando se abre una cuenta de una empresa, cumplimiento la revisa; si la aprueba, se abre la cuenta de depósito.» Procesos así existen en todo banco, pero suelen vivir en correos, en hojas de cálculo o en un programa a medida que solo entiende quien lo escribió. Cambiar un paso significa pedir un desarrollo, y nadie puede ver en qué paso está cada caso.

La idea: el proceso como un plano que se aprueba

Sección titulada «La idea: el proceso como un plano que se aprueba»

El orquestador ejecuta procesos descritos en BPMN 2.0, el estándar para dibujar procesos de negocio: eventos de inicio, tareas automáticas, tareas de personas, decisiones y fin. El motor es Flowable (código abierto) y FINORA lo rodea de controles bancarios:

flowchart LR
  E((Inicio:<br/>evento del core)) --> T1[Consultar el core<br/>por el gateway]
  T1 --> D{¿Supera el umbral?}
  D -- sí --> H[Tarea de persona<br/>cuatro ojos]
  D -- no --> T2[Registrar en el core]
  H -- aprobado --> T2
  H -- rechazado --> F2((Fin))
  T2 --> F((Fin))

El orquestador no toca la base del core: todas sus llamadas pasan por el gateway (https://<su-gateway>/v1), con sus alcances, su idempotencia y su bitácora.

Una definición de proceso recorre un ciclo fijo:

stateDiagram-v2
  [*] --> DRAFT: se sube el BPMN
  DRAFT --> PENDING_APPROVAL: se envía a aprobación
  PENDING_APPROVAL --> APPROVED: otra persona aprueba
  PENDING_APPROVAL --> REJECTED: otra persona rechaza
  APPROVED --> CURRENT: se activa
  CURRENT --> RETIRED: se retira o la reemplaza otra versión
  • Quien creó o envió una definición no puede aprobarla ni rechazarla: el orquestador responde 403 MAKER_CHECKER, y la base de datos lo refuerza con una restricción propia.
  • Solo hay una versión vigente (CURRENT) por proceso. Al activar una nueva, la anterior pasa a RETIRED: los casos en curso terminan con su versión y los nuevos usan la vigente.

Destinos y callDestination: ninguna llamada sin aprobar

Sección titulada «Destinos y callDestination: ninguna llamada sin aprobar»

Un destino es una conexión con nombre lógico (por ejemplo, finora-core) hacia una URL, con sus credenciales cifradas. El mismo proceso sirve en otro ambiente cambiando solo la URL del destino. Los destinos también pasan por maker-checker: un alta queda PENDING_APPROVAL y no se puede usar hasta que la apruebe otra persona; un cambio sobre un destino aprobado queda como cambio pendiente y la versión aprobada sigue en uso mientras tanto. La API nunca devuelve las credenciales.

Dentro del BPMN, toda tarea automática es una llamada a un destino con callDestination: se dice el destino, el método, la ruta y qué variables van y vuelven.

La política de seguridad: el BPMN no es código

Sección titulada «La política de seguridad: el BPMN no es código»

Un BPMN podría, en teoría, ejecutar cualquier programa. El orquestador lo impide al subirlo y otra vez al activarlo:

  • Las tareas automáticas solo pueden ser callDestination. No se admiten clases Java, expresiones arbitrarias, scripts, ni tareas de correo, HTTP directo o consola.
  • En las expresiones solo son visibles las variables del proceso y dos ayudas propias; pedir cualquier otro componente del servidor falla.
  • El XML se lee de forma segura (sin entidades externas) y debe tener exactamente un proceso ejecutable.
  • Un proceso puede iniciar sin evento, por temporizador o por mensaje. Señales, condiciones y otros eventos de inicio se rechazan.

Una tarea de persona se asigna a un grupo (por ejemplo, oficial-cumplimiento). Marcada con cuatro ojos, quien inició el caso no puede completarla aunque pertenezca al grupo: responde 403 CUATRO_OJOS. Quien completa queda registrado en la historia del caso. Es el mismo principio que en el core: Cuatro ojos.

Una llamada puede fallar por la red o porque el core no responde a tiempo. Las tareas automáticas se reintentan solas y, si se agotan los intentos, el caso queda en incidente con el mensaje del error; corregida la causa, se reintenta a mano. Lo importante es que un reintento no duplica la operación: cada escritura viaja con una clave de idempotencia estable por caso y por paso, de modo que si el primer intento sí llegó al core, el segundo recibe la misma respuesta en lugar de registrar el asiento dos veces. Iniciar un caso con la misma clave de idempotencia devuelve el mismo caso.

El core publica eventos de negocio (por ejemplo AccEntryPosted cuando se asienta un comprobante, AccountChanged cuando cambia una cuenta, TransactionPosted cuando se registra una transacción) y puede entregarlos por webhook. El orquestador tiene un receptor para ellos:

POST /api/v1/webhooks/finora-core/{mensaje}
X-Finora-Signature: t=<segundos>,v1=<HMAC-SHA256 de "t." + cuerpo>
X-Finora-Webhook-Id: <id estable de la entrega>
X-Finora-Event-Type: AccEntryPosted
sequenceDiagram
  participant Core as FINORA Core
  participant O as Orquestador
  participant M as Motor BPMN
  Core->>O: webhook firmado (evento)
  O->>O: verifica la firma y el sello de tiempo (300 s)
  alt firma inválida o vieja
    O-->>Core: 401
  else firma válida
    O->>M: inicia la versión vigente que escucha {mensaje}
    M-->>O: caso nuevo (o el mismo, si es un reintento)
    O-->>Core: 201 (o 200 si ya existía)
  end
  • La firma se verifica con el secreto de la suscripción, en tiempo constante; un sello de tiempo con más de 300 segundos de diferencia se rechaza.
  • X-Finora-Webhook-Id es la clave de idempotencia: el core la mantiene igual en todos sus reintentos, así que un reintento devuelve el caso que ya se había iniciado en lugar de abrir otro.
  • El caso recibe el evento completo como variable (evento), más eventType, webhookId y la fuente.