# Event-Driven Architecture — Mud Sentinel

**Documento:** `arquitetura/06-event-driven.md`  
**Versão:** 1.0.0  
**Status:** Vigente

---

## 1. Posicionamento

O Mud Sentinel **não** é “event-driven everywhere”.  
Adota **EDA seletiva**: eventos onde desacoplamento, retry e fan-out geram valor claro; request/response onde consistência imediata e UX simples importam.

**Justificativa:** EDA total aumenta complexidade de consistência eventual, debugging e ordenação — custo indevido no MVP.

---

## 2. Quando EDA é obrigatória ou fortemente recomendada

| Cenário | Motivo |
|---------|--------|
| Conclusão de ingestão → busca + grafo + métricas | Fan-out multi-módulo |
| Export de dossiê / geração de artefato | Longo, retryable |
| Completions de IA e embeddings | Timeout, custo, rate limit de provedor |
| Alertas de watchlist | Não bloquear thread de ingestão |
| Metering de uso (billing) | Não perder contagem se billing estiver lento |
| Mirror analítico de auditoria (se separado) | Isolar escrita quente |

---

## 3. Quando NÃO usar EDA

| Cenário | Motivo |
|---------|--------|
| Login / refresh token | Precisa de resposta imediata e consistente |
| Autorização de um request | Segurança síncrona no boundary |
| Pequenos CRUDs de configuração | Overkill |
| Leitura de ficha para UI | Query síncrona no store adequado |

---

## 4. Tipos de eventos

### 4.1 Domain Events

Fatos dentro de um bounded context (`CaseFinalized`). Podem ser handled in-process e/ou publicados.

### 4.2 Integration Events

Contrato estável entre contextos (`ingestion.ingest_run.published.v1`).

### 4.3 Audit Events

Ver política de auditoria — canal dedicado, retenção e imutabilidade lógica próprias.

---

## 5. Contratos de evento

Campos mínimos:

```text
event_id          UUID
event_type        string namespaced + version
occurred_at       RFC3339
tenant_id         UUID | null (somente se aplicável)
producer          service/module
correlation_id    UUID
causation_id      UUID | null
payload           object (schema versionado)
```

**Regras:**

- Compatibilidade backward por versão (`v1`, `v2`).
- Consumidores idempotentes (`event_id` / chave de negócio).
- Sem segredos; minimizar PII.

---

## 6. Topologia MVP

```text
Producer (module) → Outbox (PostgreSQL) → Publisher → Redis Queue/Streams → Consumers
```

**Transactional Outbox** é o padrão obrigatório quando o evento precisa ser publicado após commit de negócio.

| Sem outbox | Com outbox |
|------------|------------|
| Risco “commit sem publish” ou “publish sem commit” | Atomicidade lógica com a transação de negócio |

**Justificativa:** em compliance, perder um evento de publicação de dados ou de metering é inaceitável.

---

## 7. Garantias

| Garantia | Nível MVP |
|----------|-----------|
| Entrega | At-least-once |
| Ordem global | Não garantida |
| Ordem por chave (ex.: entity_id) | Melhor esforço / partição lógica quando necessário |
| Idempotência do consumidor | Obrigatória |

Exactly-once ponta a ponta **não** é compromisso do MVP (custo/infra).

---

## 8. Dead letters e reprocessamento

- Falhas após N retries → DLQ com motivo.
- Reprocessamento auditado (quem, quando, recorte).
- Poison messages não bloqueiam a fila principal indefinidamente.

---

## 9. Evolução para log de eventos

Se throughput ou replay analítico exigir, avaliar **Redpanda/Kafka** via ADR, preservando contratos `event_type`.

Vantagens: replay, múltiplos consumidores independentes.  
Desvantagens: ops, custo, complexidade de schemas.  
Só adotar com métricas (msgs/s, consumidores, necessidade de replay).

---

## 10. Observabilidade de eventos

Métricas: published, consumed, lag, retry, DLQ depth.  
Trace: `correlation_id` propagado.  
Alertas: lag acima do SLO de ingestão; DLQ > 0 por período.

---

## 11. Resumo normativo

1. EDA onde há fan-out, duração ou resiliência.
2. Outbox para eventos pós-commit.
3. Idempotência e contratos versionados.
4. Sem EDA como dogma.
