Architecture Decision Records (ADRs)
SSOT dos padrões arquiteturais da Plataforma OLP. Cada ADR documenta uma decisão, suas alternativas, consequências e como verificar conformidade.
Por que ADRs?
A plataforma cresceu com decisões espalhadas em memórias internas, comentários de código e docs avulsos. Esta seção consolida os padrões em formato canônico — para onboarding rápido, revisões de PR objetivas e para que mudar um padrão exija superseder um ADR, não apenas reescrever código.
Como ler
Cada ADR segue:
- Contexto — qual problema/restrição motivou a decisão
- Decisão — o que foi escolhido (a regra)
- Alternativas consideradas — pelo menos duas, com pros/cons
- Consequências — positivas e negativas
- Trade-offs — tabela direta
- Conformidade — como verificar / o que viola
- Débito técnico — violações conhecidas no código atual
- Referências
Status
| ID | Título | Status | Data | Categoria |
|---|---|---|---|---|
| ADR-001 | Fábrica de Clientes Supabase | ✅ Aceito | 2026-04-30 | Backend / Segurança |
| ADR-002 | Adapter Pattern para Integrações Externas | ✅ Aceito | 2026-04-30 | Backend / Integrações |
| ADR-003 | Edge Function como Orquestrador (action-dispatch) | ✅ Aceito | 2026-04-30 | Backend / API |
| ADR-004 | Frontend Gateway Abstraction (invokeEdge) | ✅ Aceito | 2026-04-30 | Frontend / Infra |
| ADR-005 | Auth via Cookie HttpOnly + Worker Reescrita | ✅ Aceito | 2026-04-30 | Segurança |
| ADR-006 | Logging Fire-and-Forget com service_role isolado | ✅ Aceito | 2026-04-30 | Backend / Observabilidade |
| ADR-007 | React Query como única fonte de cache | ✅ Aceito | 2026-04-30 | Frontend / Estado |
| ADR-008 | Registries Declarativos em TypeScript | ✅ Aceito | 2026-04-30 | Frontend / Backend |
| ADR-009 | Sanitização de Erro em 2 Camadas | ✅ Aceito | 2026-04-30 | Segurança / UX |
| ADR-010 | Atomic Rendering & Anti-Flash | ✅ Aceito | 2026-04-30 | Frontend / UX |
| ADR-011 | service_role vs RLS — categorias e nomenclatura | ✅ Aceito | 2026-04-06 | Backend / Segurança |
| ADR-013 | Email Outbox: Trigger Direto + Cron Safety Net | ✅ Aceito | 2026-05-10 | Backend / Performance |
Status: Proposto → Aceito → Superseded (com link para o que substituiu) → Deprecated.
Dependências entre ADRs
Diagrama textual de quem depende de quem. Setas A ──> B significam "A apoia-se em B" ou "A é condição para B".
┌──────────────────────────────────────────────┐
│ │
ADR-005 (Cookie HttpOnly Auth) │
│ ▼
├──> ADR-001 (Client Factory) ─────> ADR-011 (service_role vs RLS)
│ │ │
│ ├──> ADR-006 (Fire-and-forget log) ┘
│ │
│ └──> ADR-002 (Adapter Pattern)
│
└──> ADR-003 (Edge Function action-dispatch)
│
└──> ADR-009 (Sanitização de erro 2 camadas)
ADR-004 (Frontend Gateway invokeEdge)
│
├──> ADR-007 (React Query como cache)
│ │
│ ├──> ADR-010 (Atomic Rendering & Anti-Flash)
│ └──> ADR-009 (Sanitização de erro — camada UI)
│
└──> ADR-005 (consumo do cookie no fetch)
ADR-008 (Registries Declarativos) — independente, consumido por FE e BELeitura recomendada por ordem
- ADR-005 primeiro — define o modelo de auth que tudo depende.
- ADR-001 + ADR-011 — fábrica de clientes e regra de service_role.
- ADR-003 + ADR-002 — como Edge Functions são organizadas e integram com terceiros.
- ADR-006 — logging que toda Edge Function chama.
- ADR-004 — porta de entrada do frontend.
- ADR-007 → ADR-010 → ADR-009 — fluxo de dados/render no FE.
- ADR-008 — convenção de metadados declarativos (pode ser lido a qualquer momento).
Princípios transversais
Esses princípios atravessam vários ADRs e guiam novas decisões:
- Fail-close: defaults negam acesso. RLS, feature gates, validações. Ver ADR-001, ADR-005, ADR-011.
- Centralização sobre repetição: 1 ponto de mudança > N pontos. Ver ADR-002, ADR-004.
- Tipo na borda, não no meio: validação Zod e contratos
{success, data|message}na entrada/saída. Ver ADR-003. - Observabilidade não-bloqueante: nunca quebrar fluxo do usuário por erro de log. Ver ADR-006.
- Frontend sem heurística de estado: estado de servidor é React Query, sempre. Ver ADR-007, ADR-010.
Quando criar um novo ADR?
Crie um ADR quando a decisão:
- Afeta mais de uma feature ou camada
- Tem alternativa não-trivial que foi descartada
- Vai durar meses/anos (não tática de sprint)
- É difícil de reverter sem refactor amplo
Não crie ADR para:
- Convenções de nomenclatura (vai em
CODING_STANDARDS) - Regras de uma feature específica (vai em
docs/features/) - Detalhes de implementação visíveis no código
Como propor / superseder
- Abrir PR criando
docs/architecture/adrs/ADR-NNN-titulo.mdcom status Proposto (use o ADR mais recente como template). - Para superseder: novo ADR com cabeçalho
Supersedes: ADR-XYZ. No ADR antigo, alterarStatus: Superseded by ADR-NNNe adicionar nota apontando para o substituto no topo. - Adicionar a entrada na tabela de Status acima e em
docs/.vitepress/config.ts(sidebar). - Atualizar o diagrama de dependências se a relação entre ADRs mudar.
- Se o ADR documenta um padrão obrigatório, refletir o resumo em
mem://index.md(Core).
Convenções
- Nome do arquivo:
ADR-NNN-slug-em-kebab-case.md. NNN é zero-padded a 3 dígitos. - Idioma: português. Termos técnicos (anon key, service role, RLS) ficam em inglês.
- Tom: declarativo. "A plataforma usa X." > "Decidimos talvez usar X."
- Código de exemplo: trechos curtos com caminho do arquivo de origem.
- Sem emojis no corpo (exceto badges de status como ✅ 🟡).