Após identificar o atendimento e o fluxo de automação associado ao canal, o Flow Service passa a controlar toda a execução da automação.
Nos artigos anteriores vimos como o webhook é recebido, validado e encaminhado para processamento de forma segura. Nesse momento, a plataforma já identificou a origem da mensagem, validou sua autenticidade, localizou o canal correspondente e criou (ou recuperou) o atendimento associado ao usuário.
É a partir dessa etapa que entra em ação o Flow Service, responsável por executar a automação configurada para aquele canal.
Neste artigo, vamos focar exclusivamente no funcionamento desse serviço, compreender quais ações ele realiza e como realiza.
]O fluxo de execução acontece da seguinte forma:
Mensagem
(fila flow.execute.queue)
│
▼
Flow Service
│
▼
Carrega Flow (JSON) do Redis Cache (estrutura base -> react-flow)
│
▼
Flow vinculado ao Canal encontrado?
│ │
Não Sim
│ ▼
│ Busca INSTANCE
│ │
│ ▼
│ Primeira interação?
│ │ │
│ Sim Não
│ │ │
│ ▼ ▼
│ Primeiro Node Último Node
│ executado
│ └──────┬───────┘
│ ▼
│ Executa Módulo
│ │
│ ▼
│ Atualiza INSTANCE
│ │
│ ▼
│ Registra STEP
│ │
│ ▼
│ Analisa retorno
│ │
│ ┌───────────┼────────────┐
│ │ │ │
│ ▼ ▼ ▼
│ Permanecer Enviar Próximo
│ no Node Resposta Node
│ │ │ │
│ │ ▼ ▼
│ │ Publica Publica
│ │ mensagem flow.execute
│ │ ao canal novamente
│ │
▼ ▼
Fim Fim
Cada mensagem recebida pelo serviço contém todas as informações necessárias para localizar o atendimento correspondente:
Esses dados são suficientes para que o Flow Service descubra exatamente em qual ponto da automação aquele atendimento se encontra.
Cada canal possui um fluxo de automação associado. Esse fluxo é armazenado como um JSON, seguindo uma estrutura semelhante ao React Flow, contendo:
Como esse fluxo sofre poucas alterações, ele permanece cacheado (REDIS), reduzindo consultas ao banco de dados.
Após localizar o fluxo, o serviço verifica se aquele atendimento já iniciou uma automação. Essa informação é obtida através da INSTANCE, responsável por armazenar o estado atual da execução. A INSTANCE contém, por exemplo:
Caso contrário, a execução continua exatamente do ponto onde havia parado.
Enquanto a INSTANCE representa o estado atual, a tabela STEPS registra todo o histórico da execução. Cada passagem por um node gera um novo registro contendo informações como:
Esse histórico facilita auditoria, depuração e reprocessamentos.
O Flow Service não conhece a implementação de cada tipo de node. Ele apenas localiza o módulo correspondente e executa sua interface padrão. Cada módulo é totalmente independente, seguindo princípios de baixo acoplamento e alta coesão. Dependendo da configuração recebida no campo data do node, o módulo poderá:
Independentemente do tipo do módulo, seu retorno possui sempre a mesma estrutura lógica. Ele pode informar que:
Essa padronização torna o motor de execução extremamente simples e desacoplado dos módulos.
Após executar o módulo, o Flow Service analisa o retorno. Existem dois comportamentos possíveis.
Alguns módulos representam estados de espera, como aguardar uma resposta do usuário. Nesse caso, a INSTANCE é atualizada e a execução é encerrada naquele ponto.
Quando uma nova mensagem chegar, o processamento continuará exatamente desse mesmo node.
Mensagem
↓
Node "Perguntar Nome"
↓
Aguardando resposta
↓
INSTANCE salva
↓
Fim
Quando o módulo indicar continuidade, o Flow Service consulta as Edges do fluxo para descobrir qual será o próximo node. Caso o próprio módulo tenha informado um destino específico (por exemplo, em uma condição ou Switch), esse caminho possui prioridade.
Após determinar o próximo node, a INSTANCE é atualizada e uma nova mensagem é publicada na fila para continuar a execução.
Node Atual
↓
Atualiza INSTANCE
↓
Descobre próximo Edge
↓
Publica novamente
↓
Flow Service continua execução
Esse modelo transforma cada etapa da automação em uma pequena unidade de trabalho, permitindo que o processamento seja distribuído entre diversas instâncias do serviço sem perder o contexto de cada atendimento.
Como cada node possui um comportamento diferente, uma boa abordagem é utilizar uma arquitetura modular baseada no padrão Strategy, onde o Flow Service atua apenas como um orquestrador. Toda a regra de negócio fica encapsulada dentro dos módulos responsáveis por cada tipo de node.
Essa organização reduz o acoplamento, facilita a criação de novos nodes e evita alterações no motor principal sempre que uma nova funcionalidade é adicionada.
src/
├── application/
│ ├── consumers/
│ │ └── flow.consumer.ts
│ │
│ ├── services/
│ │ ├── flow.service.ts
│ │ ├── instance.service.ts
│ │ ├── step.service.ts
│ │ └── flow-cache.service.ts
│ │
│ └── dto/
│
├── domain/
│ ├── entities/
│ │ ├── flow.ts
│ │ ├── instance.ts
│ │ └── step.ts
│ │
│ ├── interfaces/
│ │ ├── node-module.ts
│ │ └── node-result.ts
│ │
│ └── repositories/
│
├── infrastructure/
│ ├── rabbitmq/
│ ├── redis/
│ ├── database/
│ └── api/
│
├── modules/
│ ├── if/
│ ├── switch/
│ ├── delay/
│ ├── http/
│ ├── database/
│ ├── send-message/
│ ├── update-attendance/
│ ├── calculate/
│ ├── webhook/
│ ├── ai/
│ └── ...
│
├── shared/
│ ├── logger/
│ ├── errors/
│ └── utils/
│
└── main.ts