Aprenda a criar especificações de feature do Claude Code a partir do código, extraindo comportamento real de rotas e componentes e gerando uma spec viva e uma lista de lacunas.

As pessoas discordam sobre o que um app faz porque lembram de versões diferentes. Suporte lembra do último ticket raivoso. Vendas lembra do caminho da demo. Engenheiros lembram do que a feature deveria fazer. Pergunte a três pessoas e terá três respostas confiantes, e nenhuma corresponde à build atual.
Com o tempo, o código vira a única fonte que se mantém atual. Docs se desviam, tickets são fechados e consertos rápidos se acumulam. Uma rota ganha uma nova regra de validação. Um toggle na UI muda um padrão. Um handler começa a retornar erros diferentes. Ninguém atualiza a especificação porque parece opcional, e cada mudança parece pequena demais para documentar.
Isso gera problemas previsíveis. Times enviam mudanças que quebram casos de borda que ninguém sabia que existiam. QA testa o caminho feliz e perde regras enterradas nos handlers. Novos colegas copiam comportamento da UI sem entender as restrições reais. Stakeholders debatem opiniões em vez de apontar para um comportamento acordado.
Um bom resultado não é um documento perfeito. É clareza compartilhada. Todo mundo deveria ser capaz de responder: "O que acontece se eu fizer X?" e "O que o sistema garante?" sem chutar. Você tem menos surpresas, ciclos de revisão menores e menos momentos de "Espera, já faz isso" porque a equipe está olhando para a mesma verdade.
Quando uma spec casa com o código, fica seguro planejar mudanças. Você consegue enxergar o que é estável, o que é acidental e o que está faltando antes de enviar.
Uma especificação viva é uma descrição curta e editável do que o app realmente faz hoje. Não é um documento único. Ela muda sempre que o comportamento muda, para que a equipe possa confiar nela.
Quando se fala em specs de feature escritas a partir do código (por exemplo, usando Claude Code), o objetivo é simples: ler o comportamento real das rotas, handlers e telas, e escrever isso em linguagem simples.
Uma especificação viva útil foca no que os usuários veem e no que o sistema promete. Deve cobrir:
O que ela não deve cobrir é como o código está organizado. Se você começar a nomear arquivos e planos de refatoração, está entrando em detalhe de implementação. Evite:
Uma lista de lacunas é separada. É uma pequena lista de incompatibilidades e desconhecimentos que você encontra ao escrever a spec.
Exemplo: uma rota rejeita arquivos acima de 10MB, mas a UI diz 25MB. Isso é uma lacuna até a equipe decidir qual regra é real e atualizar o código ou a spec.
Comece pequeno. Se tentar documentar o app inteiro, vai acabar com um monte de notas que ninguém confia. Escolha uma fatia que os usuários possam descrever em uma frase, como "convidar um colega", "checkout" ou "resetar senha". Bons escopos são uma área de feature, um módulo ou uma jornada de usuário do ponto de entrada ao resultado.
Escolha seu ponto de entrada com base em onde a verdade vive:
Antes de ler o código, colecione alguns inputs para que discrepâncias se destaquem rápido: quaisquer docs de API existentes, notas antigas de produto, tickets de suporte e os "pontos de dor conhecidos" que as pessoas reclamam. Isso não substitui o código, mas ajuda a notar estados faltantes como erros, casos de borda e permissões.
Mantenha o formato da spec sem frescuras e consistente. Times se alinham mais rápido quando toda spec lê do mesmo jeito.
Use essa estrutura repetidamente e suas specs de feature permanecerão legíveis, comparáveis e fáceis de atualizar.
Comece pelos pontos de entrada do servidor. Rotas e handlers mostram "o que o app faz" em termos concretos: quem pode chamá-las, o que precisam enviar, o que recebem de volta e o que muda no sistema.
Liste as rotas no escopo e mapeie cada uma para uma intenção do usuário. Não escreva "POST /api/orders." Escreva "Fazer um pedido" ou "Salvar rascunho." Se você não consegue nomear a intenção em palavras simples, isso já é uma lacuna de spec.
Ao ler cada handler, capture inputs e regras de validação como requisitos voltados ao usuário. Inclua campos obrigatórios, formatos permitidos e regras que geram erros reais. Por exemplo: "Email deve ser válido", "Quantidade deve ser pelo menos 1", "Data de início não pode ser no passado."
Escreva checagens de auth e roles do mesmo jeito. Em vez de "middleware: requireAdmin", documente: "Apenas admins podem cancelar qualquer pedido. Usuários regulares só podem cancelar o próprio pedido dentro de 10 minutos." Se o código verifica propriedade, feature flags ou limites por tenant, inclua também.
Depois, anote outputs e resultados. O que o sucesso retorna (um ID criado, um objeto atualizado)? Como são as falhas comuns (401 não autenticado, 403 sem permissão, 404 não encontrado, 409 conflito, 422 erro de validação)?
Por fim, registre efeitos colaterais porque fazem parte do comportamento: registros criados ou atualizados, emails ou notificações enviados, eventos publicados, jobs em background enfileirados e qualquer coisa que dispare outros fluxos. Esses detalhes evitam surpresas quando times dependerem da spec mais tarde.
Rotas dizem o que o app pode fazer. Componentes dizem o que os usuários realmente experienciam. Trate a UI como parte do contrato: o que aparece, o que é bloqueado e o que acontece quando algo dá errado.
Comece encontrando as telas de entrada da feature. Procure o componente de página, wrappers de layout e alguns componentes de "decisão" que controlam fetch, permissões e navegação. Geralmente é aí que o comportamento real vive.
Ao ler componentes, capture regras que o usuário percebe: quando ações estão desabilitadas, passos obrigatórios, campos condicionais, estados de carregamento e como erros aparecem (erros inline no campo vs toast, auto-retry, botões de "tentar novamente"). Também observe comportamento de estado e cache como dados desatualizados aparecendo primeiro, atualizações otimistas ou timestamps de "último salvo".
Fique atento a fluxos ocultos que mudam silenciosamente o que usuários veem. Busque feature flags, buckets de experimentos e gates apenas para admins. Observe redirecionamentos silenciosos também, como enviar usuários deslogados para login ou usuários sem acesso para uma tela de upgrade.
Exemplo concreto: na tela "Alterar Email", documente que Salvar fica desabilitado até o email ser válido, um spinner aparece durante a requisição, sucesso aciona um banner de confirmação, e erros de validação do backend aparecem abaixo do input. Se o código mostra uma flag como newEmailFlow, note ambas as variantes e o que muda.
Escreva cada fluxo de UI como passos curtos (o que o usuário faz, o que a UI faz em resposta) e mantenha condições e erros próximos ao passo afetado. Isso deixa a spec legível e facilita achar lacunas.
Notas brutas de rotas e componentes são úteis, mas difíceis de discutir. Reescreva o que você observou numa spec que PM, designer, QA e engenheiro possam ler e concordar.
Um padrão prático é uma user story por rota ou tela. Mantenha pequeno e específico. Por exemplo: "Como usuário autenticado, posso resetar minha senha para recuperar acesso." Se o código mostra comportamento diferente por papel (admin vs usuário), separe em stories distintas em vez de esconder em notas de rodapé.
Depois escreva critérios de aceitação que espelhem caminhos reais do código, não o produto ideal. Se o handler retorna 401 quando o token falta, isso é um critério. Se a UI desabilita enviar até um campo ser válido, isso é um critério.
Inclua regras de dados em linguagem simples, especialmente as que causam surpresas: limites, ordenação, unicidade, campos obrigatórios. "Usernames devem ser únicos (checado ao salvar)" é mais claro que "índice único."
Casos de borda muitas vezes fazem a diferença entre um bom doc e um doc útil. Aponte estados vazios, valores nulos, retentativas, timeouts e o que o usuário vê quando uma chamada de API falha.
Quando você bate em desconhecidos, marque-os em vez de adivinhar:
Esses marcadores viram perguntas rápidas para a equipe em vez de suposições silenciosas.
Uma lista de lacunas não é um segundo Jira. É um registro curto e baseado em evidências de onde código e comportamento desejado não batem, ou onde ninguém consegue explicar claramente o que é "correto". Feito bem, vira uma ferramenta de acordo, não de planejamento.
Seja rígido sobre o que conta como lacuna:
Ao registrar uma lacuna, inclua três partes para que ela fique fundamentada:
Evidência é o que mantém a lista longe de opiniões. Exemplo: "POST /checkout/apply-coupon aceita cupons expirados, mas CouponBanner.tsx os bloqueia na UI. Impacto: receita e confusão do usuário. Tipo: bug ou decisão pendente (confirmar regra pretendida)."
Mantenha curto. Defina um limite rígido, como 10 itens na primeira passada. Se encontrar 40 problemas, agrupe em padrões (inconsistências de validação, checagens de permissão, estados vazios) e mantenha apenas os exemplos principais.
Evite datas e planejamento dentro da lista de lacunas. Se precisar de propriedade, mantenha leve: anote quem deve tomar a decisão (produto) ou quem pode verificar o comportamento (engenharia), e mova o planejamento real para seu backlog.
Escolha um escopo pequeno e de alto tráfego: checkout com cupons e opções de envio. O objetivo não é reescrever o produto, só capturar o que o app faz hoje.
Comece pelas rotas backend. Frequentemente é aí que as regras aparecem primeiro. Você pode encontrar rotas como POST /checkout/apply-promo, GET /checkout/shipping-options, e POST /checkout/confirm.
A partir desses handlers, escreva comportamento em palavras simples:
restricted.Depois verifique componentes de UI. Um PromoCodeInput pode mostrar que os totais só atualizam após uma resposta bem-sucedida e que erros aparecem inline sob o input. Um componente ShippingOptions pode selecionar automaticamente a opção mais barata no primeiro carregamento e acionar uma atualização completa do detalhamento de preços quando o usuário altera a opção.
Agora você tem uma spec legível e uma pequena lista de lacunas. Por exemplo: mensagens de erro diferem entre a rota de cupom e a UI ("Invalid code" vs "Not eligible"), e ninguém consegue apontar uma regra clara de arredondamento de imposto (por item vs total do pedido).
No planejamento, a equipe concorda sobre a realidade primeiro e só então decide o que mudar. Em vez de debater opiniões, você revisa comportamentos documentados, escolhe uma inconsistência para corrigir e deixa o resto como "comportamento atual conhecido" até valer a pena revisitar.
Uma spec só ajuda se a equipe concorda que corresponde à realidade. Faça uma leitura curta com um engenheiro e uma pessoa de produto. Mantenha objetivo: 20–30 minutos focados no que usuários podem fazer e no que o sistema faz em resposta.
Durante a revisão, transforme afirmações em perguntas sim/não. "Quando um usuário chega nesta rota, nós sempre retornamos 403 sem sessão?" "Esse estado vazio é intencional?" Isso separa comportamento pretendido de comportamento acidental que entrou com o tempo.
Concordem no vocabulário antes de editar. Use as palavras que os usuários veem na UI (rótulos de botão, títulos de página, mensagens). Adicione nomes internos apenas quando ajudem engenheiros a achar o código (nomes de rota, nomes de componente). Isso evita desencontros como produto dizer "Workspace" enquanto a spec diz "Org."
Para manter atual, torne propriedade e cadência explícitas:
Se você usa uma ferramenta como Koder.ai, snapshots e rollback ajudam a comparar "antes" e "depois" ao atualizar uma spec, especialmente após uma grande refatoração.
A maneira mais rápida de perder confiança numa spec é descrever o produto que você quer, não o produto que você tem. Tenha uma regra rígida: toda afirmação deve ser respaldada por algo que você possa apontar no código ou numa tela real.
Outra armadilha comum é copiar a forma do código para o documento. Uma spec que lê "Controller -> Service -> Repository" não é uma spec, é um mapa de pastas. Escreva em termos voltados ao usuário: o que aciona a ação, o que o usuário vê, o que é salvo e como os erros aparecem.
Permissões e papéis costumam ser ignorados até o fim, e então tudo quebra. Adicione regras de acesso cedo, mesmo que estejam confusas. Aponte quais papéis podem ver, criar, editar, excluir, exportar ou aprovar, e onde a regra é aplicada (só UI, só API, ou ambos).
Não pule caminhos não-happy. Comportamento real se esconde em retentativas, falhas parciais e regras baseadas em tempo como expirações, cooldowns, jobs agendados ou limites "apenas uma vez por dia". Trate esses pontos como comportamentos de primeira classe.
Uma checagem rápida para trazer lacunas à tona é verificar:
Por fim, mantenha sua lista de lacunas em movimento. Cada lacuna deve ser rotulada como: "desconhecido, precisa de decisão", "bug, corrigir" ou "feature ausente, planejar". Se nada é rotulado, a lista estaciona e a spec deixa de ser "viva."
Faça uma passada rápida por clareza, cobertura e ação. Alguém que não escreveu deve entender o que a feature faz hoje e o que ainda está incerto.
Leia a spec como um novo colega no primeiro dia. Se ele conseguir resumir a feature em um minuto, você está perto. Se continuar perguntando "onde isso começa?" ou "qual é o caminho feliz?", aperte a abertura.
Verifique:
Cada lacuna deve ser específica e testável. Em vez de "Tratamento de erro confuso", escreva: "Se o provedor de pagamento retorna 402, a UI mostra um toast genérico; confirmar mensagem desejada e comportamento de retry." Adicione uma única próxima ação (perguntar ao produto, adicionar um teste, inspecionar logs) e note quem deve responder.
Escolha uma área de feature e limite em 60 minutos. Escolha algo pequeno, mas real (login, checkout, busca, uma tela de admin). Escreva uma frase de escopo: o que está incluído e o que está fora.
Execute o fluxo de trabalho uma vez do início ao fim: percorra rotas/handlers chave, trace o fluxo principal da UI e escreva comportamentos observáveis (inputs, outputs, validação, estados de erro). Se travar, registre a pergunta como uma lacuna e siga em frente.
Quando terminar, compartilhe a spec onde a equipe pode comentar e defina uma regra: qualquer mudança de comportamento enviada deve atualizar a spec na mesma janela de entrega, mesmo que sejam cinco linhas.
Mantenha lacunas separadas do backlog. Agrupe em "comportamento desconhecido", "comportamento inconsistente" e "testes faltantes", e revise rapidamente cada semana para decidir o que importa agora.
Se rascunhar e iterar parecer lento, um construtor baseado em chat como Koder.ai pode ajudar a obter uma primeira versão rapidamente. Descreva a feature, cole trechos-chave ou nomes de rota, refine a redação por conversa e exporte a fonte quando precisar. O ponto é velocidade e clareza compartilhada, não um processo maior.
Comece por uma fatia pequena e visível para o usuário (por exemplo, “resetar senha” ou “convidar um colega”). Leia as rotas/handlers para capturar regras e resultados, depois leia o fluxo de UI para registrar o que os usuários realmente veem (estados desabilitados, erros, redirecionamentos). Escreva usando um template consistente e registre os desconhecidos como uma lista separada de lacunas.
Default: trate o comportamento atual do código como fonte de verdade e documente-o.
Se o comportamento parecer acidental ou inconsistente, não “corrija” no spec — marque como uma lacuna com evidência (onde você viu e o que acontece), e então decida atualizar o código ou a especificação.
Mantenha simples e repetível. Um template prático é:
Isso mantém as specs legíveis e facilita identificar discrepâncias.
Escreva regras como requisitos visíveis ao usuário, não como anotações de código.
Exemplos:
Capture o que aciona um erro e o que o usuário vê quando isso acontece.
Foque no que é observável:
Efeitos colaterais importam porque afetam outras features e as expectativas de suporte/ops.
Se a UI bloqueia algo que a API permite (ou vice-versa), registre como uma lacuna até que uma decisão seja tomada.
Anote:
Depois concordem em uma regra e atualizem tanto o código quanto a especificação.
Mantenha a lista curta e baseada em evidências. Cada item deve ter:
Evite agendar ou transformar numa segunda backlog.
Documente explicitamente em vez de esconder:
Inclua:
Geralmente é aí que surgem surpresas e bugs.
Mantenha curto: uma leitura de 20–30 minutos com um engenheiro e um product.
Transforme afirmações em checagens sim/não (por exemplo, “Sempre retornamos 403 quando não autorizado?”). Alinhe o vocabulário usando as palavras da UI (rótulos e mensagens) para que todos signifiquem a mesma coisa.
Deixe a spec próxima ao código e faça atualizações como parte do envio.
Padrões práticos:
O objetivo é pequenas edições frequentes — não uma grande reescrita.