← Volver a proyectos

Workflow Automation Engine

Core contributor · backend + frontend
Ejecutor sobre grafo dirigido: 21 tipos de step (condiciones, loops, sub-workflows)
Sandbox aislado (128MB por isolate) con DSL propio transpilado con Babel
Replay estilo Temporal para verificar determinismo — crítico en un sistema financiero

Automatización de workflows · Motor de ejecución · Fintech B2B en EE.UU.

Una plataforma de automatización visual estilo Zapier, pensada para un dominio financiero regulado: cada corrida vive en una VM aislada con un tope duro de memoria, la lógica del usuario se compila a través de un DSL propio en vez de correr como JavaScript crudo, y cualquier ejecución pasada se puede reproducir paso a paso para verificar que da el mismo resultado. Fue el servicio de mayor carga de toda la plataforma. Trabajé tanto en el motor de ejecución como en el editor visual.

20+tipos de step
128MBtope de memoria por isolate

¿Qué problema resuelve el Workflow Automation Engine?

La operación de negocio en préstamos involucra procesos largos y ramificados: traer datos de proveedores externos, aplicar reglas de decisión, transformar payloads entre formatos, llamar APIs de partners, esperar respuestas asíncronas, escalar, reintentar. Estos flujos cambiaban todo el tiempo y variaban por cliente, así que hardcodearlos no era sostenible. Necesitaban ser configurables por gente que no programa —pero también manejan plata real, lo cual significa que “configurable” no podía significar “inseguro” o “impredecible”.

¿Cómo funciona el motor de ejecución?

El editor visual es un lienzo basado en nodos donde el usuario compone flujos a partir de steps tipados y los conecta en caminos ramificados, con edición de código inline para la lógica de cada step.

El motor de ejecución es la parte sustancial. Corre un grafo de steps dirigido con control de flujo real —más de 20 tipos de step, entre condiciones, tablas de decisión, loops, saltos, splits en paralelo, sub-workflows anidados, llamadas a APIs externas, consultas a base de datos, mapeo y transformación de datos, evaluación de fórmulas, operaciones de archivos y pausa/resume asíncronos. Como soporta loops y saltos, el grafo es genuinamente cíclico —no un DAG— así que el motor resuelve el próximo step en cada iteración en tiempo de ejecución, en vez de precomputar un orden topológico.

¿Qué decisiones técnicas sostienen el Workflow Automation Engine?

Ejecutar código de usuario, seguro

Una VM aislada por ejecución, con tope duro de memoria

Los usuarios escriben lógica que corre en un sistema financiero de producción. Un eval crudo o un sandbox blando no eran aceptables. Cada ejecución corre dentro de una instancia de VM aislada con un tope duro de 128 MB de memoria y una superficie de runtime deliberadamente mínima.

  • Tope duro de 128 MB por isolate, superficie de runtime mínima y controlada
  • Sin estado compartido entre ejecuciones — un workflow no puede leer datos de otra corrida
  • Concurrencia acotada por memoria, no por CPU → escala horizontalmente, no verticalmente
Un lenguaje propio, no JavaScript crudo

Un DSL compilado a través de un transpiler

La lógica del usuario se escribe en un lenguaje específico de dominio, parseado y compilado a través de un transpiler con un plugin de compilador propio —visitors para declaraciones, expresiones, identificadores, acceso a miembros— hacia código ejecutable seguro.

  • Control total sobre qué puede expresar el usuario, sin exponer JavaScript crudo
  • Mensajes de error específicos del dominio, no stack traces crudos de JS
  • El lenguaje puede evolucionar y recompilarse sin exponer el runtime de abajo
Determinismo, probado

Replay: de una suposición a algo que se verifica solo

La propiedad que más importaba: la misma entrada siempre tiene que producir la misma salida. Un workflow que se comporta distinto en silencio al re-ejecutarse es un problema de corrección y de auditoría en un sistema financiero.

  • Reproduce cualquier ejecución pasada, instrucción por instrucción, contra el resultado original
  • Estado de falla explícito: "el replay divergió, esta ejecución fue no-determinística"
  • Modo de ejecución en sombra para comparar corridas lado a lado

Ejecución asíncrona y en producción

Los flujos de larga duración se despachan a una cola de mensajes y los procesa el mismo servicio corriendo como consumidor: la misma imagen sirve requests HTTP de forma síncrona y consume la cola de forma asíncrona, con el rol determinado por cómo arranca y no por dos bases de código separadas. Los mensajes que fallan reintentan con backoff y caen a una dead-letter queue, con el estado de la ejecución persistido en todo momento.

Cierre

Este fue el servicio de mayor carga de toda la plataforma, corriendo workflows financieros críticos para el negocio en producción, escalado horizontalmente para el pico de volumen de clientes. Lo que más me importa de este proyecto no es la lista de tipos de step —es la disciplina de tratar el determinismo como algo que se prueba, no como algo que se asume, en un sistema donde una ejecución que no se puede reproducir es, directamente, un problema de auditoría.