Arregla 2 problemas del flujo de subir fotos desde el email:
- El enlace iba a /formulario (form completo) y al enviarlo re-ejecutaba
procesarLead, que VOLVÍA a llamar. Ahora el email apunta a /solicitud/[id]/fotos,
una página ligera (SubirFotos): solo sube fotos (+ nota opcional) al lead de la
URL, re-señala perfilCompleto y NO llama.
- Guarda en procesarLead: si el lead ya tiene llamada_completada, no se vuelve a
llamar (ni se pisa la transcripción real del webhook).
Copy de la página en COPY-GUIDE §3.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- retell.ts: la llamada saliente manda metadata.lead_id; helpers obtenerLlamada
(GET /v2/get-call, dato autoritativo) y descargarGrabacion (guarda el audio
en nuestro sistema como data URI).
- /api/retell/webhook: en call_analyzed/call_ended relee la llamada por call_id,
guarda la transcripción real en lead.transcripcion, descarga la grabación a
lead.audio_url y deja el análisis + duración en un evento de pipeline. Seguro
por re-fetch (no se fía del body del webhook).
- orchestrator/pedirLlamada: pasan leadId; procesarLead ya no guarda transcript
simulado cuando la llamada es real (lo rellena el webhook).
- La ficha del panel ya mostraba transcripción + audio: ahora se pueblan solos.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Prompt del agente de voz (Retell, en caliente + docs/retell-setup.md):
recuerda al cliente que envíe fotos del espacio por WhatsApp o por el enlace
del email, para que el render sea de su reforma.
- pedirLlamada: envía automáticamente el email con el enlace al formulario al
solicitar la llamada (antes solo con un botón manual), para que la frase del
agente "te enviamos un email" sea cierta. Best-effort.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Reescribe los emails del funnel (entrega del presupuesto + enlace al
formulario) con plantilla HTML mobile-first de una columna, dark mode, botón
"bulletproof" en tabla, tipografías de sistema y versión en texto plano.
- mailer.ts: construirEmailHtml/construirEmailText compartidos; acento en el
color de marca del reformista (resolveTheme) + logo si es URL absoluta; copy
con jerarquía y CTA orientado a resultado.
- finalizar.ts: pasa la marca del tenant y un CTA de contacto (wa.me del
reformista o mailto) al email de entrega.
- actions.ts: pasa la marca al email con el enlace al formulario.
- COPY-GUIDE §6.b: asuntos (+alternativas), preheader, headline y cuerpo
mejorados.
Probado: render visual (light) de ambos emails y envío real por SMTP.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Acerca el cálculo a tarifas de mercado sin rehacer el modelo lineal €/m²:
- Impermeabilización como partida propia en zonas húmedas (cocina/baño/integral)
- Extras fijos que no escalan con m²: boletín (siempre), tuberías (piso anterior
a 2000) y cambio de distribución (mover inodoro/ducha/bañera)
- Intensidad por tipo en fontanería/electricidad (baseline cocina) para que un
integral no escale como un baño
- Factor de zona por provincia en tramos (Madrid/BCN 1.40, islas 1.30, capitales
1.20, rural 0.85, resto 1.00)
- 2 preguntas nuevas en el formulario del cliente para disparar los extras
- Panel de precios: campo de impermeabilización + sección de extras fijos
- Seed recalibrado (mano de obra, extras, catálogo suelo/pared)
- Migración 0009 (leads.anterior_a_2000, leads.cambio_distribucion, pricing_config.extras)
- Tests del motor ampliados (impermeabilización, extras, intensidad por tipo)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Llamada (/llamada): "Llamar ahora" dispara la llamada saliente de Retell;
"Programar" registra fecha/hora. Tras pedir, ofrece enviar por email el
enlace al formulario para subir las imágenes.
- WhatsApp (/whatsapp): arranca la conversación vía webhook al flujo externo
(con el teléfono del lead) y pide confirmación; al confirmar, agradece y
sigue por WhatsApp.
- actions: pedirLlamada, enviarEnlaceFormularioEmail, iniciarWhatsapp,
confirmarWhatsapp.
Verificado en navegador: las 3 pantallas y sus transiciones.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Paso intermedio /solicitud/[id]: el cliente elige llamada, WhatsApp o
formulario (crearLead ahora redirige aquí, no a /fotos).
- /formulario: FormularioZonas permite añadir varias zonas, cada una con tipo,
m², acabado, notas y fotos; /fotos queda como redirect.
- guardarDetallesYFotos: guarda fotos (antes, por zona) y notas (por zona),
agrega los campos del lead (m² suma, tipo único o 'integral', calidad más
alta, tasteText concatenado) para el presupuesto orientativo inmediato, y
señala perfilCompleto al flujo externo.
- Elimina FotosUploader (sustituido por FormularioZonas).
Verificado en navegador: 2 zonas → presupuesto al instante + notas por zona +
evento de perfil en DB.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- / y /b2b sirven la landing B2B estática (rewrites beforeFiles)
- /{slug} resuelve el funnel del reformista (app/[slug]/page.tsx) con
branding propio (TenantBrand) y atribución de leads por tenant
- crearLead(slug) y páginas /solicitud usan el tenant del lead
- Panel: edición del slug del funnel + URL pública en /panel/empresa
- Helper de slugs reservados para evitar colisiones con rutas reales
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
El formulario de la landing ahora crea un lead real en BD y redirige a
/solicitud/[id]/fotos, donde el cliente sube fotos y datos de la reforma.
El orquestador simula los pasos de IA (pre-llamada, llamada, render) y
calcula el presupuesto DE VERDAD con el catálogo del reformista, dejando
el lead listo en el panel con render y desglose.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>