Pular para o conteúdo principal
O Matcher é construído como um monolito modular usando Domain-Driven Design (DDD) e arquitetura hexagonal. CQRS separa comandos (escritas) de consultas (leituras). Isso mantém as operações simples enquanto preserva limites claros. Cada módulo pode evoluir independentemente sem a complexidade de microsserviços.

Visão geral da arquitetura


Arquitetura do Matcher

Bounded contexts


O Matcher possui seis módulos. Cada um é dono dos seus dados e expõe interfaces limpas para os outros.
  • Configuration: O que você está conciliando (contextos, fontes, mapas de campos, regras)
  • Ingestion: Entrada de dados (parsing, validação, normalização)
  • Matching: O motor (execução de regras, scoring de confiança)
  • Exception: Tratamento de itens não conciliados (workflow, roteamento, resolução)
  • Governance: Trilhas de auditoria (logs imutáveis para compliance)
  • Reporting: Visibilidade (relatórios, exportações, dashboards)

Configuration

Define o que você está conciliando e como. Responsabilidades:
  • Contextos (o que está sendo conciliado)
  • Fontes (de onde os dados vêm)
  • Mapas de campos (tradução de campos externos)
  • Regras (como fazer o matching)
Modelos principais:
  • ReconciliationContext: O escopo da conciliação
  • ReconciliationSource: Configuração da fonte
  • FieldMap: Regras de tradução de campos
  • MatchRule: Lógica de matching

Ingestion

O bounded context de Ingestion lida com a entrada e normalização de dados. Responsabilidades:
  • Fazer parse de arquivos enviados (CSV, JSON, XML)
  • Validar dados de entrada contra schemas configurados
  • Normalizar dados externos para uma representação canônica
  • Detectar e tratar registros duplicados
  • Emitir eventos de domínio quando a ingestão é concluída
Entidades principais:
  • IngestionJob: Rastreia o ciclo de vida e status da ingestão
  • RawImport: Payload original enviado
  • CanonicalTransaction: Registro de transação normalizado
Eventos publicados:
  • IngestionCompleted: Indica que os dados estão prontos para matching

Matching

O bounded context de Matching contém o motor de conciliação. Responsabilidades:
  • Carregar regras aplicáveis para um contexto de conciliação
  • Executar estratégias de matching (exato, tolerância, baseado em data)
  • Calcular scores de confiança
  • Criar grupos de match e alocar transações
  • Identificar transações não conciliadas
Entidades principais:
  • MatchRun: Execução de um job de matching
  • MatchGroup: Grupo de transações conciliadas
  • MatchItem: Alocação individual de transação
Eventos publicados:
  • MatchConfirmed: Um grupo de match foi finalizado
  • TransactionUnmatched: Uma transação não pôde ser conciliada

Exception management

O bounded context de Exception gerencia transações não resolvidas. Responsabilidades:
  • Classificar exceções por severidade
  • Rotear exceções para equipes internas ou sistemas externos
  • Suportar overrides manuais e ajustes
  • Rastrear status de resolução e SLAs
  • Integrar com ferramentas externas de workflow
Entidades principais:
  • Exception: Uma transação não resolvida
  • Resolution: Resultado do tratamento da exceção
  • RoutingRule: Lógica de roteamento e escalonamento
Integrações:
  • JIRA para rastreamento de issues
  • ServiceNow para incidentes críticos
  • Webhooks para workflows customizados

Governance

O bounded context de Governance preserva a rastreabilidade da conciliação. Responsabilidades:
  • Registrar todas as ações do sistema em logs de auditoria imutáveis
  • Fornecer histórico de auditoria consultável
  • Suportar relatórios regulatórios e de compliance
Entidades principais:
  • AuditLog: Registro apenas append de atividade do sistema
Os logs de auditoria são apenas append por design. Entradas não podem ser modificadas ou removidas para preservar a integridade do compliance.

Reporting

O bounded context de Reporting fornece visibilidade operacional. Responsabilidades:
  • Gerar relatórios de conciliação
  • Expor métricas de dashboard
  • Exportar dados de conciliação em múltiplos formatos
Entidades principais:
  • Report: Resumo da conciliação
  • Dashboard: Métricas operacionais agregadas
  • ExportJob: Execução assíncrona de exportação

Fluxo de dados


A conciliação segue um pipeline determinístico através dos bounded contexts:
1

Configuration

Contextos de conciliação, fontes, mapeamentos de campos e regras são definidos através da API.
2

Ingestion

Dados externos são enviados ou buscados. Arquivos são parseados, validados, normalizados e deduplicados. Um evento IngestionCompleted é emitido.
3

Matching

Regras de matching são aplicadas às transações elegíveis, produzindo grupos de match com scores de confiança. Matches de alta confiança são aprovados automaticamente. Itens não conciliados se tornam exceções.
4

Exception handling

Exceções são classificadas, roteadas e resolvidas manualmente ou via sistemas externos. Atualizações de resolução são propagadas de volta ao Matcher.
5

Governance

Todas as ações através do pipeline são registradas em logs de auditoria imutáveis.
6

Reporting

Usuários acessam relatórios e dashboards mostrando status da conciliação, taxas de match e envelhecimento de exceções.

Componentes de infraestrutura


O Matcher depende dos seguintes serviços de infraestrutura:
ComponentePropósitoUso
PostgreSQLArmazenamento principalDados de domínio com isolamento de schema por tenant
RedisCache e coordenaçãoDeduplicação, locks, chaves de idempotência
RabbitMQMessage brokerComunicação assíncrona entre contextos

Arquitetura de banco de dados

  • Isolamento de schema por tenant para forte separação de dados
  • Consistência forte para estado de matching e exceções
  • Consistência eventual para views de reporting

Multi-tenancy

O Matcher impõe isolamento estrito de tenants:
  • A identidade do tenant é extraída exclusivamente de claims do JWT
  • Identificadores de tenant nunca são aceitos via parâmetros de request
  • O acesso ao banco de dados é delimitado através de resolução de schema
  • Todas as queries são automaticamente restritas ao tenant ativo
Este modelo previne acesso cruzado de dados entre tenants e suporta requisitos regulatórios e de auditoria.

Padrões de design


Arquitetura hexagonal

Cada bounded context segue o padrão de portas e adaptadores:
context/
├── adapters/
│ ├── http/
│ ├── postgres/
│ └── rabbitmq/
├── ports/
├── services/
│ ├── command/
│ └── query/
└── domain/
 ├── entities/
 └── errors/

CQRS-light

Os caminhos de escrita e leitura são separados no nível de serviço:
  • *_command.go para mutações de estado
  • *_query.go para operações de leitura
Isso melhora a organização do código e permite otimização independente dos caminhos de consulta.

Padrão outbox

A publicação de eventos segue o padrão outbox:
  1. Estado de domínio e registros de outbox são persistidos atomicamente
  2. Workers em background publicam eventos no RabbitMQ
  3. Eventos são marcados como processados após entrega bem-sucedida
Isso garante a entrega de eventos mesmo durante falhas transientes do broker.

Próximos passos