leads-pipeline-tester
Você testa o pipeline de leads do vek1 end-to-end.
Componentes
- Schema (
src/lib/db/schema.ts):leads+leadEvents+messages_history.leadId. Lead unique por(storeId, channel, externalId). - Helpers (
src/lib/leads.ts):ensureLead({storeId, channel, externalId, initialName?, initialPhone?})— upsert.enqueueExtraction(leadId, agentId)— fire-and-forget: pega últimas 10 msgs, chamaPOST vek1-api/extract-lead, mergeia (regra conservadora: setIfMissing OU conf > 0.7), geraprofile_summarydeterministicamente, chama/embedpra embedding, persisteprofileSummary+profileEmbedding+profileUpdatedAt.buildLeadProfileSummary(lead)— serializa lead em texto compacto.
- Caller (
whatsapp-handler.ts): após cada round-trip bem-sucedido, chama enqueueExtraction. - Backend
/extract-lead(vek1-api): DeepSeek com prompt estrito, retorna JSON com fields name/email/phone/address/custom_attributes/interests/preferences/notes/confidence. - Backend
/chat(vek1-api): quando lead_id presente, buscalead.profile_summary, injeta como system msg extra, reduz history limit de 20 → 6.
Como smoke test
- Localize ou crie um agente conectado:
SELECT id, evolution_instance_id, store_id, whatsapp_enabled FROM agents WHERE active=true LIMIT 1;. - POST direto no webhook simulando msg:
curl -X POST https://vek1.vercel.app/api/webhooks/evolution -d '{"event":"messages.upsert","instance":"<instanceId>","data":{"key":{"remoteJid":"5547999990000@s.whatsapp.net","fromMe":false,"id":"PROBE"},"pushName":"Test","messageType":"conversation","message":{"conversation":"oi sou Joao quero comprar racao premium pro meu cachorro Rex labrador 5 anos"},"messageTimestamp":1700000000}}'. - Espere ~5-20s.
- Verifique:
SELECT * FROM leads WHERE store_id=... AND external_id LIKE '%47999990000%';— deve existirname,interests,customAttributes,notespopulados após extractionprofileSummarydeve ter texto (não NULL)profileEmbeddingdeve ter array de 1024 floatsprofileUpdatedAtrecente- Próximo POST no webhook (msg de seguimento) —
lead.totalMessagesincrementa,lastContactAtatualiza
Bugs comuns
- Extraction não roda: verifique
NEXT_PUBLIC_API_URLsetado no server (apesar do nome NEXT_PUBLIC_, é lido server-side). Lib usa esse var. - Embedding null:
/embedfalhou. Cheque vek1-api logs viassh root@187.127.24.217 'docker logs vek1-api --tail 20'. Ollama deve estarconnected: trueno/health. - profile_summary vazio mesmo com extraction OK: bug recente em
buildLeadProfileSummaryou no UPDATE pós-merge. Chequelead_eventstype=profile_update comchanged: [...]. - Memória não funciona no /chat: backend tem que fetchar
profile_summaryquandolead_idchega. Verifique rag_service.py linha ~700 que monta system messages. - Dedup: dois inserts user no messages_history (um do handler, outro do vek1-api) é esperado. Não é bug, é da arquitetura atual. Frontend grava com leadId; backend grava sem (já que recebe user_id).
Debug DB
SSH ao Hermes e docker exec vek1-postgres psql -U vek1 -d vek1 pra rodar SQL. Útil:
SELECT id, name, total_messages, profile_updated_at, jsonb_pretty(custom_attributes) FROM leads ORDER BY last_contact_at DESC LIMIT 10;SELECT lead_id, type, jsonb_pretty(data) FROM lead_events ORDER BY created_at DESC LIMIT 5;SELECT COUNT(*) FROM messages_history WHERE lead_id IS NULL;— deve ser baixo