Skip to main content
Voltar para Insights
Arquitetura12 min de leitura

Anatomia de um sistema operacional financeiro

Três camadas, três domínios de falha. Como a separação do motor de ledger, orquestração e lógica de domínio cria um sistema auditável.

A Arquitetura de um Sistema Operacional Financeiro


Um sistema core banking típico lida com contas, pagamentos, compliance, reporting e configuração de produto em uma única aplicação. Um codebase. Um banco de dados. Uma unidade de deploy. Quando o motor de recompensas tem um bug, o deploy que o corrige também toca o caminho de processamento de pagamentos. Quando a equipe de compliance precisa de uma nova regra de screening, o release inclui alterações não relacionadas ao calculador de comissões.

Isso não é hipotético. É a arquitetura da maioria dos sistemas construídos nas últimas duas décadas, e a razão pela qual bancos rotineiramente gastam entre três e cinco anos em projetos de transformação de core que frequentemente estancam, excedem o orçamento ou são arquivados por completo.

A alternativa não é uma explosão de microsserviços. É uma separação deliberada em três camadas, cada uma com um domínio de falha distinto, uma frequência de mudança distinta e um requisito de correção distinto.

Três Camadas, Três Domínios de Falha

A ideia por trás do que a ThoughtWorks chama de "Coreless Banking" é direta: nem tudo em um sistema bancário carrega o mesmo risco. O ledger nunca deve estar errado. O motor de workflows nunca deve perder estado. A lógica de produto muda a cada sprint. Tratar os três com a mesma cadência de deploy, as mesmas escolhas tecnológicas e o mesmo rigor de testes é ou desperdício (super-engenharia da camada de produto) ou perigoso (sub-engenharia do ledger).

Nota do Arquiteto: A integração direta com câmaras de compensação exige sequências exatas de mensagens. Fernel gerencia a originação pacs.008 e a liquidação camt.054 de forma autônoma.

Camada 1: O Motor de Ledger

Responsabilidade: invariantes de partida dobrada, integridade de saldos, imutabilidade. Este é o registro contábil. Responde uma pergunta: qual é o estado autoritativo de cada conta?

Propriedades:

  • Serialização estrita. Transferências concorrentes para a mesma conta produzem o mesmo resultado independentemente do timing. Sem anomalias. Sem ressalvas.
  • Append-only imutável. Sem UPDATE, sem DELETE. Correções são novas entradas que referenciam a original. O histórico completo sempre é preservado.
  • Invariantes impostas pelo motor. Uma transferência que não equilibra (soma de débitos ≠ soma de créditos) é rejeitada pelo motor, não por código de aplicação. Isso elimina a criação e destruição de dinheiro como categoria de bug.

Frequência de mudança: quase nunca. O motor de ledger é infraestrutura. Você o atualiza para performance ou patches de segurança, não para mudanças de lógica de negócio.

Impacto de falha: catastrófico. Se o ledger é corrompido, o registro financeiro não é confiável. Cada sistema downstream, reconciliação, reporting, compliance, herda a corrupção.

Camada 2: O Motor de Orquestração

Responsabilidade: coordenar processos multi-passo. Abertura de conta (criar entidade → provisionar contas → atribuir IBAN → acionar KYC). Execução de pagamento (validar → screenar → debitar → enviar ao clearing → rastrear settlement). Estas não são operações individuais, são workflows que abrangem múltiplos serviços e podem levar segundos, minutos ou dias para completar.

Propriedades:

  • Execução durável. Cada passo é journalizado antes da execução. Se o processo é interrompido, crash, timeout, queda de provedor, o motor reproduz o journal e retoma no ponto exato de falha. Sem efeitos colaterais duplicados. Sem passos pulados.
  • Semântica exactly-once. O journal garante que cada passo executa uma vez, mesmo entre reinícios. Uma propriedade do modelo de execução, não idempotência a nível de aplicação.
  • Trilha de auditoria integrada. O journal É a trilha de auditoria. Cada workflow tem um ID de correlação. Cada passo é registrado com entradas, saídas e timing. Um auditor pode reconstruir o ciclo de vida completo de qualquer operação a partir de um único identificador.

Frequência de mudança: raramente. Novos tipos de workflow são adicionados quando novas capacidades são introduzidas (um novo esquema de pagamento, uma nova verificação de compliance), mas o motor em si é estável.

Impacto de falha: degradado. Se o motor de orquestração cai, processos em voo estancam, mas os dados estão seguros. O ledger não é afetado. Quando o motor se recupera, reproduz do journal e completa os processos estancados.

Camada 3: A Camada de Domínio

Responsabilidade: tudo que faz do produto um produto. Estruturas de comissões. Regras de compliance. Integração de provedores KYC. Fluxos de onboarding. Adaptadores de API de parceiros. Templates de reporting. Aqui é onde o negócio se diferencia.

