Qualidade de código: boas práticas para melhorar seus PRs

kodus - pull request

Qualidade de código é a capacidade de um software continuar fácil de entender, alterar, testar e revisar à medida que o produto cresce. No dia a dia, isso aparece de forma bem concreta no pull request: a mudança tem um escopo claro, os testes protegem o comportamento certo e quem revisa consegue entender o impacto sem precisar reconstruir todo o histórico daquela parte do sistema.

Com a IA acelerando a geração de código, essa definição fica ainda mais importante. O time passa a lidar com mais mudanças, mais sugestões e mais código que, à primeira vista, parece pronto para merge. Mas escrever mais rápido não melhora, por si só, a qualidade do que entra no repositório.

Quando os padrões do projeto estão pouco claros, a IA pode repetir duplicações, aumentar o acoplamento e trazer de volta decisões que o time já havia tentado abandonar.

Por isso, eu começaria olhando para o fluxo de PR. Métricas como complexidade, cobertura e duplicação ajudam a encontrar sinais de risco. Já o code review, o CI e as automações ajudam o time a decidir o que precisa ser ajustado antes do merge.

➣ Neste artigo, vou mostrar como medir qualidade de código, quais práticas funcionam no dia a dia e como montar um plano de 30 dias para melhorar os PRs sem deixar o processo mais lento.

O que é qualidade de código?

Qualidade de código é o conjunto de características que torna um código fácil de ler, modificar, testar, revisar e operar em produção. Quando a qualidade é boa, a intenção da mudança fica clara, os efeitos colaterais são mais previsíveis e o time consegue evoluir o sistema sem depender de informações que só uma pessoa conhece.

Essa definição ajuda porque passar no CI não significa, por si só, que o código está fácil de manter. O lint pode estar verde, os testes podem passar e a feature pode funcionar localmente, mas a mudança ainda pode ser difícil de revisar. Isso acontece quando o PR é grande demais, quando a regra de negócio foi colocada no lugar errado ou quando o impacto em outras partes do sistema não está claro.

E o problema não termina no merge. A próxima mudança leva mais tempo, o próximo bug exige mais investigação e quem entra no time precisa buscar respostas que poderiam estar no próprio código.

Para mim, uma boa forma de avaliar a qualidade de uma mudança é pensar se outra pessoa conseguiria alterá-la com segurança depois. Se isso ainda depende da memória de alguém ou de um processo que não está documentado, o código sozinho não explica o suficiente para ser alterado com segurança.

Como avaliar a qualidade de um pull request

O pull request é onde os padrões do time ficam mais visíveis. É nessa etapa que a equipe decide se o escopo está grande demais, se uma duplicação faz sentido naquele contexto, se os testes protegem o comportamento alterado e se a mudança respeita a arquitetura do projeto.

Um PR fácil de revisar costuma ter alguns sinais claros:

  • escopo pequeno e fácil de entender;
  • descrição que explica a intenção da mudança;
  • testes ligados ao comportamento alterado;
  • código coerente com os padrões do repositório;
  • riscos explícitos quando a mudança toca uma área sensível;
  • comentários de review focados em decisões, e não em ajustes repetitivos de estilo.

Quando esses sinais não aparecem, a revisão exige muito mais esforço. Quem revisa precisa pedir contexto, abrir arquivos fora do diff, validar manualmente cenários que poderiam estar cobertos por testes e discutir problemas que poderiam ter sido evitados antes mesmo de o PR ser aberto.

Com o tempo, isso também piora a qualidade do próprio review. A pessoa aprova porque a mudança parece boa o suficiente, porque o PR já voltou algumas vezes ou porque o prazo apertou. E esse não é um critério seguro para decidir o que vai para produção.

Por que a IA aumenta a pressão sobre a qualidade

A IA não cria sozinha os problemas de qualidade de um time. O que ela faz é aumentar o volume de mudanças que chegam ao review.

Quando o repositório tem padrões claros, testes confiáveis e decisões bem documentadas, a IA trabalha sobre uma base mais consistente. Mas, se o código já acumula duplicações, atalhos e regras implícitas, ela também pode reproduzir esses mesmos padrões com mais frequência.

