Prompt completo · cole no Claude Code
Construa o seu próprio SaaS de disparos com IA
E-mail marketing, API oficial do WhatsApp, disparo em massa, gestão de grupos e encurtador com deeplink num app só. O prompt guia você desde a criação das contas até o teste de invasão antes de ir pro ar.
Ferramentas (base de 22 mil leads)R$ 39.768/ano
Resend + SupabaseUS$ 45/mês
O que ele substitui
E-mail marketingCampanhas, automações, aberturas e cliquesno lugar do ActiveCampaign
WhatsApp API oficialTemplates, utility, custo por mensagemno lugar do ManyChat
Disparo em massaVários números, intervalo e aquecimentono lugar do PlugLead
Gestão de gruposCria o próximo grupo e troca o link sozinhono lugar do SendFlow
Encurtador e deeplinkRodízio de links e abertura direto no appno lugar do Switchy
O que você vai precisar
- Claude Code instalado e uma assinatura do Claude.
- Um domínio próprio com acesso ao DNS. ~R$ 40/ano no Registro.br
- Supabase para banco, login e arquivos. grátis para testar · US$ 25/mês no Pro
- Resend para os e-mails. grátis até 3 mil/mês · US$ 20/mês para 50 mil
- Conta na Meta (Business Manager) para a API oficial. paga só por mensagem, direto para a Meta
- Vercel e GitHub para publicar o painel. grátis para começar
- Uma VPS, só se quiser o disparo não oficial e os grupos. ~R$ 30 a 60/mês
Você não precisa saber programar. O próprio prompt manda o Claude te guiar em cada conta, cada registro de DNS e cada chave, um passo por vez.
Segurança em primeiro lugar
O prompt obriga o Claude a construir o sistema pensando que alguém vai tentar invadir:- Toda rota fechada por padrão, login só por convite e 2FA para administradores.
- RLS em 100% das tabelas e cada empresa isolada das outras.
- Chaves de API criptografadas no banco e nunca enviadas para o navegador.
- Todo webhook com assinatura conferida, limite de tentativas e proteção contra XSS, CSRF e SSRF.
- Um teste de invasão com 10 ataques que precisa passar antes de ir pro ar.
O prompt
Você vai construir comigo, do zero, um SaaS de disparos para quem faz lançamento e marketing digital. Ele substitui 5 ferramentas pagas: e-mail marketing (tipo ActiveCampaign), disparo pela API oficial do WhatsApp (tipo ManyChat), disparo em massa pelo WhatsApp não oficial (tipo PlugLead), gestão de grupos de WhatsApp (tipo SendFlow) e encurtador com deeplink (tipo Switchy).
Eu não sou programador. Trabalhe em fases, explique o que está fazendo em português simples, e só avance para a próxima fase quando a anterior estiver funcionando e testada. Quando precisar que eu faça algo fora do código (criar conta, configurar DNS, copiar uma chave), me dê o passo a passo clicável e espere eu confirmar.
SEGURANÇA É A PRIORIDADE NÚMERO 1. Esse sistema vai guardar a base de leads, chaves de API e números de WhatsApp de um negócio de verdade. Um vazamento aqui expõe milhares de pessoas e pode banir meus números. Toda decisão de arquitetura deve partir do princípio de que alguém VAI tentar invadir. Nunca troque segurança por velocidade de entrega. Se algo inseguro for mais fácil, me avise e faça do jeito seguro.
==================================================
1. STACK (use exatamente esta, não troque sem me perguntar)
==================================================
- Painel + API: Next.js (App Router) com TypeScript estrito, hospedado na Vercel.
- Banco, login e arquivos: Supabase (Postgres, Auth, Storage, pg_cron, pg_net). Plano Pro (US$ 25/mês) quando for para produção.
- E-mail: Resend (plano Pro, US$ 20/mês para 50 mil e-mails).
- WhatsApp oficial: Meta WhatsApp Cloud API, direto na Meta, sem intermediário.
- WhatsApp não oficial e grupos: um "worker" separado em Node.js 22 + Fastify + Baileys, rodando em Docker numa VPS pequena (2 GB de RAM + 2 GB de swap), atrás do Caddy com HTTPS automático. Esse módulo é OPCIONAL: pergunte se eu quero antes de construir.
- Validação de dados: zod em TODA entrada (formulários, rotas, webhooks, variáveis de ambiente).
- Testes: Vitest para regras de negócio e um roteiro de testes de segurança (seção 9).
==================================================
2. FASE 0 — CONTAS E CONFIGURAÇÃO (me guie, um item por vez)
==================================================
Antes de escrever código de produção, me conduza por cada item abaixo. Para cada um: diga para que serve, mande o passo a passo, diga exatamente qual valor eu devo guardar e EM QUAL ARQUIVO colocar. Regra de ouro: eu NUNCA colo chave secreta aqui no chat. Você cria um arquivo .env.example com os nomes das variáveis (sem valores) e eu preencho o .env.local sozinho. Confira que .env* está no .gitignore antes do primeiro commit.
2.1 Domínio
- Preciso de um domínio próprio (ex.: meunegocio.com.br) num provedor de DNS (Registro.br, Cloudflare, Hostinger etc.).
- Vamos usar subdomínios: painel (app.), e-mails (envio.), links curtos (ir.) e worker (wa.). Explique cada um.
2.2 Supabase
1. Criar conta em supabase.com → New project. Região: São Paulo (sa-east-1). Senha do banco: gerada pelo próprio Supabase, salva no gerenciador de senhas.
2. Em Project Settings → API Keys: anotar a URL do projeto, a chave publishable (sb_publishable_…, pode ir pro navegador) e criar uma chave secret (sb_secret_…, SÓ no servidor). Se o projeto mostrar as chaves antigas anon/service_role, use as novas.
3. Authentication → Sign In / Providers: deixar só e-mail; DESLIGAR "Allow new users to sign up" (usuários entram só por convite); ligar confirmação de e-mail; exigir senha forte (mínimo 12 caracteres, com vazamento checado).
4. Authentication → Multi-Factor: ativar TOTP. Admins são obrigados a usar 2FA.
5. Authentication → URL Configuration: Site URL = https://app.SEU-DOMINIO; redirect URLs só do seu domínio e localhost.
6. Database → Extensions: ativar pg_cron e pg_net.
7. Instalar a Supabase CLI, fazer `supabase login` e `supabase link`. Todo o schema vai em migrations versionadas (nada criado na mão pelo painel).
8. Quando for para produção: plano Pro (backups diários) e Network Restrictions se o plano permitir.
2.3 Resend + DNS
1. Criar conta em resend.com. Ativar 2FA na conta.
2. Domains → Add Domain → usar o SUBDOMÍNIO de envio (ex.: envio.meunegocio.com.br), não o domínio raiz. Isso protege a reputação do domínio principal. Região: a mais próxima disponível.
3. O Resend mostra os registros DNS. Me ensine a criar cada um no meu provedor, copiando os valores EXATOS do painel:
- MX no subdomínio "send" (retorno de bounces).
- TXT de SPF no subdomínio "send".
- TXT de DKIM (resend._domainkey).
- TXT de DMARC (_dmarc), começando com `v=DMARC1; p=none; rua=mailto:…` e, depois de 2–4 semanas sem problemas, subir para p=quarantine.
Se o DNS for Cloudflare, os registros ficam "DNS only" (nuvem cinza). Explique que a propagação pode levar de minutos a horas e clique em Verify até ficar verde.
4. Ativar open tracking e click tracking no domínio (sem isso toda campanha mostra 0 aberturas).
5. API Keys → Create → permissão "Sending access", restrita ao domínio de envio. Nunca use "Full access" no app.
6. Webhooks → Add endpoint → https://app.SEU-DOMINIO/api/webhooks/resend, eventos: sent, delivered, delivery_delayed, bounced, complained, opened, clicked. Guardar o signing secret.
7. Aquecer o domínio: primeiros dias com volumes pequenos para quem mais abre, subindo aos poucos.
2.4 Meta WhatsApp Cloud API (oficial)
1. business.facebook.com: ter um Business Manager verificado (verificação de empresa).
2. developers.facebook.com → Create App → tipo Business → adicionar o produto WhatsApp.
3. Adicionar um número de telefone que NÃO esteja em uso no app do WhatsApp comum, verificar por SMS/ligação, definir nome de exibição.
4. Business Settings → System Users → criar um usuário de sistema Admin, atribuir o app e a conta do WhatsApp (WABA) e gerar um token PERMANENTE com as permissões whatsapp_business_messaging e whatsapp_business_management. Nunca use o token temporário de 24h em produção.
5. Anotar: WABA ID, Phone Number ID, App Secret (App Settings → Basic) e criar um Verify Token aleatório longo.
6. Webhook: WhatsApp → Configuration → URL https://app.SEU-DOMINIO/api/webhooks/meta + Verify Token; assinar o campo "messages".
7. IMPORTANTE: assinar o app à WABA (POST /{WABA_ID}/subscribed_apps). Sem isso o webhook nunca dispara e não aparece erro nenhum.
8. Adicionar método de pagamento na Meta. Explique a cobrança por mensagem (marketing, utility, authentication; serviço dentro da janela de 24h) e que no Brasil a Meta cobra direto, sem margem de intermediário.
2.5 Vercel
1. Criar conta, conectar o repositório do GitHub (privado), importar o projeto.
2. Colocar as variáveis de ambiente no painel da Vercel (Production e Preview separadas). Nada de segredo com prefixo NEXT_PUBLIC_.
3. Apontar app.SEU-DOMINIO e ir.SEU-DOMINIO para a Vercel.
4. Ativar 2FA na Vercel e no GitHub.
2.6 VPS (só se eu quiser o módulo não oficial)
1. VPS Ubuntu LTS com 2 GB de RAM. Criar 2 GB de swap.
2. Endurecer o servidor ANTES de instalar qualquer coisa: login só por chave SSH, desligar senha e login de root, usuário sem privilégio com sudo, firewall (ufw) liberando só 22, 80 e 443, fail2ban, atualizações automáticas de segurança.
3. Docker + Docker Compose, container rodando como usuário não root, Caddy na frente com HTTPS em wa.SEU-DOMINIO.
4. O worker NÃO tem painel público: só aceita chamadas do app com token de serviço + HMAC (seção 7).
==================================================
3. ARQUITETURA
==================================================
- Multi-tenant desde o dia 1: toda tabela de negócio tem organization_id. Tabela organization_members (user_id, organization_id, role: owner | admin | operator | viewer). Uma função SQL `is_member(org_id, min_role)` usada em TODAS as policies.
- O navegador lê dados pelo Supabase com a chave publishable, sempre sob RLS. Toda escrita sensível, todo envio e toda chamada externa passam por rotas do servidor (Next.js Route Handlers / Server Actions) que validam a sessão, a organização e o papel do usuário.
- A chave secret do Supabase só existe no servidor e no worker. Nunca no bundle do navegador.
- Filas no banco (tabelas de jobs com status), não em memória. Assim nada se perde em deploy ou queda. Um job do pg_cron (via pg_net) chama a cada minuto uma rota protegida /api/cron/tick com um CRON_SECRET no header.
- Cada envio grava a linha "reservada" (status sending) com índice único ANTES de chamar o provedor. Se cair no meio, fica marcado como "incerto" em vez de mandar duplicado.
- Erro de banco é sempre 503 e o job volta pra fila. NUNCA tratar erro como "lista vazia" (já vi sistema anunciar "0 destinatários" porque o banco caiu).
- O PostgREST devolve no máximo 1.000 linhas por consulta: pagine toda leitura de contatos.
- Telefones normalizados em E.164 e com uma chave auxiliar que ignora o 9º dígito brasileiro (a Meta às vezes devolve o número sem o 9 e você perde os status de entrega).
- Nunca use ON DELETE CASCADE de números/sessões para mensagens e campanhas. Use SET NULL. Apagar um número não pode apagar o histórico.
==================================================
4. MÓDULOS (construa nesta ordem)
==================================================
4.1 Contatos (base de tudo)
- Contatos com nome, e-mail, telefone, tags, origem, consentimento (e-mail e WhatsApp separados, com data e origem do opt-in), opt-out por canal.
- Importação de CSV com prévia, mapeamento de colunas, deduplicação por e-mail e pela chave de telefone, relatório de linhas inválidas. Limite de tamanho do arquivo.
- Validação de e-mail e telefone no formulário de captura público (dado ruim custa alcance).
- Segmentos salvos (tags inclui/exclui, origem, data de entrada, engajamento).
- Lista de supressão global por organização: descadastro, bounce e spam valem para todas as campanhas.
4.2 E-mail marketing (substitui ActiveCampaign)
- Remetentes (nome, e-mail do domínio verificado, reply-to, endereço postal para o rodapé).
- Editor de campanha com HTML sanitizado no servidor (DOMPurify/sanitize-html), versão texto gerada automaticamente, prévia e envio de teste.
- Campanha: público congelado no momento do disparo (snapshot), agendamento, envio pelo Batch API do Resend em lotes de 100 com pausa entre lotes, limite diário por remetente que continua no dia seguinte.
- UM ponto único de envio que SEMPRE adiciona: rodapé de descadastro, endereço postal, headers List-Unsubscribe e List-Unsubscribe-Post: List-Unsubscribe=One-Click.
- Descadastro: token = e-mail + HMAC truncado (segredo próprio, nunca reaproveitar outra chave). GET mostra uma página de confirmação (robôs de antivírus abrem links); POST descadastra.
- Webhook do Resend: verificação Svix no corpo BRUTO, rejeitar sem assinatura, tolerância de 5 minutos no timestamp, idempotência pelo svix-id. Hard bounce e spam vão automaticamente para a supressão.
- Automações: sequências com etapas (espera X dias, envio em horário fixo no fuso de São Paulo, condição "abriu?/clicou?"). Ao inscrever, cria uma linha por etapa com índice único (inscrição, etapa). Supressão checada de novo na hora do envio.
- Relatórios: enviados, entregues, aberturas, cliques por link, bounces, descadastros.
4.3 WhatsApp API oficial (substitui ManyChat)
- Contas (WABA ID, Phone Number ID, token e app secret CRIPTOGRAFADOS, verify token).
- Sincronizar templates da Meta (nome, idioma, categoria, variáveis). Criar template pelo painel.
- Disparo: escolher template, mapear variáveis, público por segmento, agendamento. Validar o número de variáveis ANTES de enviar (evita o erro 132000). Pool de envio com concorrência configurável (padrão 20, reduzir se vier erro 130429).
- Webhook: responder 200 na hora e processar depois; exigir X-Hub-Signature-256 (HMAC-SHA256 com o app secret, corpo bruto, comparação em tempo constante). Sem header = rejeita. Status só avança (sent < delivered < read; failed só sobrescreve sent). Casar status com e sem o 9º dígito.
- CUSTO: gravar categoria e cobrança (campo pricing do webhook) de cada mensagem e mostrar um painel "quanto gastei com a Meta este mês" por categoria. Configurar o preço por mensagem em R$ por categoria.
- Opt-out por palavra-chave (SAIR, PARAR) que marca o contato e bloqueia novos disparos.
- Traduzir códigos de erro da Meta para mensagens humanas (ex.: 132015 = template pausado pela Meta).
- Inbox simples com a janela de 24h visível.
4.4 WhatsApp não oficial — disparo em massa (substitui PlugLead) [opcional, no worker]
- Conectar números por QR Code ou código de pareamento. Estado de autenticação salvo no banco, UMA LINHA POR CHAVE (um JSON gigante regravado a cada mudança derruba o banco). Reconexão com backoff exponencial. Não ativar sincronização do histórico completo (causa falta de memória).
- Campanha 1:1: lista, mensagem com {{variáveis}}, mídia, intervalo aleatório entre envios (padrão 15–40 s, mínimo 3 s), pausa longa a cada N mensagens, limite diário por número somando todas as campanhas, só uma campanha por número por vez.
- Aquecimento: limite diário progressivo para números novos (ex.: 20 → 40 → 80 → … por dia) configurável.
- Trava otimista por linha (pending → sending) para nunca enviar duas vezes. Status "aguardando" (automático) separado de "pausado" (manual). Pausar/cancelar responde em até 3 s.
- Aviso fixo na tela: "API não oficial viola os termos do WhatsApp e pode banir o número. Use com números aquecidos e só para quem pediu para receber. Volume grande vai pela API oficial."
4.5 Grupos de WhatsApp (substitui SendFlow) [no worker]
- Criar grupos em lote com prefixo e numeração (Grupo 01, 02…), foto quadrada, descrição, admins, só admins enviam.
- Campanha de grupos: linha do tempo de mensagens agendadas (texto, imagem, vídeo, áudio, arquivo, enquete), menção silenciosa a todos, intervalo entre grupos, 3 tentativas com backoff, registro por (mensagem × grupo).
- Rotação automática: quando um grupo passa do limite (ex.: 250), RESERVAR primeiro (marca full_handled_at) para não criar dois, criar o próximo com o número seguinte, copiar foto/descrição/admins, incluir na campanha e trocar o link de convite no encurtador. Se falhar, libera a reserva e tenta no próximo evento.
- Contar entradas e saídas por evento e por uma verificação periódica a cada 15 min.
4.6 Encurtador, redirect e deeplink (substitui Switchy)
- Links em ir.SEU-DOMINIO/slug, com destino único ou vários destinos em rodízio (round-robin).
- Rodízio ATÔMICO numa função SQL (UPDATE … RETURNING), nunca ler-e-gravar no Node.
- "Fixo por pessoa": cookie por slug (30 dias) para quem clica de novo cair no mesmo grupo e não gastar uma vaga.
- Resposta 302 com Cache-Control: no-store.
- Registro de cliques: data, slug, destino, país, tipo de dispositivo, origem (UTM), SEM guardar IP completo (guarde um hash com sal diário, por LGPD).
- Deeplink: detectar o user-agent e abrir o app nativo quando possível, com fallback para a versão web:
- Instagram (perfil/post), YouTube (vídeo/canal), WhatsApp (wa.me com texto), Telegram.
- Android: intent:// com package e browser_fallback_url. iOS: esquema do app com fallback por tempo.
- Detectar navegadores internos (Instagram, Facebook, TikTok) e oferecer "abrir no navegador".
- Testar em iPhone e Android de verdade antes de dar como pronto.
- Painel de cliques por link e por destino.
==================================================
5. BLINDAGEM DE SEGURANÇA (obrigatório, não negociável)
==================================================
Acesso
- Negar por padrão: TODA rota de API exige sessão válida. Rotas públicas ficam numa lista explícita e curta (health, /r/slug, webhooks, formulário público de captura, descadastro). Nova rota sem estar na lista = protegida.
- Em cada rota: validar a sessão no servidor (supabase.auth.getUser, nunca confiar só no cookie), checar que o usuário pertence à organization_id do recurso e tem o papel necessário. Testar IDOR: usuário da organização A nunca lê nem altera nada da B, mesmo trocando IDs na URL.
- Papéis ficam em tabela própria ou app_metadata, NUNCA em user_metadata (o usuário consegue editar).
- Cadastro público desligado; entrada só por convite com link de uso único e validade curta. 2FA obrigatório para owner/admin.
- Sessão em cookie httpOnly, Secure, SameSite=Lax. Verificar Origin em toda requisição que altera dados (CSRF).
- Nunca usar segredo padrão no código ("fallback secret"). Se uma variável obrigatória faltar, o app NÃO sobe (validar o env com zod na inicialização).
Banco (Supabase)
- RLS ligado em 100% das tabelas, sem nenhuma policy "using (true)" e sem acesso para o papel anon. Escrever as policies com is_member().
- Segredos de integrações (chaves do Resend, tokens da Meta, app secret) guardados CRIPTOGRAFADOS (Supabase Vault ou AES-256-GCM com chave em variável de ambiente) e NUNCA devolvidos ao navegador. O front lê uma view sem as colunas secretas e só vê "••••1234".
- Funções SQL com SECURITY DEFINER só quando indispensável, com search_path fixo e checagem de permissão dentro.
- Storage com buckets PRIVADOS e URLs assinadas de curta duração. Validar tipo e tamanho de arquivo no servidor. Nada de upload anônimo.
- Rodar o Security Advisor e o Performance Advisor do Supabase a cada migration e zerar os alertas críticos.
Webhooks e integrações
- Todo webhook (Meta, Resend, worker): corpo bruto + HMAC + comparação em tempo constante + rejeitar sem assinatura + tolerância de tempo + idempotência por ID do evento. Responder rápido e processar em fila.
- Worker não oficial: só aceita chamadas com token de serviço + assinatura HMAC + timestamp; nenhuma rota aberta; CORS fechado; o app nunca expõe a URL do worker para o navegador.
- Qualquer busca de URL externa (mídia, prévia de link) bloqueia IPs internos e metadata de nuvem (proteção contra SSRF).
Entradas e saídas
- zod em toda entrada; limites de tamanho em texto, listas e arquivos.
- Escapar HTML em tudo que vem do usuário e entra em e-mail ou na tela (XSS). Sanitizar o HTML do editor no servidor.
- Escapar % e _ em buscas com LIKE/ILIKE. Nunca montar SQL por concatenação.
- Encurtador: aceitar só destinos http/https; bloquear javascript:, data:, file: e redirecionamento para o próprio encurtador em loop.
Limites e abuso
- Rate limit por IP e por usuário (tabela no Postgres com janela deslizante, sem serviço pago): login, formulário público, descadastro, criação de link, webhooks.
- Formulário público com honeypot e limite por IP.
- Bloqueio temporário após várias falhas de login.
Infra e cabeçalhos
- Headers: Content-Security-Policy restritiva, Strict-Transport-Security, X-Frame-Options DENY, X-Content-Type-Options nosniff, Referrer-Policy strict-origin-when-cross-origin, Permissions-Policy.
- HTML do painel com Cache-Control no-store; service worker (se houver) nunca guarda páginas autenticadas.
- Dependências fixadas com lockfile; rodar npm audit; GitHub com Dependabot e secret scanning ligados; gitleaks no pre-commit.
Logs, auditoria e LGPD
- Logs sem senha, token, chave ou conteúdo de mensagem. Mascarar e-mail e telefone.
- Tabela audit_log: quem fez o quê e quando (login, convite, exportação, disparo, alteração de chave, exclusão).
- Exportar e apagar dados de um contato a pedido (LGPD). Guardar a prova de consentimento.
- Backup: plano Pro do Supabase + export semanal criptografado. Me ensinar a restaurar.
==================================================
6. BANCO DE DADOS (base mínima, ajuste se precisar)
==================================================
organizations, organization_members, invites, audit_log, rate_limits,
contacts, contact_tags, segments, suppressions,
email_senders, email_campaigns, email_recipients, email_sends, email_events, email_sequences, email_sequence_steps, email_enrollments,
wa_accounts, wa_templates, wa_broadcasts, wa_sends, wa_webhook_events, wa_costs,
wa_sessions, wa_session_keys, wa_bulk_campaigns, wa_bulk_targets,
wa_groups, wa_group_campaigns, wa_group_messages, wa_group_sends, wa_group_members,
links, link_targets, link_clicks,
jobs (fila genérica: tipo, payload, status, tentativas, próximo_em, erro).
Todas com organization_id, created_at, updated_at, RLS e índices nas colunas de filtro.
==================================================
7. COMUNICAÇÃO APP ↔ WORKER
==================================================
- O app chama o worker por HTTPS com header Authorization: Bearer WORKER_TOKEN + X-Signature (HMAC do corpo + timestamp). O worker rejeita qualquer coisa fora disso.
- O worker avisa o app (entrada em grupo, status, QR code novo) por webhook assinado do mesmo jeito.
- Grupos e disparo não oficial rodam em processos separados se o volume crescer (a criptografia de grupos do Baileys trava o loop de eventos por minutos).
- Health check + alerta por e-mail se nenhum número estiver conectado ou se o container reiniciar em loop.
==================================================
8. PAINEL
==================================================
- Visão geral: envios do mês por canal, custo do mês (Resend, Supabase, Meta), números conectados, próximos disparos agendados.
- Menus: Contatos, E-mail, WhatsApp Oficial, WhatsApp Não Oficial, Grupos, Links, Configurações (integrações, equipe, segurança).
- Tudo em português do Brasil, responsivo, com estados vazios explicando o próximo passo.
==================================================
9. ANTES DE IR PARA PRODUÇÃO: TESTE DE INVASÃO
==================================================
Rode e me mostre o resultado de cada um destes ataques contra o próprio sistema (em ambiente de teste):
1. Ler cada tabela usando só a chave publishable, sem login. Esperado: nada.
2. Chamar cada rota da API sem login. Esperado: 401 (exceto a lista pública).
3. Logado na organização A, tentar ler/editar/apagar recursos da B trocando IDs. Esperado: 403/404.
4. Mandar webhooks falsos (sem assinatura, assinatura errada, timestamp velho, evento repetido). Esperado: rejeitado ou ignorado.
5. Colocar <script> e HTML malicioso no nome do contato, no assunto e no editor. Esperado: nada executa.
6. Criar link curto para javascript: e para um IP interno. Esperado: bloqueado.
7. 50 tentativas de login erradas seguidas. Esperado: bloqueio temporário.
8. Procurar segredos no bundle do navegador (buscar por sb_secret, re_, EAA, whsec). Esperado: nenhum.
9. Rodar o Security Advisor do Supabase. Esperado: zero críticos.
10. No worker: chamar qualquer rota sem token/HMAC. Esperado: 401.
Só considere pronto quando os 10 passarem.
==================================================
10. ORDEM DE ENTREGA
==================================================
Fase 0 contas → Fase 1 base (auth, organizações, RLS, convites, auditoria, rate limit, headers) → Fase 2 contatos → Fase 3 e-mail → Fase 4 WhatsApp oficial + custos → Fase 5 encurtador + deeplink → Fase 6 worker (não oficial + grupos), se eu quiser → Fase 7 testes de invasão → Fase 8 deploy e checklist final.
No fim de cada fase: me diga o que foi feito, como testar com as minhas mãos, e o que ficou pendente.
Comece pela Fase 0: me faça as perguntas que precisar (nome do projeto, domínio, se quero o módulo não oficial) e depois me guie pelo Supabase.
Como usar: crie uma pasta vazia, abra o Claude Code dentro dela, cole o prompt inteiro e responda às perguntas da Fase 0.
O disparo pela API não oficial viola os termos do WhatsApp e pode banir o número. Use só com números aquecidos e com quem pediu para receber. Mande volume grande pela API oficial e respeite a LGPD.