Communitygithub.com

Competências Claude para construção de backends

Habilidades do agente Claude Code para construir, testar e ajustar ambientes de avaliação RL agentivos — um padrão de quatro habilidades (guardião, depurador de validação, ajustador de pontuação, loop de iteração) mais um revisor adversarial de 24 pontos.

O que é Competências Claude para construção de backends?

Esta competência, 'building-backends', é a base para todo trabalho de backend na plataforma Claude Code. Ela define regras e princípios não negociáveis que garantem consistência entre todos os serviços construídos. A competência estabelece uma arquitetura clara em camadas (transporte → serviços → domínio → repositórios) com dependências apontando para dentro, e fornece diretrizes para design de API, camada de dados, segurança, concorrência, observabilidade e testes. Útil para desenvolvedores que usam Claude Code, Cursor ou Codex, esta skill atua como um guardião que deve ser lido antes de qualquer código de servidor ser escrito, assegurando que o engenheiro siga as melhores práticas e que o sistema seja escalável, seguro e manutenível. Ela se complementa com skills específicas como api-service-scaffold e db-migration-guardian para tarefas mais detalhadas.

Funciona com✓Claude Code~Codex CLI✓Cursor✓Antigravity
npx skills add omonuj/claude-skills

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

building-backends

Esta é a habilidade fundamental para trabalho de backend. Leia-a antes de escrever qualquer código de servidor — ela define os padrões e os pontos inegociáveis para que todos os serviços sejam consistentes, e então delega para as habilidades específicas os procedimentos detalhados. Se uma regra aqui conflitar com uma convenção local do repositório, o repositório vence; se não houver conflito, siga-a.

Primeiro, entenda antes de construir

  • Leia o código existente antes de adicionar algo. Combine com o framework, modelo de erro, camadas, nomenclatura e estilo de teste do repositório. Um padrão "correto" que luta contra a base de código é o padrão errado. Introduzir uma segunda maneira de fazer algo que o repositório já faz é um defeito, não uma melhoria.
  • Esclareça o contrato, não a implementação. Conheça as entradas, saídas, casos de erro, quem chama e as expectativas de consistência/latência antes de escolher um design. A maior parte do retrabalho em backend vem de construir o contrato errado rapidamente.
  • Prefira o óbvio. Soluções comprovadas, legíveis e óbvias em vez de engenhosas. O backend roda sem supervisão às 3h da manhã; otimize para o engenheiro de plantão que precisa entendê-lo meio sonolento, não para elegância.

Arquitetura — as regras

  • Camadas com dependências apontando para dentro. transporte (http) → serviços (casos de uso) → domínio (entidades/regras), e serviços → repositórios (E/S) → domínio. O domínio não importa nada para fora nem faz E/S. Se uma seta de importação apontar na direção errada, o design está quebrado.
  • Handlers orquestram, serviços decidem, repositórios fazem E/S. Um handler analisa/valida a entrada, chama um serviço, mapeia o resultado para uma resposta — sem lógica de negócio. Um repositório é o único lugar que toca em um banco de dados, fila ou HTTP externo.
  • Mantenha o domínio testável sem infraestrutura. Se não for possível testar unitariamente a lógica central sem um banco de dados ou rede, a lógica está na camada errada.
  • Uma única raiz de composição. Construa a configuração, conecte as dependências e inicie o servidor em um único lugar. Todo o resto recebe suas dependências; nada sai para construir globais singleton.
  • Projete sem estado. O estado de sessão/scratch vive em um armazenamento compartilhado (banco de dados/cache), não na memória do processo, para que o serviço escale horizontalmente e sobreviva a uma reinicialização. Se você está armazenando em cache em uma variável de nível de módulo, pare e pense.

→ Para montar o esqueleto com essas camadas já conectadas, use api-service-scaffold.

Design de API — as regras

  • Contratos explícitos e versionados. Versione a API (URL ou cabeçalho) desde o primeiro dia; nunca faça uma mudança que quebre a compatibilidade em um contrato já publicado — adicione a nova forma ao lado e descontinue a antiga.
  • Valide toda entrada no limite para um valor tipado. O núcleo nunca vê um corpo de requisição bruto. Rejeite entrada inválida com 422 e detalhamento por campo; nunca confie no cliente.
  • Um modelo de erro, mapeado uma vez. O código de domínio levanta erros tipados (NotFoundError, ConflictError, ValidationError, UnauthorizedError…); um mapeador de limite único os transforma em status + { code, message, details? }. Nunca vaze stack traces ou mensagens internas. 404 para "não encontrado" e "não é seu" — distingui-los vaza existência.
  • Formas consistentes. Mesmo envelope para sucesso, mesmo envelope para erros, paginação consistente (cursor em vez de offset para conjuntos grandes), uso consistente de maiúsculas/minúsculas nos campos. Um chamador deve aprender suas convenções uma vez.
  • Idempotência para operações inseguras. PUT/DELETE são idempotentes por definição; torne POSTs que podem ser repetidos seguros com uma chave de idempotência. Redes repetem — um cliente cobrado duas vezes é um bug de design.
  • Códigos de status corretos. 2xx sucesso, 4xx culpa do chamador, 5xx sua culpa. Uma falha de validação é 422, não 200-com-um-corpo-de-erro; uma falha de autenticação é 401/403, não 400.

