Prepara deploy de Luisa + image-worker: Dockerfiles + GET endpoints

- Dockerfiles multistage (node:20-alpine) + .dockerignore para mvp/Whatsapp-bot
  (expone 3000+3001, persiste prompts) y mvp/image-worker (expone 3001).
- Añade los 2 GET que el bot necesita y faltaban en la API:
  GET /api/leads/:id (estado del lead) y GET /api/leads/:id/conversacion (historial).
- Limpia el package.json/lock de la raíz (baileys colado por error; no es workspace).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Carlos Narro
2026-06-08 10:36:14 +02:00
parent 25669f3008
commit d34925cd7f
8 changed files with 111 additions and 748 deletions

View File

@@ -1,13 +1,29 @@
import { eq } from 'drizzle-orm';
import { db } from '@/db';
import { leads, conversacionWhatsapp } from '@/db/schema';
import { jsonResponse } from '@/lib/api/funnel-auth';
import { autorizado, jsonResponse } from '@/lib/api/funnel-auth';
import { validarBotRequest } from '@/lib/api/bot-request';
import { conversacionSchema } from '@/lib/funnel/bot-schemas';
export const runtime = 'nodejs';
export const dynamic = 'force-dynamic';
// Historial de la conversación de WhatsApp (orden cronológico) para que el bot recupere el contexto.
export async function GET(req: Request, { params }: { params: Promise<{ id: string }> }) {
if (!autorizado(req)) return jsonResponse({ ok: false, error: 'No autorizado.' }, 401);
const { id } = await params;
const turnos = await db
.select({
rol: conversacionWhatsapp.rol,
mensaje: conversacionWhatsapp.mensaje,
createdAt: conversacionWhatsapp.createdAt,
})
.from(conversacionWhatsapp)
.where(eq(conversacionWhatsapp.leadId, id))
.orderBy(conversacionWhatsapp.createdAt);
return jsonResponse(turnos, 200);
}
// Añade un turno de la conversación de WhatsApp al historial del lead, y opcionalmente actualiza
// el estado del mensaje (estado_wa) y el paso del bot (bot_step) en el lead.
export async function POST(req: Request, { params }: { params: Promise<{ id: string }> }) {

View File

@@ -0,0 +1,34 @@
import { eq } from 'drizzle-orm';
import { db } from '@/db';
import { leads } from '@/db/schema';
import { autorizado, jsonResponse } from '@/lib/api/funnel-auth';
export const runtime = 'nodejs';
export const dynamic = 'force-dynamic';
// Estado del lead para el bot de WhatsApp: le permite retomar la conversación (botStep, viabilidad,
// extracción en crudo) tras un reinicio sin perder contexto. Devuelve el objeto plano (no envuelto).
export async function GET(req: Request, { params }: { params: Promise<{ id: string }> }) {
if (!autorizado(req)) return jsonResponse({ ok: false, error: 'No autorizado.' }, 401);
const { id } = await params;
const [lead] = await db
.select({
id: leads.id,
nombre: leads.nombre,
telefono: leads.telefono,
botStep: leads.botStep,
estadoWa: leads.estadoWa,
espacio: leads.espacio,
rangoM2: leads.rangoM2,
estilo: leads.estilo,
presupuestoDeclarado: leads.presupuestoDeclarado,
viable: leads.viable,
})
.from(leads)
.where(eq(leads.id, id))
.limit(1);
if (!lead) return jsonResponse({ ok: false, error: 'Lead no encontrado.' }, 404);
return jsonResponse(lead, 200);
}