7 min de leitura
code-review
cultura-desenvolvimento
git-workflow
qualidade-código
equipas-pequenas

Code Reviews em Equipas Pequenas: Processo que Escala de 3 a 5 Developers

Estrutura prática de code reviews para equipas reduzidas. Automação, critérios claros, e fluxo Git que não sufoca produtividade nem compromete qualidade.

Code Reviews em Equipas Pequenas: Processo que Escala de 3 a 5 Developers

Code Reviews em Equipas Pequenas: Processo que Escala de 3 a 5 Developers

TL;DR

  • Code reviews em equipas de 3-5 pessoas precisam de automação pesada (linters, type checkers) para não virarem gargalos: aponta erros óbvios antes de humanos lerem código.
  • Dois tipos de PR: "bloqueantes" (lógica crítica, dados, segurança) e "não-bloqueantes" (UI, docs, refactor): critérios claros = ciclos mais rápidos.
  • Máximo 1 aprovador por PR em não-bloqueantes, 2 em bloqueantes: menos confusão, responsabilidade clara, e mantém velocidade acima de tudo.
  • Template de PR obrigatório com contexto + screenshot/vídeo: reduz perguntas durante revisão e economia de ~30% do tempo de feedback.
  • Rotação semanal de "reviewer da semana": evita bottleneck numa única pessoa e força toda a gente a conhecer o código.

O Problema Real com Code Reviews em Equipas Pequenas

Quando tens 3-5 developers, code review é um dilema classicamente português: ou fazes superficialmente e quebras coisas, ou fazes a sério e ninguém consegue ser produtivo porque fica tudo à espera de aprovação.

Vi isto inúmeras vezes. Uma startup fintech com 4 engineers onde cada PR passava por 3 pessoas, 2 rondas de comentários, e demorava 48 horas a ser merged. Resultado: developers em ping-pong permanente, features a atrasar, moral em baixo. Ninguém estava satisfeito: nem quem fazia review (pressão constante), nem quem abria PR (sentia-se microscopado).

O verdadeiro problema é que code review em equipas pequenas é essencialmente um acto de confiança combinada com verificação automatizada. Não podes permitir-te ter humanos a fazer linting ou a procurar bugs óbvios. Precisas de máquinas a fazer o trabalho sujo, e humanos focados em lógica, arquitectura, e segurança.

1. Automação: Metade da Batalha já Ganha

Antes de qualquer humano ler a tua PR, ela tem de passar por um gauntlet de verificação automatizada. Isto não é luxo. É obrigatório.

O mínimo absoluto:

  1. Linting e formatting (ESLint, Prettier para JavaScript/TypeScript; rustfmt para Rust; black para Python).
  2. Type checking (TypeScript stricto, mypy, ou equivalente).
  3. Testes unitários e integração (Jest, Vitest, pytest: pelo menos 70% coverage nas funcionalidades novas).
  4. Security scanning (Snyk, GitHub Advanced Security, ou semelhante).
  5. Build success (a PR tem de compilar/passar em staging antes de sequer chegar ao olho humano).

Configurar isto corretamente poupava tempo bruto num projecto interno. Um CRM em Next.js com Convex que tínhamos, antes de introduzir CI/CD decente, recebia PRs com erros de TypeScript que só eram apanhados em review. Depois de setup correcto com GitHub Actions (10 minutos de configuração), 40% das PRs falhavam automaticamente antes de chegarem a um humano.

Aqui está um exemplo real de CI/CD pipeline para uma stack Next.js + TypeScript + Convex:

name: PR Validation

on:
  pull_request:
    branches: [main, develop]

jobs:
  validate:
    runs-on: ubuntu-latest
    
    steps:
      - uses: actions/checkout@v4
      
      - uses: actions/setup-node@v4
        with:
          node-version: "22.0.0"
          cache: "npm"
      
      - run: npm ci
      
      - name: TypeScript Check
        run: npx tsc --noEmit
      
      - name: Lint
        run: npm run lint
      
      - name: Format Check
        run: npx prettier --check .
      
      - name: Unit Tests
        run: npm run test:unit
      
      - name: Build Check
        run: npm run build
      
      - name: Security Scan
        run: npx snyk test --severity-threshold=high
        
  database:
    runs-on: ubuntu-latest
    if: contains(github.head_ref, 'schema') || contains(github.head_ref, 'migration')
    
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: "22.0.0"
      
      - run: npm ci
      
      - name: Validate Migrations
        run: npm run migrations:validate

Resultado esperado: De 5 PRs abertas, 2-3 falham automaticamente. Developer arranja, refaz PR em 5 minutos. Humano só vê PRs que passaram nas máquinas.

2. Classificar PRs: Bloqueantes vs Não-Bloqueantes

Nem todas as PRs têm o mesmo risco. Tratar uma mudança de CSS igual a uma mudança de lógica de pagamento é estúpido.

Define dois tipos claros:

Bloqueantes (requerem 2 aprovações):

  • Qualquer mudança a código crítico: lógica de pagamento, autenticação, acesso a dados sensíveis.
  • Mudanças a schema de base de dados ou migrations.
  • Alterações a infraestrutura ou CI/CD.
  • Qualquer coisa que afecte SLA ou uptime.

Não-bloqueantes (1 aprovação, mais rápido):

  • UI/UX (exceto se mudar fluxo crítico).
  • Refactorings internos que mantêm comportamento.
  • Documentação.
  • Testes novos.
  • Dependências não críticas.

Exemplo: Um formulário de contacto pode passar com 1 review. Um webhook de confirmação de pagamento não.

Configure isto no GitHub com branch protection rules:

