El bot (Luisa) es externo y no toca Postgres directamente. Cuatro endpoints
autenticados con Bearer FUNNEL_API_KEY, validados con zod:
- POST /api/leads/:id/conversacion → turno de chat (+ estado_wa/bot_step)
- POST /api/leads/:id/perfil → update parcial del lead (extracción)
- POST /api/leads/:id/calificacion → upsert de lead_calificacion
- POST /api/leads/:id/intento → registro en intentos_contacto
Helpers compartidos lib/api/funnel-auth.ts (autorizado + jsonResponse) y
lib/api/bot-request.ts (validarBotRequest: auth + JSON + zod + lead existe).
La ruta de ingesta se refactoriza para reutilizar funnel-auth (DRY).
Schemas puros en lib/funnel/bot-schemas.ts con tests, y doc en api-docs.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
POST /api/leads/:id/ingesta (Bearer FUNNEL_API_KEY): acepta items foto/texto
etiquetados por zona y momento, más flags perfilCompleto y finalizar.
- ingesta-schema.ts: zod del cuerpo (union discriminada foto|texto), exportado
para test; rechaza llamadas vacías.
- route.ts: auth 401, valida lead (404), inserta fotos (orden continúa el máx)
y notas, traza fotos_subidas; perfilCompleto→señalarPerfilCompleto,
finalizar→finalizarYEntregar.
- 10 tests del schema. Verificado por HTTP: 401/200/422/404 y finalizar genera
el pdf_url y avanza el lead a whatsapp_entregado.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>