MÓDULO 2.4

📝 ADRs e Documentação de Decisão

Architecture Decision Records são a memória do projeto. Neste módulo, você vai aprender a documentar decisões arquiteturais de forma que qualquer pessoa — hoje ou daqui a 2 anos — entenda o porquê de cada escolha.

7
Tópicos
30 min
Duração
Interm.
Nível
Prática
Tipo
1

📄 O que são ADRs

Architecture Decision Records são documentos curtos e estruturados que registram decisões arquiteturais significativas: o contexto, a decisão tomada e suas consequências. Vivem no repositório junto ao código, são versionados com git e revisados como qualquer outro artefato. São a “memória institucional” que impede que cada novo desenvolvedor redescubra (e frequentemente reverta) decisões anteriores.

💡 Conceito Principal

Um ADR tem quatro elementos fundamentais:

  • Contexto — Qual problema motivou a decisão? Quais forças estão em jogo?
  • Decisão — O que foi escolhido e por quê. Sempre com “because”.
  • Consequências — O que melhora e o que piora com essa decisão
  • Status — Proposed, Accepted, Deprecated ou Superseded

📊 Caso Real: Spotify

O Spotify tem mais de 1.000 ADRs públicos internamente e mediu o impacto da prática:

  • 40% menos discussões repetidas sobre decisões já tomadas
  • Onboarding 30% mais rápido para novos desenvolvedores
  • Consistência entre squads que trabalham em domínios similares
  • Rastreabilidade completa — sempre se sabe por que algo foi decidido daquela forma

✓ O que FAZER

  • Tratar ADRs como código — versionado, revisado, mergeado
  • Escrever ADRs no momento da decisão, não depois
  • Incluir alternativas rejeitadas e os motivos

✗ O que NÃO fazer

  • Documentar na Confluence e esperar que alguém leia
  • Escrever ADRs com 10 páginas — ideal é 1 página
  • Documentar depois de implementar — o contexto já se perdeu

💡 Dica Prática

Comece hoje: crie uma pasta docs/adr/ no seu repositório e escreva o primeiro ADR sobre uma decisão recente. Não precisa ser perfeito — ADR ruim é melhor que nenhum ADR. O hábito se constrói com a prática.

2

✍️ Como Escrever um Bom ADR

Um bom ADR segue o template de Michael Nygard: Título, Data, Status, Contexto, Decisão, Consequências. A chave é o “because” — a decisão sem justificativa não é um ADR, é um anúncio. ADRs ruins dão falsa sensação de documentação e são piores que nenhum ADR.

📋 Template de ADR (Michael Nygard)

# ADR-001: Usar PostgreSQL como banco primário

Status: Accepted
Date: 2024-01-15
Deciders: Time de Plataforma

## Contexto
Precisamos de um banco relacional com suporte a JSON, full-text search e extensões geoespaciais...

## Decisão
Usaremos PostgreSQL because atende todos os requisitos e o time já tem expertise...

## Consequências
+ Ecossistema maduro, comunidade ativa
- Precisamos de expertise em tuning de PostgreSQL

✓ Bom ADR

  • “Escolhemos PostgreSQL porque precisamos de transações ACID e o time tem expertise”
  • Inclui alternativas rejeitadas: MongoDB descartado por falta de transações multi-document
  • Cabe em uma página — conciso e direto

✗ Mau ADR

  • “Decidimos usar PostgreSQL” — sem contexto nem justificativa
  • 10 páginas de análise comparativa que ninguém lê
  • Escrito 6 meses depois da decisão — contexto perdido

📊 Formatos Populares

  • Nygard (original) — Título, Status, Contexto, Decisão, Consequências
  • MADR (Markdown ADR) — Adiciona Alternativas Consideradas e Prós/Contras estruturados
  • Y-Statement — “No contexto de X, enfrentando Y, decidimos Z para atingir W, aceitando Q”
  • Lightweight ADR — Apenas 3 seções: Problema, Decisão, Impacto

💡 Dica Prática

Use o formato MADR se seu time gosta de estrutura, ou Nygard se prefere simplicidade. O formato importa menos que a consistência. Escolha um e use para todos os ADRs — não misture formatos no mesmo projeto.

3

🔎 Quando Criar um ADR

