Lista de Verificação de Prontidão para Produção
Cada entrada indica o que verificar. Aplique o que se adequa ao estágio do projeto usando os níveis de estágio em CLAUDE.md; se nenhum estiver definido, infira o estágio (Protótipo, MVP, Produção ou Escala) e declare-o. Em revisões, marque as entradas que não se adequam ao estágio como "não aplicável ainda", com o gatilho que as tornaria relevantes.
1. Segurança e controle de acesso
- Autorização: Verifique permissões no lado do servidor em cada endpoint e para cada objeto acessado, não apenas no login (previne IDOR e BOLA). Com Supabase, Firebase ou backends semelhantes, a segurança em nível de linha ou as regras de segurança devem estar habilitadas e testadas.
- Validação de Entrada: Valide tipo, comprimento, formato e intervalo em cada limite de confiança com uma biblioteca de esquemas (Zod, Pydantic ou equivalente). A validação no lado do cliente é para UX, nunca para segurança.
- Injeção de SQL: Use apenas consultas parametrizadas ou bindings de ORM. Permita em lista de permissões identificadores dinâmicos, como colunas de ordenação.
- XSS: Confie na proteção do framework. Evite
innerHTML,dangerouslySetInnerHTMLev-htmlcom dados não confiáveis, ou sanitize com uma biblioteca aprovada como DOMPurify. Adicione uma Política de Segurança de Conteúdo. - CSRF: Para sessões baseadas em cookies, use cookies SameSite mais tokens CSRF ou verificações de Origin em requisições de mudança de estado. Nunca mude o estado em GET.
- CORS: Permita em lista de permissões origens exatas. Nunca reflita origens arbitrárias ou permita um curinga com credenciais. CORS não é controle de acesso.
- SSRF: Quando o servidor busca URLs fornecidas pelo usuário, permita em lista de permissões destinos, bloqueie endereços privados, loopback e link-local para IPv4 e IPv6 (incluindo metadados de nuvem em
169.254.169.254), e re-verifique após redirecionamentos e resolução de DNS. - Gerenciamento de Segredos: Carregue segredos de variáveis de ambiente ou de um gerenciador de segredos. Eles nunca aparecem em código, logs, imagens de contêiner ou histórico do git, e qualquer coisa que vazou deve ser rotacionada.
- IAM: Aplique o menor privilégio a cada pessoa, serviço e token. Use credenciais separadas por ambiente e por serviço, e nunca use chaves de root ou admin em aplicações.
- OAuth: Use um provedor ou biblioteca comprovado em vez de autenticação personalizada. Use Authorization Code com PKCE para clientes de navegador e celular, correspondência exata de URI de redirecionamento, validação de estado e escopos mínimos.
- Rotação de JWT: Use tokens de acesso de curta duração, rotacione tokens de atualização com detecção de reutilização e chaves de assinatura rotacionadas através de IDs de chave (
kid) e JWKS. Sempre verifique assinatura, algoritmo, emissor, audiência e expiração. - Segurança de Senhas e Sessões: Faça hash de senhas com Argon2id ou bcrypt. Defina cookies de sessão como HttpOnly, Secure e SameSite. Ofereça MFA onde as contas possuem valor.
- TLS: Sirva HTTPS em todos os lugares com renovação automática de certificado, TLS 1.2 mínimo (prefira 1.3) e HSTS. Nunca desabilite a verificação de certificado.
- Criptografia em Trânsito: Criptografe o tráfego interno, bem como o tráfego público, incluindo conexões de serviço, banco de dados, cache e fila.
- Criptografia em Repouso: Criptografe bancos de dados, discos, backups e armazenamento de objetos, com chaves em um KMS. Considere criptografia em nível de campo para dados altamente sensíveis.
- Cabeçalhos de Segurança: Defina Content-Security-Policy (incluindo frame-ancestors contra clickjacking), Strict-Transport-Security,
X-Content-Type-Options: nosniffe Referrer-Policy. - WAF: Coloque um firewall de aplicação web com conjuntos de regras gerenciados na frente de aplicações de produção públicas.
- Proteção DDoS: Confie na proteção do provedor (Cloudflare, AWS Shield ou padrões da plataforma) mais limites de taxa e limites de escalonamento automático, para que um ataque não se torne uma conta ilimitada.
- Segurança da Cadeia de Suprimentos: Execute varreduras de vulnerabilidades de dependências (npm audit, pip-audit, Dependabot ou similar) no CI. Verifique se cada novo pacote é real, nomeado corretamente e mantido.
- Uploads de Arquivos: Verifique o tipo pelo conteúdo, não pela extensão, limite o tamanho, armazene no armazenamento de objetos sob nomes aleatórios e sirva arquivos privados através de URLs assinadas de curta duração.
- Logs de Auditoria: Registre quem fez o quê e quando para ações sensíveis (eventos de autenticação, alterações de permissão, exportações de dados, movimentação de dinheiro) em armazenamento somente para anexação.
- Privacidade e Dados Pessoais: Colete o mínimo, saiba onde os dados pessoais estão, mantenha-os fora dos logs, defina a retenção e ofereça suporte a exclusão e exportação onde leis como GDPR ou CCPA se aplicam.
2. Dados e bancos de dados
- Indexação de Banco de Dados: Indexe colunas usadas em filtros, junções e ordenações em tabelas que crescerão, incluindo chaves estrangeiras. Evite índices redundantes que lentificam as escritas.
- Otimização de Consultas: Verifique planos com
EXPLAINpara consultas lentas ou frequentes. Selecione apenas as colunas necessárias e evite envolver colunas indexadas em funções dentro de cláusulas WHERE. - Consultas N+1: Encontre loops que consultam uma vez por item. Substitua-os por junções, carregamento antecipado ou lotes.
- Pooling de Conexões: Dimensione pools para os limites do banco de dados. Em serverless, use um pooler (PgBouncer, RDS Proxy ou o pooler do provedor) porque cada instância abre suas próprias conexões.
- Transações: Agrupe escritas de várias etapas que devem ser bem-sucedidas ou falhar juntas em uma única transação e escolha o nível de isolamento deliberadamente.
- Restrições: Reforce a integridade no banco de dados com NOT NULL, UNIQUE, chaves estrangeiras e restrições CHECK. As verificações do aplicativo sozinhas perdem para condições de corrida.
- Paginação: Pagine cada endpoint de lista e consulta com um tamanho de página limitado. Prefira paginação por cursor (keyset) para dados grandes ou em mudança.
- Dinheiro e Tempo: Armazene dinheiro como unidades menores inteiras ou um tipo decimal. Armazene timestamps em UTC e converta apenas para exibição.
- Réplicas de Leitura: Adicione-as apenas quando as leituras sobrecarregarem o primário e lide com a latência de replicação, especialmente quando os usuários leem suas próprias escritas.
- Replicação: Saiba se é síncrona ou assíncrona e quantos dados um failover pode perder.
- Particionamento: Particione tabelas muito grandes (geralmente por tempo) para manter índices e manutenção gerenciáveis e expire dados antigos descartando partições.
- Fragmentação (Sharding): Trate como último recurso após indexação, cache, réplicas e escalonamento vertical. Escolha uma chave de fragmentação que evite pontos de acesso e consultas entre fragmentos.
- Migrações de Banco de Dados: Mantenha as migrações versionadas, revisadas, automatizadas nas implantações e reversíveis quando possível. Para tempo de inatividade zero, use expand-and-contract: adicione, preencha, troque e remova em uma versão posterior. Faça backup antes de alterações destrutivas.
- Versionamento de Esquema: Versione contratos de dados (esquemas de banco de dados, cargas de eventos, esquemas de API) para que o código antigo e novo possam ser executados lado a lado durante as implantações.
3. Concorrência e sistemas distribuídos
- Condições de Corrida: Procure por código "verificar-depois-agir" (saldos, inventário, nomes de usuário únicos, resgate de cupons). Corrija com atualizações atômicas, restrições, transações ou bloqueios.
- Segurança de Thread: Sincronize ou elimine estado mutável compartilhado entre threads, workers e tarefas assíncronas. Variáveis globais de módulo são frequentemente compartilhadas entre requisições.
- Bloqueio Otimista: Verifique uma coluna de versão ou ETag na atualização para registros de baixa contenção e retorne 409 ou 412 em conflito.
- Bloqueio Pessimista: Use
SELECT ... FOR UPDATEpara seções críticas de alta contenção e mantenha os bloqueios curtos. - Deadlocks: Adquira bloqueios em uma ordem consistente, mantenha as transações curtas e tente novamente em erros de deadlock.
- Bloqueios Distribuídos: Use-os apenas para coordenação entre processos, com concessões que expiram e tokens de cercamento (fencing tokens). Prefira restrições de banco de dados ou filas quando estas forem suficientes.
- Transações Distribuídas: Evite confirmação de duas fases entre serviços. Mantenha os limites transacionais dentro de um banco de dados quando possível.
- Padrão Saga: Para fluxos de trabalho que abrangem serviços, encadeie transações locais com ações compensatórias e torne cada etapa idempotente.
- Teorema CAP: Durante uma partição de rede, um sistema deve escolher consistência ou disponibilidade. Decida por recurso: saldos e inventário precisam de consistência, enquanto feeds e contadores podem tolerar obsolescência.
- Consistência Eventual: Onde for aceito, projete UI e lógica para leituras desatualizadas e faça as atualizações convergirem.
- Eleição de Líder: Quando exatamente uma instância deve atuar (agendadores, workers singleton), use uma concessão ou um primitivo da plataforma, nunca uma instância codificada.
- Partições de Rede: Assuma que qualquer chamada pode falhar no meio ou ser bem-sucedida sem uma resposta. Projete com timeouts, idempotência e reconciliação.
- Skew de Clock: Nunca confie em clocks entre máquinas para ordenação ou correção. Use timestamps de banco de dados, números de sequência ou relógios lógicos e permita uma pequena margem em verificações de expiração de token.
- Descoberta de Serviço: Resolva serviços através de DNS, da plataforma ou de um registro, nunca IPs codificados.
4. Resiliência e tolerância a falhas
- Timeouts: Dê a cada chamada de saída (HTTP, banco de dados, cache, fila, API LLM) timeouts de conexão e de requisição que se encaixem no próprio prazo do chamador.
- Tentativas (Retries): Tente novamente apenas falhas transitórias (timeouts, erros de conexão, 429, 502, 503, 504) em operações idempotentes, com tentativas limitadas. Evite tentar novamente em todas as camadas ao mesmo tempo, o que multiplica a carga.
- Backoff Exponencial: Faça backoff exponencialmente com jitter e honre os cabeçalhos
Retry-After. - **Disjuntores (Circuit Breakers):] Pare de chamar uma dependência com falha após erros repetidos, falhe rapidamente com um fallback e teste para recuperação.
- Idempotência: Dê a operações que podem ser repetidas (pagamentos, pedidos, manipuladores de webhook, jobs) uma chave de idempotência ou chave natural, para que duplicatas não tenham efeito extra.
- Backpressure: Limite filas, buffers e concorrência. Quando sobrecarregado, reduza a carga ou retorne 429 ou 503 em vez de aceitar trabalho ilimitado.
- Anteparos (Bulkheads): Isole recursos (pools ou workers separados) para que uma dependência lenta não possa esgotar tudo.
- Degradação Graciosa: Decida o que ainda funciona quando uma dependência está inativa, como dados em cache, um modo somente leitura ou ocultar temporariamente um recurso.
- Desligamento Gracioso: Ao receber
SIGTERM, pare de aceitar novo trabalho, finalize requisições e jobs em andamento e feche as conexões. - **Verificações de Saúde (Health Checks):] Exponha um endpoint de saúde barato para o balanceador de carga ou plataforma.
- Sondas de Vivacidade e Prontidão (Liveness & Readiness Probes): A sonda de vivacidade detecta apenas um processo travado e não deve depender de serviços externos, ou uma interrupção de banco de dados reinicia tudo. A sonda de prontidão decide se uma instância deve receber tráfego e pode verificar dependências.
- Failover: Saiba o que acontece quando o banco de dados primário, zona ou provedor falha. Automatize onde o tempo de atividade é importante e teste.
5. Mensageria, trabalho em segundo plano e tempo real
- Filas de Mensagens: Mova trabalho lento, repetível ou em rajada (e-mails, processamento de mídia, chamadas de terceiros) para fora do caminho da requisição para uma fila com workers.
- Semântica de Entrega: Assuma entrega pelo menos uma vez, então os consumidores devem ser idempotentes. Não presuma ordenação a menos que o sistema a garanta por chave.
- Filas de Cartas Mortas (Dead Letter Queues):] Roteie mensagens que esgotam as tentativas para uma DLQ com um alerta e um caminho de repetição. Nunca as descarte silenciosamente ou tente novamente para sempre.
- Pub/Sub: Use para fan-out para vários consumidores independentes, com esquemas de eventos definidos e propriedade.
- Arquitetura Orientada a Eventos: Adote-a quando o desacoplamento vale o custo de depuração. Trate eventos como contratos versionados e mantenha as requisições rastreáveis através deles.
- Outbox Transacional: Quando uma escrita de banco de dados também deve publicar um evento, escreva ambos em uma transação (uma tabela de outbox) e retransmita assincronamente, o que evita o problema de escrita dupla.
- Tarefas Cron: Torne as tarefas agendadas idempotentes, seguras para executar duas vezes ou em sobreposição, limitadas a uma instância por vez e monitoradas para execuções perdidas ou com falha.
- WebSockets: Autentique na conexão, envie heartbeats, reconecte com backoff e planeje para várias instâncias (pub/sub compartilhado ou sessões aderentes).
- Eventos Enviados pelo Servidor (SSE):] Prefira-os sobre WebSockets para streams unidirecionais do servidor para o cliente, como notificações, progresso e streaming de tokens LLM.
- Long Polling: Use como fallback quando WebSockets e SSE não estiverem disponíveis, com timeouts e um limite em conexões mantidas.
- Webhooks: Para webhooks recebidos, verifique assinaturas (HMAC), rejeite timestamps obsoletos para interromper repetições, reconheça rapidamente e processe assincronamente e desduplique por ID de evento. Para webhooks de saída, assine cargas, tente novamente com backoff e versione os formatos de evento.
6. Tráfego, borda e rede
- Limitação de Taxa (Rate Limiting):] Limite por usuário, chave de API e IP em endpoints públicos, de autenticação e caros (login, registro, redefinição de senha, OTP, chamadas LLM). Retorne 429 com
Retry-After. - Balanceamento de Carga: Distribua o tráfego entre instâncias verificadas quanto à saúde. Mantenha os servidores de aplicação sem estado para que qualquer instância possa atender qualquer requisição.
- Proxies Reversos: Encerre TLS, comprima e aplique limites de tamanho do corpo e timeout no proxy. Confie em
X-Forwarded-Forapenas de proxies conhecidos para que IPs de cliente não possam ser falsificados. - Gateways de API: Centralize autenticação, limitação de taxa, roteamento e validação quando houver vários serviços ou uma API pública. Um aplicativo único raramente precisa de um.
- CDN: Sirva ativos estáticos e mídia através de um CDN com longos tempos de vida de cache e nomes de arquivo com hash de conteúdo.
- DNS: Abaixe os TTLs antes das migrações, gerencie registros como código quando possível e espere atrasos de propagação.
- TCP vs UDP: Padrão para protocolos baseados em TCP. Use UDP apenas para tráfego sensível à latência que tolera perda (mídia em tempo real, jogos), com tratamento em nível de aplicação.
- HTTP/2 e HTTP/3: Habilite-os na borda ou CDN para multiplexação e conexões mais rápidas. Isso geralmente é configuração, não código de aplicação.
- gRPC: Use para chamadas de serviço internas que precisam de contratos estritos ou streaming, com um deadline em cada chamada. Navegadores precisam de gRPC-Web ou um gateway.
7. Cache
- Cache: Armazene em cache apenas após medir uma necessidade e defina a chave, TTL e público de cada cache. Nunca armazene dados específicos do usuário ou dependentes de permissão em um cache compartilhado sob uma chave genérica.
- Cache de Borda: Defina
Cache-Controlexplicitamente, marque respostas personalizadas como private ou no-store e use stale-while-revalidate onde a atualização for ...
[truncado para tradução]