Branch: main
Require a pull request before merging
Require approvals: 1 (ou 2 consoante label)
Require conversation resolution before merging: true
Require status checks to pass: true (CI/CD pipeline)

E usa labels automáticos no template de PR (vê próxima secção).

3. Template de PR: Contexto é Ouro

A maioria das equipas abre PRs com descrição a 2 linhas. Depois a revisão fica um ping-pong de perguntas: "Porque mudaste isto?", "Isto afecta X?", "Testaste com Y?".

Um template obrigatório reduz isto drasticamente. Aqui está um que realmente funciona:

## Descrição
Breve resumo do que muda e porquê.

## Contexto
- Issue/ticket associado (link)
- Porquê esta abordagem vs alternativas
- Impacto em partes do sistema

## Screenshots / Vídeo
[Se é mudança visual, anexa screenshot. Se é fluxo complexo, vídeo de 15s]

## Checklist
- [ ] Testes novos ou actualizados
- [ ] Documentação actualizada
- [ ] Sem breaking changes (ou documented)
- [ ] Testado em staging
- [ ] Performance verificada (se aplicável)

## Tipo de PR
<!-- Remove os que não aplicam -->
- Bug fix
- Feature
- Refactor
- Docs
- Infrastructure

<!-- Requer 1 ou 2 aprovações? -->
- [ ] Bloqueante (2 aprovações necessárias)

Isto não é boilerplate vazio. Obriga o developer a pensar antes de abrir PR, e economiza 30-40% do tempo de revisão porque o contexto já está lá.

4. Rotação de Reviewer: Evita Bottleneck

Uma equipa de 4 pessoas, 1 reviewer "natural" (senior, ou "o que percebe de tudo"), e de repente essa pessoa está num inferno: 8-10 PRs pendentes, Slack cheio, produtividade própria destroçada.

Solução: Rotação semanal de reviewer designado.

Segunda: Developer A é reviewer. Terça: Developer B. Quarta: Developer C. Quinta/Sexta: Developer D. Próxima semana recomeça.

Regra de ouro: Se é o teu dia de review, dedicar 2 horas de manhã e 1 de tarde especificamente a reviews. Código pessoal pausa.

Benefício adicional: Toda a gente aprende o código da equipa ao ter de o revisar. Não há "a pessoa que sabe disto".

Ferramentas como GitHub assignee automation ou Slack bots podem avisar quem é o reviewer do dia:

# Script simples que roda num workflow
REVIEWERS=("alice" "bob" "charlie" "diana")
DAY=$(date +%A)
WEEK_NUMBER=$(date +%V)
REVIEWER_INDEX=$((WEEK_NUMBER % ${#REVIEWERS[@]}))
REVIEWER=${REVIEWERS[$REVIEWER_INDEX]}
echo "🔍 Reviewer desta semana: $REVIEWER"

5. Timing: SLA para Reviews

"SLA para reviews? Não parece um bocado corporativo?"

Talvez. Mas sem deadline, PRs ficam esquecidas. Aqui está o que funciona:

  • Bloqueantes: Aprovação ou feedback em 4 horas de trabalho.
  • Não-bloqueantes: Em 24 horas.
  • Se depois de 48h ninguém respondeu: Author tem permissão para ping directamente Slack ou self-merge (com cautela).

Isto elimina o "ei, esqueceste da minha PR" que consome energia mental.

6. Feedback Construtivo, Não Gatekeeping

Um gotcha real que vejo: reviewers transformam-se em gatekeepers. "Isto não é como eu faria", "Prefiro este padrão".

Diferenciar:

  • Must-fix (segurança, performance, bugs): Bloqueador real.
  • Should-consider (style, optimizações menores): Sugestão.
  • Nice-to-have (nitpicks): Comentário educacional, não bloqueia.

Marcar claramente no comentário:

❌ MUST-FIX: SQL injection risk aqui. Preparestatement obrigatório.

💡 SHOULD-CONSIDER: Cached result aqui? User.getById é N+1 a database.

📚 NICE-TO-HAVE: Conhecias que lodash tem memoize? Mais elegante que isto.

Isto mantém a qualidade sem criar fricção.

7. Merge Strategy: Squash vs Rebase vs Merge

Para equipas pequenas, a recomendação é squash + rebase:

  • Squash: Uma PR = Um commit (história limpa, fácil revert).
  • Rebase: Mantém linha temporal linear, evita merge commits.

Configure no GitHub:

Settings > Pull Requests > Allow squash merging ✓
Allow merge commits ✗
Allow rebase merging ✓

E no momento de merge, o GitHub oferece a opção. Padrão: squash com mensagem clara.

Squash commit: "feat: add two-factor auth to login flow (#234)"

8. Armadilha Comum: Perfeccionismo Paralisa

Vira-se isso com frequência: Revisor quer que a PR seja perfeita. Developer adiciona 15 comentários. Author fica desmotivado. Feature arrasta-se por uma semana.

Regra: Se a PR passa testes, mantém standard de qualidade existente, e não quebra nada, aprova-a. Refactorings "mais perfeitos" vão para a próxima iteração, ou é task separada.

Código 80% agora é melhor que código 100% em 3 semanas.

Conclusão

Code review em equipas pequenas é menos sobre ser perfecionista e mais sobre ser prático. Automação pesada, critérios claros, rotação para evitar bottlenecks, e feedback focado em segurança + arquitetura. Isto escala de 3 developers a 5 sem implosão.

Se estás a enfrentar um problema parecido, marca uma conversa em https://impact-origin.com/agendamento.

Impact OriginGostaste deste artigo?Na Impact Origin ajudamos fundadores e equipas a construir e escalar software à medida, do MVP da startup ao próximo passo. Se tens um projeto em mente, vamos falar.