Um visualizador de repositórios que fiz no verão passado tem oito commits na primeira semana. Os quatro primeiros não tocam uma única linha de aplicação: são o init a partir do meu template e três commits de documentação. O quinto já é o app inteiro.
Não foi disciplina. Foi que, ao escrever o documento, descobri que meu modelo mental da integração estava errado, e consertar isso num .md custava vinte minutos em vez de dois dias.
O erro de começar pelo código numa integração alheia
Quando a lógica é sua, ler o código é a melhor documentação que existe. Quando depende de uma API alheia, não: o que você precisa saber não está no seu código nem no deles. Está nos limites, nas cotas e nos parâmetros descontinuados.
Nesse visualizador confundi por um tempo duas conexões com o mesmo provedor. O OAuth de login e o token de servidor para ler a API parecem a mesma coisa e não são. Um serve para um humano entrar, o outro para o servidor ler. Falham de formas diferentes. Escrever isso num documento separado em duas seções foi o que me fez ver que um visualizador de repositórios públicos só precisava do segundo.
Se eu tivesse começado pelo código, teria descoberto isso no terceiro 401.
O que exatamente eu documento antes da primeira linha
Não documento o design do meu app. Documento o que não controlo. Em concreto:
- Os limites reais, medidos, não citados. Não basta copiar "5.000 requisições por hora" do site. Pedi ao endpoint de cota: 60/h sem autenticar, 5.000/h autenticado, 30/min na busca. E medi que um
304 Not Modifiednão gasta cota — 4972, 4972, 4972 com condicionais, e 4971 na mesma chamada semIf-None-Match. Esse número se repetindo é o argumento central do documento, e sem executar você não o tem. - O que não dá para automatizar. O OAuth App não se cria por CLI: não há endpoint para criá-lo nem para ler o client secret, que é mostrado uma única vez no navegador. É um passo manual, e no dia em que você montar o ambiente de novo terá esquecido.
- Os tetos que surpreendem em produção. 2.000 criações de token por hora, que é teto de logins, não de requisições. E reautorização forçada se um usuário entra dez vezes numa hora. Nenhum dos dois aparece quando você lê o happy path.
- O que a decisão NÃO resolve. Anotei que obrigar login não elimina a necessidade de cache condicional, porque o bucket do usuário é compartilhado com o PAT dele e com outros apps que atuem em seu nome. Se você não escreve isso, a decisão te dá uma falsa segurança.
Nada disso é opinável. São fatos que ou você comprova ou inventa.
Os cookbooks: testar cada peça isolada antes de integrá-la
Num serviço de IA para análise documental fiz o mesmo de outra forma. Antes que qualquer peça entrasse no serviço, cada uma tinha um cookbook: um script que a executa sozinha, escreve sua saída numa pasta e se registra num run_all_cookbooks. Parser de PDF, chunker, embeddings, detector de números, extração verificável. Um por peça.
O valor não é o teste. É que, quando a saída do chunker muda de forma, isso aparece num arquivo de texto em vez de numa falha três camadas acima. Ao passar o pipeline para assíncrono, os cookbooks viraram runners com asyncio.run e a migração foi feita peça a peça, não de uma vez.
O custo é que é preciso apagá-los quando deixam de valer. Meses depois há um commit que remove os cookbooks descontinuados. Um cookbook que já não corresponde à peça é pior que nenhum.
A documentação como fonte de verdade para auditar depois
Numa galeria de conceitos de UI escrevi primeiro um guia de design da peça — tamanhos, escada de espaçamento, escala de cinzas, qual primitivo se usa para quê — e depois auditei o código contra ele.
O interessante é que a auditoria corrigiu o guia, não só o código. Três coisas que o .md dizia a menos: que o cinza acompanhante se gradua em cinco degraus e não em dois; que a escada de espaçamento tem quatro degraus e não três, porque chamá-la de três transformava seis usos legítimos em desvio; e que os três diálogos são na verdade o mesmo diálogo, com a mesma caixa e o mesmo cabeçalho, e por não dizer isso a correção tinha sido aplicada a apenas um.
Sem documento prévio esses três achados não existem. Você não tem contra o que comparar e tudo o que encontra é "eu acho que".
Quando isso é perda de tempo
O critério que uso:
- Se a integração é sua de ponta a ponta, não documente antes. O código é a verdade e o documento envelhece.
- Se é um protótipo que você vai jogar fora, também não. Um jogo que escrevi em um dia não tem nada escrito e está bem assim.
- Se o documento vai repetir o que a referência oficial diz, não o escreva. Só agrega se tiver suas medições, suas versões e as armadilhas que couberam a você.
E há uma falha que me custou caro: o documento escrito antes carrega dentro as suas suposições. No visualizador, a seção de hospedagem descrevia uma plataforma serverless porque eu dei isso como certo ao redigir o escopo, não porque alguém tivesse decidido. Ao corrigir para um contêiner de vida longa, a conclusão inteira mudou: em serverless o SDK de agentes não cabia; num worker com quinze minutos de limite de requisição, cabia.
Por isso o passo seguinte não é opcional. Há um commit cujo único trabalho é verificar o documento contra fontes vivas: executar a consulta que aparece no guia, mandar uma versão de API inválida para que a própria API enumere as válidas, comprovar que per_page=500 é cortado para 100 em silêncio, tipar o snippet que não compilava em modo estrito. Esse commit descobriu que 18 de 20 "issues" devolvidas eram na verdade pull requests.
Um documento sem verificar é uma suposição com formatação bonita. Um documento verificado é a única parte da integração que não vai mentir para você daqui a seis meses.
