Módulo 2: Branching y Decisiones Avanzadas

Decisiones con Datos Calculados (Pre-Cómputo)

Descripción de la cápsula

Has visto en cápsulas anteriores el patrón "Set antes de IF/Switch". Esta cápsula lo formaliza como un principio de diseño: toda decisión compleja debería operar sobre campos pre-calculados, no sobre datos crudos.

Suena obvio cuando lo dices. Pero la mayoría de los workflows en producción no lo hacen — operan IFs sobre $json.body.algo directamente, repiten cálculos en varios nodos, y se vuelven imposibles de mantener. Aplicar pre-cómputo consistentemente es lo que diferencia workflows caseros de workflows profesionales.

En esta cápsula vas a aprender los 4 tipos de campos calculados más útiles, cómo estructurar el "Set de categorización", el patrón "data preparation pipeline" para workflows complejos, y los anti-patrones comunes al precomputar.


Lo que vas a aprender

Al terminar esta cápsula serás capaz de:

  • Aplicar pre-cómputo como principio de diseño en todo workflow
  • Identificar los 4 tipos de campos calculados típicos
  • Diseñar "data preparation pipelines" para workflows complejos
  • Reconocer cuándo NO precomputar (no es la solución universal)
  • Decidir entre 1 Set grande vs varios Sets según el caso

El principio: separar "qué decir" de "cómo decirlo"

Imagina escribir un script:

Mal:

"Si el monto, dividido por la cantidad de items, multiplicado por el factor de descuento que depende del país, ajustado al impuesto local, es mayor que el threshold de aprobación que cambia según el tipo de cliente y horario..."

Bien:

"El precio efectivo es X. El threshold de aprobación es Y. Si X > Y, requiere aprobación."

El primero es ininteligible. El segundo es claro. La diferencia: conceptos calculados con nombre vs lógica esparcida.

En workflows pasa lo mismo. Pre-computar crea conceptos con nombre que el resto del workflow usa.


Los 4 tipos de campos calculados

Tipo 1: Categorías derivadas

Calcular a qué categoría pertenece un item. Resultado: string descriptivo.

Ejemplos:

  • lead_category: "enterprise" | "mid_market" | "smb" | "self_serve"
  • region: "na" | "eu" | "latam" | "apac"
  • priority: "high" | "medium" | "low"
  • tier: "vip" | "standard" | "trial"

Tipo 2: Flags (Booleans)

Calcular si cumple cierta condición. Resultado: true/false.

Ejemplos:

  • is_corporate: true si email corporativo
  • is_vip: true si monto > X
  • is_business_hours: true si dentro de 9am-6pm L-V
  • has_complete_documentation: true si campos requeridos llenos

Tipo 3: Métricas derivadas (números)

Calcular valores numéricos a partir de datos crudos.

Ejemplos:

  • days_since_registration: diferencia entre now y registration_date
  • total_amount_with_taxes: amount * (1 + tax_rate)
  • lead_score: cálculo de scoring con varios factores
  • customer_age: derivado de birth_date

Tipo 4: Datos formateados

Preparar strings listos para mostrar/enviar.

Ejemplos:

  • slack_message: ya con emojis, formato, datos sustituidos
  • email_subject: con datos dinámicos
  • readable_date: ISO timestamp → "11 de mayo de 2026"
  • url_short: URL acortada para mostrar

Patrón completo: Data Preparation Pipeline

Workflows complejos se benefician de un pipeline de preparación al inicio:

[Trigger]
   │
   ▼
[Set 1: Normalizar]
  - Convertir tipos (string → number)
  - Trim espacios
  - Lowercase emails
  - Defaults para campos faltantes
   │
   ▼
[Set 2: Validar]
  - is_valid (Boolean)
  - invalid_reason (String)
   │
   ▼
[Filter: solo items válidos]
   │
   ▼
[Set 3: Categorizar y enriquecer]
  - lead_category
  - region
  - flags varios
  - métricas derivadas
   │
   ▼
[Lógica del workflow (IF, Switch, etc.)]
  - Solo opera sobre campos pre-calculados
  - Decisiones simples y legibles

Beneficios

  • Separation of concerns: preparación está en un lugar; lógica en otro
  • Debuggable: inspeccionas el Set 3 y ves exactamente qué categoría calculó
  • Reutilizable: si otro workflow usa los mismos campos, copy-paste del Set 3
  • Mantenible: cambias el cálculo de categoría = cambias 1 nodo

