Serviços
Diagrama de Fluxo
Resumo de Fluxos por Trigger
| Trigger | Fila de entrada | Pipeline | Quem cria o run |
|---|---|---|---|
| schedule / manual | runs → items | collect → process (transform interno) | Scheduler / API |
| webhook | items direto | process (transform interno) | Webhook Service |
| queue (externa) | items direto | process (transform interno) | Consumer |
Rastreabilidade — O que cada trigger grava
Cada tipo de trigger grava registros diferentes no banco. A tabela abaixo explicita o que é persistido por tipo de integração:
Registros de execução
| Registro | Standard (pulling) | Gateway | Webhook (listener) | Fila externa (consumer) |
|---|---|---|---|---|
execution_run | Sim | Sim (agregador) | Sim | Sim |
execution_items | Sim (N por run) | Não | Sim (1 por request) | Sim (1 por mensagem) |
- Gateway não cria
execution_items— oexecution_runfunciona como agregador (correlation ID) para os http_logs. - Standard cria N items via fan-out no collect. Cada item tem
input_payload,output_payload,status,attempts. - Webhook e Consumer criam 1 item por request/mensagem recebida, processado pelo Item Worker.
HTTP logs (http_logs)
| Tipo de log | Descrição | Standard | Gateway | Webhook | Consumer |
|---|---|---|---|---|---|
internal | Plataforma → serviço de integração (collect) | Sim | — | — | — |
internal | Plataforma → serviço de integração (execute) | — | Sim | — | — |
external | Integração → API externa | Sim | Sim | Sim | Sim |
incoming | Request recebido pelo webhook | — | — | Sim | — |
incoming_rejected | Request rejeitado (HMAC inválido) | — | — | Sim | — |
- Logs
internaldo process não são gravados — o resultado já está noexecution_item(output_payload,status,error). - Logs
externalsão a única forma de rastrear as chamadas HTTP feitas à API do parceiro — sempre gravados. - Todos os logs são enfileirados no BullMQ (
logs) e persistidos de forma assíncrona pelo Log Writer.
Queue logs (queue_logs)
| Tipo | Descrição | Standard | Gateway | Webhook | Consumer |
|---|---|---|---|---|---|
queue-log | Mensagem recebida de fila externa | — | — | — | Sim |
- Apenas o Consumer grava
queue_logs— registra a mensagem original da fila externa para auditoria.
Fluxo Detalhado — Schedule (Fan-out)
Fluxo Detalhado — Webhook (Item Único)
Fluxo Detalhado — Consumer de Fila Externa
Tabela de Responsabilidades
| Serviço | Porta | Conhece DB | Conhece Fila | Chama Outros |
|---|---|---|---|---|
| API | :3100 | Sim | Sim (publica) | Não |
| Scheduler | — | Sim (lê configs) | Sim (publica) | Não |
| Webhook | :3002 | Sim (grava run) | Sim (publica) | Não |
| Runner | — | Sim | Sim (consome) | Sim (integrações via HTTP) |
| Monitor | :3010 | Sim (leitura) | Sim (leitura) | Não |
| Integração X | :401x | Não | Não | Apenas sistema externo |
API (:3100)
| Método | Rota | Descrição |
|---|---|---|
| GET | /health | Health check |
| GET | /runs | Lista runs do tenant |
| GET | /runs/:id | Detalhes de um run |
| GET | /runs/:id/items | Items de um run |
| POST | /runs/:id/reprocess | Reprocessa items falhos |
| GET | /configs | Lista configs do tenant |
| PUT | /configs/:id | Atualiza config |
| POST | /configs/:id/pause | Pausa/despausa handler |
| GET | /admin/queues | Bull Board (dashboard de filas) |
Headers obrigatórios: x-tenant-id (exceto /health e /admin).
Contrato HTTP, Triggers, Schedule e Direção
Detalhes sobre o contrato HTTP das integrações (collect/process, gateway/execute), modos de trigger (pulling/listener/gateway), formatos de schedule e direção (inbound/outbound) estão documentados no Blueprint.
Runner — Orquestrador Central
O Runner é o coração da plataforma. Roda 3 workers:
| Worker | Fila | Responsabilidade |
|---|---|---|
| Run Worker | runs | Consome run jobs, chama collect, faz fan-out |
| Item Worker | items | Processa cada item (POST /process, transform é interno), gerencia retry |
| Log Writer | logs | Persiste http_logs e queue_logs de forma assíncrona |
Controles por handler:
concurrency— máximo de jobs simultâneosrate_limit_per_minute— limite de chamadas à API externa- Pausa/resume individual sem afetar outros handlers
Lifecycle — Ativo / Pausado / Inativo
O estado operacional de uma integração é controlado por duas colunas booleanas na tabela configs:
| Coluna | Default | Descrição |
|---|---|---|
enabled | false | Integração configurada e ativada pelo tenant |
paused | false | Suspensão temporária sem perder config nem credenciais |
A combinação dessas colunas resulta em três estados:
┌──────────────────┐
│ enabled? │
└────┬────────┬────┘
Não │ │ Sim
▼ ▼
┌─────────┐ ┌──────────────┐
│ Inativo │ │ paused? │
│ (off) │ └──┬────────┬──┘
└─────────┘ Não│ │Sim
▼ ▼
┌─────────┐ ┌─────────┐
│ Ativo │ │ Pausado │
│ (ok) │ │(paused) │
└─────────┘ └─────────┘
| Estado | enabled | paused | Cor | Ícone |
|---|---|---|---|---|
| Ativo | true | false | success-soft | check-circle |
| Pausado | true | true | warning-soft | pause-circle |
| Inativo | false | — | gray-soft | x-circle |
Resolução: resolveOperatingStatus() em @hg/shared.
O que cada serviço faz por estado:
| Serviço | Inativo (enabled=false) | Pausado (paused=true) | Ativo |
|---|---|---|---|
| Scheduler | Não agenda (reload a cada 60s) | Não agenda (reload a cada 60s) | Cria cron jobs |
| API Gateway | 404 — config not found or disabled | 409 — integration is paused | Executa normalmente |
| Webhook | 404 — config not found or disabled | Processa normalmente* | Processa normalmente |
| Consumer | Erro — não processa mensagem | Processa normalmente* | Processa normalmente |
| Run Worker | Processa normalmente* | skipped — marca run como skipped | Processa normalmente |
| Item Worker | Processa normalmente* | Processa normalmente* | Processa normalmente |
* Campos marcados indicam que o serviço não checa esse estado atualmente — jobs já enfileirados serão processados.
Endpoint de controle:
POST /configs/:id/pausecom body{ paused: boolean }— alterna entre pausado e ativo.
Observações:
- O Scheduler recarrega configs a cada 60 segundos. Mudanças de estado levam até 1 minuto para refletir no agendamento.
- Pausar é mais eficaz para jobs em fila: o Run Worker respeita
pausede marca comoskipped. O campoenablednão é checado pelos workers. - Desativar (
enabled=false) bloqueia imediatamente as bordas (API Gateway, Webhook), mas jobs já no BullMQ continuam sendo processados.
Logging de Aplicação (Pino)
Todos os serviços usam um logger centralizado via createLogger(name) de @hg/core. Ele retorna uma instância de Pino com dual output:
| Destino | Quando | Formato |
|---|---|---|
| stdout | Sempre | pino-pretty (dev, se disponível) ou JSON |
| Arquivo | LOG_FILE_ENABLED !== 'false' (padrão: ativo) | JSON (pino-roll, rotação diária) |
Arquivos de log ficam em logs/<service>/ na raiz do projeto (ou relativo a LOG_FILE_DIR):
logs/
├── api/
│ ├── api.2026-03-30.log
│ └── api.1 ← arquivo corrente (renomeado na rotação)
├── runner/
├── scheduler/
└── monitor/
Limpeza automática: no boot de cada serviço, arquivos .log mais antigos que LOG_FILE_RETENTION dias são removidos.
Uso nos serviços:
- Fastify services (API, Monitor, Webhook, integrações):
Fastify({ logger: createLogger('nome') })— o Fastify usa a instância Pino diretamente. - Runner: logger principal + child loggers por worker (
log.child({ worker: 'run' })). - Scheduler, Consumer: logger standalone (
createLogger('scheduler')).
Variáveis de ambiente:
| Variável | Default | Descrição |
|---|---|---|
LOG_LEVEL | debug (dev) / info (prod) | Nível mínimo de log |
LOG_FILE_ENABLED | true | false para desativar escrita em arquivo |
LOG_FILE_RETENTION | 7 | Dias de retenção dos arquivos de log |
LOG_FILE_DIR | ./logs | Diretório base dos logs |
Importante: Este logger é para logs de aplicação (startup, shutdown, erros internos, debug). Os logs de HTTP (request/response das integrações) continuam sendo gravados de forma assíncrona via fila logs → http_logs/queue_logs no banco.
Monitor — APM Interno
Serviço standalone de monitoramento, deployável em servidor separado. Funciona como APM interno, oferecendo visibilidade centralizada de todo o sistema.
Porta: 3010 (configurável via PORT)
O que monitora:
| Collector | Fonte | Dados |
|---|---|---|
| Service Health | Redis (heartbeat) | Status up/down de cada serviço, uptime, PID |
| Queue Metrics | BullMQ | Waiting, active, completed, failed, delayed por fila |
| Execution Stats | PostgreSQL | Runs/items por status, taxa de sucesso, throughput/hora |
| Circuit Breakers | Redis | Estado e falhas de cada circuit breaker |
| Error Rates | PostgreSQL | DLQ total/por integração, últimas falhas, trend 24h |
| System Metrics | Redis INFO + pg_stat | Memória Redis, conexões DB |
Mecanismo:
- Polling a cada 15s (configurável via
POLL_INTERVAL_MS) coleta dados de todos os collectors - Snapshot cacheado no Redis (TTL 30s) e publicado via pub/sub para SSE
- Cross-tenant (sem RLS) — visão sistêmica, não por tenant
- Heartbeat: todos os serviços publicam
heartbeat:<nome>no Redis com TTL auto-expire. Se o serviço morrer, a key expira e o monitor detecta como offline.
Rotas:
| Método | Path | Descrição |
|---|---|---|
| GET | /health | Health do próprio monitor |
| GET | /snapshot | Snapshot completo do sistema |
| GET | /services | Status dos serviços |
| GET | /queues | Métricas das filas |
| GET | /execution | Stats de execução |
| GET | /circuit-breakers | Estado dos circuit breakers |
| GET | /errors | Erros e DLQ |
| GET | /system | Métricas de infraestrutura |
| GET | /events | SSE com push de snapshots |