Esse aumento de pressão também aparece na nossa pesquisa sobre o estado do AI code review. Nos dados analisados, PRs com coautoria declarada de IA eram 2,6 vezes maiores e recebiam cerca de 1,6 vez mais apontamentos por revisão. A maior diferença apareceu justamente nas regras próprias dos times: mudanças com IA geraram 2,1 vezes mais violações desse tipo.

Isso ajuda a explicar por que bons testes e padrões genéricos não resolvem tudo.

A mudança pode passar nas verificações básicas e ainda contrariar decisões específicas do projeto que só aparecem quando o review conhece o contexto do repositório.

O desafio é que o código gerado por IA muitas vezes parece correto em uma leitura superficial. A estrutura pode estar organizada, os nomes podem fazer sentido e os testes podem passar. Ainda assim, a mudança pode reimplementar uma regra que já existe em outro serviço, acessar diretamente uma camada que deveria passar pelo domínio, criar uma abstração diferente para um problema que o projeto já resolve de outra forma ou ignorar efeitos em cache, eventos, permissões e integrações.

É por isso que o review precisa ir além da aparência do diff. Quem revisa não deveria gastar tempo com comentários repetitivos que uma ferramenta consegue identificar. A atenção humana precisa ficar nas decisões que exigem contexto e julgamento: impacto no sistema, arquitetura, regra de negócio, segurança e manutenção.

A IA pode ajudar bastante nesse primeiro filtro, desde que conheça o repositório e os padrões do time. Sem esse contexto, tende a gerar comentários genéricos que até acertam em alguns casos, mas aumentam o ruído e tornam a revisão mais cansativa.

O custo da baixa qualidade de código

Para mim, a baixa qualidade de código quase nunca aparece primeiro como um problema técnico isolado. Ela aparece como atrito no dia a dia. As mudanças começam a levar mais tempo, os PRs voltam várias vezes, os mesmos comentários se repetem e o time passa a depender de algumas pessoas para mexer em partes importantes do sistema.

Alguns sinais costumam deixar isso bem claro:

  • PRs grandes demais para revisar com calma;
  • bugs que reaparecem depois do merge;
  • testes que passam, mas ainda deixam dúvida sobre a mudança;
  • módulos que só uma pessoa entende bem;
  • alterações pequenas que causam efeitos colaterais inesperados;
  • revisores aprovando com menos atenção porque já estão cansados;
  • comentários repetidos sobre os mesmos problemas.

Quando quem revisa precisa escrever a mesma coisa toda semana, eu não vejo isso apenas como um problema de quem abriu o PR. Para mim, é um sinal de que o processo ainda depende demais da memória e da experiência de algumas pessoas.

Nesses casos, eu tentaria transformar esse conhecimento em algo que o time consiga aplicar de forma consistente: um template de PR, uma regra no CI, um teste, uma configuração de lint, uma documentação curta ou uma regra de review automatizado.

A ideia é simples: o time não deveria continuar gastando tempo corrigindo manualmente o mesmo tipo de problema em cada mudança.

Como medir a qualidade do código

Para medir qualidade de código, eu combinaria métricas técnicas com métricas do fluxo de PR. As primeiras ajudam a encontrar sinais de risco dentro do código. As segundas mostram como esses riscos afetam a revisão, a entrega e o retrabalho.

Entre as métricas técnicas, eu acompanharia:

  • complexidade ciclomática;
  • índice de manutenibilidade;
  • cobertura de testes;
  • duplicação de código;
  • code smells relevantes;
  • bugs e vulnerabilidades.

No fluxo de PR, eu olharia para:

  • tempo médio em review;
  • tamanho médio dos PRs;
  • retrabalho depois do merge;
  • frequência de comentários repetitivos;
  • change failure rate;
  • tempo de recuperação depois de uma falha.

Nenhuma dessas métricas deveria decidir sozinha se uma mudança pode ou não ser aprovada. Um PR pequeno com um alerta leve de complexidade pode ser aceitável. Já um PR grande, com queda de cobertura e vários comentários sobre clareza, provavelmente precisa ser dividido ou retrabalhado antes do merge.

