# Estratégia de Modularização — Mud Sentinel

**Documento:** `arquitetura/03-modularizacao.md`  
**Versão:** 1.0.0  
**Status:** Vigente

---

## 1. Objetivo

Definir como o sistema é particionado para permitir evolução por muitos anos: times paralelos, deploys seguros, substituição de adapters e extração eventual de serviços — sem transformação em big ball of mud.

---

## 2. Estratégia oficial: Modular Monolith por Bounded Context

Cada bounded context é um **módulo** com:

- API pública interna (facade / application services).
- Modelo de domínio próprio.
- Persistência própria (tabelas prefixadas / schemas lógicos).
- Eventos de domínio publicados quando outros contextos precisam reagir.
- **Zero** import de detalhes internos de outro módulo (adapters, tabelas, entidades internas).

**Justificativa:** maximiza coesão e reduz acoplamento acidental; mantém deploy único no MVP (menor custo operacional).

---

## 3. Regras de dependência entre módulos

```text
Permitido:
  Application Module A  →  Public API / Events de Module B
  Adapters              →  Application ports do próprio módulo
  Workers               →  Application use cases

Proibido:
  Domain A → Domain B (exceto Shared Kernel mínimo)
  Domain → Framework / ORM / HTTP / LLM SDK
  Module A.infrastructure → Module B.infrastructure
  Controllers acessarem repositórios de outro contexto diretamente
```

**Enforcement:** regras de lint de import (ex.: `import-linter` / boundaries no ESLint) + code review checklist.

---

## 4. Mapa de módulos

| Módulo | Pacote lógico | Dono sugerido |
|--------|---------------|---------------|
| `iam` | Identity & Access | Platform |
| `tenancy` | Tenants, quotas | Platform |
| `catalog` | Entidades e atributos | Data |
| `search` | Indexação/consulta | Data |
| `graph` | Relacionamentos | Intelligence |
| `ingestion` | Conectores e runs | Data |
| `risk` | Regras e scores | Intelligence |
| `cases` | Dossiês e exports | Product |
| `ai` | Orquestração de IA | Intelligence |
| `billing` | Planos e uso | Platform |
| `audit` | Trilha | Platform / Security |
| `notify` | Notificações | Platform |
| `shared_kernel` | IDs, erros, props transversais | Architecture |

---

## 5. Comunicação entre módulos

### 5.1 Síncrona (in-process)

Usar **apenas** via interface pública do módulo (application service / query service), nunca via SQL cruzado.

**Quando:** leitura consistente imediata no mesmo request (ex.: autorizar + buscar ficha).

### 5.2 Assíncrona (eventos)

Publicar **domain events** / **integration events** para fan-out.

**Quando:** ingestão concluída → indexar busca + atualizar grafo; caso exportado → notificar; uso de IA → metering.

Ver [EDA](06-event-driven.md).

---

## 6. Modularização de conectores (ingestion)

Cada fonte pública é um **plugin de conector** com contrato:

- `discover` / `fetch` / `parse` / `normalize` / `publish`
- versionamento semântico do conector
- schema de saída versionado
- testes de contrato com fixtures gravadas (VCR/golden files)

**Justificativa:** fontes mudam unilateralmente; isolamento evita contagiar o core.

---

## 7. Modularização de IA

- Templates de prompt versionados fora do código hardcoded espalhado.
- Providers atrás de port `CompletionProvider`, `EmbeddingProvider`.
- Políticas de grounding e redaction no módulo `ai`, não na UI.

---

## 8. Feature flags e entitlements

Features de produto são gateadas por `billing`/`tenancy` entitlements + flags de release.

**Regra:** módulo de domínio consulta porta `EntitlementChecker`; não hardcodeia nome de plano em regras de negócio profundas.

---

## 9. Critérios para extrair um módulo a serviço

Somente com ADR e evidência de ≥1:

1. Escalabilidade elástica distinta (CPU/memória/IO).
2. Ciclo de release incompatível com o monólito.
3. Isolamento de falha crítico (ex.: LLM provider instável).
4. Fronteira de compliance (dados com residência especial).

Até lá: package boundaries rigorosos valem mais que rede.

---

## 10. Anti-padrões proibidos

| Anti-padrão | Por quê |
|-------------|---------|
| “Utilitário global” com regras de vários contextos | Erosão de limites |
| Shared database tables sem dono | Acoplamento oculto |
| Eventos genéricos `SomethingChanged` sem contrato | Fragilidade |
| UI chamando múltiplos repositórios cross-context | Bypass de application layer |
| Cópia de entidades entre módulos sem ACL | Modelos divergentes e bugs |

---

## 11. Glossário e linguagem ubíqua

Cada módulo mantém glossário curto no próprio README de módulo (quando código existir). Termos conflitantes entre contextos são resolvidos explicitamente (Context Mapping: Partner / Customer-Supplier / ACL).
