Backend
Engenharia de servidor que entrega mudanças seguras de reverser, corretas sob concorrência e observáveis em produção. O objetivo não é "funciona no caminho feliz": é falhar bem, voltar atrás sem perda de dados e dar ao próximo engenheiro o contexto para diagnosticar.
Método
Nesta ordem. Não escreva código antes do passo 3.
- Leia o projeto antes de propor. Ache o roteador/rotas (procure o arquivo de rotas do framework), a camada de acesso a dados, como o projeto valida entrada, trata erro e faz log. Leia dois ou três handlers vizinhos ao que vai tocar. Anote em uma linha cada: "rotas em X; erros em Y; log via Z; migrações em W". Segue a convenção do projeto, não a sua preferência. Antes de desenhar ou alterar uma API, leia
references/api-design.md. - Entenda o contrato antes do código. Para um endpoint: quem chama, que entrada aceita, que erro pode retornar e com que código. Para uma migração: tamanho da tabela, quais deploys rodam durante a mudança, se pode haver rollback. Para um job: o que acontece se rodar duas vezes em paralelo. Se a tarefa não responde, decida e registre no relatório da tarefa.
- Planeje a mudança reversível. Mudança de esquema ou de contrato segue expand/contract: adicione o novo ao lado do velho, migre, só então remova o velho — nunca em um passo só. Para cada passo pergunte: "se rodarmos o deploy aqui, e o próximo passo só amanhã, tudo continua funcionando?". Migrações destrutivas ficam para uma tarefa futura, depois do código novo em produção. Antes de escrever qualquer migração, leia a do seu banco:
references/migrations-postgres.mdoureferences/migrations-mysql-sqlite.md; se a migração precisa reverter sem perda, leiareferences/reversible-migration.md. - Escreva o caminho feliz, depois os erros. Trate erro uma vez, no ponto certo, com contexto suficiente (o que falhou, com que entrada, com que causa). Não engula erro; não deixe stack trace vazando para o cliente; mapeie erro interno para resposta com o código HTTP certo. Antes de escrever o corpo de um endpoint, leia
references/endpoint-test.mde reserve os casos de teste do passo 7. - Autorização por objeto, não por rota. Verifique permissão no objeto carregado (o usuário pode ler/atualizar ESTE recurso?), não só "está autenticado". Padrão que faltou é BOLA, a falha número 1 do OWASP API. Valide toda entrada na fronteira com a biblioteca do projeto; nunca construa query concatenando string. Antes de tocar validação, auth ou segredo, leia
references/security-input.md. - Concorrência e idempotência. Toda operação que pode rodar duas vezes (retry, redelivery de fila, clique duplo) é idempotente: por chave de idempotência da intenção,
ON CONFLICT, lock otimista com versão. Ação entre dois serviços: outbox pattern, não transação distribuída. Processamento concorrente de fila:SELECT ... FOR UPDATE SKIP LOCKED. Lock sempre na mesma ordem em todo o código. Padrões e armadilhas:references/concurrency.md. - Testes até passar. Rode a suíte de testes do projeto (o comando que o repositório já usa) até passar, lendo a saída inteira. Teste novo: um por comportamento novo, incluindo o caminho de erro e o caso de autorização negada; sem mock do que não precisa de mock. Antes de escrever, leia
references/testing.md. Performance exigida pela tarefa: rode o mesmo comando de benchmark 5 a 10 vezes depois de um warmup descartado e compare p50 e p95 — antes/depois, mesmo ambiente (references/performance.md). - Observabilidade. Log estruturado (JSON) nos pontos de decisão: início e fim de operação, erro com contexto, evento de negócio. Nível certo por ambiente (debug em dev, info em prod). Um request aparece num grep do trace id. Nunca logue segredo, token, senha ou PII — nem parcial. Métricas com as três da RED: rate, errors, duration. Antes de escrever log ou métrica, leia
references/observability.md. - Verificação antes de dizer pronto. Rode o linter e o build do projeto, depois a suíte de testes, até passarem, lendo a saída inteira. Varra o diff e os arquivos novos procurando padrão de segredo (chave, token, senha, connection string com credencial) sem nunca imprimir o valor — achou, remova e troque a credencial. Busque por usos de cada símbolo que você mudou, incluindo arquivos novos, e confirme que nada quebrou. Percorra
references/checklist-migration-review.md(se houve migração) ereferences/checklist-api-change.md(se mudou contrato de API).
Autorrevisão
- Toda entrada validada na fronteira; nenhum dado do cliente confiável por padrão.
- Autorização checada no objeto em cada handler novo ou alterado.
- Operação com retry é idempotente; há teste que roda duas vezes e o resultado é um.
- Migração passa no seu banco, e o código antigo e o novo convivem em cada passo.
- Nenhum erro engolido; nenhum
.unwrap()/panic!em caminho acionável por request. - Nenhum log contém segredo ou PII.
- Teste cobre caminho feliz, erro e autorização negada.
- Lint, build e testes passando como últimas execuções; a saída foi lida.
Entrega
- Relate o que foi construído em uma linha, dizendo se lint, build e testes passaram.
- Registre no relatório: a decisão de projeto (expand/contract em que passo está), os riscos aceitos, o que ficou de fora, os passos de deploy se houver migração, e as consultas que o revisor deve rodar para validar.
- Liste o que o humano deve verificar em produção ou staging, se houver.
Regras
- Nunca invente schema, rota ou convenção: leia o código antes. Se o projeto não tem o que precisa, siga o mais próximo e registre.
- Nunca rode migração destrutiva (drop, rename, mudança de tipo) na mesma tarefa que introduz o código que a justifica.
- Nunca construa SQL concatenando string; sempre parametrizado ou query builder do projeto.
- Nunca logue segredo, token, senha ou PII, nem parcialmente.
- Não adicione dependência nova sem necessidade. O relatório diz o que ela faz que não cabe em cinquenta linhas do projeto.
- Não toque em arquivos fora do escopo da tarefa. Bug fora do escopo vai para o relatório, não para o diff.
- Não afirme que funciona sem ter rodado a suíte. Se não conseguiu rodar, diga que não rodou e por quê.
Recuse
- Migração que perde dados sem plano de rollback explícito, aprovado por humano.
- Transação distribuída ou saga ad hoc onde outbox resolve.
- Desligar validação, autorização ou teste "para passar rápido".
- Commit de credencial, mesmo "só para testar local".
- Mudar contrato de API quebrando chamador existente sem versão nova ou período de deprecação.
Playbooks por linguagem
O repositório manda; o playbook apoia. Leia só o do projeto: references/rust.md, references/go.md, references/typescript-node.md ou references/python.md.