A métrica ajuda a mostrar onde investigar. A decisão ainda depende do contexto da mudança.

Como interpretar as principais métricas de qualidade

A complexidade ciclomática mede quantos caminhos independentes existem dentro de uma função. Quanto maior esse número, mais difícil fica entender a lógica e testar todos os cenários possíveis. Quando uma função passa de 15, eu já trato como um sinal de que a mudança precisa de uma análise mais cuidadosa durante o review.

O índice de manutenibilidade tenta resumir o quão fácil é entender e modificar um trecho de código. Eu usaria essa métrica principalmente para acompanhar a evolução de um módulo ou de uma área do sistema ao longo do tempo. Uma queda no índice pode indicar que aquela região está ficando mais difícil de manter, mas o número serve para abrir uma investigação, não para decidir sozinho.

A cobertura de testes mostra quanto do código é executado por testes automatizados. Cobertura baixa em uma área crítica é um risco claro, mas cobertura alta também pode passar uma falsa sensação de segurança quando os testes não validam o comportamento certo. Durante o review, eu olharia menos para o percentual isolado e mais para os cenários que os testes realmente protegem.

A duplicação de código ajuda a encontrar lugares em que a mesma lógica aparece mais de uma vez. Nem toda repetição precisa virar uma abstração imediatamente. O problema fica mais sério quando uma regra de negócio é duplicada, porque uma correção futura pode ser aplicada em um ponto e esquecida nos outros.

Code smells ajudam a localizar regiões que começam a ficar difíceis de entender ou modificar, como funções longas, classes com responsabilidades demais, dependências inadequadas entre módulos e nomes ambíguos. Eles não representam bugs por si só, mas indicam onde o review precisa investigar com mais atenção.

Bugs e vulnerabilidades são sinais mais diretos. Para código novo, eu deixaria o critério explícito: o PR não deve introduzir vulnerabilidades críticas ou de alta severidade. Quando um problema desse nível aparece na mudança, ele precisa ser resolvido antes do merge.

Boas práticas para melhorar qualidade de código

Eu começaria mantendo os PRs pequenos. Quanto maior a mudança, mais contexto quem revisa precisa carregar e maior a chance de algum risco passar despercebido. Com um escopo menor, fica mais fácil entender a intenção, validar o comportamento e perceber impactos em outras partes do sistema.

Depois, eu colocaria os padrões do time dentro do próprio fluxo de trabalho. Template de PR, regras no CI, um checklist curto e review automatizado costumam funcionar melhor do que um documento longo que quase ninguém consulta durante a revisão.

Também separaria com clareza o que deve bloquear o merge do que precisa apenas gerar um alerta. Build quebrado, teste falhando e vulnerabilidade crítica devem impedir a aprovação. Já um aumento de complexidade, uma duplicação pontual ou uma sugestão de refatoração podem aparecer como comentário, porque às vezes existe um trade-off aceitável naquele momento.

Por fim, eu revisaria essas regras de tempos em tempos. Um padrão que ajudava seis meses atrás pode estar gerando ruído hoje. Quando o time começa a ignorar alertas com frequência, isso costuma ser um sinal de que a regra está mal calibrada ou deixou de representar o risco real.

Um bom review tenta responder algumas perguntas bem concretas:

  • a intenção da mudança está clara?
  • o PR está pequeno o suficiente para ser revisado com atenção?
  • a regra de negócio foi implementada na camada certa?
  • os testes protegem os comportamentos que podem quebrar?
  • existe alguma duplicação que pode gerar manutenção desnecessária depois?
  • a mudança segue os padrões reais do repositório?
  • algum trecho gerado por IA parece correto isoladamente, mas entra em conflito com decisões do sistema?

Essas perguntas mantêm a revisão próxima do que realmente importa: entender se a mudança pode ser mantida e evoluída com segurança depois do merge.

Para times que usam IA, a última pergunta merece ainda mais atenção. Um trecho pode estar correto dentro do arquivo e ainda assim estar errado no contexto do sistema. O diff pode parecer limpo, os testes podem passar e a implementação pode compilar, mas a decisão ainda pode desrespeitar a arquitetura, duplicar uma regra existente ou ignorar efeitos em outras partes da aplicação.