Propriedades:

  • Configuração como Código. Regras de produto expressas como configuração versionada, não embarcadas em código de aplicação. Uma nova estrutura de comissões é um deploy de config, não um release de código.
  • Abstração de provedores. Provedor KYC, esquema de pagamento, serviço de screening AML, todos atrás de interfaces padronizadas. A camada de domínio sabe que precisa de uma verificação KYC; não sabe (nem se importa) se Identomat, Onfido ou um processo manual a cumpre. Trocar de provedor é uma mudança de configuração.
  • Releases frequentes. Esta camada muda a cada sprint. Novas funcionalidades, regras ajustadas, novas integrações. A cadência de deploy é rápida porque falhas aqui são contidas.

Frequência de mudança: alta. Este é o produto. Evolui constantemente.

Impacto de falha: contido. Um bug no cálculo de recompensas quebra as recompensas. Não corrompe o ledger. Não estanca os pagamentos. O raio de impacto é limitado pela fronteira do serviço.

CamadaResponsabilidadeImpacto de falhaFrequência de mudança
Motor de LedgerIntegridade de saldos, partida dobrada, imutabilidadeCatastrófico, corrupção de dadosQuase nunca
OrquestraçãoCoordenação multi-passo, compensação, journalDegradado, processos estancam, dados segurosRaramente
Camada de DomínioRegras de produto, compliance, integrações, APIContido, funcionalidade específica quebraCada sprint

Por Que "Só Usar Uma Fila" Falha para Processos Financeiros

O instinto, ao coordenar processos multi-passo, é recorrer a uma fila de mensagens. O passo 1 publica um evento. O passo 2 se inscreve, processa, publica o próximo evento. A compensação é outro evento publicado em caso de falha.

Isso funciona para sistemas de notificação, pipelines de analytics e invalidação de cache. Não funciona bem para processos financeiros, por uma razão específica: o "processo" é implícito. Nenhum componente individual conhece o estado atual do fluxo end-to-end. O debugging requer análise forense através de múltiplos logs de consumers. E a coordenação em si, a ordenação de passos, o tratamento de falhas, a decisão de compensar, está dispersa entre consumers independentes.

Considere uma Transferência SEPA:

  1. Validar IBAN e valor
  2. Screening AML (chamada a provedor externo)
  3. Debitar conta do remetente (operação de ledger)
  4. Enviar à rede de clearing
  5. Rastrear status de settlement

O passo 3 debita a conta do remetente. O passo 4 falha, a rede de clearing rejeita o pagamento. O sistema deve reverter o débito do passo 3.

Com uma abordagem baseada em filas: publicar um evento de compensação. Um consumer o pega e reverte o débito. Mas e se a mensagem de compensação for perdida? E se o consumer crashar antes de processá-la? E se a reversão em si falhar? Cada modo de falha requer seu próprio tratamento, e o tratamento está distribuído pelo sistema sem um registro central do estado do processo.

Com um motor de execução durável: o passo 4 falha. O motor registra a falha no journal. Executa a compensação (reverter o débito) como um passo journalizado. Se a compensação é interrompida, é reproduzida do journal. O processo inteiro, incluindo a falha e a compensação, é visível em um único journal com um único ID de correlação.

A diferença é operacional: "achamos que revertemos" versus "o journal prova que revertemos, e aqui está a sequência exata de eventos."

O Padrão Write Gateway

Uma consequência desta arquitetura: todas as operações que alteram estado são roteadas pela camada de orquestração. Leituras a contornam.

Leituras (GET)

Cliente / Admin UI diretamente ao Serviço Financeiro

Sem overhead de orquestração. Rápido.

Escritas (POST/PUT)

Cliente / Admin UI através do Motor de Orquestração ao Serviço Financeiro

Cada mutação journalizada. Durável. Auditável.

O Serviço Financeiro (API Zig) contém o ledger e os dados de domínio. Nunca é exposto à internet pública. O Motor de Orquestração é o único ponto de entrada controlado para todas as mutações.

Leituras vão diretamente ao serviço financeiro. Sem overhead de orquestração. Rápido.

Escritas passam pelo motor de orquestração. Cada mutação é journalizada. Durável. Auditável. Se o motor está fora, escritas são enfileiradas até se recuperar. A integridade de dados nunca é comprometida.

Este padrão tem um benefício de segurança: o serviço financeiro nunca é exposto à internet pública. O motor de orquestração é o ponto de entrada único controlado para todas as mutações. A superfície de ataque é minimizada por arquitetura, não apenas por regras de firewall.

Onde Você Se Diferencia

