> ## 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.

# Guia de Design de Workflows

> Desenhe workflows do Flowker com confiança — tipos de nó, arestas, padrões reais, transições de status e boas práticas para orquestração.

Projete workflows no Flowker com clareza e controle. Este guia apresenta os tipos de nós, arestas, padrões do mundo real, transições de status, limites técnicos e boas práticas para ajudar você a construir orquestrações confiáveis e fáceis de manter.

## Tipos de nós

***

Todo workflow é construído a partir de nós. Cada nó possui um `type` que define como o Flowker o processa em tempo de execução.

### trigger

O ponto de entrada de um workflow. Todo workflow deve começar com um nó trigger. Quando a execução começa, o motor entra por esse nó e inicia o roteamento a partir dele.

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

### executor

Chama um executor externo, um serviço HTTP, API ou provedor registrado no Flowker. Este é o bloco fundamental para integração com motores de fraude, provedores de pagamento, serviços de notificação e outros sistemas externos.

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

### conditional

Avalia uma expressão contra o contexto de execução e roteia para diferentes ramificações com base no resultado. Use nós condicionais para implementar lógica de ramificação, por exemplo, roteando para um caminho de aprovação quando o risco é alto, ou continuando diretamente quando é baixo.

```json theme={null}
{
  "id": "node-risk-decision",
  "type": "conditional",
  "name": "Evaluate Risk Score"
}
```

### action

Representa operações internas do workflow que não envolvem chamadas externas, como transformar dados, emitir eventos ou registrar mudanças de estado.

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

## Arestas

***

Arestas conectam nós e definem caminhos de execução. Cada aresta inclui os seguintes campos:

| Campo          | Descrição                                                                       |
| -------------- | ------------------------------------------------------------------------------- |
| `id`           | Identificador único da aresta.                                                  |
| `source`       | ID do nó de origem.                                                             |
| `target`       | ID do nó de destino.                                                            |
| `sourceHandle` | Porta de saída do nó de origem de onde a aresta se origina.                     |
| `condition`    | Expressão que deve ser avaliada como verdadeira para que a aresta seja seguida. |
| `label`        | Rótulo legível usado para visualização e depuração.                             |

### Exemplo de aresta

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

O campo `condition` é avaliado contra o contexto de execução. Se omitido, a aresta é sempre seguida quando o nó de origem é concluído com sucesso.

## Transições de status

***

Workflows seguem um ciclo de vida bem definido. Compreender essas transições é essencial para implantar e evoluir workflows com segurança.

<Frame>
  <img src="https://mintcdn.com/lerian-49cb71fc/ZrZBZTM4DWnrahSd/images/pt/d2/flowker-workflow-status-transitions.svg?fit=max&auto=format&n=ZrZBZTM4DWnrahSd&q=85&s=1b2eb019306e6bad7cce84d3f1c5a2ec" alt="Diagrama de transição de status de workflow mostrando três estados: draft, active e inactive. Uma seta rotulada 'activate' aponta de draft para active. Uma seta rotulada 'deactivate' aponta de active para inactive. Uma seta rotulada 'draft' aponta de inactive de volta para draft." width="817" height="327" data-path="images/pt/d2/flowker-workflow-status-transitions.svg" />
</Frame>

* **draft** — O estado inicial. Todas as modificações (adicionar nós, editar arestas, alterar configurações) são permitidas apenas no status `draft`.
* **active** — Um workflow que foi ativado. Pode ser executado. Nenhuma modificação é permitida enquanto estiver ativo.
* **inactive** — Um workflow que foi desativado. Não pode mais ser executado, mas pode ser movido de volta para `draft` para edição.

### Regras

* Apenas um workflow em `draft` pode ser ativado (transição: `draft → active`).
* Apenas um workflow `active` pode ser desativado (transição: `active → inactive`).
* Apenas um workflow `inactive` pode ser movido de volta para draft (transição: `inactive → draft`).
* Tentar uma transição inválida retorna o erro `FLK-0102`.
* Tentar modificar um workflow que não está em `draft` retorna o erro `FLK-0103`.

