v2.0

Lógica de Rotas

Referência completa da sintaxe de condições. Operadores, funções, acesso a variáveis e armadilhas comuns.

Formato das condições

Por padrão, sem nenhuma condição de rota configurada, o processo simplesmente segue o fluxo: cada etapa executa e passa para a próxima na sequência em que aparecem no canvas, sem desviar para lugar nenhum. Uma condição de rota (ou "decisão de rota") é o que quebra essa linearidade: a regra que decide qual etapa executa em seguida, em vez de simplesmente seguir a próxima da sequência. O processo lê variáveis já disponíveis (capturadas antes, vindas de um conector, de um parâmetro de inicialização) e usa esse valor para escolher o caminho: "se o status for aprovado, vá para Emitir Nota; se for rejeitado, vá para Tratar Rejeição". É o mecanismo por trás de qualquer ramificação do fluxo, o equivalente a um if / else if / else dentro do processo.

Toda etapa tem lógica de rota, não só a Decisão O campo Definir a próxima Etapa após execução, com o mesmo builder de condições descrito nesta página, existe em qualquer tipo de etapa. Navegar, Preencher, Regra Customizada, todas. A etapa de Decisão não é a única forma de rotear: ela existe para padronizar e deixar o fluxo mais legível, concentrando as decisões do processo em cards fáceis de identificar no canvas, em vez de espalhar condições de rota dentro de etapas que também fazem outra coisa.
Desativar preserva a rota escrita O checkbox Definir a próxima Etapa após execução é a chave de verdade: desmarcá-lo desliga a rota sem apagar a regra escrita, e a etapa segue direto para a próxima da sequência. A condição fica guardada, pronta para reativar depois. Um rótulo ATIVADO (verde) ou DESATIVADO (vermelho) ao lado do checkbox mostra o estado atual.
Builder visual de Condições para Rotas com múltiplas regras combinadas
Condições para Rotas: a Regra 1 combina três condições (SE / E / OU) e aponta para "Abre Planilha".

Qualquer etapa com uma condição de rota configurada, Decisão ou não, ganha um badge 🔀 na lateral do card no canvas:

Badge de rota configurada no canto do card
O badge 🔀, fora do card, identifica de relance que aquela etapa tem uma condição de rota configurada, sem precisar abrir a etapa para saber.

É o mesmo tipo de indicador visual do badge ⊘ de Execução Condicional, só que para rotas em vez de condição de execução, e a legenda completa de ícones e badges do canvas está em Agent Builder → Cards, badges e conexões.

Configuração das rotas de uma etapa de Decisão.
Configuração das rotas de uma etapa de Decisão.

As condições de rota são expressões JavaScript avaliadas pelo runtime no momento da execução. Toda variável do processo é substituída pelo seu valor antes da avaliação:

Ciclo de avaliação de uma condição
// Condição escrita:
Number({valor_total}) > 1000 && {status} == 'aprovado'

// Em tempo de execução, com {valor_total}='1500' e {status}='aprovado':
Number('1500') > 1000 && 'aprovado' == 'aprovado'
// → true → esta rota é seguida

Escrevendo rotas no modo manual

O builder visual (SE / +E (AND) / +OU (OR)) cobre a maioria dos casos, inclusive combinando várias condições numa única regra. O exemplo do início da página tem uma Regra 1 com três linhas: connector.status == "OK" E CNPJ_LIST.length > 0 OU connector.status != undefined. Para lógica que esse builder não expressa, clique em ✎ Manual e escreva o script diretamente:

No campo Valor do builder, digite o texto direto (aprovado) ou {variável}, sem aspas, inclusive misturando os dois (Ticket-{id}). O builder grava a sintaxe JavaScript certa por trás, aspas incluídas quando for texto. Isso vale só para o builder visual: no modo Manual abaixo, o script é JavaScript de verdade, e texto sem aspas quebra a etapa.