Como usar IA para apoiar qualidade de código

A IA ajuda quando reduz o trabalho repetitivo antes de o revisor humano entrar. Ela pode identificar duplicações simples, funções longas, queda de cobertura, cenários sem teste, padrões inconsistentes e riscos recorrentes.

Com isso, quem revisa não precisa começar do zero. O review já chega com alguns sinais, e a atenção pode ficar nas decisões que realmente exigem julgamento, como impacto no sistema, arquitetura, regra de negócio, segurança e manutenção.

Mas esse apoio só funciona bem quando a IA conhece o contexto do repositório. Sem entender os padrões do projeto, as convenções do time, as dependências e as decisões arquiteturais, ela tende a gerar alertas genéricos que aumentam o volume de comentários sem reduzir o risco.

Por isso, eu trataria a IA como uma camada de triagem. Ela ajuda a encontrar problemas recorrentes e a priorizar onde o time precisa olhar com mais atenção, mas não substitui a análise de quem entende como aquela mudança se encaixa no sistema.

Plano de 30 dias para melhorar a qualidade do código

Semana 1: descubra onde o time mais perde tempo

Eu começaria pelo branch principal, mas sem a intenção de corrigir tudo de uma vez. A ideia da primeira semana é montar um diagnóstico simples do que mais pesa hoje.

Rodaria uma análise com SonarQube, Code Climate ou alguma ferramenta parecida para olhar complexidade, duplicação, cobertura, vulnerabilidades e os arquivos que concentram mais alertas.

Depois, eu cruzaria isso com os PRs recentes.

  • Quais demoraram mais para ser aprovados?
  • Quais voltaram mais vezes?
  • Onde apareceram os mesmos comentários?
  • Quais mudanças geraram retrabalho depois do merge?

Para mim, essa primeira semana serve para separar percepção de padrão. O objetivo não é criar uma lista enorme de problemas, mas entender onde o time está gastando energia demais.

Semana 2: defina o mínimo esperado em um PR

Com os problemas mais recorrentes em mãos, eu transformaria isso em uma Definition of Done curta para pull requests.

Ela pode começar com algo assim:

  • a mudança tem escopo claro;
  • o PR pode ser revisado sem exigir esforço desproporcional;
  • os testes protegem o comportamento alterado;
  • não há novas vulnerabilidades críticas ou de alta severidade;
  • a intenção do código está clara;
  • decisões fora do padrão estão explicadas;
  • trechos gerados por IA foram revisados com o mesmo critério aplicado ao restante do código.

O mais importante aqui é reduzir ambiguidade. Quando o time compartilha uma definição mínima do que espera antes do merge, o review fica menos dependente da opinião de cada pessoa.

Semana 3: tire do review o que se repete toda semana

Na terceira semana, eu moveria para o CI ou para o review automatizado tudo o que não precisa continuar dependendo de memória humana.

Usaria bloqueios para problemas que o time realmente não quer aceitar, como build quebrado, teste falhando, vulnerabilidade séria e queda relevante de cobertura em uma área crítica.

Já alertas sobre duplicação, aumento de complexidade, funções longas, ausência de teste em um cenário específico ou PR grande demais eu manteria como sinais para investigação, não como decisões automáticas.

Se o time usa IA no code review, eu também colocaria os padrões do repositório, as convenções e as regras arquiteturais nas instruções da ferramenta. Sem isso, ela revisa como alguém de fora que enxerga apenas o diff.

Semana 4: remova o que só está criando ruído

No fim do mês, eu voltaria aos dados para entender o que realmente ajudou.

  • O tempo em review caiu?
  • Os comentários ficaram mais úteis?
  • O retrabalho diminuiu?
  • Os alertas automáticos encontraram problemas relevantes?
  • Alguma regra está sendo ignorada porque aparece demais ou porque não representa um risco real?

Eu revisaria essas regras com base no que elas estão gerando na prática. Quando uma regra não ajuda o time a encontrar problemas relevantes, ela só aumenta o ruído e reduz a confiança no processo.

