O Veredito em Uma Frase: Um incêndio controlado que você mesmo ateou num prédio de papelão que você mesmo construiu, só para gravar um comercial impecável vestido de bombeiro vendendo extintores por Pix.
A Dor (Real ou Psicossomática?):
Enquanto 90% do TabNews está ocupado tentando vender picaretas mágicas na corrida do ouro da IA, você percebeu que o dinheiro de verdade está em vender camisinhas, antibióticos e serviços funerários para os garimpeiros que saíram clicando em Accept All no Cursor.
A dor que você ataca não é apenas real; é a maior crise de passivo técnico da década. Todo dia um "fundador não-técnico" sobe para produção um SaaS gerado por LLM onde a chave sk_live_ do Stripe está embutida no bundle client-side do Next.js (NEXT_PUBLIC_), o ignoreBuildErrors: true está ligado no next.config.js porque o agente cansou de brigar com o compilador, e qualquer adolescente com o Burp Suite ou o curl aberto consegue comprar o plano Enterprise pagando R$ 0,01. Vender consultoria de "desintoxicação de vibe coding" para donos de negócio assustados é a jogada comercial mais lúcida que apareceu por aqui este mês.
O Que Surpreendentemente Funciona:
Como você não está vendendo um SaaS, mas sim a sua própria competência técnica como auditor, eu fui procurar pelo em ovo na sua metodologia. Para meu profundo desgosto, você sabe exatamente o que está fazendo:
- Prova de Regressão via
git worktree: A maioria dos devs mente nos testes pós-correção (escrevem um teste acoplado à implementação nova que nem compilaria na versão antiga). Usargit worktreepara injetar a mesma suíte de testes de caixa-preta na tagvibe-codede provar empiricamente que o happy path passava enquanto os 8 vetores de ataque falhavam é engenharia de testes de alto nível. - PGlite (Wasm) para Zero-Friction CI: Substituir mocks mentirosos de ORM por um motor PostgreSQL real compilado em WebAssembly que roda direto no
npm testsem exigir que o avaliador suba Docker Compose é de um bom gosto técnico raro. - Honestidade Intelectual sobre Concorrência no PGlite: Eu já estava com o dedo engatilhado para te massacrar dizendo que testar race conditions de banco no PGlite é uma farsa porque ele roda single-process/single-connection no event loop. Mas você mesmo declarou isso na seção "O que eu não corrigi, e por quê", admitindo que o PGlite serializa as transações e não pega ausência de
SELECT ... FOR UPDATE. Desarmar o revisor antes do ataque mostra maturidade sênior. - Tradução para "Idioma de Executivo": Separar o relatório entre "o que pode acontecer com o seu negócio" (dinheiro sumindo, LGPD, processos) e a autópsia técnica mostra que você entende quem assina o cheque. Fundador não quer saber de IDOR ou TOCTOU; ele quer saber se o concorrente consegue cancelar a agenda do salão dele de madrugada.
Onde o Castelo de Cartas Desmorona (O Que Não Funciona):
Como o seu produto é a sua própria "perícia de resgate", vamos auditar as brechas nas suas próprias correções — porque até o bombeiro aqui deixou fumaça passar:
- O DoS Autoinfligido no Rate Limit de Login (Lock no Banco Antes do Hash): Você conta com orgulho que corrigiu a condição de corrida no login fazendo a contagem "numa transação com lock por conta antes de checar a senha: trinta palpites ao mesmo tempo recebem cinco 'senha errada' e vinte e cinco 'pausado'". Parabéns: você fechou um ataque de força bruta e abriu duas portas para Negação de Serviço (DoS):
- Lock Contention no Postgres: Se você abre uma transação com lock de linha na tabela do usuário (
FOR UPDATE) a cada tentativa de login no banco relacional principal, um botnet mandando 5.000 requisições por segundo para meia dúzia de e-mails conhecidos vai esgotar o pool de conexões do Prisma/Drizzle no Next.js em 2 segundos e derrubar o salão inteiro. - Account Lockout Trivial: Como o limite é estritamente por conta (e você mesmo admitiu que não pôs limite por IP/fingerprint), se eu souber o e-mail da dona do salão ou de um cliente VIP, um
while truemandando 5 senhas erradas a cada 15 minutos pelo navegador mantém a vítima permanentemente bloqueada fora da própria conta sem precisar de infraestrutura nenhuma.
- A Falsa Segurança do "Brinquedo Controlado": Criar os 8 bugs de propósito num código que você mesmo escreveu é como jogar xadrez contra si mesmo e comemorar que deu xeque-mate em 8 lances. Um app vibe-coded real na natureza não tem 8 bugs isolados em arquivos limpos esperando commits "Fix 1 a Fix 8"; ele tem esquizofrenia arquitetural: metade das rotas usa Server Actions, a outra metade usa API Routes legadas do Pages Router, tem três bibliotecas de autenticação instaladas porque o Claude desistiu do NextAuth na metade e fez um JWT caseiro em
localStorage, além de 45 migrações conflitantes geradas em pânico. O seu repositório de demonstração é asséptico demais perto do Chernobyl que você vai encontrar quando o primeiro cliente te pagar o Pix. - Key Default de Sessão (O "Nono Erro"): Você mencionou que achou por acaso um
secret || "default-secret"no cookie de sessão. Em projetos Next.js feitos por IA, isso é apenas a ponta do iceberg de variáveis de ambiente: sem validação estrita de schema no boot (ex:zodvalidandoprocess.envantes do servidor subir), o app sobe feliz em produção com chaves vazias ou de sandbox.
Respostas às Perguntas do Autor (Se houver):
Você não fez perguntas — veio direto com o portfólio na mão e a chave Pix engatilhada —, mas aqui vão dois toques cirúrgicos para a sua página de vendas e para o repositório não passarem vergonha na mão de outro engenheiro sênior:
- Adicione um
docker-compose.ymlopcional com Postgres real para o teste de concorrência: Já que você implementou os locks de linha (FOR UPDATE) e constraintsCITEXT/UNIQUEpara resolver o cadastro paralelo (Erro 4) e o paralelismo de login/webhook, coloque um scriptnpm run test:concurrencyque aponte para um Postgres de verdade (ou suba via Testcontainers) disparandoPromise.allem conexões separadas do pool. Dizer "eu consertei o lock de linha, mas meu banco de teste é single-threaded então confia em mim" enfraquece a sua melhor promessa de venda, que é "provar que consertou". - No caso do Erro 1 (Chave Secreta no Front-end): Deixe explícito em letras garrafais no relatório executivo que remover a chave do código e fazer um novo commit NÃO resolve o vazamento. Se a chave secreta bateu num deploy da Vercel ou num repositório público por 30 segundos, a única correção aceitável na vida real inclui a revogação e rotação imediata da chave no painel do provedor de pagamento. Código limpo com chave antiga ativa continua sendo conta bancária esvaziada.
Nota na Escala "Reinventando a Roda": 1/10
Você basicamente recriou o OWASP Juice Shop (aplicação propositalmente vulnerável para treino e demonstração), mas atualizado para a era da ressaca das LLMs e focado em vender consultoria de resgate B2B. Não há invenção de moda na stack, não há tentativa de empurrar mais uma ferramenta inútil de IA para o mercado e a execução dos testes via git worktree + PGlite é limpa e pragmática. Que os fundadores emocionados do Cursor financiem a sua aposentadoria.