### Movendo um workflow inativo de volta para draft

Se você desativou um workflow e quer editá-lo novamente, mova-o de volta para `draft` chamando [`POST /v1/workflows/{id}/draft`](/pt/reference/flowker/move-workflow-to-draft). Isso torna o workflow editável sem precisar cloná-lo.

Isso é útil quando você desativou um workflow por engano ou quando quer iterar sobre um workflow existente em vez de criar uma cópia.

<Note>
  Apenas workflows inativos podem ser movidos para draft. Se você precisar modificar um workflow ativo sem tirá-lo do ar, use a abordagem de clone descrita abaixo.
</Note>

### Iterando com segurança usando clone

Para modificar um workflow ativo, clone-o primeiro. A clonagem cria um novo `draft` a partir de qualquer status, copiando todos os nós e arestas. Você pode então atualizar, testar e ativá-lo sem impactar a versão atual.

Esta é a abordagem recomendada para versionamento em produção.

## Limites técnicos

***

| Limite                                  | Valor | Código de erro |
| --------------------------------------- | ----- | -------------- |
| Máximo de nós por workflow              | 100   | `FLK-0113`     |
| Máximo de arestas por workflow          | 200   | `FLK-0114`     |
| Payload máximo de entrada para execução | 1 MB  | `FLK-0506`     |

Tenha esses limites em mente ao projetar fluxos complexos. Workflows com mais de \~50 nós geralmente indicam que o fluxo deve ser dividido em workflows menores e compostos.

## Padrões comuns

***

### Sequencial

O padrão mais simples. Os nós são executados em uma sequência linear. Use quando cada etapa depende da anterior e nenhuma ramificação é necessária.

<Frame>
  <img src="https://mintcdn.com/lerian-49cb71fc/ZrZBZTM4DWnrahSd/images/pt/d2/flowker-pattern-sequential.svg?fit=max&auto=format&n=ZrZBZTM4DWnrahSd&q=85&s=3318cc7e6c0826ab8489add0dedd60d0" alt="Padrão de workflow sequencial: um nó trigger se conecta a um primeiro nó executor, que se conecta a um segundo nó executor, que se conecta a um terceiro nó executor. Todas as conexões são setas direcionadas formando uma linha reta." width="957" height="268" data-path="images/pt/d2/flowker-pattern-sequential.svg" />
</Frame>

**Exemplo: Orquestração de pagamento**

```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" }
  ]
}
```

### Ramificação condicional

Um nó `conditional` avalia uma expressão e roteia a execução de acordo. Cada aresta de saída carrega sua própria `condition`.

<Frame>
  <img src="https://mintcdn.com/lerian-49cb71fc/ZrZBZTM4DWnrahSd/images/pt/d2/flowker-pattern-conditional.svg?fit=max&auto=format&n=ZrZBZTM4DWnrahSd&q=85&s=180839d3366c7b1276688da07798223b" alt="Padrão de workflow com ramificação condicional: um nó trigger se conecta a um nó executor, que se conecta a um nó conditional. O nó conditional tem duas setas de saída: uma rotulada 'Path A' apontando para um primeiro nó executor, e uma rotulada 'Path B' apontando para um segundo nó executor." width="999" height="394" data-path="images/pt/d2/flowker-pattern-conditional.svg" />
</Frame>

