> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lerian.studio/llms.txt
> Use this file to discover all available pages before exploring further.

# Guía de diseño de workflows

> Diseña workflows de Flowker con confianza — tipos de node, edges, patrones reales, transiciones de estado y mejores prácticas de orquestación.

Diseña workflows en Flowker con claridad y control. Esta guía recorre los tipos de nodes, edges, patrones del mundo real, transiciones de estado, límites técnicos y mejores prácticas para ayudarte a construir orquestaciones confiables y mantenibles.

## Tipos de nodes

***

Todo workflow se construye a partir de nodes. Cada node tiene un `type` que define cómo Flowker lo procesa en tiempo de ejecución.

### trigger

Un node trigger es un punto de entrada de ejecución. Los workflows en draft pueden estar incompletos, pero la activación requiere al menos un node trigger. Cuando una ejecución comienza mediante un trigger, el motor entra por ese node y enruta desde él.

Los ejemplos de esta página muestran solo la topología de nodes. Un node trigger real también lleva un `triggerType` y la configuración de ese trigger en su `data` — consulta [Configurar un trigger de webhook](/es/flowker/configuring-a-webhook-trigger) o [Ejecutar un workflow con un schedule](/es/flowker/running-a-workflow-on-a-schedule).

```json theme={null}
{
  "id": "node-trigger",
  "type": "trigger",
  "name": "Payment Received"
}
```

### executor

Llama a un servicio externo a través de una configuración de provider. Este es el bloque de construcción principal para integrarse con motores de fraude, providers de pago, servicios de notificación y otros sistemas externos.

Los ejemplos de esta página muestran solo la topología de nodes. Un node executor real también lleva un `providerConfigId` y, si usa un executor del catálogo, un `executorId` en su `data`. Un node que llama a una operación de un documento OpenAPI cargado omite `executorId` y lleva `operation_path` y `operation_method` — consulta la [Guía de integración](/es/flowker/integration-guide).

```json theme={null}
{
  "id": "node-fraud-check",
  "type": "executor",
  "name": "Check Fraud Score"
}
```

### conditional

Evalúa una condición contra el contexto de ejecución y enruta hacia diferentes ramas según el resultado. Usa nodes conditional para implementar lógica de ramificación, por ejemplo, dirigir hacia un flujo de aprobación cuando el riesgo es alto, o continuar directamente cuando es bajo.

La condición vive en `data.condition` del node. Una expresión de texto libre se evalúa como booleana y produce el handle de salida `true` o `false`; cada edge de salida declara qué handle sigue mediante `sourceHandle`. Los nodes conditional creados en la Console usan una condición estructurada basada en casos, donde cada caso enruta hacia su propio handle de salida — consulta el [Editor de canvas](/es/flowker/console/canvas-editor).

```json theme={null}
{
  "id": "node-risk-decision",
  "type": "conditional",
  "name": "Evaluate Risk Score",
  "data": { "condition": "node-fraud-check.riskScore < 70" }
}
```

### action

Representa una operación interna síncrona `set_output`. Puede escribir un valor de salida interpolado y, opcionalmente, reemplazar el estado de respuesta HTTP síncrona. No proporciona una pausa integrada, emisión genérica de eventos ni una operación genérica de cambio de estado.

```json theme={null}
{
  "id": "node-record-approval",
  "type": "action",
  "name": "Record Approval Decision"
}
```

## Edges

***

Los edges conectan nodes y definen las rutas de ejecución. Cada edge incluye los siguientes campos:

