Code review eficaz: como revisar mudanças sem travar a equipe
Uma boa revisão não procura impor preferências pessoais. Ela verifica se a mudança resolve o problema com risco, complexidade e operação aceitáveis.
A revisão começou pelo código errado Considere uma pull request hipotética com o título: Ajusta processamento do checkout. O diff altera 38 arquivos. Há mudanças no cálculo do frete, na criação do pedido, no tratamento de cupons, no envio de e mail e na estrutura do banco. A descrição informa apenas: Corrige o problema solicitado. O primeiro revisor abre o maior arquivo e comenta: Esse nome poderia ser menor. O segundo discute a escolha entre aspas simples e duplas. O terceiro aprova porque os testes passaram. Nenhum deles perguntou: qual defeito estava sendo corrigido; como reproduzi lo; quais regras de negócio mudaram; se a operação pode cobrar duas vezes; como a migração de banco será aplicada; o que acontecerá se o deploy falhar; se o comportamento anterior continua compatível. A revisão não falhou porque deixou passar um detalhe sintático. Ela falhou porque analisou linhas sem compreender a mudança. O code review começa antes do diff Uma revisão eficaz precisa responder a quatro perguntas em ordem: Abrir diretamente a aba de arquivos induz o revisor a avaliar o que é fácil de enxergar: nomes, formatação e pequenos trechos. O contexto exige esforço adicional, mas determina o que realmente importa. Antes de ler o código, procure na descrição: problema ou requisito; comportamento anterior; comportamento esperado; escopo; decisão técnica; riscos conhecidos; evidência de teste; impacto de banco, configuração e infraestrutura; plano de publicação; condição de rollback. A documentação do GitLab sobre merge request reviews orienta o revisor a começar pela descrição e pelas discussões antes de inspecionar o diff. O objetivo é compreender a intenção que será avaliada, não apenas a forma do código. Quando a descrição não permite isso, o comentário mais útil pode ser: Necessário: inclua um cenário reproduzível, o comportamento esperado e o impacto desta mudança no fluxo de pagamento. Sem esse contexto, não consigo verificar se a implementação atende à regra correta. Esse pedido não é burocracia. É uma pré condição para revisar. Uma pull request precisa ser revisável Mudanças pequenas não são automaticamente simples, e mudanças grandes não são automaticamente ruins. O problema aparece quando o escopo impede que uma pessoa construa um modelo mental confiável. A orientação do Google sobre mudanças pequenas favorece alterações autocontidas porque são mais fáceis de compreender, testar e reverter. Isso não cria um limite universal de linhas. Uma divisão possível para o exemplo do checkout seria: Essa separação só funciona quando cada etapa mantém o sistema em estado válido. Fragmentar artificialmente uma mudança em commits ou PRs que não funcionam isoladamente apenas desloca a complexidade. Use estes sinais para pedir divisão: múltiplos objetivos independentes; refatoração misturada com mudança funcional; atualização de dependências sem relação com a tarefa; alterações em muitas camadas sem explicação; arquivos gerados misturados ao código; migração de dados junto com redesign amplo; dificuldade para explicar a ordem de leitura. O fluxo Git com branches curtas e integração frequente ajuda a reduzir acúmulo sem transformar cada linha em uma solicitação separada. Um roteiro para ler a mudança Depois do contexto, percorra a revisão por risco. 1. Interface e contrato Verifique o que outros componentes percebem: endpoint; evento; schema; argumento; tipo; mensagem de erro; comportamento de função pública; formato de banco; configuração. Pergunte se consumidores antigos continuarão funcionando. 2. Regra de negócio Procure condições, transições e limites. No checkout: preço é recalculado no servidor; cupom pertence ao cliente; estoque é validado; pedido não é criado duas vezes; pagamento não é repetido; falha parcial possui tratamento. 3. Segurança Avalie: autenticação; autorização por objeto; exposição de dados; validação de entrada; segredos; logs; permissões; dependências; chamadas externas. Mudanças em autenticação, autorização, criptografia ou dados sensíveis podem exigir alguém com conhecimento específico. O guia de revisão do Google Engineering Practices recomenda buscar pessoas qualificadas quando a revisão envolve áreas especializadas. 4. Falhas e concorrência O caminho feliz costuma ser o mais visível. Procure: timeout; repetição; duas requisições simultâneas; serviço externo indisponível; transação interrompida; mensagem duplicada; processo reiniciado; fila atrasada; dado ausente. 5. Testes Não pergunte apenas se “há testes”. Pergunte: qual risco cada teste protege; o teste falha antes da correção; o cenário usa componentes reais suficientes; autorização foi verificada; contrato foi preservado; erro foi exercitado; fixtures representam o caso; o teste é determinístico. A relação entre risco e camada de validação é aprofundada na estratégia de testes web. 6. Operação Revise elementos que não aparecem na tela: migração; variável; segredo; healthcheck; métrica; log; alerta; compatibilidade durante o deploy; consumo de recurso; rollback. Código correto localmente ainda pode produzir uma publicação inviável. Nem todo comentário possui o mesmo peso Uma fonte recorrente de atrito é deixar que o autor adivinhe se uma observação bloqueia a aprovação. Uma convenção simples: Prefixo Significado BLOQUEIO Risco que impede o merge NECESSÁRIO Alteração exigida para aprovação PERGUNTA Contexto ausente ou decisão não compreendida SUGESTÃO Alternativa opcional NIT Ajuste pequeno, não bloqueante ELOGIO Boa decisão que merece ser preservada FORA DO ESCOPO Problema real a registrar separadamente Exemplo ruim: Isso está errado. Exemplo útil: BLOQUEIO — autorização: a consulta busca o pedido apenas por id . Em um ambiente multiempresa, isso permite que uma identidade autenticada tente acessar pedidos de outra organização. Inclua o escopo da organização na consulta e um teste que reproduza o acesso cruzado. O segundo comentário indica: categoria; impacto; evidência; ação esperada; teste necessário. Outro exemplo: SUGESTÃO: extrair o cálculo para uma função pura pode simplificar os testes. Não considero necessário para este merge se a equipe preferir manter a estrutura atual. A etiqueta impede que uma preferência opcional se transforme em rodada adicional. Comente o código, não a pessoa Compare: Você complicou essa função. com: Esta função agora combina validação, consulta e persistência. A separação pode facilitar o tratamento de erro e os testes. O primeiro comentário atribui o problema ao autor. O segundo descreve uma propriedade observável da implementação. O guia do Google sobre comentários de revisão recomenda explicar o raciocínio, manter respeito e distinguir exigência de orientação. Também recomenda reconhecer boas soluções. Um elogio específico transmite padrão técnico: ELOGIO: manter a migração aditiva antes de remover a coluna antiga permite que versões anterior e nova coexistam durante o deploy. Isso ensina tanto quanto um bloqueio. Preferências de estilo pertencem à automação Formatação, imports, lint, tipos e padrões mecânicos devem ser verificados pelo pipeline sempre que possível. O pipeline de CI/CD deve remover da revisão humana o trabalho determinístico. Isso libera atenção para aspectos que não cabem em uma regra estática. Uma exceção ocorre quando a convenção ainda não foi automatizada. Nesse caso, registre o padrão em documentação e transforme o posteriormente em verificação. O revisor também possui responsabilidade pelo fluxo Uma revisão perfeita que chega tarde demais ainda cria custo. O guia do Google sobre velocidade de revisão recomenda responder rapidamente sem interromper constantemente períodos de concentração. Não existe um prazo universal. A equipe precisa definir seu acordo. Exemplo: reconhecer a solicitação no mesmo período de trabalho; concluir mudanças pequenas dentro de um dia útil; sinalizar quando a revisão exige especialista; devolver imediatamente PR sem contexto ou claramente grande; indicar ausência e substituto; priorizar correções de produção. Métricas úteis: tempo até a primeira resposta; tempo em espera pelo revisor; tempo em espera pelo autor; número de rodadas; idade das PRs abertas; proporção de mudanças reabertas; defeitos relacionados após o merge. Não use esses números para ranquear pessoas. Uma revisão de permissão crítica não pode ser comparada mecanicamente a uma atualização de texto. Quando sair dos comentários A conversa assíncrona deixa de ser eficiente quando: o mesmo ponto retorna em várias rodadas; a discussão depende de arquitetura; autor e revisor usam termos diferentes; o problema exige navegar pelo sistema; o risco precisa de decisão rápida; há tensão crescente; existem muitas alternativas válidas. Faça uma conversa curta, compartilhe a tela e registre a decisão final na pull request. Sem o registro, o contexto desaparece e a mesma discussão retorna meses depois. CODEOWNERS reduz o problema de “quem revisa?” O GitHub permite solicitar automaticamente revisores definidos em CODEOWNERS e exigir aprovações antes do merge. Exemplo: O arquivo não substitui propriedade real. Se toda área aponta para a mesma pessoa, apenas formaliza um gargalo. Proteja também alterações ao próprio CODEOWNERS e aos workflows. Template mínimo de pull request Um template deve ser curto o suficiente para ser preenchido e específico o suficiente para melhorar a revisão. Critério para aprovar O padrão do Google Engineering Practices não exige perfeição: a mudança pode ser aprovada quando melhora a saúde do código e não introduz risco que justifique bloqueio. Uma aprovação responsável significa: o objetivo foi compreendido; o desenho é aceitável; regras críticas foram verificadas; testes correspondem aos riscos; segurança e operação foram consideradas; observações bloqueantes foram resolvidas; sugestões opcionais estão claramente identificadas. O code review não deve provar que o software não possui defeitos. Deve fornecer evidência proporcional ao impacto da mudança. A revisão mais eficaz não é a que deixa mais comentários. É a que ajuda a equipe a integrar uma mudança compreendida, verificável e operável.