**Exemplo: Verificação 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" },
    { "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": "approved",
      "condition": "n2.fraudScore < 70",
      "label": "Approved"
    },
    {
      "id": "e4",
      "source": "n3",
      "target": "n5",
      "sourceHandle": "rejected",
      "condition": "n2.fraudScore >= 70",
      "label": "Rejected"
    }
  ]
}
```

## Exemplos do mundo real

***

### Verificação antifraude

Uma transação chega, uma pontuação de fraude é obtida, e a execução é roteada para aprovação ou rejeição.

```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" },
    { "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": "approved",
      "condition": "n2.fraudScore < 70",
      "label": "Low risk"
    },
    {
      "id": "e4",
      "source": "n3",
      "target": "n5",
      "sourceHandle": "rejected",
      "condition": "n2.fraudScore >= 70",
      "label": "High risk"
    }
  ]
}
```

### Orquestração de pagamento

Um fluxo linear que valida os dados de pagamento recebidos, roteia para o provedor apropriado e envia uma confirmação.

```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

Os documentos de um cliente são verificados por um serviço externo. Um nó condicional avalia se uma revisão manual é necessária. Se sim, uma ação de aprovação manual é acionada antes de ativar a conta.

```json theme={null}
{
  "nodes": [
    { "id": "n1", "type": "trigger",     "name": "Onboarding Started" },
    { "id": "n2", "type": "executor",    "name": "Run Document Check" },
    { "id": "n3", "type": "conditional", "name": "Manual Review Required?" },
    { "id": "n4", "type": "action",      "name": "Request Manual Approval" },
    { "id": "n5", "type": "executor",    "name": "Activate Account" }
  ],
  "edges": [
    { "id": "e1", "source": "n1", "target": "n2", "label": "Start" },
    { "id": "e2", "source": "n2", "target": "n3", "label": "Check complete" },
    {
      "id": "e3",
      "source": "n3",
      "target": "n4",
      "sourceHandle": "review",
      "condition": "n2.reviewRequired == true",
      "label": "Needs review"
    },
    {
      "id": "e4",
      "source": "n3",
      "target": "n5",
      "sourceHandle": "clear",
      "condition": "n2.reviewRequired == false",
      "label": "Auto-approved"
    },
    { "id": "e5", "source": "n4", "target": "n5", "label": "Approved" }
  ]
}
```

### Fluxo de aprovação manual

Uma solicitação é enviada para revisão. Uma ação de aprovação aguarda uma decisão. Um nó condicional então roteia para o caminho de aprovação ou rejeição.

```json theme={null}
{
  "nodes": [
    { "id": "n1", "type": "trigger",     "name": "Request Submitted" },
    { "id": "n2", "type": "executor",    "name": "Submit for Review" },
    { "id": "n3", "type": "action",      "name": "Await Approval Decision" },
    { "id": "n4", "type": "conditional", "name": "Decision Received" },
    { "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": "approved",
      "condition": "n3.decision == 'approved'",
      "label": "Approved"
    },
    {
      "id": "e5",
      "source": "n4",
      "target": "n6",
      "sourceHandle": "rejected",
      "condition": "n3.decision == 'rejected'",
      "label": "Rejected"
    }
  ]
}
```

## Boas práticas

***

### Convenções de nomenclatura de nós

Use nomes descritivos e orientados a ações que comuniquem o que o nó faz, e não qual é o seu tipo.

* **correto**: `Validate Payment Data`, `Get Fraud Score`, `Notify Customer`, `Await Approval`
* **errado**: `executor1`, `conditional node`, `node3`

Bons nomes tornam os workflows legíveis sem precisar abrir a configuração do nó. Eles também aparecem em logs de auditoria e rastreamentos de execução, tornando a depuração significativamente mais rápida.

### Expressões de condição em arestas

As condições nas arestas são avaliadas contra o contexto de execução. Mantenha-as simples e explícitas:

* Use comparações diretas de campos: `<nodeId>.status == 'approved'`
* Use comparações numéricas: `<nodeId>.riskScore < 70`
* Use campos booleanos: `<nodeId>.reviewRequired == true`

Evite expressões complexas que são difíceis de ler ou depurar. Se a lógica não for trivial, considere rotear através de um nó `conditional` que encapsula a decisão com um nome claro.

Uma expressão inválida retorna `FLK-0105`. Sempre valide as expressões antes de ativar um workflow.

