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:

  1. 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.
  2. 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.