Revisão de código assíncrona: como dar feedback escrito de qualidade

1. Fundamentos da Revisão Assíncrona

1.1 Definição e diferenças para revisão síncrona

A revisão de código assíncrona ocorre quando o revisor analisa o código em um momento diferente do autor, geralmente por meio de pull requests (PRs) em plataformas como GitHub, GitLab ou Bitbucket. Diferentemente do pair programming, onde dois desenvolvedores trabalham juntos em tempo real, a revisão assíncrona permite que cada parte examine as mudanças no seu próprio ritmo, documentando o feedback por escrito.

Enquanto o pair programming favorece a troca imediata de ideias, os pull requests exigem que o feedback seja claro o suficiente para ser compreendido sem contexto adicional. Isso torna a comunicação escrita uma habilidade central para revisores em equipes remotas ou distribuídas.

1.2 Por que o feedback escrito exige mais cuidado

A ausência de tom de voz, expressões faciais e linguagem corporal faz com que comentários escritos possam ser interpretados de forma negativa. Uma frase como "Isso está errado" pode soar agressiva, mesmo que a intenção seja apenas apontar um problema técnico. Por isso, o revisor precisa escolher palavras com cuidado para transmitir a mensagem sem gerar atritos desnecessários.

1.3 O papel na cultura de equipes remotas

Em equipes distribuídas, a revisão assíncrona é a principal forma de colaboração técnica. Ela permite que pessoas em fusos horários diferentes contribuam sem depender de horários de reunião. No entanto, para que funcione bem, é essencial que o feedback seja estruturado, respeitoso e acionável.

2. Estruturando o Feedback: Clareza e Organização

2.1 Como separar comentários por tipo

Agrupar comentários por categoria ajuda o autor a priorizar as respostas. Uma boa prática é usar marcadores como:

  • Crítico: problemas que quebram a funcionalidade ou comprometem segurança
  • Sugestão: melhorias de performance, legibilidade ou boas práticas
  • Questão: dúvidas sobre a lógica ou decisão de design
  • Elogio: reconhecimento de partes bem implementadas

Exemplo:

## Comentários sobre o PR #42

### Crítico
- Linha 15: A validação de entrada está ausente. Isso pode causar SQL injection.

### Sugestão
- Linha 30: Considere usar `async/await` em vez de `.then()` para melhor legibilidade.

### Questão
- Linha 45: Por que optou por um `switch` em vez de um objeto de mapeamento?

### Elogio
- A separação de responsabilidades no módulo de autenticação ficou excelente.

2.2 Uso de títulos e numeração

Para PRs com muitos comentários, numere cada ponto para facilitar a referência cruzada. Por exemplo:

1. [Crítico] Função `processData` não trata erros de rede
2. [Sugestão] Extrair a lógica de formatação para um helper
3. [Questão] O método `retry` é realmente necessário aqui?

2.3 Uma ideia por comentário

Evite misturar múltiplos problemas em um único comentário. Isso dificulta a resposta e pode fazer com que algum ponto seja esquecido. Prefira:

Comentário 1: A função `validateEmail` não cobre o caso de domínios com acentos.
Comentário 2: O teste para `validateEmail` está incompleto — falta o caso de e-mail vazio.

Em vez de:

A função validateEmail não cobre acentos e o teste está incompleto. Além disso, a documentação está desatualizada.

3. Linguagem e Tom: Como Escrever sem Parecer Agressivo

3.1 Preferência por perguntas abertas

Perguntas convidam o autor a explicar sua decisão, em vez de se sentir atacado. Compare:

  • Afirmação categórica: "Isso está errado. Deveria usar const em vez de let."
  • Pergunta aberta: "Essa variável é reatribuída em algum momento? Se não, const seria mais adequado."

3.2 Uso de “eu” e “nós”

Expressar a opinião como pessoal ou coletiva suaviza o tom:

  • "Eu não entendi a lógica aqui. Pode explicar?"
  • "Nós poderíamos melhorar a legibilidade se extraíssemos essa condição para uma função."