### Estratégias de tratamento de erros

Projete workflows para lidar com falhas de forma explícita:

* Adicione caminhos de rejeição a partir de nós `conditional` para cada ponto de decisão que pode falhar.
* Use nós `executor` separados para lógica de retry ou provedores de fallback.
* Nomeie os caminhos de erro de forma clara (por exemplo, `Reject and Notify`, `Fallback to Manual Review`) para que os logs de auditoria sejam autoexplicativos.

### Evitando ciclos

O Flowker usa um mecanismo de detecção de ciclos baseado em DFS em tempo de execução. Se um ciclo for detectado durante a execução, o workflow falha com `FLK-0508`. Ciclos não são detectados em tempo de design, portanto valide a estrutura das suas arestas antes de ativar.

Regras para prevenir ciclos:

* As arestas devem sempre apontar para frente no fluxo, nunca de volta para um nó executado anteriormente.
* Revise o grafo visualmente antes de ativar qualquer workflow com ramificações ou caminhos de junção.
* Se um retry ou loop for necessário, modele-o como uma invocação de workflow separada, não como uma aresta de retorno no grafo atual.

### Versionamento via clone

Nunca edite um workflow ativo diretamente. Em vez disso:

<Steps>
  <Step>
    Clone o workflow (cria um novo `draft` com todos os nós e arestas copiados).
  </Step>

  <Step>
    Faça suas alterações no rascunho.
  </Step>

  <Step>
    Teste o rascunho com execuções.
  </Step>

  <Step>
    Ative a nova versão.
  </Step>

  <Step>
    Desative a versão antiga se ela não for mais necessária.
  </Step>
</Steps>

Isso preserva o histórico de execução da versão ativa e oferece um caminho de rollback caso a nova versão apresente problemas.

## Criando workflows a partir de templates

***

Em vez de construir um workflow do zero, você pode criá-lo a partir de um template pré-construído no catálogo. Templates fornecem estruturas prontas de nós e arestas para padrões comuns — validação de pagamentos, verificações de fraude, fluxos de onboarding e mais.

Chame [`POST /v1/workflows/from-template`](/pt/reference/flowker/create-workflow-from-template) com o ID do template, um nome para o novo workflow e quaisquer parâmetros que o template requer. O resultado é um novo workflow com status `draft` que você pode revisar, personalizar e ativar.

<Accordion title="Exemplo de requisição">
  ```json theme={null}
  POST /v1/workflows/from-template

  {
    "templateId": "payment-validation",
    "params": {
      "providerConfigId": "a1b2c3d4-e5f6-4789-a012-345678901234",
      "currency": "USD"
    },
    "name": "Payment Validation - USD",
    "description": "Valida pagamentos USD antes da escrituração no ledger"
  }
  ```
</Accordion>

Para descobrir templates disponíveis e seus parâmetros obrigatórios, use os endpoints [Listar templates do catálogo](/pt/reference/flowker/list-catalog-templates) e [Consultar template do catálogo](/pt/reference/flowker/get-catalog-template). O endpoint de detalhe do template retorna um JSON Schema descrevendo os parâmetros esperados, incluindo opções dinâmicas para campos que referenciam configurações de provider.

## Referência de erros

***

Os seguintes códigos de erro são relevantes para o design e a execução de workflows:

| Código     | Descrição                                                     |
| ---------- | ------------------------------------------------------------- |
| `FLK-0102` | Transição de status inválida                                  |
| `FLK-0103` | Workflow não pode ser modificado — não está no status draft   |
| `FLK-0105` | Expressão condicional inválida                                |
| `FLK-0113` | Nós em excesso — o máximo é 100                               |
| `FLK-0114` | Arestas em excesso — o máximo é 200                           |
| `FLK-0506` | Payload de entrada da execução muito grande — o máximo é 1 MB |
| `FLK-0508` | Ciclo detectado durante a execução do workflow                |