Cuándo 1 Set grande vs varios Sets

1 Set grande

[Set: todo]
- normalizar 5 campos
- calcular 4 categorías
- agregar 3 flags
- formatear 2 strings

Pros: menos nodos en el canvas. Más rápido de ejecutar.

Contras: difícil de debuggear (todo o nada). Difícil de leer cuando hay 15+ campos.

Varios Sets pequeños

[Set: normalizar] → [Set: validar] → [Set: enriquecer]

Pros: cada Set tiene un propósito claro. Debuggable independientemente.

Contras: más nodos. Ligeramente más lento (insignificante en práctica).

Decisión práctica

  • Workflow simple (5-10 campos): 1 Set grande
  • Workflow complejo (15+ campos o multi-etapa): varios Sets
  • Cuando dudes: varios Sets pequeños. Mantenibilidad gana sobre performance casi siempre.

Cuándo NO precomputar

Pre-cómputo es buena práctica pero no universal. No lo hagas cuando:

1. El campo se usa una sola vez

Si solo necesitas dias_desde_registro en un solo IF, calcular inline es OK:

{{ DateTime.now().diff(DateTime.fromISO($json.registration_date), 'days').days > 7 }}

Crear un Set previo para algo de uso único agrega overhead sin beneficio.

2. El cálculo es trivial

Para una transformación simple como .toLowerCase() o .trim(), no es necesario un Set específico — puedes hacerlo donde se use.

3. Performance es crítica

(Raro en workflows típicos pero existe.) Sets adicionales agregan latencia microscópica. Si tu workflow corre 10,000 veces por hora, podría importar.


Patrón: lookup tables en lugar de IF/Switch grandes

Para mapeos categóricos extensos, una tabla de lookup suele ser más limpia que muchos IFs.

Ejemplo

Mapear country (ISO code) a region:

Mal: IF en cadena o Switch grande

{{
  ["US", "CA", "MX"].includes($json.country) ? "na" :
  ["GB", "DE", "FR", "ES", "IT"].includes($json.country) ? "eu" :
  ["BR", "AR", "CL", "CO", "PE"].includes($json.country) ? "latam" :
  "other"
}}

Bien: lookup table

{{
  ({
    'US': 'na', 'CA': 'na', 'MX': 'na',
    'GB': 'eu', 'DE': 'eu', 'FR': 'eu', 'ES': 'eu', 'IT': 'eu',
    'BR': 'latam', 'AR': 'latam', 'CL': 'latam', 'CO': 'latam', 'PE': 'latam'
  })[$json.country] || 'other'
}}

Ventajas:

  • Más fácil agregar país nuevo (1 entrada en el objeto)
  • Más fácil de leer cuando son muchos países

Para tablas muy grandes (50+ entries), considera mantenerlas en un Sheet/DB separado y leer con un nodo.


Refactoring: convertir workflow "spaghetti" a "pipeline"

Si tienes un workflow existente con lógica esparcida, el refactor:

Antes (anti-patrón)

[Webhook]
   │
[IF: $json.body.amount > 100] ← cálculo en condición
   │
[Set: agregar campo X] ← preparación tardía
   │
[IF: $json.email.toLowerCase().endsWith('.com')] ← cálculo en condición
   │
[Slack: "Mensaje con {{ $json.body.name.split(' ')[0] }}..."]] ← cálculo en mensaje

Cada nodo hace cálculos. Imposible saber qué pasa sin leer cada expression.

Después (pipeline)

[Webhook]
   │
[Set 1: Normalizar]
- amount_num: Number($json.body.amount)
- email_lower: $json.body.email.toLowerCase()
- first_name: $json.body.name.split(' ')[0]
   │
[Set 2: Categorizar]
- is_high_value: amount_num > 100
- is_com_domain: email_lower.endsWith('.com')
   │
[IF: is_high_value AND is_com_domain]
   │
[Slack: "Mensaje con {{ $json.first_name }}..."]

Cada Set tiene rol claro. Los IFs operan sobre Booleans simples. Slack usa campos pre-formateados.


Trampas comunes

Trampa 1: Pre-computar todo, incluso lo no necesario

Qué pasa: Tu Set tiene 30 campos. La mayoría no se usan. Workflow más lento de leer.

