Proposta 1 — Outbox + Knative Eventing + Inbox + RabbitMQ DLQ¶
Status: Brainstorming de consultoria — ver aviso metodológico
Resolve: dual-write, ausência de retry/DLQ ordenado, redrive artesanal (achados de integracao-wfm-eforce-ordem-servico.md)
Contexto¶
O eForce Worker grava estado da Ordem de Serviço no MongoDB e, hoje, publica eventos de forma não-atômica em relação a essa gravação — a discussão em chat identificou isso como dual-write clássico: se o processo cair entre a gravação e a publicação, o evento simplesmente não sai, sem qualquer mecanismo de correção além de redrive manual observado pelo próprio desenvolvedor do eForce. Não há DLQ, então uma mensagem problemática bloqueia a partition inteira do Kafka até intervenção manual.
Como o fluxo é majoritariamente intra-domínio (WFM/eForce), a proposta usa o MongoDB — que já é o store primário do eForce — como origem de verdade do Outbox, evitando introduzir uma dependência transacional externa.
Diagrama C4 — Contêineres¶
Design patterns aplicados¶
| Padrão | Papel nesta proposta |
|---|---|
| Transactional Outbox | Transaction Table + Outbox Table gravadas na mesma transação Mongo — elimina o dual-write, a causa raiz do gap identificado na sessão |
| Change Data Capture (via Change Streams) | Relay lê a Outbox Table sem acoplamento direto ao código de escrita, publicando no Kafka de forma assíncrona |
| Soft delete + TTL parcial | Linhas da Outbox marcadas published em vez de removidas de imediato; índice TTL parcial só sobre linhas já publicadas, preservando auditoria por uma janela |
| Inbox / Idempotent Consumer | Necessário porque a entrega do Outbox é at-least-once — sem Inbox, o Worker reprocessaria eventos duplicados após qualquer retry |
| Ordered delivery por partition key | Knative Kafka Broker usa a extensão CloudEvents de partitioning para garantir ordenação por numeroOS — sem isso, duas atualizações da mesma OS poderiam ser aplicadas fora de ordem |
| Dead Letter Exchange + TTL (retry ladder) | RabbitMQ escolhido para a DLQ em vez de mais tópicos Kafka — decisão deliberada para não amplificar a pressão de custo já documentada (~120 cores dedicados ao barramento, achado da Ata 10) |
Cenários de aplicação¶
| Cenário | Proposta se aplica? |
|---|---|
| Eventos intra-domínio, precisam ordenação por chave de negócio (ex.: número da OS) | Sim — é o caso central desta proposta |
| Domínio já usa MongoDB como store primário | Sim — Outbox aproveita a transação nativa do Mongo, sem infraestrutura extra |
| Domínio persiste primariamente em Oracle (ex.: microsserviços de Atendimento) | Não diretamente — nesse caso Oracle AQ/TxEventQ dá atomicidade de graça com a escrita de negócio, sem precisar de Outbox (ver recomendação já registrada por Castellani na sessão de 24/07, addendum à Ata 09) |
| Necessidade de reconstruir o estado de um agregado a partir do histórico completo de eventos | Não — isso é Event Sourcing (Proposta 2), não Outbox |
| Necessidade de arquivar eventos para consulta/replay histórico de longo prazo | Não é o foco desta proposta — ver Proposta 3 (complementar, não concorrente) |
Riscos e trade-offs em aberto¶
- Knative/OpenShift Serverless: capacidade da plataforma existe (é Kubernetes), mas o checklist de licenciamento registra zero evidência de uso ou licenciamento confirmado até 14/08/2026 — pré-requisito a validar antes de qualquer prova de conceito.
- Latência do Relay: Change Streams introduz uma etapa de polling entre a gravação e a publicação — não é síncrono como um dual-write ingênuo, mas também não é zero-latência.
- Novo componente operacional: RabbitMQ para DLQ significa mais um broker para operar, monitorar e dar suporte, mesmo que a decisão evite amplificar custo de tópicos Kafka.
- Sem validação de campo: nenhuma parte desta proposta foi discutida com a equipe de barramento nem com o desenvolvedor do eForce — é ponto de partida técnico, não solução acordada.