From anti-vibe-coding
This skill should be used when the user asks about 'API design', 'N+1 problem', 'idempotency', 'idempotent APIs', 'DTOs', 'data transfer objects', 'webhooks', 'websockets', 'SSE', 'REST vs GraphQL', 'SQL vs NoSQL', 'race conditions in APIs', 'API concurrency', 'gRPC', 'AMQP', 'RabbitMQ', 'message queue', 'GraphQL schema', 'GraphQL depth', 'DataLoader', 'pagination', 'cursor pagination', 'keyset pagination', 'REST URL design', 'status codes', 'API versioning', 'HATEOAS', 'filtering', 'sorting', 'Protocol Buffers', or needs to analyze and audit API endpoints. Provides expert consultation on API design patterns, protocols, anti-patterns, and best practices.
How this skill is triggered — by the user, by Claude, or both
Slash command
/anti-vibe-coding:api-design [API design question or endpoint to analyze][API design question or endpoint to analyze]This skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
<!-- profile-aware-preface:start -->
__tests__/stack-aware-preface-wire.test.tslib/api-design-prefaces.test.tslib/api-design-prefaces.tsreferences/api-concurrency.mdreferences/api-protocols.mdreferences/communication-patterns.mdreferences/database-selection.mdreferences/dtos.mdreferences/graphql-patterns.mdreferences/idempotency.mdreferences/n-plus-one.mdreferences/rest-advanced.mdreferences/typescript-contracts.md// 2026-05-15 (Luiz/dev): Plano 04 fase-01 — profile-aware-preface (PRD §RF-MH-05).
// Lê context UMA vez via readPrefaceContext (Plano 01). Lookup table per-skill (G3).
// Quando ctx.profile === null: fallback default = comportamento v6.2 intacto (CA-02).
import { readPrefaceContext } from '../lib/preface-context'
import { API_DESIGN_PREFACE_BY_PROFILE, DEFAULT_API_DESIGN_PREFACE } from './lib/api-design-prefaces'
const ctx = readPrefaceContext(process.cwd())
const preface = ctx.profile
? (API_DESIGN_PREFACE_BY_PROFILE[ctx.profile] ?? DEFAULT_API_DESIGN_PREFACE)
: DEFAULT_API_DESIGN_PREFACE
// Quando ctx.profile é não-nulo, prepend preface ao corpo da skill.
// Quando null, behavior idêntico a v6.2 (CA-02).
Se preface for não-vazio, inicie sua resposta com o conteúdo de preface e em seguida proceda com a consulta de API design normal.
Se preface for vazio (profile null), comportamento v6.2 intacto — sem preface, ir direto ao corpo.
// 2026-05-16 (Luiz/dev): Plano 03 fase-01 — stack-aware-preface (PRD §Mecanismo Skill wire-up, D11).
// G1 do plano: bloco verbatim do Plano 01 fase-04 (security wire). Path fixo .claude/knowledge/INDEX.md (D11).
// CA-09: se INDEX ausente, preface = ''; comportamento da skill = v6.3.1 intacto.
import { getStackKnowledgePreface } from '../security/lib/stack-aware-preface'
const stackKnowledgePreface = getStackKnowledgePreface(process.cwd())
Se stackKnowledgePreface for não-vazio, prepende esta frase ao início da resposta (após o preface profile-aware, se ambos existirem). Se vazio, ignore — comportamento da skill segue do bloco profile-aware-preface acima sem mudança (CA-09).
// 2026-05-15 (Luiz/dev): wire-up CA-09 v6.3.0 (closed em v6.3.1 RF-SH-02) — non-blocking warning.
// G2 do plano02: NUNCA bloqueia execução — alinhado com stale-detector.ts:8-10.
// G6 do plano02: capabilities.json AUSENTE NÃO emite warning falso (silently null).
// G7 do plano02: shape atual de capabilities.json não tem `storedChecksums` — check direto por age.
// SYNC: logica espelhada em skills/lib/__tests__/stale-warning.test.ts:checkStaleCapabilities.
import { readFileSync } from 'node:fs'
import { join } from 'node:path'
const __STALE_THRESHOLD_MS = 24 * 60 * 60 * 1000 // 24h — CA-09 PRD v6.3.1
function __readCapabilitiesGeneratedAt(projectRoot: string): string | null {
try {
const raw = readFileSync(join(projectRoot, 'discovery', 'capabilities.json'), 'utf-8')
const parsed = JSON.parse(raw) as { generated_at?: unknown }
return typeof parsed.generated_at === 'string' ? parsed.generated_at : null
} catch {
return null
}
}
const __caps_generated_at = __readCapabilitiesGeneratedAt(process.cwd())
if (__caps_generated_at !== null) {
const __age = Date.now() - new Date(__caps_generated_at).getTime()
if (Number.isFinite(__age) && __age > __STALE_THRESHOLD_MS) {
process.stderr.write('capabilities.json stale (>24h) — run /init --refresh\n')
}
}
Modo Consultor de API Design. Neste modo, ENSINAR e ANALISAR — nunca gerar codigo.
Usar este conhecimento para responder perguntas, auditar endpoints existentes e guiar decisoes de design de APIs.
Estes dois principios devem informar TODA decisao de design de API. Nao sao regras de transporte — sao restricoes de contratos.
"Com usuarios suficientes de uma API, todos os comportamentos observaveis do sistema serao dependidos por alguem, independente do que voce promete no contrato."
Na pratica: o contrato real e o comportamento observado, nao o contrato documentado. Consumidores dependem de latencia acidental, de campos extras nao documentados, de erros retornados fora de spec — e quebram quando esses "detalhes" mudam.
Implicacoes de design:
/anti-vibe-coding:decision-registry add decisoes de contrato que afetam consumers.Evite forcar consumers a escolher entre multiplas versoes da mesma API simultaneamente. Problemas de diamond dependency ocorrem quando dependencias transitivas requerem versoes incompativeis.
Design para um mundo onde apenas uma versao existe por vez: estenda, nao bifurque. Adicione campos opcionais com defaults retro-compatíveis antes de criar /api/v2. Quando a quebra e inevitavel, a migracao deve ser sequencial (todos movem juntos), nao paralela.
Conexao: versioning de path (
/api/v1/) emreferences/rest-advanced.mde o mecanismo de transporte. Esta regra e o principio de design que determina QUANDO criar uma nova versao.
O problema N+1 ocorre quando uma query inicial busca N itens e, para cada item, dispara uma query adicional para dados relacionados. Resultado: 1 + N queries ao banco.
Quando acontece:
Regra de ouro: query dentro de loop = N+1.
Relacao e conhecida no momento da query?
SIM → Eager Loading (select_related, include, with)
NAO →
Multiplos itens precisam da mesma relacao?
SIM → Batch Loading (DataLoader, WHERE IN)
NAO → JOIN explicito ou Subquery
Referencia completa:
references/n-plus-one.md— tabela de estrategias, exemplos de codigo, deteccao, checklist de verificacao.
Uma operacao idempotente produz o mesmo resultado independente de quantas vezes for executada. Critico para sistemas distribuidos onde retries sao inevitaveis.
Principio fundamental: NAO confiar apenas na spec REST. Verificar a implementacao real. Um PUT que faz counter = counter + 1 NAO e idempotente, apesar de PUT ser "idempotente por spec".
Operacao envolve dinheiro?
SIM → Idempotencia OBRIGATORIA (chave UUID ou composta)
NAO →
Operacao tem side-effects irreversiveis? (email, SMS)
SIM → Idempotencia RECOMENDADA
NAO →
Operacao e naturalmente idempotente? (GET, PUT, DELETE)
SIM → Apenas validar a implementacao
NAO → Avaliar caso a caso (POST com unique constraint pode bastar)
Referencia completa:
references/idempotency.md— tabela de verbos HTTP, estrategias de implementacao, anti-patterns, checklist.
DTOs definem EXATAMENTE quais dados entram e saem da API. Criam barreira de seguranca entre o mundo externo e o modelo de dominio.
Regras fundamentais:
API e publica ou consumida por terceiros?
SIM → DTOs separados OBRIGATORIOS (input + output + versionamento)
NAO →
Modelo tem campos sensiveis? (password, tokens, internal IDs)
SIM → Output DTO OBRIGATORIO (no minimo)
NAO →
Modelo aceita campos que o usuario NAO deveria controlar? (role, isAdmin)
SIM → Input DTO OBRIGATORIO (no minimo)
NAO → Avaliar se a complexidade justifica
Referencia completa:
references/dtos.md— tabela input vs output, regras, anti-patterns, checklist. Modelagem de contrato em tempo de compilacao (unions + branded IDs):references/typescript-contracts.md
Quem inicia a comunicacao?
SERVIDOR EXTERNO (Stripe, GitHub) → Webhook
SEU SISTEMA →
Comunicacao precisa ser bidirecional?
SIM → WebSocket
NAO →
Frequencia de eventos?
ALTA (multiplas/segundo) → WebSocket
MEDIA (a cada poucos segundos) → SSE
BAIXA (esporadica) → Polling ou Webhook interno
Resumo rapido:
| Padrao | Direcao | Caso de uso tipico |
|---|---|---|
| Webhook | Externo → Voce | Pagamento aprovado, deploy concluido |
| WebSocket | Bidirecional | Chat, jogos, dashboards tempo real |
| SSE | Servidor → Cliente | Notificacoes, feeds, progresso |
Seguranca critica em Webhooks: SEMPRE validar HMAC signature. Endpoint de webhook e PUBLICO — sem validacao, qualquer atacante simula eventos.
Referencia completa:
references/communication-patterns.md— seguranca detalhada, boas praticas, escalabilidade, checklists.
Comecar com SQL (PostgreSQL). Migrar para NoSQL apenas com problema comprovado que SQL nao resolve eficientemente.
Justificativa: SQL resolve 90%+ dos casos; PostgreSQL suporta JSON, full-text search, extensoes; migrar SQL→NoSQL e mais facil que o contrario; ACID e crucial.
Dados sao relacionais com integridade referencial?
SIM → SQL (PostgreSQL)
NAO →
Precisa de ACID / transacoes?
SIM → SQL (PostgreSQL)
NAO →
Padrao de acesso principal?
KEY-VALUE simples (cache, sessao) → Redis
DOCUMENTOS com schema variavel → MongoDB/Firestore
GRAFOS com traversal profundo → Neo4j
ESCRITA MASSIVA + analise temporal → Cassandra/ClickHouse
NAO TEM CERTEZA → SQL (PostgreSQL)
Referencia completa:
references/database-selection.md— comparativo detalhado, ACID vs BASE, polyglot persistence, anti-patterns, checklist.
"O usuario PRECISA esperar por esta operacao para continuar?"
Se a resposta e NAO, mover para background.
Usuario precisa do resultado para continuar?
SIM →
Operacoes sao independentes entre si?
SIM → Promise.all (paralelo)
NAO → Sequencial (await em serie)
NAO →
Multiplos consumers precisam reagir?
SIM → PubSub / Event Queue
NAO → Background Job simples
Resumo de estrategias:
| Estrategia | Quando usar |
|---|---|
| Background Job | Operacao unica demorada (email, imagem) |
| PubSub / Event Queue | Multiplos consumers independentes |
| Promise.all | Operacoes independentes no mesmo request |
| Streaming (SSE) | Resultado progressivo ao cliente |
Referencia completa:
references/api-concurrency.md— exemplos praticos, identificacao de oportunidades, anti-patterns, checklist.
Referencia completa:
references/api-protocols.md
Request-response CRUD? → HTTP/REST ✓ (padrao)
Bidirecional real-time? → WebSockets
Garantia de entrega assincrona? → AMQP (RabbitMQ, SQS)
Server-to-server alta performance? → gRPC
Browser como cliente? → HTTP/REST ou WebSocket (NAO gRPC)
Resumo:
| Protocolo | Caso de uso | Formato |
|---|---|---|
| HTTP/REST | CRUD, APIs publicas | JSON |
| WebSocket | Chat, jogos, dashboards | JSON/binario |
| AMQP | Filas, processamento assincrono | Qualquer |
| gRPC | Microservicos server-to-server | Protocol Buffers |
Regra: HTTP/REST + WebSocket cobre 90% dos casos. gRPC e AMQP para cenarios especificos com necessidade comprovada.
Referencia completa:
references/graphql-patterns.md
Quando usar GraphQL (e quando NAO):
Multiplos clientes com necessidades diferentes? → GraphQL
Overfetching/underfetching comprovado? → GraphQL
CRUD simples sem relacoes complexas? → REST ✓
API publica para terceiros? → REST ✓
Regras essenciais:
errors, nao status code — GraphQL sempre retorna 200. Monitorar campo errorsReferencia completa:
references/rest-advanced.md
GET /products (nao /getProducts)/products (nao /product)/users/:id/orders/:orderId/items/api/v1/products/order-items (nao /orderItems)Dataset grande (>10K registros)? → Cursor pagination ✓
Precisa de "ir para pagina X"? → Offset/Page pagination
Dados mudam frequentemente? → Cursor pagination ✓
Caso simples? → Page pagination (intuitivo)
| Tipo | Exemplo | Pro | Contra |
|---|---|---|---|
| Page | ?page=3&limit=10 | Intuitivo, "pagina X de Y" | Inconsistente com dados mutaveis |
| Offset | ?offset=20&limit=10 | Flexivel | Performance degrada em datasets grandes |
| Cursor | ?cursor=abc&limit=10 | Consistente, performante | Sem "ir para pagina X" |
REGRA CRITICA: SEMPRE paginar endpoints de colecao. NUNCA retornar todos os registros.
| Operacao | Status Code |
|---|---|
| GET com dados | 200 OK |
| POST criou recurso | 201 Created |
| DELETE sem body | 204 No Content |
| Validacao falhou | 400 Bad Request |
| Nao autenticado | 401 Unauthorized |
| Sem permissao | 403 Forbidden |
| Nao encontrado | 404 Not Found |
| Rate limit | 429 Too Many Requests |
NUNCA retornar 200 para tudo. Status codes semanticos sao obrigatorios.
Justificativas comuns que encobrem decisoes de design ruins. Cada "Realidade" aponta para onde o conteudo ja existe nesta skill.
| Racionalizacao | Realidade |
|---|---|
| "Vou documentar os contratos depois" | DTOs e schemas Zod sao a documentacao. Sem eles, o contrato e ambiguo desde o dia 1. → references/dtos.md |
| "Sem paginacao por agora, os dados sao poucos" | A REGRA CRITICA e paginar sempre — colecoes crescem. Adicionar paginacao depois quebra consumers existentes (Lei de Hyrum). → secao 9 / references/rest-advanced.md |
| "Vou versionar quando precisar" | Versionar depois e quebrar. Contratos publicos precisam de versionamento desde o lancamento; campos extras sao dependencias implicitas (Regra de Uma Versao). → secao 0 / references/dtos.md |
| "Ninguem usa esse comportamento nao documentado" | Lei de Hyrum: com usuarios suficientes, alguem ja depende. Remover quebra producao silenciosamente. → secao 0 |
| "Mantemos duas versoes em paralelo para nao quebrar ninguem" | Versoes paralelas criam diamond dependency e dobram custo de manutencao. A solucao e extensao retro-compativel + migracao sequencial. → Regra de Uma Versao (secao 0) |
| "Validacao so no front-end, confio no meu cliente" | Front-end e UX, nao seguranca. Qualquer cURL ignora o front. Validacao e Mass Assignment sao vulnerabilidades reais. → references/dtos.md "Validacao SEMPRE no back-end" |
| "API interna nao precisa de contrato formal" | APIs internas acumulam consumers silenciosamente. Sem contrato, qualquer mudanca e uma surpresa. DTOs e protocols se aplicam igualmente. → secoes 3 e 7 |
Lista de auditoría rapida. Cada item aponta para a referencia com o diagnostico completo.
{ data: [...] } em sucesso, { error: "..." } em falha sem envelope consistente) → references/rest-advanced.md (status codes / error formats){ message }, outros { error }, outros { errors: [] }) → references/rest-advanced.mdreferences/dtos.mdreferences/dtos.md versioningreferences/rest-advanced.md REGRA CRITICA/getUser, /createOrder, /deleteItem) → secao 9 / references/rest-advanced.mdreferences/communication-patterns.md (HMAC + validacao) / references/dtos.mdAo receber uma pergunta ou pedido de analise:
references/)/anti-vibe-coding:decision-registry add se for decisao arquiteturalNUNCA gerar codigo neste modo. Apenas ensinar, analisar e recomendar.
Direcionar para implementacao:
/anti-vibe-coding:tdd-workflow para iniciar implementacao/anti-vibe-coding:consultant para decisoes mais amplas$ARGUMENTS
npx claudepluginhub luyzkk/anti-vibe-coding --plugin anti-vibe-codingGuides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.