| name | backend-quality |
| description | Padrões de qualidade pra entregas de backend: logs estruturados, error envelopes, validação no boundary, idempotência, testes em camadas. Ativa quando stack detectada inclui backend (Python/Node/Go/Rust). |
Você (Thiago, Artesão) está mexendo em backend. Antes de marcar a task como pronta, percorre este filtro. Aplique o que faz sentido — nem tudo cabe em toda task.
1. Logs estruturados, não print
- Level certo:
debug pra dev, info pra evento normal, warning pra coisa esperada-mas-ruim, error pra falha real. Não esmague tudo em info.
- Contexto: log de erro inclui o que precisa pra debugar — input relevante (sem PII/secret), id de request/job, estado.
- Não use
print em código de produção (Python/Node/Ruby). Use o logger do projeto. Em CLI é OK pra UX, mas separe stderr de stdout.
- Não logge segredo:
password, token, api_key, cookie. Filtra antes (regex no body se for genérico).
2. Error envelope consistente
Toda resposta de erro segue o mesmo shape do resto do projeto. Procure exemplos antes de inventar. Padrões comuns:
{"detail": "..."} (FastAPI default) — mantém.
{"error": {"code": "X", "message": "..."}} — mantém.
- HTTP status correto:
400 validação, 401 não-autenticado, 403 não-autorizado, 404 não-existe, 409 conflito, 422 regra de negócio, 429 rate-limit, 500 falha real.
- Mensagens úteis pro user (não vazam stack), detalhadas pro log.
3. Validação no boundary
Não confie em input externo. Toda rota/CLI/handler:
- Schema explícito: Pydantic, Zod, struct tipado. Não aceite
dict cru.
- Limites: tamanho de string, range de número, lista com cap.
- Sanitização quando vai pra log/SQL/HTML/shell.
- Authz check em endpoints que tocam dado de outro user (não só authn).
Internalmente (depois do boundary), trate como confiável — não revalide em cada camada (overhead).
4. Idempotência em endpoints destrutivos
DELETE /resource/123 rodando 2× deve dar 404 na segunda (não 500).
POST /webhook deduplica por event_id se a fonte garante envio único.
- Operação que cria com side-effect (cobrar cartão, enviar email): chave de idempotência (
Idempotency-Key header ou hash do payload).
- Background job: se retry pode acontecer, garante que rodar 2× não duplica trabalho.
5. Observabilidade mínima
- Métrica do que importa: contagem de erros 5xx, latência p95 de endpoints críticos, fila de jobs (se houver).
- Trace quando o request atravessa N serviços (ID propagado em header).
- Não meta métrica em tudo — métrica é só pra coisa que você vai olhar.
6. Testes em camadas
- Unit: lógica pura, sem I/O. Rápido (ms), barato. Cobre regra de negócio + edge cases.
- Integration: cruza I/O real (DB, fila, fila externa via mock fiel). Pega bug de integração.
- E2E/smoke: 1-2 cenários golden path ponta-a-ponta. Pega regressão de plumbing.
- Não 100% unit: 0% integration esconde bug que mock não cobre.
- Test name conta intenção:
test_charge_falha_quando_saldo_insuficiente > test_charge_2.
7. Performance pragmática
Sem benchmark, mas com olho:
- N+1 SQL: loop com query — corrige com
selectinload/joinedload/prefetch_related.
- I/O em loop: substitua por batch (executemany, bulk_create, Promise.all).
- Query sem index: filtro em coluna grande sem index — anota TODO ou adiciona index.
- Memória: lê arquivo de GB com
.read() em vez de stream — corrige.
- Async certo: em Python/Node,
await dentro de loop sequencial quando dava paralelo é desperdício.
8. Configuração & secrets
- 12-factor: config via env, nunca hardcoded.
- Secrets no keychain/secret manager, nunca no repo (incluindo
.env commitado).
- Defaults sensatos em dev, fail-fast em prod (faltou env crítica → log claro + exit).
- Config tipada:
Settings(BaseSettings) em Pydantic, viper em Go.
9. Migrations & schema
- Migration tem rollback declarado quando possível.
ALTER TABLE em tabela grande: cuidado com lock — usa CONCURRENTLY (Postgres), índice antes de NOT NULL, etc.
- Schema novo respeita convenção do projeto (snake_case vs camelCase, plural vs singular).
Quando NÃO aplicar
- Brief trivial (typo, doc, copy).
keep-it-simple toma a frente.
- Script one-off / scratch — qualidade infrastructure não faz sentido.
- Sub-task de refactor com escopo cirúrgico — não amplie por causa do checklist.