Skip to content

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:

  1. Contexto — qual problema/restrição motivou a decisão
  2. Decisão — o que foi escolhido (a regra)
  3. Alternativas consideradas — pelo menos duas, com pros/cons
  4. Consequências — positivas e negativas
  5. Trade-offs — tabela direta
  6. Conformidade — como verificar / o que viola
  7. Débito técnico — violações conhecidas no código atual
  8. Referências

Status

IDTítuloStatusDataCategoria
ADR-001Fábrica de Clientes Supabase✅ Aceito2026-04-30Backend / Segurança
ADR-002Adapter Pattern para Integrações Externas✅ Aceito2026-04-30Backend / Integrações
ADR-003Edge Function como Orquestrador (action-dispatch)✅ Aceito2026-04-30Backend / API
ADR-004Frontend Gateway Abstraction (invokeEdge)✅ Aceito2026-04-30Frontend / Infra
ADR-005Auth via Cookie HttpOnly + Worker Reescrita✅ Aceito2026-04-30Segurança
ADR-006Logging Fire-and-Forget com service_role isolado✅ Aceito2026-04-30Backend / Observabilidade
ADR-007React Query como única fonte de cache✅ Aceito2026-04-30Frontend / Estado
ADR-008Registries Declarativos em TypeScript✅ Aceito2026-04-30Frontend / Backend
ADR-009Sanitização de Erro em 2 Camadas✅ Aceito2026-04-30Segurança / UX
ADR-010Atomic Rendering & Anti-Flash✅ Aceito2026-04-30Frontend / UX
ADR-011service_role vs RLS — categorias e nomenclatura✅ Aceito2026-04-06Backend / Segurança
ADR-013Email Outbox: Trigger Direto + Cron Safety Net✅ Aceito2026-05-10Backend / Performance

Status: PropostoAceitoSuperseded (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".

text
                       ┌──────────────────────────────────────────────┐
                       │                                              │
   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 BE

Leitura recomendada por ordem

  1. ADR-005 primeiro — define o modelo de auth que tudo depende.
  2. ADR-001 + ADR-011 — fábrica de clientes e regra de service_role.
  3. ADR-003 + ADR-002 — como Edge Functions são organizadas e integram com terceiros.
  4. ADR-006 — logging que toda Edge Function chama.
  5. ADR-004 — porta de entrada do frontend.
  6. ADR-007 → ADR-010 → ADR-009 — fluxo de dados/render no FE.
  7. 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

  1. Abrir PR criando docs/architecture/adrs/ADR-NNN-titulo.md com status Proposto (use o ADR mais recente como template).
  2. Para superseder: novo ADR com cabeçalho Supersedes: ADR-XYZ. No ADR antigo, alterar Status: Superseded by ADR-NNN e adicionar nota apontando para o substituto no topo.
  3. Adicionar a entrada na tabela de Status acima e em docs/.vitepress/config.ts (sidebar).
  4. Atualizar o diagrama de dependências se a relação entre ADRs mudar.
  5. 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 ✅ 🟡).