| Campo          | Descripción                                                                                                                                                                                                   |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`           | Identificador único del edge.                                                                                                                                                                                 |
| `source`       | ID del node de origen.                                                                                                                                                                                        |
| `target`       | ID del node de destino.                                                                                                                                                                                       |
| `sourceHandle` | Handle de salida del node de origen que sigue este edge. Obligatorio para enrutar desde un node conditional: debe coincidir con el resultado de la rama (`true` o `false` para una condición de texto libre). |
| `condition`    | Campo legado de texto libre mantenido por compatibilidad. No se evalúa para el enrutamiento — déjalo vacío en workflows nuevos.                                                                               |
| `label`        | Etiqueta legible utilizada para visualización y depuración.                                                                                                                                                   |

### Ejemplo de edge

```json theme={null}
{
  "id": "edge-approved",
  "source": "node-risk-decision",
  "target": "node-process-payment",
  "sourceHandle": "true",
  "label": "Approved"
}
```

El enrutamiento depende del tipo del node de origen. Un node conditional evalúa su `data.condition` y sigue el único edge de salida cuyo `sourceHandle` coincide con el resultado de la rama; si ningún edge coincide, esa rama termina. Todos los demás tipos de node siguen todos sus edges de salida cuando se completan exitosamente.

## Transiciones de estado

***

Los workflows siguen un ciclo de vida bien definido. Comprender estas transiciones es clave para desplegar y evolucionar workflows de manera segura.

<Frame>
  <img src="https://mintcdn.com/lerian-49cb71fc/SEOef3JqTInYAAau/images/es/d2/flowker-workflow-status-transitions.svg?fit=max&auto=format&n=SEOef3JqTInYAAau&q=85&s=e5aaa7faaec7b1dcf89afee3ae0f70cc" alt="Diagrama de transición de estados del workflow mostrando tres estados: draft, active e inactive. Una flecha etiquetada 'activate' apunta de draft a active. Una flecha etiquetada 'deactivate' apunta de active a inactive. Una flecha etiquetada 'draft' apunta de inactive de vuelta a draft." width="817" height="327" data-path="images/es/d2/flowker-workflow-status-transitions.svg" />
</Frame>

* **draft** — El estado inicial. Todas las modificaciones (agregar nodes, editar edges, cambiar configuración) solo están permitidas en estado `draft`.
* **active** — Un workflow que ha sido activado. Puede ser ejecutado. No se permiten modificaciones mientras está activo.
* **inactive** — Un workflow que ha sido desactivado. Ya no puede ser ejecutado, pero puede moverse de vuelta a `draft` para edición.

### Reglas

* Solo un workflow en `draft` puede ser activado (transición: `draft → active`).
* Solo un workflow en `active` puede ser desactivado (transición: `active → inactive`).
* Solo un workflow en `inactive` puede moverse de vuelta a draft (transición: `inactive → draft`).
* Intentar una transición inválida devuelve el error `FLK-0102`.
* Intentar modificar un workflow que no está en `draft` devuelve el error `FLK-0103`.

### Mover un workflow inactivo de vuelta a draft

Si desactivaste un workflow y quieres editarlo de nuevo, muévelo de vuelta a `draft` llamando a [`POST /v1/workflows/{id}/draft`](/es/reference/flowker/move-workflow-to-draft). Esto hace que el workflow sea editable sin necesidad de clonarlo.

Esto es útil cuando desactivaste un workflow por error o cuando quieres iterar sobre un workflow existente en lugar de crear una copia.

<Note>
  Solo los workflows inactivos pueden moverse a draft. Si necesitas modificar un workflow activo sin sacarlo de línea, usa el enfoque de clone descrito a continuación.
</Note>

### Iterar de forma segura con clone

Para modificar un workflow activo, primero clónalo. La clonación crea un nuevo `draft` desde cualquier estado, copiando todos los nodes y edges. Luego puedes actualizar, probar y activar sin impactar la versión actual.

Este es el enfoque recomendado para el versionado en producción.

## Límites técnicos

***

| Límite                                     | Valor | Código de error |
| ------------------------------------------ | ----- | --------------- |
| Máximo de nodes por workflow               | 100   | `FLK-0113`      |
| Máximo de edges por workflow               | 200   | `FLK-0114`      |
| Máximo del payload de entrada de ejecución | 1 MB  | `FLK-0506`      |

Ten en cuenta estos límites al diseñar flujos complejos. Los workflows con más de \~50 nodes generalmente indican que el flujo debería dividirse en workflows más pequeños y componibles.

## Patrones comunes

***

### Secuencial

El patrón más simple. Los nodes se ejecutan en una secuencia lineal. Úsalo cuando cada paso depende del anterior y no se requiere ramificación.

<Frame>
  <img src="https://mintcdn.com/lerian-49cb71fc/SEOef3JqTInYAAau/images/es/d2/flowker-pattern-sequential.svg?fit=max&auto=format&n=SEOef3JqTInYAAau&q=85&s=ab88ee0fab8765366cefbb5d007cbea5" alt="Patrón de workflow secuencial: un node trigger se conecta a un primer node executor, que se conecta a un segundo node executor, que se conecta a un tercer node executor. Todas las conexiones son flechas dirigidas formando una línea recta." width="957" height="268" data-path="images/es/d2/flowker-pattern-sequential.svg" />
</Frame>

**Ejemplo: Orquestación de pagos**

```json theme={null}
{
  "nodes": [
    { "id": "n1", "type": "trigger",  "name": "Payment Initiated" },
    { "id": "n2", "type": "executor", "name": "Validate Payment Data" },
    { "id": "n3", "type": "executor", "name": "Route to Provider" },
    { "id": "n4", "type": "executor", "name": "Send Confirmation Notification" }
  ],
  "edges": [
    { "id": "e1", "source": "n1", "target": "n2", "label": "Start" },
    { "id": "e2", "source": "n2", "target": "n3", "label": "Valid" },
    { "id": "e3", "source": "n3", "target": "n4", "label": "Routed" }
  ]
}
```

### Ramificación condicional

Un node `conditional` evalúa su condición y enruta la ejecución en consecuencia. El resultado de la rama selecciona qué edge de salida se sigue, según la coincidencia del `sourceHandle`.

<Frame>
  <img src="https://mintcdn.com/lerian-49cb71fc/SEOef3JqTInYAAau/images/es/d2/flowker-pattern-conditional.svg?fit=max&auto=format&n=SEOef3JqTInYAAau&q=85&s=7e33991b6437ddba54a9356371268244" alt="Patrón de workflow con ramificación condicional: un node trigger se conecta a un node executor, que se conecta a un node conditional. El node conditional tiene dos flechas de salida: una etiquetada 'Path A' apuntando a un primer node executor, y una etiquetada 'Path B' apuntando a un segundo node executor." width="999" height="394" data-path="images/es/d2/flowker-pattern-conditional.svg" />
</Frame>

**Ejemplo: Verificación antifraude**

```json theme={null}
{
  "nodes": [
    { "id": "n1", "type": "trigger",     "name": "Transaction Received" },
    { "id": "n2", "type": "executor",    "name": "Get Fraud Score" },
    {
      "id": "n3",
      "type": "conditional",
      "name": "Evaluate Score",
      "data": { "condition": "n2.fraudScore < 70" }
    },
    { "id": "n4", "type": "executor",    "name": "Approve Transaction" },
    { "id": "n5", "type": "executor",    "name": "Reject Transaction" }
  ],
  "edges": [
    { "id": "e1", "source": "n1", "target": "n2", "label": "Start" },
    { "id": "e2", "source": "n2", "target": "n3", "label": "Score received" },
    {
      "id": "e3",
      "source": "n3",
      "target": "n4",
      "sourceHandle": "true",
      "label": "Approved"
    },
    {
      "id": "e4",
      "source": "n3",
      "target": "n5",
      "sourceHandle": "false",
      "label": "Rejected"
    }
  ]
}
```

## Ejemplos del mundo real

***

### Verificación antifraude

Una transacción llega, se obtiene una puntuación de fraude y la ejecución se enruta hacia aprobación o rechazo.

```json theme={null}
{
  "nodes": [
    { "id": "n1", "type": "trigger",     "name": "Transaction Received" },
    { "id": "n2", "type": "executor",    "name": "Get Fraud Score" },
    {
      "id": "n3",
      "type": "conditional",
      "name": "Evaluate Fraud Score",
      "data": { "condition": "n2.fraudScore < 70" }
    },
    { "id": "n4", "type": "executor",    "name": "Approve Transaction" },
    { "id": "n5", "type": "executor",    "name": "Reject and Notify" }
  ],
  "edges": [
    { "id": "e1", "source": "n1", "target": "n2", "label": "Start" },
    { "id": "e2", "source": "n2", "target": "n3", "label": "Score received" },
    {
      "id": "e3",
      "source": "n3",
      "target": "n4",
      "sourceHandle": "true",
      "label": "Low risk"
    },
    {
      "id": "e4",
      "source": "n3",
      "target": "n5",
      "sourceHandle": "false",
      "label": "High risk"
    }
  ]
}
```

### Orquestación de pagos

Un flujo lineal que valida los datos de pago entrantes, los enruta al provider adecuado y envía una confirmación.

```json theme={null}
{
  "nodes": [
    { "id": "n1", "type": "trigger",  "name": "Payment Initiated" },
    { "id": "n2", "type": "executor", "name": "Validate Payment Data" },
    { "id": "n3", "type": "executor", "name": "Route to Payment Provider" },
    { "id": "n4", "type": "executor", "name": "Send Confirmation" }
  ],
  "edges": [
    { "id": "e1", "source": "n1", "target": "n2", "label": "Start" },
    { "id": "e2", "source": "n2", "target": "n3", "label": "Valid" },
    { "id": "e3", "source": "n3", "target": "n4", "label": "Payment routed" }
  ]
}
```

### Onboarding KYC

Usa un workflow para enviar una revisión de documentos a un sistema de aprobación externo. Flowker no tiene una pausa integrada: para una revisión humana asíncrona, inicia una ejecución de workflow posterior y separada cuando tu sistema de aprobación publique su decisión.

### Flujo de aprobación manual

Una solicitud se envía para revisión. Un executor consulta la decisión de la revisión en el sistema externo. Un node conditional luego enruta hacia el camino de aprobación o rechazo. Las ejecuciones de Flowker corren de principio a fin — no existe un paso de pausa integrado, así que una decisión humana debe venir de un sistema externo que el workflow consulta.

```json theme={null}
{
  "nodes": [
    { "id": "n1", "type": "trigger",     "name": "Request Submitted" },
    { "id": "n2", "type": "executor",    "name": "Submit for Review" },
    { "id": "n3", "type": "executor",    "name": "Get Approval Decision" },
    {
      "id": "n4",
      "type": "conditional",
      "name": "Decision Received",
      "data": { "condition": "n3.decision == 'approved'" }
    },
    { "id": "n5", "type": "executor",    "name": "Process Approved Request" },
    { "id": "n6", "type": "executor",    "name": "Notify Rejection" }
  ],
  "edges": [
    { "id": "e1", "source": "n1", "target": "n2", "label": "Start" },
    { "id": "e2", "source": "n2", "target": "n3", "label": "Submitted" },
    { "id": "e3", "source": "n3", "target": "n4", "label": "Decision received" },
    {
      "id": "e4",
      "source": "n4",
      "target": "n5",
      "sourceHandle": "true",
      "label": "Approved"
    },
    {
      "id": "e5",
      "source": "n4",
      "target": "n6",
      "sourceHandle": "false",
      "label": "Rejected"
    }
  ]
}
```

## Mejores prácticas

***

### Convenciones de nomenclatura de nodes

Usa nombres descriptivos y orientados a la acción que comuniquen lo que hace el node, no de qué tipo es.

* **correcto**: `Validate Payment Data`, `Get Fraud Score`, `Notify Customer`, `Get Approval Decision`
* **incorrecto**: `executor1`, `conditional node`, `node3`

Los buenos nombres hacen que los workflows sean legibles sin necesidad de abrir la configuración del node. También aparecen en los registros de ejecución y sus trazas, lo que hace que la depuración sea significativamente más rápida.

### Expresiones de condición

Las condiciones de texto libre en los nodes conditional se evalúan contra el contexto de ejecución en tiempo de ejecución. Mantenlas simples y explícitas:

* Usa comparaciones directas de campos: `<nodeId>.status == 'approved'`
* Usa comparaciones numéricas: `<nodeId>.riskScore < 70`
* Usa campos booleanos: `<nodeId>.reviewRequired == true`
* Combínalas con `AND` / `OR` cuando sea necesario: `<nodeId>.score < 70 AND <nodeId>.verified == true`

Evita expresiones complejas que sean difíciles de leer o depurar. Si la lógica no es trivial, dale al node `conditional` un nombre claro que encapsule la decisión.

Una condición ausente o que falla al evaluarse en tiempo de ejecución hace fallar la ejecución (`FLK-0105` identifica una expresión condicional inválida). Siempre prueba las condiciones antes de activar un workflow.

### Estrategias de manejo de errores

Diseña los workflows para manejar los fallos de forma explícita:

* Agrega rutas de rechazo desde nodes `conditional` para cada punto de decisión que pueda fallar.
* Usa nodes `executor` separados para lógica de reintentos o providers de respaldo.
* Nombra las rutas de error de forma clara (por ejemplo, `Reject and Notify`, `Fallback to Manual Review`) para que los registros de ejecución sean autoexplicativos.

### Evitar ciclos

Flowker utiliza una protección contra ciclos basada en DFS en tiempo de ejecución. Si se detecta un ciclo durante la ejecución, el workflow falla con `FLK-0508`. Los ciclos no se detectan en tiempo de diseño, por lo que debes validar la estructura de edges antes de activar.

Reglas para prevenir ciclos:

* Los edges siempre deben apuntar hacia adelante en el flujo, nunca de vuelta a un node previamente ejecutado.
* Revisa el grafo visualmente antes de activar cualquier workflow con rutas de ramificación o convergencia.
* Si se necesita un reintento o bucle, modélalo como una invocación de workflow separada, no como un edge de retorno en el grafo actual.

### Versionado mediante clone

Nunca edites un workflow activo directamente. En su lugar:

<Steps>
  <Step>
    Clona el workflow (crea un nuevo `draft` con todos los nodes y edges copiados).
  </Step>

  <Step>
    Realiza tus cambios en el borrador.
  </Step>

  <Step>
    Valida o previsualiza el borrador. Actívalo antes de ejecutar pruebas de ejecución.
  </Step>

  <Step>
    Activa la nueva versión.
  </Step>

  <Step>
    Desactiva la versión anterior si ya no es necesaria.
  </Step>
</Steps>

Esto preserva el historial de ejecución de la versión activa y te proporciona una ruta de reversión limpia si la nueva versión tiene problemas.

## Referencia de errores

***

Los siguientes códigos de error son relevantes para el diseño y la ejecución de workflows:

| Código     | Descripción                                                          |
| ---------- | -------------------------------------------------------------------- |
| `FLK-0102` | Transición de estado inválida                                        |
| `FLK-0103` | El workflow no puede ser modificado — no está en estado draft        |
| `FLK-0105` | Expresión condicional inválida                                       |
| `FLK-0113` | Demasiados nodes — el máximo es 100                                  |
| `FLK-0114` | Demasiados edges — el máximo es 200                                  |
| `FLK-0506` | Payload de entrada de ejecución demasiado grande — el máximo es 1 MB |
| `FLK-0508` | Ciclo detectado durante la ejecución del workflow                    |