3.3 Evitar palavras que soam como ordens

Substitua imperativos por sugestões educadas:

Evitar Preferir
"Corrija isso." "Sugiro corrigir isso para evitar o bug."
"Você deve usar async/await." "Que tal usar async/await aqui?"
"Isso está errado." "Pode ser que isso cause um problema de concorrência."

4. Foco no Código, Não na Pessoa

4.1 Separar comportamento da intenção

Comente sobre o código, não sobre o desenvolvedor. Em vez de "Você esqueceu de tratar o erro", diga "O tratamento de erro está ausente nesta função."

4.2 Oferecer alternativas sem invalidar a original

Reconheça que existem múltiplas soluções válidas:

A abordagem atual funciona, mas uma alternativa que talvez seja mais performática é usar um Map em vez de um objeto. O que acha?

4.3 Exemplos construtivo vs. destrutivo

Destrutivo:

Isso está mal escrito. Refatore tudo.

Construtivo:

A função está fazendo muitas coisas ao mesmo tempo. Sugiro dividi-la em três funções menores (parse, validate, save). Posso ajudar com um esboço se quiser.

5. Priorização e Contexto: O Que Comentar e Quando

5.1 Diferenciar tipos de problema

  • Erro funcional: o código não funciona como esperado
  • Violação de estilo: não segue o guia de estilo do time
  • Oportunidade de melhoria: funciona, mas pode ser melhorado

5.2 Indicar urgência

Use rótulos ou emojis para sinalizar prioridade:

🔴 Bloqueante: A query SQL é vulnerável a injeção.
🟡 Sugestão: Considere adicionar índices na tabela.
🟢 Opcional: Poderia renomear a variável para `userList`.

5.3 Fornecer contexto técnico

Explique por que a mudança é importante:

Essa função é chamada 1000 vezes por segundo. Usar `Array.includes` aqui tem complexidade O(n). Sugiro trocar por um Set, que é O(1).

6. Ferramentas e Boas Práticas de Comunicação Escrita

Inclua exemplos de código para ilustrar sua sugestão:

Sugestão de implementação alternativa:

async function fetchUser(id) {
  const response = await fetch(`/api/users/${id}`);
  if (!response.ok) throw new Error('Falha na requisição');
  return response.json();
}

Links para documentação interna ou externa também agregam valor:

Veja a seção sobre "Error Handling" no nosso guia de estilo: [link para documento interno]

6.2 Evitar ruído

Não comente código que já está em discussão em outro thread, a menos que seja para adicionar um ponto novo. Também evite comentar fora do escopo do PR — foque nas mudanças propostas.

6.3 Revisar o próprio feedback

Antes de enviar, releia seus comentários com um olhar crítico: "Isso soaria bem se eu estivesse recebendo?" Ajuste o tom se necessário.

7. Ciclo de Fechamento: Como Conduzir a Conversa até a Aprovação

7.1 Como responder a respostas do autor

Quando o autor discorda ou pede esclarecimentos, mantenha a calma e foque nos fatos:

Entendo seu ponto. Minha preocupação principal é a performance. Se você puder mostrar benchmarks que comprovam que a abordagem atual é equivalente, posso aprovar como está.

7.2 Saber quando aprovar com ressalvas

Aprovar com ressalvas é útil quando o PR é majoritariamente correto, mas há pontos opcionais. Exemplo:

Aprovado. Os dois pontos de estilo que levantei são opcionais — podem ser ajustados em um PR futuro.

Já solicitar uma nova rodada deve ser reservado para problemas bloqueantes.

7.3 Criar um resumo final

Ao final do PR, escreva um breve resumo do que foi aprendido:

Resumo da revisão:
- A validação de entrada foi adicionada (comentário 1)
- A função `processData` foi refatorada para usar async/await (comentário 3)
- Decidimos manter o `switch` por simplicidade (comentário 5)

Lições aprendidas: sempre validar entrada de dados em endpoints públicos.

Isso documenta o conhecimento para toda a equipe e evita que os mesmos problemas se repitam.


Referências