A camada de dados — as regras

  • O banco de dados é a fonte da verdade; imponha invariantes lá. Chaves estrangeiras, restrições de unicidade, NOT NULL e verificações pertencem ao esquema, não apenas ao código da aplicação — o código da aplicação tem bugs e condições de corrida; o banco de dados não mente.
  • Transações encapsulam invariantes e são tão curtas quanto possível. Tudo que deve ser tudo-ou-nada vai em uma transação; não faça trabalho lento (chamadas externas, computação pesada) enquanto segura uma. Transações longas seguram bloqueios e deixam todos os outros com fome.
  • Espere concorrência. Duas requisições atingirão a mesma linha ao mesmo tempo. Use bloqueio otimista (uma coluna de versão) ou isolamento apropriado; nunca faça leitura-modificação-escrita em uma viagem de ida e volta sem proteção.
  • Migrações são compatíveis com versões anteriores e reversíveis. Nunca mude o significado de uma coluna em uma única implantação; expanda → migre → contraia. Nunca adquira um bloqueio que bloqueie a tabela em uma tabela quente. Toda migração é enviada com um rollback testado.
  • Cuidado com o N+1. Busque dados relacionados em um conjunto, não em um loop de consultas. Perfis a contagem de consultas em endpoints reais, não apenas a latência.
  • Indexe as consultas que você realmente executa — e apenas essas. Um índice não utilizado é amplificação de escrita sem benefício.

→ Para os mecanismos de migração (bloqueios, expandir-contrair, backfills, rollbacks), use db-migration-guardian.

Segurança — a linha de base (inegociável)

  • Autentique e depois autorize, em toda requisição, no lado do servidor. Nunca confie em uma afirmação do cliente sobre quem ele é ou o que pode fazer. Verifique a propriedade em cada acesso a recurso — "Eu tenho um token válido" ≠ "este registro é meu".
  • Parametrize toda consulta. Nunca use SQL construído com strings. O mesmo para qualquer interface injetável (shell, LDAP, template).
  • Segredos vêm do ambiente/gerenciador de segredos, nunca do código. Nada sensível no código fonte, logs ou mensagens de erro. (Veja a habilidade secrets-management.)
  • Menor privilégio em toda parte — usuários de banco de dados, credenciais de serviço, funções na nuvem com escopo exato para o que o serviço precisa.
  • Limite de taxa e defina timeouts em endpoints de entrada e chamadas de saída. Uma chamada ilimitada ou um endpoint sem limite é uma negação de serviço à espera de acontecer.
  • Valide e codifique nos limites para prevenir injeção e SSRF; trate toda entrada externa, incluindo de outros serviços internos, como não confiável.

Concorrência, jobs e falha

  • Assuma que toda chamada externa falha. Defina timeouts, adicione novas tentativas limitadas com backoff + jitter e um disjuntor para dependências instáveis. Uma nova tentativa sem timeout é como uma dependência lenta derruba todo o serviço.
  • Torne as operações idempotentes para que uma nova tentativa (sua ou do chamador) seja segura.
  • Trabalho em segundo plano vai para uma fila, não no caminho da requisição. A requisição enfileira; um trabalhador processa; falhas caem em uma fila de letras mortas para inspeção, não em um silencioso catch {}.
  • Falhe alto, degrade com elegância. Exponha erros à telemetria; quando uma dependência não crítica estiver fora, degrade (sirva dados obsoletos, pule o enriquecimento) em vez de 500 toda a requisição.

Observabilidade faz parte de "pronto", não é um complemento

Um serviço que você não pode depurar em produção não está pronto. Logs estruturados, métricas RED/USE e rastreamento vinculados a um único ID de correlação vão sendo adicionados conforme você constrói, não após o primeiro incidente.

→ Use backend-observability para os detalhes de instrumentação e as diretrizes de cardinalidade/PII.

Postura de teste

  • Teste o comportamento através da superfície pública (o endpoint / o caso de uso), não internos privados — para que os testes sobrevivam a refatorações.
  • Uma pirâmide, não um sorvete: muitos testes unitários rápidos na lógica de domínio/serviço, um conjunto focado de testes de integração sobre o banco de dados real e a fiação, alguns testes ponta a ponta em caminhos críticos.
  • Cada correção de bug recebe um teste de regressão que falha antes da correção e passa depois.
  • Testes determinísticos. Sem dependência de relógio, rede ou ordenação; semeie dados explicitamente; isole testes uns dos outros.

Procedimento para qualquer tarefa de backend

  1. Leia o código ao redor; fixe o contrato (entradas/saídas/erros/chamadores/consistência).
  2. Coloque o trabalho na camada correta; mantenha o domínio livre de E/S.
  3. Valide a entrada no limite; use o modelo único de erro; retorne o status correto.
  4. Coloque invariantes no banco de dados + uma transação curta; lide com concorrência; planeje migrações como expandir-contrair.
  5. Aplique a linha de base de segurança (autorização + propriedade, consultas parametrizadas, segredos, timeouts/limites).
  6. Torne chamadas externas e jobs resilientes e idempotentes.
  7. Instrumente enquanto constrói; adicione testes na camada correta, incluindo um teste de regressão para qualquer bug.
  8. Confirme com a Definição de pronto da habilidade específica relevante.

Definição de pronto

  • Camadas respeitadas (domínio não faz E/S; dependências apontam para dentro); uma única raiz de composição.
  • Toda entrada validada no limite; um modelo de erro mapeado uma vez; códigos de status corretos; contrato versionado.
  • Invariantes impostos no banco de dados; transações curtas; concorrência tratada; migrações compatíveis com versões anteriores + reversíveis.
  • Linha de base de segurança atendida: verificações de autorização + propriedade, consultas parametrizadas, segredos externos, timeouts/limites de taxa presentes.
  • Chamadas externas/jobs idempotentes e resilientes; trabalho em segundo plano fora do caminho da requisição.
  • Observabilidade conectada (logs/métricas/rastreamento em um ID de correlação); testes nas camadas corretas, verdes, com cobertura de regressão.

Habilidades Relacionadas