Modo manual das Condições para Rotas, com o script route.js
Modo manual, o mesmo builder da imagem anterior, como script: as três condições da Regra 1 viram uma única expressão entre colchetes, e o catch-all aparece como o segundo par [{JS} true].goto(...).

O script gerado segue o formato [condição].goto(destino) :: [condição].goto(destino). Cada Regra do builder visual vira um par [condição].goto(destino), e :: é só o separador entre regras: uma linha por rota, na mesma ordem em que aparecem no builder (o botão Remover some com um par inteiro; ↑/↓ reordena os pares, na mesma posição em que reordenam as regras no builder). Os detalhes de como o runtime avalia cada par estão em A função goto(), a seguir. O editor route.js só troca o builder visual por texto livre. Alguns pontos práticos desse modo:

A função goto()

Seja pelo builder visual ou pelo modo manual, cada rota que você configura vira uma chamada de goto(). A função que efetivamente desvia o fluxo. O script de rota é uma sequência de pares [condição].goto(destino) separados por :::

Script de rota gerado pelo builder
[{status} == 'aprovado'].goto({Emitir Nota}) :: [{status} == 'rejeitado'].goto({Tratar Rejeição}) :: [{JS} true].goto(terminate())

Leitura: se {status} for 'aprovado', vá para a etapa Emitir Nota; senão, se for 'rejeitado', vá para Tratar Rejeição; senão (regra padrão), encerre o processo.

Destinos aceitos pelo goto()

DestinoEfeito
goto({Nome da Etapa})Salta para a etapa com esse nome, sempre entre chaves, exatamente como está no campo Nome da Etapa.
goto(continue())Segue para a próxima etapa na sequência (opção Continuar do builder).
goto(terminate())Encerra o processo (opção Encerrar Processo do builder). No canvas, aparece como o ponto vermelho ⏺.

A regra padrão [{JS} true]

A última regra do script usa o prefixo {JS} com a condição true. É o catch-all: se nenhuma condição anterior for satisfeita, o goto() dela decide o destino. O builder gera essa regra a partir do campo de rota padrão; nunca deixe o script sem ela, ou o fluxo fica sem destino quando nada casa.

Ordem importa Os pares são avaliados da esquerda para a direita (de cima para baixo no builder). O primeiro [condição] verdadeiro executa o seu goto() e os demais são ignorados.

Acesso a variáveis

SintaxeO que acessaExemplo
{variavel} Parâmetro de inicialização do processo ou variável definida por script {empresa_id} == 'ACME'
{nome_do_campo} Campo capturado por mapeamento (Mapeamento de Dados). O nome vem do campo Nome da linha de mapeamento, não do nome da etapa {status_nf} == 'aprovado'
{nome_do_campo}[0] Primeiro item de uma captura em lista. O [0] vem depois da chave {numeros}[0] != undefined
A variável entra na condição com o valor que ela guarda: texto como texto, número como número, lista como lista e objeto como objeto. Uma variável com tipo declarado (Número, Moeda, Verdadeiro/Falso, Lista, Objeto) chega no tipo. Texto capturado da tela, ou digitado numa variável sem tipo, chega como texto: para comparar como número, use Number({valor}). Uma lista comparada com um número é comparada pelo tamanho ({lista} == 0 equivale a {lista}.length == 0), e aceita o índice fora da chave, {lista}[0], ou o atalho {lista}[] para o primeiro item. Detalhes: Arrays e listas.

Operadores de comparação

OperadorSignificadoExemplo
==Igual{status} == 'aprovado'
!=Diferente{status} != 'pendente'
>Maior que (use Number() para números)Number({total}) > 1000
<Menor queNumber({total}) < 500
>=Maior ou igualNumber({score}) >= 70
<=Menor ou igualNumber({tentativas}) <= 3

Operadores lógicos