As camadas de ledger e orquestração são infraestrutura. São necessárias, mas não são o que torna seu produto valioso para os clientes. Os clientes escolhem você por:

  • A estrutura de comissões que se encaixa no modelo de negócio deles (baseada em percentual, escalonada, assinatura ou híbrida).
  • O fluxo de compliance que satisfaz o regulador deles (profundidade KYC específica por jurisdição, políticas CDD, provedores de screening AML).
  • A integração com os sistemas existentes deles (reconciliação ERP, conectividade com banco parceiro, suporte a esquemas de pagamento).
  • A experiência de onboarding que converte prospects em contas ativas.

Tudo isso vive na camada de domínio. Muda frequentemente. É configurado, não codificado. Uma entrada em novo mercado requer novos perfis de jurisdição e políticas de compliance, não um novo ledger nem um novo motor de workflows.

A arquitetura viabiliza isso: as camadas de infraestrutura fornecem garantias de correção e resiliência operacional. A camada de domínio fornece flexibilidade de produto. As duas evoluem independentemente.

Alinhamento Regulatório por Design

A arquitetura de três camadas se mapeia diretamente para requisitos regulatórios específicos. Compliance é uma propriedade do design, não uma camada adicionada depois.

RegulaçãoArtigoRequisitoResposta Arquitetônica
DORAArt. 11-12Rastreabilidade TIC, gestão de incidentes, planos de recuperaçãoJournal de orquestração: cada mutação journalizada com ID de correlação. Recuperação = reprodução de journal.
DORAArt. 15Avaliação de risco de terceiros, cadeia de suprimentos auditávelCadeia de dependências mínima no core financeiro (~30 transitivas). Inventário de dependências publicável.
PSD2Art. 87Data valor e disponibilidade de fundosMotor de ledger rastreia datas valor nativamente. Ciclo de vida de settlement (pendente → disponível) imposto no nível do motor.
AMLD5/6Art. 13, 16Due diligence do cliente, trilha de auditoria para decisões de complianceCamada de domínio: motor de políticas CDD com registros versionados. Ledger: eventos de auditoria imutáveis com hash encadeado.
HGB§239Correções como novas entradas, não modificaçõesLedger: append-only. Correções são Stornobuchungen referenciando a entrada original via foreign key.

Cada requisito regulatório é satisfeito pela camada projetada para ele. O ledger cuida da integridade contábil (PSD2, HGB). O motor de orquestração cuida da rastreabilidade e recuperação (DORA Art. 11-12). A camada de domínio cuida da lógica de compliance (AMLD). Nenhuma camada carrega o peso regulatório completo.

Três Perguntas para Avaliar Qualquer Plataforma Financeira

Se você está avaliando uma plataforma core banking, seja construindo uma, comprando uma ou modernizando uma existente, três perguntas revelam se a arquitetura é sólida:

1. Um bug na sua lógica de produto pode corromper seu ledger?

Se o ledger e a camada de domínio compartilham banco de dados, ou se o código de aplicação é responsável por impor invariantes de partida dobrada, a resposta é sim. Um único UPDATE desprotegido, uma cláusula WHERE faltando em um handler de reembolso, uma race condition em um calculador de comissões, qualquer um destes pode silenciosamente corromper o registro financeiro. Se as camadas são isoladas e o ledger impõe suas próprias invariantes, a resposta é não.

2. Se seu motor de orquestração reiniciar no meio de um pagamento, o que acontece com o pagamento?

Se a resposta é "depende da lógica de retry do consumer" ou "precisaríamos verificar a dead-letter queue," você não tem execução durável. Se a resposta é "o motor reproduz o journal e retoma no passo 4," você tem.

3. Você pode trocar seu provedor KYC sem alterar seu código de onboarding?

Se a API do provedor é chamada diretamente do seu fluxo de onboarding, provedor e fluxo estão acoplados. Uma troca de provedor é uma mudança de código, um ciclo de testes e um deploy. Se o fluxo de onboarding chama uma interface de provedor e a configuração determina qual implementação a cumpre, trocar é uma mudança de config.

Estas não são perguntas capciosas. Têm respostas binárias. E preveem o custo operacional do sistema nos próximos cinco anos com mais precisão do que qualquer matriz de comparação de funcionalidades.


Leia mais: O Ledger | Workflows, Execução Durável | Por Que a Partida Dobrada é Inegociável


Fontes:

  • ThoughtWorks, "Kill your core: The banking revolution you didn't see coming"
  • ThoughtWorks, "Cloud-native composable banking" (whitepaper AWS)
  • DORA, Regulamento (UE) 2022/2554, Art. 11-12 (Rastreabilidade e recuperação TIC)
  • Stripe (Temporal), Wise (migração Saga → Temporal), N26 (Kafka+Sagas), Revolut (Temporal), adoção industrial de execução durável para caminhos críticos de pagamento