// Smoke test de los EPs del bot de WhatsApp contra un entorno real. // Crea un lead de PRUEBA, ejerce los 4 EPs por HTTP, verifica las escrituras en la BD y borra // el lead (el cascade limpia las filas hijas). No toca leads reales. // // Uso (PowerShell): // $env:DATABASE_URL="postgres://..."; $env:BASE_URL="https://reformix.dv3.com.es"; $env:FUNNEL_API_KEY="..." // node mvp/b2c/api-docs/smoke-bot-eps.mjs // // DATABASE_URL solo hace falta para crear/verificar/limpiar el lead de prueba; el bot real // únicamente necesita BASE_URL + FUNNEL_API_KEY para usar los EPs. import postgres from 'postgres'; const { DATABASE_URL, BASE_URL, FUNNEL_API_KEY } = process.env; if (!DATABASE_URL || !BASE_URL || !FUNNEL_API_KEY) { console.error('Faltan env: DATABASE_URL, BASE_URL y FUNNEL_API_KEY son obligatorias.'); process.exit(1); } const sql = postgres(DATABASE_URL, { prepare: false }); async function api(path, body) { const r = await fetch(`${BASE_URL}${path}`, { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${FUNNEL_API_KEY}` }, body: JSON.stringify(body), }); const json = await r.json().catch(() => null); return { status: r.status, json }; } let leadId; let ok = true; const check = (label, cond, extra) => { ok = ok && cond; console.log(`${cond ? 'OK ' : 'FAIL'} ${label}${extra ? ` ${extra}` : ''}`); }; try { const [tenant] = await sql`select id, nombre from tenants limit 1`; if (!tenant) throw new Error('No hay tenants en la BD.'); console.log(`tenant: ${tenant.nombre} (${tenant.id})`); const inserted = await sql` insert into leads (tenant_id, nombre, telefono, email, tipo_reforma, consent_privacidad, consent_contratacion) values (${tenant.id}, 'TEST EP Bot (smoke)', '+34600000000', 'smoke-bot-ep@example.com', 'cocina', true, true) returning id`; leadId = inserted[0].id; console.log(`lead de prueba creado: ${leadId}\n`); const r1 = await api(`/api/leads/${leadId}/conversacion`, { rol: 'user', mensaje: 'Quiero reformar la cocina', estadoWa: 'leido', botStep: 'espacio', }); check('POST conversacion → 200', r1.status === 200, JSON.stringify(r1.json)); const r2 = await api(`/api/leads/${leadId}/perfil`, { tipoReforma: 'cocina', m2Suelo: 12.5, calidadGlobal: 'premium', urgencia: 'alta', viable: true, botStep: 'tamano', }); check('POST perfil → 200', r2.status === 200, JSON.stringify(r2.json)); const r3a = await api(`/api/leads/${leadId}/calificacion`, { score: 60, nivel: 'C', criterios: { fase: 'inicial' } }); check('POST calificacion #1 (insert) → 200', r3a.status === 200, JSON.stringify(r3a.json)); const r3b = await api(`/api/leads/${leadId}/calificacion`, { score: 82, nivel: 'A', notasAgente: 'Lead caliente' }); check('POST calificacion #2 (upsert) → 200', r3b.status === 200, JSON.stringify(r3b.json)); const r4 = await api(`/api/leads/${leadId}/intento`, { canal: 'whatsapp', numeroIntento: 1, resultado: 'exitoso', completado: true, metadata: { origen: 'smoke' }, }); check('POST intento → 200', r4.status === 200, JSON.stringify(r4.json)); console.log('\n— verificación en BD —'); const conv = await sql`select rol, mensaje from conversacion_whatsapp where lead_id=${leadId}`; check('conversacion_whatsapp: 1 turno', conv.length === 1, JSON.stringify(conv)); const [lead] = await sql` select tipo_reforma, m2_suelo, calidad_global, urgencia, viable, bot_step, estado_wa from leads where id=${leadId}`; check( 'leads(perfil): cocina/12.5/premium/alta/viable + bot_step=tamano + estado_wa=leido', lead.tipo_reforma === 'cocina' && Number(lead.m2_suelo) === 12.5 && lead.calidad_global === 'premium' && lead.urgencia === 'alta' && lead.viable === true && lead.bot_step === 'tamano' && lead.estado_wa === 'leido', JSON.stringify(lead), ); const calif = await sql`select score, nivel, notas_agente from lead_calificacion where lead_id=${leadId}`; check( 'lead_calificacion: 1 fila tras upsert, score=82 nivel=A notas conservadas', calif.length === 1 && calif[0].score === 82 && calif[0].nivel === 'A' && calif[0].notas_agente === 'Lead caliente', JSON.stringify(calif), ); const intentos = await sql`select canal, resultado, completado, numero_intento from intentos_contacto where lead_id=${leadId}`; check( 'intentos_contacto: 1 intento whatsapp exitoso completado', intentos.length === 1 && intentos[0].canal === 'whatsapp' && intentos[0].resultado === 'exitoso' && intentos[0].completado === true && intentos[0].numero_intento === 1, JSON.stringify(intentos), ); } finally { if (leadId) { await sql`delete from leads where id=${leadId}`; console.log(`\nlead de prueba borrado: ${leadId}`); } await sql.end(); } console.log(`\n${ok ? 'TODO OK ✅' : 'HAY FALLOS ❌'}`); process.exit(ok ? 0 : 1);