- Migración 0011: leads.bot_step (TEXT) = paso actual de la conversación del bot (Luisa), para verlo en el panel y poder retomar chats cortados. TEXT (no enum) para que el bot evolucione su vocabulario sin migración. - docs/handoff-whatsapp-simon.md: spec de integración del bot (DB única, lead desde el form, reparto DB-directa vs EP, tablas que escribe, alineación de enums/tipos a los nuestros, bot_step, webhooks y conectividad). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
5.2 KiB
Handoff WhatsApp (Luisa) — para Simón
Cómo integra el bot de WhatsApp con la app Reformix. Una sola base de datos (la de la app;
Postgres). El lead se crea siempre desde el form web, así que cuando el cliente elige WhatsApp
el lead ya existe y te pasamos su leadId. No creas leads tú.
1. Cómo arranca tu flujo
Cuando el cliente elige "WhatsApp" en el funnel, la app hace POST al webhook
WHATSAPP_START_WEBHOOK_URL (lo configuras tú y nos lo pasas) con:
{ "leadId": "uuid", "telefono": "+34...", "nombre": "...", "empresa": "Reformas Ejemplo" }
A partir de ahí Luisa escribe al telefono y trabaja siempre con ese leadId.
2. Reparto: qué escribes en la DB directamente vs qué mandas por el EP
| Acción | Cómo |
|---|---|
| Historial del chat, calificación, intentos, jobs, estado del bot | DB directa (tus tablas, ver §3) |
| Subir fotos del cliente + notas/datos que extraes | EP POST /api/leads/:id/ingesta |
| Señalar "perfil completo" / devolver renders / cerrar y entregar | EP (flags perfilCompleto / finalizar) |
Por qué el EP para fotos/cierre: ahí se dispara nuestra lógica (motor de presupuesto, PDF,
email, señales). Si escribieras lead_fotos a mano, esa lógica no corre. Doc del EP:
mvp/b2c/api-docs/README.md. Auth: Authorization: Bearer <FUNNEL_API_KEY>.
3. Tablas que escribes directamente (ya creadas en la DB única)
conversacion_whatsapp— un registro por turno:lead_id,rol(user/assistant/system),mensaje,media_type,media_url,transcripcion_audio.intentos_contacto—lead_id,canal(whatsapp),resultado,completado,numero_intento,duracion_seg.lead_calificacion— 1 por lead:lead_id(único),score(0-100),nivel(A/B/C/D),criterios(jsonb).worker_jobs— cola async si la usas:tipo(analisis_fotos/render/presupuesto_ia),estado_job,payload,webhook_url.leads(UPDATE sobre el lead existente), columnas que te tocan:bot_step(TEXT) — paso actual de la conversación (ver §5).estado_wa— entrega del mensaje (sin_enviar/enviado/entregado/leido/fallido). No es el paso de la conversación.- Extracción en crudo:
espacio,rango_m2,estilo,presupuesto_declarado(TEXT),viable(boolean),fotos_solicitadas_at(timestamp),canal_origen. - Datos normalizados para el presupuesto:
tipo_reforma,m2_suelo,calidad_global,urgencia,presupuesto_target,taste_text.
Los
idse autogeneran (gen_random_uuid()); no llames auuid_generate_v4()en SQL (esta DB no tiene la extensiónuuid-ossp).
4. Enums y tipos: usa NUESTROS valores (esto es lo que hay que alinear en el bot)
Tu esquema reformix-full tenía otros valores. En la DB única mandan estos:
tipo_reforma → cocina · bano · salon · comedor · integral · otro
oficina/local/otros → usa otro.
urgencia → alta · media · baja (tu inmediata → alta).
lead_estado → nuevo · contactado · visita_agendada · presupuesto_enviado · ganado · perdido
en_proceso/calificado → contactado; cliente → ganado; archivado → perdido.
pipeline_stage → no lo escribas. Lo gestiona nuestro funnel/EP automáticamente.
Tipos: estructural = boolean (no texto). calidad_global = enum basica/media/premium (no 1-10; la extracción cruda de calidad va en estilo/taste_text).
5. bot_step (estado de la conversación de Luisa) — NUEVO, persistido
Columna leads.bot_step (TEXT, nullable). Guarda el paso actual para verlo en el panel y poder
retomar si el chat se corta. Valores sugeridos (puedes ajustar el vocabulario, es TEXT):
apertura → espacio → tamano → estilo → urgencia → presupuesto → pide_fotos → fotos_recibidas → completado
Terminales: no_viable, abandonado.
6. Webhooks salientes de la app (los recibes/encadenas tú)
WHATSAPP_START_WEBHOOK_URL— inicio (§1).PERFIL_WEBHOOK_URL— cuando se marcaperfilCompleto, te llega toda la data por zona para generar renders/agente (payload en api-docs §webhooks).WHATSAPP_WEBHOOK_URL— entrega: cuando el PDF está listo, te llega{ pdfBase64, telefono, ... }para mandarlo por WhatsApp.
Pásanos las 3 URLs y las ponemos en producción (Dokploy).
7. Lo que hace la app sola (no lo dupliques)
pipeline_stage, cálculo del presupuesto orientativo, generación del PDF y envío del
email los hace la app cuando llamas al EP con finalizar. Tú aportas fotos/notas y el estado
de la conversación; nosotros producimos el entregable.
8. Conectividad (ops)
La DB es el Postgres de la app en Dokploy (host interno reformix-db-…). Si tu bot corre en la
misma red de Dokploy puede conectarse directo; si es externo, hay que exponer credenciales/host.
Decidir con Carlos. Para el EP solo necesitas la URL pública + FUNNEL_API_KEY.
Resumen de lo que necesito de ti (Simón): (1) las 3 URLs de webhook, (2) confirmar que el bot usa nuestros enums/tipos (§4), (3) cómo te conectas a la DB (directo en red Dokploy o externo).