vek1 — gotchas
Gotchas e armadilhas
Numeração estável; resolvidos ficam riscados com referência ao PR/commit que fixou.
Resolvidos pré-2026-05-20
README/CHECKLIST mentem sobre stack de testes✅ PR #40 (Jest → Vitest)Typo✅ PR #33NEXT_PUBLIC__EVOLUTION_API_KEY(2 underlines)✅ rota deletada em PR #43NEXT_PUBLIC_OPENAI_API_KEYvaza no client✅ rota deletada PR #38api/documents/route.tsfiltra coluna inexistenteDuas regras divergentes "1 agente ativo por store"✅ centralizado no vek1-api (PR #66+)✅ agora thin shim apiClient (PR #70)lib/supabase.tsviola padrão Server Actions✅ PR #36useCompanyProfiledesloga em qualquer erro✅ unificado em apiClient PR #67/#69useCreateAgentcaminho real, não Server Action✅ Drizzledocuments.embeddingtipo erradovector(1024)corretoMúltiplos clients Supabase paralelos✅ Supabase removido- Lock files duplicados versionados — continua (
bun.lock+package-lock.json) ✅ Supabase removidoSUPABASE_PROJECT_IDnão documentada✅ PR #34/instance-settingsna whitelist públicaPPR sem Suspense✅ PR #39 + #41 (Cache Components)Landing hydration bug✅ PR #35- Pricing landing ≠ pricing real — landing tem R$199/99/49 hardcoded; spec billing tem Starter R$79/Pro R$299/Business R$899. Drift até billing ser implementado.
✅ PR #38/agents/test/[id]duplicata morta- Componentes soltos em
components/raiz — convençãocomponents/[feature]/violada por ~25+ arquivos. Continua. permanece — Drizzle define text livre; app convenção (messages_history.rolesem CHECKuser|assistant|tool|debug). Tolerado.Trigger bucket via INSERT em✅ Supabase removidostorage.bucketsApenas uma migration versionada→ mudou: zero migrations versionadas;db:push --forcedireto. Risco de drift entre dev/prod resolvido por agentschema-migrator.Sem✅ PR #37.env.example- Wizard upload erro handling fraco — continua (falha em batch upsert mostra inline, user pode perder ao mudar de step). Tech debt.
removida no PR #43product_documentsvestigialremovida no PR #43product_eventsnão plugadaNext 16✅ PR #42middleware.ts→proxy.ts
Novos (pós-cutover api-first)
27. DATABASE_URL via TCP plaintext
Senha do Postgres trafega em texto claro pela internet entre Vercel e VPS (porta 5434, sslmode=disable). Risco real. Pendente TLS (cert + key + pg_hba, ou PgBouncer/nginx stream TLS).
28. db:push --force dropa indexes não-Drizzle
hnsw vector indexes (documents.embedding, leads.profile_embedding) e unique constraints custom (leads (store_id, channel, external_id)) NÃO são definidos no schema Drizzle — Drizzle dropa em push destrutivo. Sempre rodar scripts/recreate-indexes.ts + re-aplicar init/01-init.sql (do repo vek1-api) após push. Agent schema-migrator cuida.
29. Better Auth manda camelCase, Pydantic exige snake_case
auth-http-adapter.ts converte com snakeKeys (out) + camelKeys (in) recursivamente. Se um campo novo for adicionado e endpoint vek1-api esperar camelCase (bug Pydantic), 422 silencioso. Sempre testar fluxo end-to-end de auth quando alterar shape.
30. Better Auth updateMany precisa de filtro manual
updatePassword chama updateMany(account, where=[userId, providerId='credential']). findManyRows retorna TODOS accounts do user (por userId só); filtragem pelo providerId é feita no adapter (30e1afa). Se outro provider for adicionado, validar lógica.
31. Verification reset-password usa findMany, não findOne
Better Auth chama findMany (não findOne) pra lookup de verification token no reset-password (e6c6ff0). Mapeamento findManyRows(verification) cobre identifier E value — se adicionar outro use case, alinhar.
32. LID privacy WhatsApp v2.3.x
Mensagem WhatsApp pode chegar com remoteJid em formato LID (*@lid) em vez de telefone real (*@s.whatsapp.net). Telefone real está em senderPn (PR #53) ou key.remoteJidAlt (PR #56). whatsapp-handler.ts tem fallback chain — se Evolution mudar shape de novo, ver agent evolution-debugger.
33. LLM hallucina product_id como slug
sales_assistant às vezes inventa product_id baseado em slug do produto. vek1-api create_order valida items contra products table e DROPA (fix(orders): drop fake product_ids before insert (FK 23503) — PR #60). Order pode terminar sem nenhum item se LLM hallucinou tudo. Prompt foi reforçado mas não 100%.
34. agents.stripe_product_id zumbi
Coluna no schema desde início, nunca preenchida. Mantida pra futuro billing. Não usar até spec Stripe ser implementada.
35. client-stats mock parcial
/client-stats ainda usa lib/mock-data.ts. Dados reais demandam billing implementado pra ter sentido de "cliente paga". Tolerado por enquanto.
36. Single OpenAI SDK 5 nas deps mas sem uso
Sobra do PR #43 cleanup. Backend (vek1-api) usa SDK Python direto contra DeepSeek; frontend não precisa. Remover em próxima limpeza de deps.
37. Lock files triplicados continuam
Pre-existing. bun.lock + package-lock.json (+ possivelmente pnpm-lock.yaml). CI usa Bun; devs em npm/pnpm causam churn de locks em PRs. Ideal: deletar package-lock.json + pnpm-lock.yaml, gitignore.