Status: sessão de 26/04 fechou os 7 ALTOS + BAIXOS rápidos + welcome email. Restam: 1 bloqueador (Stripe key) + 9 MÉDIOS + 2 itens estratégicos. Detalhes técnicos completos em auditoria-pre-launch-2026-04-26.mdx.
🚨 BLOQUEADOR — antes do launch público
Rotacionar Stripe live keys
Onde está vazado:SETUP_QUANDO_VOLTAR.md:13-14 (committed em 147fb2d, está no git history).
Plano combinado: rotacionar DEPOIS de fazer 1 teste de compra real, pra não quebrar o fluxo de validação.
Passo a passo (você faz):
- Stripe Dashboard → API Keys → roll do
STRIPE_SECRET_KEYlive - Stripe Dashboard → Webhooks → roll do
STRIPE_WEBHOOK_SECRET - Atualizar ambos no Supabase Edge Functions Secrets
- Confirmar via curl que a chave antiga foi rejeitada
- Me chamar pra deletar
SETUP_QUANDO_VOLTAR.mde reescrever git history (BFG ougit filter-repo)
📋 9 MÉDIOS — atacar amanhã (27/04/2026, ~3-4h)
Sugestão de ordem por impacto + tempo:Lote 1 — quick wins (~30min)
1. Habilitar Leaked Password Protection (1 click no Supabase)- Supabase Dashboard → Auth → Policies → “Leaked password protection”
- Sem código. Sem custo. Bloqueia signups com senhas comprometidas (HaveIBeenPwned).
pg_net pro schema extensions
- Validar antes que cron jobs de mensalidades reminder não quebram (eles usam
pg_net.http_post).
rate_limit_log
- Hoje RLS habilitado, zero policies → tabela inacessível por user (correto), mas Supabase advisor flagged.
- Adicionar
CREATE POLICY "deny_all" ON rate_limit_log FOR ALL USING (false);+ comentário SQL explicando intenção.
Lote 2 — refactors (~1h)
4. CentralizarPLAN_LIMITS (eliminar duplicação 3-way)
- Hoje espalhado em:
lib/constants.ts:30(só OFX_IMPORTS_PER_MONTH)hooks/use-subscription.ts:27-61(PLANS completo com pricing)app/crypto/_actions/crypto-actions.ts:34(PLAN_LIMITS hardcoded)
- Criar
lib/plans.tsúnico com tipoPlanKey+getLimitsFor(plan). Remover duplicações.
app/cartoes/_actions/ofx-actions.tslinhas 307, 407, 416, 426, 602, 611, 695, 709, 843- Substituir
userIdpor hash, valores por contadores ({ count: N }), nomes de assinaturas (Netflix/Spotify) por categorias agregadas. - Política de privacidade promete “sem dados de transações em logs públicos” — atual viola.
Lote 3 — security hardening (~1.5h)
6. CSRF em admin actions- Confirmar
serverActions.allowedOriginsestá configurado emnext.config.js - Adicionar test de regression que dispara
resetPasswordde origem externa e espera reject
app/cartoes/_actions/ofx-actions.ts:79-98(assertMonthlyLimit) eapp/crypto/_actions/crypto-actions.ts:34-76(assertUnderLimit)- Hoje: SELECT count → check → INSERT (3 etapas, race possível em paralelo)
- Fix: RPC PostgreSQL com
SELECT ... FOR UPDATEna mesma transaction, ou unique constraintUNIQUE(user_id, date_trunc('month', created_at)).
components/auth-provider.tsx:116: hojesignOut({ scope: 'local' })só limpa client- Adicionar server action que chama
supabaseAdmin.auth.admin.signOut(userId, 'global')em background depois do local signOut. Sem bloquear UX.
middleware.ts:46-58faz timeout 5s na RPCis_super_admin(fail-closed, OK)lib/admin-auth.ts:15-19chama mesma RPC SEM timeout — pode pendurar action- Adicionar
Promise.racecom timeout 10s + throwAdminAuthError('FORBIDDEN')
🔍 ALTOS pendentes da sessão de 26/04
Estes ALTOS do relatório original ficaram para depois e merecem atenção:A5. Edge Runtime warnings em @supabase/ssr
Build mostra:
@supabase/ssr@^0.7.0 (atual) tem fix. Se não, considerar pin em versão alternativa ou aceitar risco e monitorar Sentry.
A8. Silent failures padrão
Catches que só fazemconsole.warn/console.error sem reportar pra Sentry:
lib/email.ts:27-37— Resend cair em prod = só descobre quando user reclamalib/auth.ts(várias) — credential stuffing invisívelapp/cartoes/_actions/ofx-actions.ts:404— assinaturas falham silenciosamente após gastos OK
✨ Estratégicos (não-bloqueantes pro launch)
Workspace invite por email
Hoje convite é link sharing puro (admin copia, manda manual). Pra wire o templateworkspace_invite do Resend, precisa:
- Adicionar campo email opcional no
WorkspaceInvitesPanel - Server action: gera invite + se email preenchido, dispara email
- Decisão de produto: email opcional (mantém compatibilidade) ou obrigatório (UX limpa, breaking)?
Stripe webhook emails
Templatespayment_received, payment_failed, subscription_canceled rodam na Edge Function Supabase do webhook do Stripe — fora do escopo do código Next.js.
Você precisa wire essas no código Deno do webhook. Onde olhar: Supabase Dashboard → Edge Functions → stripe-webhook (ou similar).
✅ O que JÁ foi feito hoje (26/04)
- 7 ALTOS: useMemo bug, sentry-example guard, env vars, open redirect, Sentry capture em error.tsx, server-only em supabase-admin, release+env Sentry
- BAIXOS limpos: pin next 15.2.4, escapes,
<img>→<Image>(7 instâncias), .gitignore + .vercelignore corrigidos - Welcome email: migration + server action idempotente + wire no /auth/callback
main: 8ca1d8f, 5c598fb, 0eed6c1, 7bf3e80.