El briefing que parecía simple
El cliente lo explicó en dos frases: comparar lo que tiene la venta en JDE con lo que un sistema externo quiere hacer con ella. Específicamente, cómo ese sistema externo quería distribuir esa venta entre distintas líneas.
Sobre el papel, suena a lógica condicional básica.
La realidad tenía tres capas que se complicaban entre sí:
- Validar si lo que pedía el sistema externo era posible dado el estado actual de la orden en JDE.
- Generar un primer array con los cambios a aplicar sobre las líneas existentes.
- Generar un segundo array con las líneas completamente nuevas que había que agregar.
Dos arrays de salida con naturaleza distinta. Reglas de negocio que mutaban con cada iteración del proyecto. Y producción esperando.

El primer intento: LEX
La primera aproximación fue con LEX. Es la herramienta natural para lógica condicional dentro de un Orchestrator sin salirte del entorno estándar. Para reglas fijas y criterios predecibles, funciona bien.
Funcionó hasta que dejó de funcionar.
Las condiciones de negocio empezaron a evolucionar. Excepciones sobre excepciones. Combinaciones de campos que no estaban previstas en el diseño original. En Lex, cada cambio era una cirugía con riesgo de romper lo que ya estaba validado. Y el ritmo de cambios del proyecto no perdonaba esa fragilidad.
Llegó el momento de asumir que Lex no era la herramienta para este problema.
El paso a Groovy y la primera fricción real
Groovy en el paso Manipulate Input es la respuesta cuando la lógica supera lo que Lex puede expresar. Tienes el lenguaje completo: bucles, estructuras de datos arbitrarias, lógica condicional sin límites.
Pero hay dos fricciones concretas que complican el trabajo en un Custom Request.
La primera es la entrada. Recibir datos desde un Data Request o un Form Request tiene sus propias reglas de estructura y si no las manejas con precisión, pasas tiempo depurando algo que no es un error de lógica sino de formato del payload.
La segunda, y más limitante para este caso, es la salida. Un Custom Request en Orchestrator devuelve un array. Uno solo. Y aquí el proceso necesitaba producir dos conjuntos de datos con estructura y propósito completamente distintos.
Con un único Orchestrator, el problema no tiene solución limpia.
La arquitectura que finalmente funcionó
La solución llegó cuando paré de intentar resolver todo en un único lugar y dividí el problema por responsabilidades.
El Orchestrator principal actúa como director de orquesta. Recibe la información del sistema externo junto con los datos de la venta en JDE y tiene una responsabilidad clara: coordinar el flujo completo sin ejecutar lógica de negocio por sí mismo.
Su primera acción es llamar al segundo Orchestrator, el de comparación, pasándole los dos conjuntos de datos iniciales. Este segundo Orchestrator es donde vive toda la inteligencia del proceso. En el paso Manipulate Input con Groovy, aplica las reglas de negocio: valida si la distribución solicitada es viable dado el estado real de la orden, calcula los deltas entre lo que hay y lo que se pide, y clasifica cada diferencia. Si durante ese proceso detecta inconsistencias o condiciones de error, las captura y las devuelve estructuradas. Si la validación es correcta, devuelve los dos arrays resultantes: el de cambios a aplicar en líneas existentes y el de líneas nuevas a agregar.
El control regresa al Orchestrator principal. Aquí se produce la validación de errores. Si el segundo Orchestrator devolvió errores, el flujo se detiene y se notifica al sistema externo con el detalle exacto del problema. Si no hay errores, el principal llama al tercer Orchestrator pasándole los dos arrays completos.
El tercer Orchestrator tiene una sola misión: ejecutar. Recibe los arrays, procesa cada sección de forma independiente y realiza las transacciones en JDE: actualiza las líneas que deben cambiar y agrega las que son nuevas.
El rol del LLM en el Groovy del segundo Orchestrator
Este punto merece honestidad, porque es donde se pone interesante para cualquiera que trabaje con JDE hoy.
El código Groovy que aplica las reglas de comparación en el segundo Orchestrator no nació de un editor de texto en solitario. Lo construí en conversación con un LLM, con prompts muy específicos: la estructura exacta del JSON de entrada, las reglas de validación en orden de precedencia, los casos de error que debía identificar y el formato concreto que necesitaban los dos arrays de salida.
El LLM no conoce JDE. No sabe qué es una orden de venta ni cómo funciona la distribución por Business Unit. Pero sí sabe construir lógica de comparación y transformación sobre estructuras JSON bien descritas. Cuando le das el contexto preciso, genera un punto de partida sólido en minutos que luego refinas con el conocimiento del negocio que ningún modelo tiene.
Esa combinación, Groovy más LLM más conocimiento profundo de JDE, es probablemente la forma de trabajo más eficiente que he encontrado para lógica compleja en Orchestrator.
Lo que cambia cuando separas responsabilidades así
Hay una lección de arquitectura aquí que va más allá del caso concreto.
Cuando un Orchestrator acumula demasiada lógica porque el problema es complejo, la respuesta instintiva es añadir más pasos, más condiciones, más capas. El resultado es un Orchestrator que funciona pero que nadie puede mantener en producción seis meses después sin miedo.
Tratar cada Orchestrator como una unidad con una responsabilidad única cambia completamente la ecuación del mantenimiento. Cuando llegó el siguiente cambio de reglas de negocio en este proyecto, la modificación fue quirúrgica: solo afectó al segundo Orchestrator. El principal y el tercero no se tocaron.
Y en un entorno donde las reglas de negocio cambian, esa capacidad de modificar sin romper vale más que cualquier optimización técnica puntual.
El impacto real en el proyecto
La distribución de ventas que antes requería revisión manual para cada caso especial ahora se procesa de forma automática, incluyendo las excepciones. El sistema externo recibe confirmación de si su solicitud fue procesada o rechazada, con el detalle del motivo, sin intervención humana.
Si tienes un proceso de integración en JDE donde la lógica ya superó lo que las herramientas estándar pueden manejar, ese es exactamente el tipo de arquitectura que diseño en consultoría. Escríbeme y cuéntame tu caso.