OperadorSignificadoExemplo
&&E lógico. Ambas as condições devem ser verdadeirasNumber({total}) > 0 && {status} == 'ok'
||OU lógico. Basta uma ser verdadeira{tipo} == 'NF-e' || {tipo} == 'CT-e'
!NÃO lógico. Inverte o resultado!({status} == 'cancelado')
// E lógico
Number({valor}) > 50000 && {status} == 'pendente'

// OU lógico
{status} == 'aprovado' || {status} == 'pago'

// Combinação
({tipo} == 'NF-e' || {tipo} == 'CT-e') && Number({valor}) > 0

Verificadores especiais

VerificadorVerdadeiro quandoExemplo
exists A variável existe e tem valor não-vazio {arquivo} exists
is empty A variável está vazia, é null ou não existe {resultado} is empty
true Sempre (usado como catch-all obrigatório) true

Métodos de string

MétodoExemploUso
.includes(){mensagem}.includes('erro')Verificar se contém substring
.startsWith(){codigo}.startsWith('NF')Verificar prefixo
.endsWith(){arquivo}.endsWith('.pdf')Verificar sufixo/extensão
.toLowerCase(){status}.toLowerCase() == 'aprovado'Comparação sem distinção de maiúsculas
.trim(){campo}.trim() != ''Ignorar espaços extras
.replace(){valor}.replace(',', '.') == '1.5'Normalizar formato antes de comparar

Conversão de tipos

FunçãoExemploUso
Number()Number({valor}) > 100Converter texto em número antes de comparar
String()String({codigo}).padStart(3, '0') == '001'Tratar um número como texto
JSON.parse()JSON.parse({json_texto}).status == 'ok'Ler um JSON guardado como texto
Math.abs()Math.abs(Number({diferenca})) < 0.01Comparar valor absoluto (tolerância)
Math.max()Math.max(Number({a}), Number({b})) > 0Usar maior valor entre dois campos
parseInt()parseInt({codigo}) == 42Ignorar parte decimal ao comparar

Arrays e listas

Uma variável é lista quando vem de uma captura em lista (inclusive as colunas da Tabulação Automática), de um caminho com [*] numa resposta de API ou de conector, de uma variável do tipo Lista ou de uma lista gravada por script. Ela entra na condição como lista, e os métodos de lista do JavaScript funcionam direto sobre ela:

OperaçãoExemplo
Tamanho da lista{itens}.length > 0
Lista vazia{itens} == 0
Primeiro elemento{itens}[] == 'inicio' ou {itens}[0] == 'inicio'
Último elemento{itens}.at(-1) == 'fim'
Contém valor{lista}.includes('aprovado')
Todos satisfazem{status_list}.every(s => s == 'ok')
Algum satisfaz{status_list}.some(s => s == 'erro')

Quando cada item da lista é um registro com campos, como a lista inteira de uma resposta de API (itens[*]) ou as linhas de uma consulta de banco, o campo se lê depois do índice, ou dentro da função:

OperaçãoExemplo
Campo do primeiro registro{pedidos}[].status == 'novo'
Campo de um registro pela posição{pedidos}[1].total > 1000
Algum registro atende{pedidos}.some(p => p.status == 'novo')
Quantos registros atendem{pedidos}.filter(p => p.total > 1000).length > 2

Armadilhas comuns

Comparar números como string

❌ Errado: comparação lexicográfica
// {total} = '10', {limite} = '9'
{total} > {limite}    // '10' > '9' → false! (string comparison)
✅ Correto: converter antes de comparar
Number({total}) > Number({limite})    // 10 > 9 → true

Comparar com null/undefined

❌ Pode falhar se variável não existe
{arquivo} == ''    // pode ser undefined se nunca foi definida
✅ Use "is empty" para verificar ausência
{arquivo} is empty    // trata null, undefined e '' igualmente

Lista que pode não existir

Variável lista que só existe se uma etapa anterior rodou
({lista} || []).length > 0

Sensibilidade a maiúsculas

Normalize antes de comparar textos vindos do sistema
{status}.toLowerCase() == 'aprovado'    // funciona com 'Aprovado', 'APROVADO', etc.