Não documente tudo, documente o que importa. ADRs são para decisões significativas — escolha de banco de dados, estilo arquitetural, protocolo de comunicação, estratégia de deploy. Over-documentation mata a prática tão rápido quanto a ausência de documentação.

💡 Regra dos 4 Critérios

Escreva um ADR se a decisão atende pelo menos um desses critérios:

  • É difícil de reverter — Mudar de banco de dados depois de 2 anos custa caro
  • Afeta múltiplos times — Padrão de comunicação entre serviços, por exemplo
  • Tem trade-offs não-óbvios — Se a resposta é óbvia, não precisa de ADR
  • Alguém vai perguntar “por quê?” daqui a 6 meses

⚠️ Armadilha: Over-Documentation

Times que documentam tudo em ADRs geram fadiga e a prática morre em semanas:

  • “ADR-042: Usar tabs em vez de espaços” — Não. Isso é linter config.
  • “ADR-043: Usar Jest para testes” — Talvez. Só se houve debate real.
  • “ADR-044: Usar Event Sourcing para pagamentos” — Sim! Decisão com alto impacto e trade-offs.

💡 Dica Prática

Teste mental rápido: “Se um dev novo entrar no time daqui a 1 ano, essa decisão vai confundi-lo?” Se sim, escreva um ADR. Se a decisão é auto-evidente pelo código, economize o tempo.

4

📂 Organizando no Repositório

ADRs devem viver junto ao código no repositório. Documentação na Confluence, Google Docs ou wikis internas é onde decisões vão para morrer. No repositório, o ADR aparece no PR review, no blame, no log — é parte do fluxo natural de desenvolvimento.

📁 Estrutura Recomendada

projeto/
├── docs/
│   ├── adr/
│   │   ├── 0001-use-postgresql.md
│   │   ├── 0002-adopt-event-sourcing-for-payments.md
│   │   ├── 0003-use-grpc-for-internal-communication.md
│   │   └── README.md  (index com links)
│   └── architecture/
│       └── c4-diagrams/
├── src/
└── ...
                    

📊 Ferramentas de ADR

  • adr-tools (CLI)adr new "Use PostgreSQL" cria o arquivo com template e numeração automática
  • Log4brains — Gera site estático navegável a partir dos ADRs Markdown do repositório
  • ADR Manager (VS Code) — Extensão para criar, visualizar e gerenciar ADRs direto no editor
  • GitHub/GitLab templates — Template de PR que exige link para ADR quando há mudança arquitetural

✓ O que FAZER

  • Numerar sequencialmente: 0001, 0002, 0003
  • Linkar ADRs nos PRs que implementam a decisão
  • Manter um README index com todos os ADRs e status

✗ O que NÃO fazer

  • Guardar ADRs na Confluence — morrem em semanas
  • Usar nomes genéricos como “decision-1.md”
  • Deletar ADRs antigos — deprecie, não apague
5

🔄 Lifecycle de um ADR

ADRs têm ciclo de vida: nascem como Proposed, são aceitos ou rejeitados, e eventualmente podem ser Superseded por uma nova decisão. O ADR antigo não é “errado” — era certo para o contexto da época. A história completa fica preservada.

🔄 Fluxo de Status

1

🔴 Proposed

ADR criado como PR. Time revisa, comenta, sugere alterações. Funciona como um RFC (Request for Comments) assíncrono.

2

🟢 Accepted

Time concorda com a decisão. PR mergeado. A partir daqui, a decisão é a referência oficial.

3

🟡 Deprecated

A decisão não é mais relevante (ex: tecnologia descontinuada). Mantido para histórico.

4

🔵 Superseded

Substituído por um novo ADR. Ex: “ADR-0023 substitui ADR-0005”. Link bidirecional entre os dois.

📊 Exemplo de Superseding

  • ADR-0005 (2022) — “Usar REST para todas as APIs” — Status: Superseded by ADR-0023
  • ADR-0023 (2024) — “Usar gRPC para comunicação serviço-a-serviço” — Status: Accepted
  • Contexto da mudança — Latência p99 entre serviços ultrapassou SLO de 50ms com REST/JSON. gRPC com protobuf reduziu para 12ms.

A história mostra que REST era correto em 2022 (time pequeno, poucos serviços) e gRPC é correto agora (20 serviços, latência crítica).

💡 Dica Prática

Nunca delete um ADR. ADRs superseded são história valiosa. Eles mostram como o pensamento do time evoluiu e por que decisões anteriores faziam sentido no contexto original. Marque como superseded e adicione o link para o ADR substituto.

