O domínio vem antes do framework

Toda decisão de arquitetura começa quando alguém tenta responder o que o sistema faz, e não como ele é construído. O domínio é o conjunto de regras que a empresa usaria para explicar o próprio negócio a um novo funcionário: como um pedido é aceito, quando o crédito de um cliente é bloqueado, o que torna um item indisponível para venda. Essas regras deveriam existir em um só lugar do código, expressas na linguagem que a operação usa.

Quando isso não acontece, o sintoma aparece na conta de manutenção. A mesma validação de crédito vive no formulário do vendedor, no serviço que gera o pedido e em uma rotina noturna que concilia dados. Toda mudança vira três mudanças, e nenhuma delas conversa com as outras.

Modularidade: fronteiras que o negócio reconhece

Modularidade não é separar pastas por camada técnica. Um controller, um service e um repository do mesmo assunto continuam sendo o mesmo módulo. A fronteira útil é a do negócio: vendas, estoque, faturamento, crédito.

Um módulo de verdade passa em alguns testes simples:

  • Pode ser alterado sem que outros times precisem revisar o mesmo código.
  • Tem dados que ele mesmo governa, e ninguém escreve neles por fora.
  • Expõe um contrato público pequeno e esconde o restante.
  • Pode ser testado sem subir a aplicação inteira.

Monólito modular atende a esses critérios com frequência. A escolha entre monólito e serviços é decisão de operação e de time, não de sofisticação. Serviços distribuídos sem fronteira de domínio apenas espalham o acoplamento pela rede, onde ele é mais caro de depurar.

Integrações: contrato explícito e falha prevista

Integração entre sistemas é onde a arquitetura é testada. Entre módulos internos ou entre a aplicação e o ERP, o ponto crítico é o mesmo: o que acontece quando a outra parte está lenta, indisponível ou responde algo inesperado.

Toda integração precisa definir:

  1. O contrato: quais dados entram, quais saem, quem é dono de cada campo e como a versão evolui.
  2. A idempotência: reenviar a mesma mensagem não pode duplicar pedido, nota ou cobrança.
  3. O comportamento na falha: fila, retentativa com espera crescente, registro do que não foi processado e um caminho claro para reprocessar.
  4. A observabilidade: rastrear um pedido específico do início ao fim, atravessando os sistemas.

Um caso comum em distribuidoras de autopeças com equipe de representantes: o pedido nasce no aplicativo de vendas, é validado no ERP e aparece no portal do cliente. Durante um tempo, o limite de crédito era calculado nos três pontos, com regras parecidas e diferentes ao mesmo tempo. O efeito aparecia no fechamento: pedido faturado para cliente com limite já comprometido, vendedor sem entender o motivo e time de TI ajustando regra em três lugares, para o mesmo problema voltar no mês seguinte.

A correção não foi trocar o ERP. Foi declarar o módulo de crédito como dono da regra, expor uma API de consulta e publicar um evento sempre que o limite mudasse. As outras pontas deixaram de calcular e passaram a consultar. Os chamados sobre faturamento indevido caíram, e cada novo canal de venda passou a integrar o mesmo contrato, em vez de reimplementar a política.

Na prática

Para quem mantém software em produção, a arquitetura se prova nos detalhes do dia a dia:

  • Antes de aceitar um novo campo ou regra, pergunte a qual módulo ele pertence. Se a resposta envolver mais de um, a fronteira está errada.
  • Trate toda integração como algo que vai falhar. Defina o que acontece quando o ERP não responde e deixe esse caminho testado, não apenas documentado.
  • Versione contratos e mantenha compatibilidade com quem ainda consome a versão anterior. Integração que quebra a cada deploy destrói a confiança da operação.
  • Use logs e rastreamento com identificador de negócio (número do pedido, código do cliente) para reconstruir o que aconteceu sem adivinhação.
  • Reveja as fronteiras a cada semestre. O domínio muda quando a empresa muda, e módulo desatualizado volta a virar monólito.

Arquitetura saudável não é a mais moderna, é a que permite mudar uma regra de negócio em um lugar e ter certeza de que o resto do sistema continuará funcionando.