O domínio antes do framework
A maior parte dos problemas de arquitetura que aparecem em produção não nasce da escolha de tecnologia. Nasce da ausência de fronteiras claras entre as regras de negócio. Quando o domínio não está definido, cada nova funcionalidade encontra um sistema em que a mesma regra existe em três lugares diferentes e nenhum deles é a referência.
Um caso típico: uma distribuidora de médio porte que vende para revendedores e também para o varejo direto. A política de prazo e desconto por volume estava implementada no momento do pedido, replicada de forma parcial no módulo de faturamento e novamente ajustada à mão no portal do representante. Enquanto a regra não mudava, ninguém percebia. Na primeira alteração de política comercial, três times fizeram três interpretações distintas no mesmo dia. O prejuízo não veio de um bug isolado, veio de não haver um único ponto responsável pela regra.
Delimitar o domínio é decidir onde uma regra mora e onde ela é apenas consultada. Isso exige nomear as áreas do negócio com a linguagem de quem opera: pedido, carteira, apuração de comissão, disponibilidade de estoque. Esses nomes precisam aparecer no código, não apenas no documento de requisitos.
Modularidade é sobre fronteiras, não sobre pastas
Separar arquivos em pastas por camada (controllers, services, repositories) organiza o repositório, mas não reduz acoplamento. Modularidade real significa que um módulo só conversa com outro por um contrato explícito e que mudanças internas não vazam para fora.
Na prática, isso aparece em decisões concretas:
- Definir o que cada módulo expõe e o que é detalhe interno.
- Impedir que um módulo leia diretamente as tabelas de outro, o que costuma ser o acoplamento mais caro de desfazer.
- Tratar o banco como detalhe de persistência, não como contrato entre áreas.
- Testar o contrato entre módulos, não apenas o comportamento interno de cada um.
O monólito modular continua sendo uma escolha defensável para a maioria das empresas brasileiras. Ele evita a complexidade operacional de vários serviços e mantém a transação simples. O que não se sustenta é o monólito sem fronteiras, aquele em que qualquer alteração exige entender o sistema inteiro. Extrair um serviço só faz sentido quando existe um motivo operacional claro, como escala muito desigual entre áreas ou um ciclo de entrega que precisa ser independente.
Integrações: contrato, versionamento e falha
Integração mal desenhada cobra caro depois. O ponto de partida é tratar toda integração como contrato entre duas partes que evoluem em ritmos diferentes: o ERP, o sistema fiscal, o marketplace, o aplicativo do cliente.
Alguns cuidados que reduzem incidentes:
- Versionar o contrato desde a primeira entrega e declarar o que pode mudar sem aviso.
- Assumir que toda chamada externa vai falhar em algum momento e definir retentativa com espera crescente.
- Tornar operações sensíveis a duplicidade idempotentes, com chave de negócio própria.
- Registrar eventos de integração em uma fila confiável antes de processar, para não perder dados quando o destino cair.
- Isolar o modelo do fornecedor em uma camada de tradução, para que uma mudança no ERP não alcance o núcleo do sistema.
Voltando à distribuidora: o portal do representante consumia a mesma base do faturamento sem contrato definido. Bastou o time financeiro alterar o critério de arredondamento para o portal passar a exibir valores divergentes. Com um contrato explícito e uma camada de tradução, a mudança teria ficado restrita a um ponto.
Na prática
Para quem mantém software em produção, arquitetura se prova no dia a dia, não no diagrama.
- Mantenha um mapa dos domínios e um responsável por cada módulo. Sem dono, a fronteira se dissolve em poucos meses.
- Registre as decisões de arquitetura com data e motivo. A pergunta sobre por que o sistema foi feito assim volta em toda manutenção.
- Antes de criar uma integração nova, escreva o contrato e combine o que acontece em caso de falha, duplicidade e mudança de versão.
- Revise acoplamentos a cada entrega relevante: alguém acessou tabela de outro módulo, alguém chamou endpoint interno por atalho.
- Trate a extração de um serviço como decisão de negócio com custo operacional, não como sinal de modernidade.
Arquitetura é, no fim, a soma das fronteiras que a empresa consegue sustentar com o time que tem. Definir domínio, preservar módulos e construir integrações com cuidado é o que evita que a manutenção do sistema se torne o maior item de custo da operação.