Manutenibilidade
Código é lido com muito mais frequência do que é escrito. A facilidade de manutenção é o que separa uma base de código de 3 anos que é uma alegria de uma que é um poço de alcatrão. Otimize para o próximo desenvolvedor, que pode ser você daqui a seis meses.
Regras
- Uma funcionalidade, um lugar. Empacote por funcionalidade (veja backend/core/SKILL.md). Uma única mudança deve tocar arquivos adjacentes, não camadas dispersas.
- Interfaces apenas nos limites dos módulos. Dentro de uma funcionalidade, classes concretas são aceitáveis. Interfaces existem para que quem chama dependa de contratos entre limites, não para decorar toda classe.
- Delete, não comente. Código morto e comentários
// TODOeternos apodrecem. O Git lembra; a IDE não precisa. - Prefira funções pequenas e puras. Mais fáceis de testar, mais fáceis de raciocinar, mais fáceis de compor. Efeitos colaterais nas bordas do sistema, não espalhados por ele.
- Testes cobrem comportamento, não implementação. Reescrever o internals não deve quebrar os testes. Se quebrar, o teste está acoplado à coisa errada.
- APIs públicas são versionadas. Mudanças bruscas por trás de uma nova versão ou um feature flag — nunca uma renomeação silenciosa.
- Injeção de dependência em vez de singletons estáticos. Estáticos são intestáveis e escondem acoplamento. Passe dependências; simule-as nos testes.
- Fixe e atualize regularmente as dependências. Arquivos de lock commited; Renovate/Dependabot abrindo PRs automaticamente. Ficar 2 anos atrasado significa uma migração não planejada de 2 semanas.
- Documente o "porquê", não o "o quê". O código mostra o quê; comentários explicam a regra de negócio, a restrição histórica, a troca não óbvia.
- Linting, formatação e verificação de tipos no CI. Não são opcionais, são bloqueantes. Humanos devem debater design, não espaçamentos.
- Mantenha o build verde e rápido. Testes instáveis ou lentos são ignorados e, uma vez ignorados, não protegem nada.
Sinais de alerta
- Um único arquivo com mais de ~500 linhas, ou uma classe com mais de ~10 métodos públicos — geralmente uma funcionalidade tentando escapar.
- Pacote "utils" compartilhado onde ajudantes órfãos vão morrer.
- Fazer mock do objeto em teste para fazer um teste passar.
- "Não mexa naquele módulo, ninguém mais entende ele."
- Tempo de build do CI medido em dezenas de minutos.