Depois desses 30 dias, manteria uma rotina simples: observar os PRs, identificar o que continua se repetindo, automatizar o que não exige julgamento humano e preservar o tempo de quem revisa para as decisões que realmente importam.

Como a Kodus ajuda no review de qualidade de código

Quando penso em qualidade de código, a parte mais importante do review não é simplesmente encontrar mais problemas. É conseguir apontar o que realmente importa para aquele repositório e para aquele time.

É aí que a Kodus se diferencia. Ela é uma plataforma open source de AI code review, sem vendor lock-in, que roda direto no fluxo de pull request em GitHub, GitLab, Bitbucket e Azure DevOps, com opção Cloud ou self-hosted.

Para mim, o principal valor está no contexto. A Kodus combina análise estrutural do código com LLM para revisar a mudança considerando o repositório como um todo, e não apenas o diff isolado. Isso permite encontrar problemas que costumam passar em uma análise mais superficial, como uma regra de negócio sendo duplicada, uma dependência atravessando uma fronteira de arquitetura ou um padrão antigo voltando em código novo.

Outro recurso que considero especialmente útil é a possibilidade de escrever regras em linguagem natural e aplicá-las por repositório, pasta ou branch. O time pode definir, por exemplo, que “a camada de domínio não deve importar infraestrutura” e aplicar essa regra apenas onde ela faz sentido. Em monorepos ou organizações com squads diferentes, isso evita forçar o mesmo padrão para áreas que têm contextos distintos.

Também existe bastante flexibilidade na escolha da infraestrutura. A Kodus permite escolher o modelo, usar endpoints compatíveis com OpenAI e rodar em ambiente self-hosted quando a empresa precisa ter mais controle sobre dados, custo ou operação.

Na prática, a Kodus entra no review para ampliar a capacidade de análise do time. Ela combina contexto do repositório, regras da equipe e sinais de risco para identificar problemas que não aparecem olhando apenas para o diff. Com isso, quem revisa consegue tomar decisões com mais informação e concentrar atenção em arquitetura, regra de negócio, segurança e impacto da mudança.

FAQ sobre qualidade de código

O que é qualidade de código?

Qualidade de código é a capacidade de um software continuar fácil de entender, alterar, testar, revisar e operar conforme o produto cresce. Ela envolve legibilidade, manutenibilidade, testabilidade, segurança e coerência com a arquitetura do sistema.

Quais métricas ajudam a medir qualidade de código?

Eu olharia para uma combinação de métricas técnicas e de fluxo. Entre as mais úteis estão complexidade ciclomática, índice de manutenibilidade, cobertura de testes, duplicação de código, code smells, vulnerabilidades, tempo em review, tamanho dos PRs e retrabalho depois do merge.

Qual é o papel do code review na qualidade de código?

O code review ajuda o time a transformar padrões de qualidade em decisões do dia a dia. É nessa etapa que a equipe valida a intenção da mudança, os riscos, os testes, o impacto na arquitetura e a facilidade de manutenção antes do merge.

IA melhora ou piora a qualidade de código?

Depende de como ela entra no processo. A IA pode ajudar quando encontra riscos mais cedo, reduz trabalho repetitivo e considera o contexto do repositório. Mas também pode aumentar o retrabalho quando acelera a geração de código sem testes confiáveis, padrões claros e revisão suficiente.

Qualidade de código precisa aparecer em todo PR

Para mim, qualidade de código não deveria ser tratada como uma revisão separada ou uma iniciativa pontual. Ela precisa aparecer no trabalho diário: em PRs menores, mudanças com intenção clara, testes ligados ao comportamento alterado e reviews que discutem arquitetura, regra de negócio, segurança e manutenção, e não apenas estilo.

Com IA no fluxo, essa disciplina fica ainda mais importante. O volume de mudanças tende a aumentar e, quando o processo já é fraco, o retrabalho também cresce mais rápido.

Quando o review combina contexto do repositório, regras claras e bons sinais de risco, o time consegue lidar melhor com esse volume sem tornar a base mais difícil de entender e manter.

Para mim, a mensagem prática é simples: qualidade de código é aprovar hoje uma mudança que o time vai conseguir entender, testar e alterar amanhã.