Cómo evitar: Precompute solo lo que el workflow downstream realmente usa. Si calculas un campo "por si acaso", probablemente no necesitas.


Trampa 2: Set con expressions imposibles de leer

Qué pasa: Un Set con expressions de 10 líneas anidadas. Más confuso que IFs esparcidos.

Cómo evitar:

  • Comentar expressions complejas (en cápsula 02 viste el patrón con //)
  • Descomponer en varios Sets si una expression es muy compleja
  • Usar Code node si la lógica realmente justifica más

Trampa 3: Olvidar actualizar el Set cuando cambian inputs

Qué pasa: Tu Set asume $json.body.email. Más tarde el trigger cambia y el campo es $json.email. Set falla silenciosamente o devuelve undefined.

Cómo evitar: Cuando refactorizas un trigger, revisar el Set inmediatamente siguiente para ajustar.


Trampa 4: Cálculos no determinísticos

Qué pasa: Tu Set incluye $now. Cada vez que ejecutas, el valor es distinto — comportamiento inconsistente entre ejecuciones del mismo input.

Cómo evitar:

  • Si necesitas timestamp consistente, capturarlo una vez en Set inicial y referenciarlo después
  • Para tests con datos pineados, el problema se mitiga (pin data captura $now del momento del pin)

Trampa 5: Pre-computar redundantemente con datos del trigger

Qué pasa: El webhook trae email_normalizado. Tu Set lo "normaliza" otra vez. Redundancia.

Cómo evitar: inspeccionar el output del trigger antes de pre-computar. Si ya viene listo, no recalcular.


Ejercicio: refactorizar a pipeline

Objetivo: practicar transformar lógica esparcida a pipeline.

Tu workflow inicial

[Webhook]
   │
[IF: Number($json.body.amount) > 1000 && $json.body.email.includes('@')]
   │
[Slack: "Lead grande: {{ $json.body.name.split(' ')[0] }} - ${{ Number($json.body.amount).toFixed(2) }}"]

Tu tarea

Refactorízalo a pipeline con:

  1. Set de normalización (amount_num, email_lower, first_name)
  2. Set de categorización (is_large_lead, formatted_amount)
  3. IF que usa el Boolean calculado
  4. Slack con expressions simples
Solución sugerida
[Webhook]
   │
[Set: normalizar]
- amount_num: {{ Number($json.body.amount) }}
- email_lower: {{ $json.body.email.toLowerCase() }}
- first_name: {{ $json.body.name.split(' ')[0] }}
   │
[Set: categorizar]
- is_large_lead: {{ $json.amount_num > 1000 && $json.email_lower.includes('@') }}
- formatted_amount: {{ '$' + $json.amount_num.toFixed(2) }}
   │
[IF: $json.is_large_lead is true]
   │
[Slack: "Lead grande: {{ $json.first_name }} - {{ $json.formatted_amount }}"]

Más nodos, mucho más legible.


Resumen y siguiente paso

  • Pre-cómputo como principio: toda decisión compleja opera sobre campos calculados, no datos crudos
  • 4 tipos de campos calculados: categorías, flags (Booleans), métricas, datos formateados
  • Pipeline pattern: normalizar → validar → categorizar → lógica
  • 1 Set grande vs varios: varios para complejo, uno para simple
  • Lookup tables para mapeos categoricos extensos (más limpio que Switch grande)
  • Cuándo NO precomputar: uso único, cálculos triviales, perf crítica
  • 5 trampas: pre-computar todo, expressions ilegibles, no actualizar al cambiar inputs, no determinístico, redundancia

Antes de avanzar deberías poder:

  • Aplicar el patrón pipeline en tus workflows
  • Decidir 1 Set vs varios según complejidad
  • Refactorizar lógica esparcida a pre-cómputo
  • Usar lookup tables cuando aplica

Lo que sigue (cápsula 05):

Cuando un workflow procesa N items, a veces necesitas filtrar progresivamente antes de hacer operaciones costosas. Filtros en cadena = el patrón de aplicar filtros secuenciales, cada uno descartando items que no cumplen condiciones, para llegar al subset relevante.


Recursos adicionales

  1. Pipeline Pattern (Wikipedia) - Concepto general.
  2. Separation of Concerns - Principio de diseño.

Creado: Mayo 11, 2026 Versión: 1.0