O domínio define o que é módulo
Antes de escolher tecnologia, a pergunta é de negócio: quais áreas da empresa têm regras próprias, vocabulário próprio e mudam por motivos diferentes? Isso é o que separa um módulo de outro. Faturamento, estoque e precificação mudam por razões distintas, muitas vezes em ritmos distintos, e por isso merecem fronteiras explícitas.
O erro comum é desenhar módulos por camada técnica (controllers, services, repositories) ou por entidade de banco. O resultado é um sistema em que qualquer alteração de regra atravessa cinco pastas e três times. Fronteira boa é aquela em que a maior parte das mudanças de uma regra de negócio fica contida em um único lugar.
Modularidade: o que sustenta o sistema quando o framework muda
Modularidade não é ter pastas separadas; é ter contratos internos e impedir atalhos. Na prática, isso significa:
- cada módulo expõe uma interface pública (funções, serviços, eventos) e esconde suas tabelas;
- nenhum módulo lê ou escreve direto na tabela de outro;
- dependências entre módulos apontam em uma direção só e não formam ciclos;
- regras de negócio ficam no módulo dono do dado, não no módulo que precisa do dado.
Exemplo concreto: uma distribuidora de médio porte opera com e-commerce, ERP e logística. A equipe do site precisa exibir saldo de estoque. A solução barata é consultar direto a tabela de estoque do ERP. Funciona até o dia em que o estoque passa a ser controlado por depósito e por reserva, e o site começa a vender item já comprometido com um pedido grande. O custo não está na mudança em si, mas em corrigir a regra em dois lugares e reconciliar pedidos divergentes. Com um módulo de estoque expondo um contrato (reservar, consultar disponibilidade, liberar), o site não precisa saber como o estoque é calculado.
Integrações: contrato explícito, acoplamento implícito
Integração é onde a arquitetura costuma vazar. Duas decisões resolvem boa parte dos problemas:
- Definir quem é dono do dado. Um sistema é a fonte da verdade de cada informação, os demais replicam ou consultam. Sem isso, dois sistemas corrigem o mesmo cadastro e o conflito aparece no fechamento do mês.
- Escolher entre chamada síncrona e evento. Síncrono para o que precisa de resposta imediata (consultar preço), assíncrono para o que pode esperar e precisa de resiliência (emitir nota, atualizar transportadora). Em integração assíncrona, idempotência e reprocessamento não são detalhe: são requisito.
Em integrações com terceiros (marketplaces, gateways, transportadoras, prefeituras para nota fiscal), vale isolar o formato externo em uma camada de tradução. Quando o provedor muda o layout do payload, a alteração fica contida ali, e não espalhada pelas regras de negócio. Versionar o contrato e manter compatibilidade por um período também evita que uma mudança de um lado quebre o outro sem aviso.
Na prática
Para quem mantém software em produção, três verificações pagam o esforço rápido:
- Liste os módulos e marque onde há acesso direto a tabela de outro módulo. Cada ocorrência é um acoplamento que vai cobrar juros na próxima mudança de regra.
- Para cada integração, escreva quem é dono do dado e o que acontece quando o outro lado está fora do ar. Se a resposta for "alguém percebe e refaz na mão", a integração está incompleta.
- Coloque prazo de validade nos contratos: versão, depreciação e aviso a quem consome.
Arquitetura, nesse nível, não é escolha de framework. É decidir onde ficam as fronteiras, o que cada parte expõe e como o resto do sistema conversa com ela. O resto é consequência.