Cada diagrama de arquitetura que vi numa wiki estava errado. Não dramaticamente errado. Apenas silenciosamente, incrementalmente errado. O serviço etiquetado como “Auth” foi dividido em três microserviços há seis meses. A seta marcada como “sync call” é agora async via uma queue. A base de dados etiquetada como “PostgreSQL” foi migrada para outra coisa durante um fire drill e ninguém atualizou a caixa.
Isto não é negligência. É física. O código muda centenas de vezes por semana. A documentação muda quando alguém se lembra. A meia-vida de um diagrama de arquitetura é aproximadamente uma sprint. Depois disso, torna-se ficção.
O objetivo não é escrever docs que nunca divaguem. O objetivo é detetar a divagação antes que ela engane o próximo engenheiro.
Por que os docs apodrecem mais depressa do que o código
O código tem um mecanismo de correção incorporado: ou compila e passa nos testes, ou não. A documentação não tem compiler, nem test suite, nem gate de CI. Um diagrama errado renderiza perfeitamente. Um ADR stale lê-se tão convincentemente como um novo.
A divergência também é social. Os engenheiros atualizam o código porque o build falha. Atualizam os docs porque se sentem culpados. A culpa é um scheduler pouco fiável.
Quando um novo engenheiro entra e lê a wiki, constrói um modelo mental do sistema. Se esse modelo está stale há seis meses, tomará decisões que agravam a confusão existente. A documentação que deveria reduzir o friction de onboarding torna-se uma fonte de desorientação subtil e cara.
As três armadilhas de ficção
Há três locais onde a documentação de arquitetura se torna ficção mais depressa.
O cemitério de wikis. Os docs de arquitetura no Confluence, Notion ou SharePoint vivem fora do repo. Não têm commit history correlacionada com mudanças de código. Quando um refactor elimina um serviço, a página da wiki sobrevive como uma ghost town digital. Nenhum build falha. Nenhum alert dispara.
A ficção do diagrama. Um diagrama bonito exportado do Lucidchart ou draw.io e colado num README parece autoritário. É também uma imagem estática. O próximo developer que muda a arquitetura tem de abrir uma design tool, encontrar o source file, atualizá-lo, reexportá-lo e colá-lo de volta. Esse workflow tem uma taxa de sobrevivência de 5%.
O README onisciente. O README de top-level que tenta documentar cada serviço, cada dependência e cada data flow num só ficheiro. Torna-se um mega-documento que todos têm medo de tocar. Eventualmente, uma alma corajosa adiciona uma nota: “This section may be outdated.” Depois outra. Depois o documento inteiro é envolto em scare quotes e abandonado.
Documentação viva que se mantém honesta
A solução não é escrever mais docs. É tornar os docs incontornáveis.
Mova os docs para o repository. Se a documentação não estiver no mesmo pull request que a mudança de código, não será atualizada. ADRs, runbooks e decision logs devem viver em docs/architecture/ ou docs/adr/ ao lado do código que descrevem. Quando um reviewer vê um refactor sem atualização de doc, pode bloquear o merge.
Gere diagramas a partir de código. Mermaid, PlantUML e Structurizr permitem definir diagramas em ficheiros de texto que vivem no repo. Um job de CI renderiza-os a cada commit. Quando a arquitetura muda, o source do diagrama muda com ela. Nenhuma design tool necessária.
<!-- docs/architecture/data-flow.md -->
## Ingestion Pipeline
```mermaid
graph LR
A[Client SDK] -->|HTTP POST| B[Ingest API]
B -->|Pub/Sub| C[Event Consumer]
C -->|Write| D[(ClickHouse)]
Este diagrama é reviewable num diff. Quando o pipeline ganha um novo Kafka topic, a mudança aparece no mesmo PR que adiciona o consumer.
**Separe o "what" do "why."** A codebase já descreve o que o sistema faz. Comments, function names e types codificam a estrutura atual. A documentação deve focar-se em por que o sistema tem o aspeto que tem. É isso que divaga silenciosamente: o raciocínio por detrás de uma decisão, não a decisão em si.
Os Architecture Decision Records capturam isto. Um ADR não é um spec. É uma nota com timestamp que diz: "On this date, for these reasons, we chose this. Here are the constraints we accepted." Quando as constraints mudam, o ADR é substituído por um novo. O registo antigo permanece como história.
## Automatize o "what," escreva o "why"
Os docs de arquitetura mais honestos são aqueles que não escreves à mão.
Os specs OpenAPI gerados a partir de controller code descrevem a tua API surface com precisão. TypeDoc, RustDoc ou Javadoc descrevem os teus types internos. Os dependency graphs gerados por `cargo tree`, `go mod graph` ou `webpack-bundle-analyzer` mostram a module structure real.
Para constraints de arquitetura de nível superior, os automated architecture tests atuam como uma safety net. Em Java, o ArchUnit pode impor regras como "no package em `domain` pode depender de `infrastructure`." Em Python, o `import-linter` faz o mesmo. Em Go, podes escrever um test pequeno que percorre a AST e falha o build se aparecer um forbidden import.
```java
// This test fails the build if architecture rules break.
@ArchTest
static final ArchRule domain_independence =
noClasses()
.that().resideInAPackage("..domain..")
.should().dependOnClassesThat()
.resideInAPackage("..infrastructure..");
Quando um developer importa acidentalmente o package errado, o build falha imediatamente. O doc de arquitetura não precisa de o avisar. O compiler faz isso.
Os trade-offs que ninguém admite
A documentação viva não é gratuita. Custa review time, CI minutes e a ocasional discussão sobre se uma mudança justifica um novo ADR.
Nem todo o sistema precisa de um diagrama. Um monolito simples com três layers não precisa de um modelo C4. O esforço para manter docs gerados deve ser proporcional à dor de misunderstanding do sistema. Se o mental model errado te custa um dia de debugging, investe uma hora num diagrama. Se te custa cinco minutos, escreve um comment.
Os docs gerados também podem mentir. Um spec OpenAPI gerado a partir de código descreve cada endpoint, incluindo os internos que te esqueceste de documentar. Um dependency graph mostra cada import, incluindo os que violam a tua arquitetura. A verdade gerada é precisa mas nem sempre útil. Ainda precisas de curadoria humana para destacar o que importa.
Os ADRs acumulam-se. Depois de dois anos, podes ter trinta ADRs em docs/adr/. A maioria será irrelevante. A solução não é eliminá-los. É marcá-los claramente: status: superseded com um link para o substituto. A história tem valor. A confusão não tem.
Uma configuração mínima que funciona
Não precisas de uma documentation platform. Precisas de três coisas no teu repo.
docs/adr/YYYY-MM-DD-title.mdpara decisões. Usa um template leve:
# ADR 012: Event Storage Backend
- Status: accepted
- Date: 2026-03-15
## Context
We need durable storage for ingestion events with sub-second query latency.
## Decision
Use ClickHouse for hot storage, S3 for cold archival.
## Consequences
- Fast analytical queries on recent data.
- Complex operational footprint compared to PostgreSQL.
- Migration path defined in ADR 013.
-
docs/architecture/*.mdcom diagramas Mermaid para system boundaries e data flow. Exige uma atualização de doc no mesmo PR que mudanças estruturais de código. -
Um architecture test que impõe a tua invariant mais cara. Se só tens uma regra, faz dela a que previne o último refactor doloroso. Adiciona mais à medida que o sistema cresce.
FAQ
Preciso de diagramar cada microserviço?
Não. Diagrama as boundaries onde as equipas fazem hand off, onde os dados cruzam trust zones e onde as falhas cascateiam. Um diagrama do teu serviço CRUD interno é normalmente desperdício. Um diagrama de quais serviços chamam o payment gateway é normalmente valioso.
E se a minha equipa já usa Confluence?
Espelha os docs críticos no repo e faz link out. A source of truth permanece no git. A wiki torna-se uma convenience layer. Se a wiki divagar, os engenheiros sabem onde encontrar a versão real.
Quantos ADRs são demasiados?
Não há um upper limit, mas há um readability limit. Se um novo engenheiro não consegue scanear docs/adr/ e compreender a evolução do sistema em dez minutos, adiciona um index. Agrupa por subsystem. Marca os registos superseded claramente.
E quanto às wikis para stakeholders não técnicos?
Product managers e executives precisam de high-level summaries. Gera-os a partir do ADR index. Não mantenhas uma narrative separada. Os mesmos factos devem fluir do source code, através dos ADRs, para human summaries. Uma source of truth, múltiplas views.
Comece com um ADR e um test
Não precisas de reformular a tua documentation culture esta semana. Escolhe a última architectural decision que causou confusão. Escreve um ADR explicando por que escolheste o que escolheste. Escolhe a invariant que gostarias que fosse imposta automaticamente. Escreve um architecture test que falha o build quando alguém a viola.
Esses dois artifacts manter-se-ão honestos porque vivem no repo, são revistos em PRs e ou passam no CI ou não são shipped. Tudo o resto, as wiki pages, os slide decks, os conference posters, é secundário. Bom de ter. Possivelmente útil. Provavelmente errado.