6

🗣️ Ferramenta de Comunicação

ADRs não são só documentação — são uma ferramenta de alinhamento assíncrono. Um ADR com status “Proposed” é um RFC que o time revisa antes da implementação. Isso elimina reuniões desnecessárias e dá a todos a chance de contribuir, independente do fuso horário.

💡 ADR como RFC

O fluxo de ADR como ferramenta de comunicação:

  • Autor propõe — Cria branch, escreve ADR, abre PR
  • Time comenta — Perguntas, sugestões, preocupações — tudo registrado no PR
  • Ajustes são feitos — Iterações até consenso (ou consent)
  • Merge = aceito — A decisão é oficial quando o PR é mergeado

📊 Caso Real: ThoughtWorks

O ThoughtWorks usa ADRs como RFCs e eliminou 80% das reuniões de decisão arquitetural:

  • Antes: Reuniões de 1h com 8 pessoas para discutir cada decisão = 8h de trabalho
  • Depois: ADR escrito em 30min, revisado assincronamente = ~2h de trabalho total
  • Bônus: Introverted devs que não falam em reuniões contribuem mais por escrito
  • Resultado: Decisões melhores, mais inclusivas, e 75% mais rápidas

✓ O que FAZER

  • Definir período de comentários (ex: 3 dias úteis)
  • Usar consent, não consensus — “alguém discorda?” vs. “todos concordam?”
  • Ter path de escalação para impasses

✗ O que NÃO fazer

  • Usar ADR para justificar decisão já tomada
  • Ignorar comentários e mergear unilateralmente
  • Deixar ADR “Proposed” por semanas sem resolução
7

📊 Métricas e Revisão

Decisões envelhecem. O que era correto com 10 usuários pode ser errado com 10 milhões. Revisar ADRs periodicamente à luz de novos dados garante que a arquitetura evolui com o sistema. Architecture Fitness Functions automatizam essa verificação.

💡 Estratégias de Revisão

  • Review trimestral — Passar pelos ADRs ativos uma vez por quarter e validar se ainda fazem sentido
  • Trigger-based — Revisar quando uma métrica ultrapassa threshold (ex: latência > SLO)
  • Incident-driven — Todo post-mortem verifica se algum ADR precisa ser revisitado
  • Scale-triggered — Ao atingir milestones de escala (10x usuários, novo mercado)

📊 Fitness Functions na Prática

Testes automatizados que verificam se a arquitetura ainda atende seus atributos de qualidade:

  • ArchUnit (Java) — “Nenhum controller importa repositório diretamente” — se alguém viola, o build quebra
  • NetArchTest (.NET) — Mesma ideia para ecossistema .NET
  • Performance budgets — CI falha se bundle size > 200KB ou se p99 > 200ms
  • Dependency checks — Alertas se dependências circulares forem introduzidas

📋 Checklist de Revisão Trimestral

  • A decisão ainda resolve o problema original?
  • Os trade-offs documentados se confirmaram?
  • Surgiram alternativas melhores desde então?
  • O contexto mudou significativamente (escala, time, requisitos)?
  • Houve incidentes relacionados a essa decisão?

💡 Dica Prática

Adicione ao template do ADR um campo “Review trigger”: uma condição que, quando atingida, sinaliza que é hora de revisitar. Ex: “Revisitar se ultrapassarmos 10k req/s” ou “Revisitar se o time crescer além de 15 pessoas”.

📋 Resumo do Módulo

ADRs são a memória do projeto — Documentos curtos que registram o porquê de cada decisão arquitetural
Contexto + Decisão + Consequências — O template básico que todo ADR deve seguir
Documente o que importa, não tudo — Use a regra dos 4 critérios para decidir quando criar um ADR
ADRs vivem no repositório — Junto ao código, versionados, revisados como PRs
Proposed → Accepted → Superseded — ADRs têm ciclo de vida; nunca delete, deprecie
ADRs são RFCs assíncronos — Ferramenta de comunicação que elimina reuniões desnecessárias
Revise periodicamente com dados — Fitness functions e triggers de revisão mantêm ADRs relevantes

Próximo Módulo:

2.5 - 🔄 Migração e Evolução — Strangler Fig, Feature Flags e estratégias para evoluir sistemas sem quebrar