Files
reformix-hackaton/specs.md
2026-05-27 10:27:27 +02:00

414 lines
34 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Reformix — Specifications & Requirements
**Fecha:** 24-may-2026
**Fuente:** Blueprint v2 (sync con Google Doc del 22-may) + sesiones de planificación 21-may → 24-may
**Estado:** ☐ Pendiente aprobación del equipo
**Versión:** 1.0
---
## Contexto
Reformix es un SaaS B2B para reformistas en España que entrega al cliente final del reformista, en menos de 5 minutos desde una landing, un **render IA antes/después** de su cocina o baño + un **presupuesto orientativo desglosado**, mediante un agente de voz IA que llama al cliente desde un número fijo provincial y la entrega final por WhatsApp. Este documento formaliza los Requisitos Funcionales (RF) y No Funcionales (RNF) usando **notación EARS** (Easy Approach to Requirements Syntax), con criterios de aceptación binarios y trazabilidad a plan → código → tests.
### Notación EARS (recordatorio)
| Patrón | Forma | Ejemplo |
|---|---|---|
| Ubicuo | *El sistema deberá [acción]* | El sistema deberá registrar timestamp de consentimiento. |
| Evento | *Cuando [trigger], el sistema deberá [acción]* | Cuando el usuario envía el formulario, el sistema deberá persistir el lead en <2 s. |
| Estado | *Mientras [estado], el sistema deberá [acción]* | Mientras una llamada esté activa, el sistema deberá grabar el audio. |
| Opcional | *Donde [feature esté disponible], el sistema deberá [acción]* | Donde el cliente incluya un DIN-A4 en la foto, el sistema deberá estimar medidas reales. |
| No deseado | *Si [condición no deseada], entonces el sistema deberá [acción]* | Si el teléfono está en Lista Robinson, entonces el sistema deberá cancelar la llamada y registrar el motivo. |
### Convención de IDs
- `RF-<superficie>-NN` — Requisitos Funcionales por superficie.
- **A** = Landing B2B (ventas a reformistas)
- **B** = Landing B2C (cliente final del reformista)
- **C** = Funnel B2C (los 5 pasos del flujo de presupuesto)
- **D** = Panel del reformista
- `RNF-<categoría>-NN` — Requisitos No Funcionales transversales.
### Fases
| Fase | Fecha | Alcance |
|---|---|---|
| **F1 — Landings** | 28-may-2026 | Landings B2B + B2C live, tracking activo, ads activos |
| **F2 — MVP** | 11-jun-2026 | Funnel B2C completo end-to-end (form → llamada → render → entrega WhatsApp) + Panel del reformista mínimo |
| F1.5 | post-hackathon | Configurador multi-tenant, validación pre-envío, NL refinement, 3 versiones B/M/P, m² automático |
| F2 (Producto) | mes 9+ | Marketplace B2C + valorador "Precio Justo" + sello certificado |
---
## Functional Requirements (RF)
### Superficie A — Landing B2B (ventas al reformista)
Objetivo: convertir tráfico de ads / outreach en pruebas gratuitas de 14 días y captar waitlist de features futuras.
| ID | Requisito (EARS) | Criterio de aceptación (binario) | Prioridad | Fase |
|---|---|---|---|---|
| RF-A-01 | El sistema deberá mostrar un hero con headline *"Tus clientes verán su reforma antes de llamarte"* y CTA primario *"Empieza gratis 14 días"*. | Inspección DOM muestra `<h1>` con el texto y un `<button>`/`<a>` apuntando a `/signup`. | Alta | F1 |
| RF-A-02 | El sistema deberá embeber una demo jugable del widget (con datos de "Reformas Ejemplo") accesible desde un CTA *"Pruébalo ahora"*. | Al hacer click se abre un iframe del widget B2C completo y se puede recorrer el flujo entero hasta recibir un render generado. | Alta | F1 |
| RF-A-03 | El sistema deberá mostrar 3 tarjetas de pricing con tier Starter (29 €), Pro (79 €, destacado) y Business (199 €), con leads incluidos y overage por tier. | Las 3 tarjetas son visibles a 1280px y 375px, Pro tiene marcador visual de "recomendado", y los precios coinciden con el blueprint. | Alta | F1 |
| RF-A-04 | El sistema deberá mostrar un bloque *"Próximamente — Doble nomenclatura"* con formulario de waitlist (solo email). | Submit del email persiste en tabla `waitlist_features` con tag `doble-nomenclatura` y muestra mensaje de confirmación. | Media | F1 |
| RF-A-05 | El sistema deberá mostrar un formulario de signup trial (email + nombre + nombre de empresa + provincia + opt-in marketing). | Submit válido crea cuenta en `accounts` con status `trial`, redirige a `/onboarding` y envía email de bienvenida en <30 s. | Alta | F1 |
| RF-A-06 | El sistema deberá disparar eventos de analítica (`landing_b2b_view`, `demo_widget_started`, `demo_widget_completed`, `pricing_view`, `signup_completed`, `waitlist_doble_nomenclatura`) a PostHog + Meta Pixel + GA. | Inspección de Network muestra los 6 eventos disparándose en el flujo correspondiente. | Alta | F1 |
| RF-A-07 | El sistema deberá mostrar enlaces a Política de Privacidad, Política de Cookies, Aviso Legal y Términos y Condiciones en el footer. | Los 4 enlaces existen, devuelven HTTP 200 y contienen los textos legales mínimos del proyecto. | Alta | F1 |
| RF-A-08 | El sistema deberá mostrar una FAQ con al menos 5 preguntas (calidad del render, precios "reales", personalización tabla precios, integración web, fin del trial). | DOM contiene `<details>` o componente FAQ con ≥ 5 entradas. | Media | F1 |
| RF-A-09 | El sistema deberá mostrar un banner de consentimiento de cookies al primer acceso, con opciones granulares (técnicas / analíticas / marketing). | Antes de aceptar, no se cargan scripts de Meta Pixel ni GA. Tras aceptar, sí. | Alta | F1 |
| RF-A-10 | Donde el visitante interactúe con la demo del widget, el sistema deberá mostrar un CTA contextual *"Quiero esto en mi web"* que pre-rellena el formulario de signup con la provincia detectada. | Tras completar la demo, aparece el CTA con cookie de tracking y al hacer click `/signup?provincia=X` se pre-rellena. | Media | F1 |
### Superficie B — Landing B2C (cliente final del reformista)
Objetivo: capturar inmediatamente el lead (teléfono) y sus fotos para disparar la llamada en <2 minutos.
| ID | Requisito (EARS) | Criterio de aceptación (binario) | Prioridad | Fase |
|---|---|---|---|---|
| RF-B-01 | El sistema deberá mostrar un hero con headline *"Recibe tu presupuesto de reforma en 5 minutos. Te llamamos en menos de 2."* y un CTA primario *"Llámame en 2 minutos"*. | DOM muestra el `<h1>` con el texto y el CTA hace scroll/abre al paso 1 del formulario. | Alta | F1 |
| RF-B-02 | El sistema deberá mostrar una imagen antes/después con copy *"Envíanos tu foto y ve cómo quedará tu reforma en 5 minutos"*. | DOM muestra un componente con dos imágenes (original + renderizada) y el texto. | Alta | F1 |
| RF-B-03 | El sistema deberá mostrar branding del reformista (logo + nombre + provincia) en el header del widget. | DOM muestra `<img>` del logo cargado y nombre de empresa. En MVP, el branding es "Reformas Ejemplo" hardcoded. | Alta | F1 |
| RF-B-04 | El sistema deberá mostrar un formulario de paso 1 con campos: nombre, teléfono (España), email, opt-in LSSI-CE (separado), opt-in RGPD, opt-in grabación. | Los 3 opt-ins son checkboxes independientes, no pre-marcados; el submit está deshabilitado si falta cualquiera. | Alta | F1 |
| RF-B-05 | Cuando el formulario del paso 1 se envíe con datos válidos, el sistema deberá persistir el lead en estado `pending_photos` y avanzar al paso 2 en <2 s. | Inspección de DB: nuevo registro `leads` con status correcto. UI cambia a paso 2 antes de 2 s. | Alta | F1 |
| RF-B-06 | El sistema deberá mostrar un componente de subida de fotos (paso 2) que acepte entre 2 y 4 imágenes JPG/PNG/HEIC. | UI rechaza con error inline si <2 o >4 fotos, o si el tipo MIME no es válido. | Alta | F1 |
| RF-B-07 | Donde el cliente incluya un DIN-A4 visible en una foto, el sistema deberá detectarlo automáticamente e indicarlo como input al pipeline de medidas. | Test con foto que contiene DIN-A4: detección flag `has_din_a4 = true` en metadata del lead. Sin DIN-A4: `false`. | Media | F2 |
| RF-B-08 | Cuando se complete el paso 2 (fotos subidas), el sistema deberá mostrar una pantalla de confirmación con cuenta atrás *"Te llamamos en <X> minutos desde <número provincial>"*. | UI muestra el número provincial real (no placeholder) y un timer visible. | Alta | F1 |
| RF-B-09 | El sistema deberá mostrar un disclaimer claro *"El presupuesto que recibirás es orientativo. El presupuesto definitivo lo confirma tu reformista en visita gratuita"* en el paso 2 antes del envío. | Texto literal presente en DOM, visible sin scroll en el viewport del paso 2. | Alta | F1 |
| RF-B-10 | Si el navegador del cliente bloquea cookies de tracking, entonces el sistema deberá seguir funcionando para captura de lead y envío de llamada (degradación). | Test con cookies bloqueadas: form + subida de fotos + disparo de llamada funcionan, solo se pierde la analítica. | Alta | F1 |
### Superficie C — Funnel B2C (los 5 pasos del flujo de presupuesto)
Objetivo: ejecutar el flujo punta a punta desde que el cliente sube fotos hasta que recibe el render + presupuesto por WhatsApp.
#### C.1 — Captura del lead
| ID | Requisito (EARS) | Criterio de aceptación (binario) | Prioridad | Fase |
|---|---|---|---|---|
| RF-C-01 | El sistema deberá validar el formato del teléfono español (E.164 o nacional) antes de aceptar el lead. | Submit con `+34666...` o `666...` válido pasa; con `123` o vacío muestra error inline. | Alta | F1 |
| RF-C-02 | El sistema deberá almacenar timestamp, IP y user-agent del consentimiento LSSI-CE y RGPD al crear el lead. | Inspección DB: registro `consents` con los 3 campos rellenos por lead. | Alta | F1 |
| RF-C-03 | Si el teléfono del lead aparece en la Lista Robinson, entonces el sistema deberá cancelar la llamada saliente, registrar `robinson_blocked = true` y enviar email al cliente con un formulario asíncrono para que solicite la llamada explícitamente. | Test con número simulado en Robinson: no se dispara llamada, registro DB tiene flag, email enviado. | Alta | F2 |
#### C.2 — Subida y procesamiento de fotos
| ID | Requisito (EARS) | Criterio de aceptación (binario) | Prioridad | Fase |
|---|---|---|---|---|
| RF-C-04 | El sistema deberá subir las fotos a S3 con cifrado at-rest y guardar las URLs en el registro del lead. | Inspección S3: objetos con `ServerSideEncryption=AES256` y bucket privado. DB: array `photo_urls` con N entradas. | Alta | F2 |
| RF-C-05 | El sistema deberá ejecutar GPT-4o Vision sobre las fotos para extraer: tipo de espacio, materiales actuales detectados, condición de iluminación, dimensiones aproximadas. | Llamada API devuelve JSON con esos 4 campos en <8 s p95. | Alta | F2 |
| RF-C-06 | El sistema deberá rechazar fotos > 10 MB y reescalar a un máximo de 2048 px en el lado mayor antes del procesamiento. | Test con foto 15 MB: rechazada con mensaje claro. Test con 4000 px: reescalada antes de enviar a Vision. | Alta | F2 |
#### C.3 — Pre-llamada (SMS + WhatsApp)
| ID | Requisito (EARS) | Criterio de aceptación (binario) | Prioridad | Fase |
|---|---|---|---|---|
| RF-C-07 | Cuando el lead complete el paso 2, el sistema deberá enviar un SMS al cliente con el texto *"En 2 minutos te llama [Reformista] desde [número provincial] para tu presupuesto"* vía Zadarma. | Test E2E: SMS recibido en <30 s con el texto correcto y el número real. | Alta | F2 |
| RF-C-08 | Cuando el lead complete el paso 2, el sistema deberá enviar un mensaje WhatsApp equivalente al SMS, vía Evolution API o WhatsApp Business API. | Test E2E: WhatsApp recibido en <30 s con el texto y desde un número Business. | Alta | F2 |
| RF-C-09 | Si la hora local del cliente está fuera del horario permitido (lun-vie 9-21, sáb 9-14), entonces el sistema deberá programar la llamada para el siguiente slot válido y avisar por SMS/WhatsApp con la hora estimada. | Test E2E: form completado a las 23:00 → llamada programada al día siguiente 9:00 y avisos enviados. | Alta | F2 |
#### C.4 — Llamada del agente de voz
| ID | Requisito (EARS) | Criterio de aceptación (binario) | Prioridad | Fase |
|---|---|---|---|---|
| RF-C-10 | Cuando se complete el paso 2 dentro del horario permitido, el sistema deberá disparar una llamada saliente del agente Retell desde un número fijo provincial Zadarma en ≤ 2 minutos. | Test E2E: tiempo entre submit y ringing del móvil < 120 s p95. | Alta | F2 |
| RF-C-11 | Mientras la llamada esté activa, el sistema deberá grabar el audio en S3 con cifrado at-rest y retención máxima 12 meses. | Inspección S3: archivo de audio por llamada, cifrado, con metadata de retención. | Alta | F2 |
| RF-C-12 | El sistema deberá iniciar la llamada con el aviso *"Hola, soy el asistente virtual de [Reformista]. Esta llamada va a ser grabada y transcrita para generar tu presupuesto. ¿Te parece bien que sigamos?"*. | Transcripción del primer turno del agente contiene literalmente esos componentes. | Alta | F2 |
| RF-C-13 | Si el cliente responde "no" al aviso de grabación, entonces el sistema deberá colgar educadamente, borrar la grabación parcial y marcar el lead como `consent_revoked`. | Test E2E: respuesta "no" → llamada termina en <15 s, audio borrado, flag en DB. | Alta | F2 |
| RF-C-14 | El sistema deberá generar el script del agente desde la configuración del reformista (tipos de reforma, opciones disponibles, tabla de precios, branding). | Cambiar configuración del reformista de "baño" a "cocina" cambia el primer prompt del agente sin redeploy. | Alta | F2 |
| RF-C-15 | El agente deberá recopilar obligatoriamente: tipo de reforma, m² aproximados, calidad (B/M/P), presupuesto target, urgencia, cambios estructurales (sanitarios / muros / distribución), preferencias estéticas. | JSON de salida tras la llamada contiene los 7 campos no nulos en > 80 % de llamadas completadas. | Alta | F2 |
| RF-C-16 | Si la duración de la llamada supera los 8 minutos, entonces el sistema deberá cerrar la conversación educadamente y proceder al pipeline con la info parcial. | Test E2E con timeout simulado: llamada cierra en ≤ 8:30 y pipeline arranca. | Alta | F2 |
| RF-C-17 | Si el cliente no descuelga, entonces el sistema deberá reintentar la llamada a los 30 minutos y a las 4 horas (máximo 3 intentos en total). | Test E2E con simulación de no-answer: registros de 3 intentos con timestamps correctos. | Alta | F2 |
| RF-C-18 | Cuando la llamada termine, el sistema deberá transcribir el audio y extraer las entidades estructuradas en JSON usando GPT-4o en <10 s p95. | Test con audio de 4 min: JSON estructurado disponible en DB en <10 s tras colgar. | Alta | F2 |
#### C.5 — Pipeline post-llamada y entrega
| ID | Requisito (EARS) | Criterio de aceptación (binario) | Prioridad | Fase |
|---|---|---|---|---|
| RF-C-19 | Cuando se cierre la llamada y exista transcripción + fotos, el sistema deberá generar un render IA antes/después con Nano Banana 2 / Image 2. | Test E2E: archivo de imagen generado en S3, URL accesible en DB, en <30 s tras transcripción. | Alta | F2 |
| RF-C-20 | Si la generación de render falla (timeout o error), entonces el sistema deberá reintentar con un proveedor alternativo (Replicate SDXL + ControlNet) y, si también falla, entregar un placeholder con disclaimer. | Test con Nano Banana caído: fallback ejecutado, render generado o placeholder visible. | Alta | F2 |
| RF-C-21 | El sistema deberá calcular el presupuesto desglosado por partidas (demolición, alicatado, fontanería, electricidad, carpintería, mano de obra, extras, licencia si aplica) aplicando la tabla de precios del reformista y el factor multiplicador por zona. | Test con inputs conocidos: el desglose coincide con el cálculo manual ±1 €. | Alta | F2 |
| RF-C-22 | Donde el agente haya detectado cambios estructurales (movimiento de sanitarios principales, derribo de muros, cambio de distribución), el sistema deberá sumar al presupuesto un rango estimado de licencia urbanística + proyecto técnico (300-1.500 €) e incluir mensaje informativo. | Test E2E con flag `structural_change=true`: presupuesto incluye partida `Licencia + Proyecto técnico` con rango. | Alta | F2 |
| RF-C-23 | El sistema deberá generar un PDF del presupuesto con branding del reformista (logo, nombre, contacto, disclaimer orientativo) usando react-pdf o Puppeteer. | Test: PDF generado, abre sin errores, contiene los elementos visuales esperados. | Alta | F2 |
| RF-C-24 | Cuando el render + PDF estén listos, el sistema deberá entregar al cliente por WhatsApp el render + PDF + CTA *"Quiero visita gratuita"* en <60 s tras finalizar la llamada. | Test E2E: tiempo entre colgar y recibir WhatsApp con los 3 elementos < 60 s p95. | Alta | F2 |
| RF-C-25 | Cuando el lead esté procesado, el sistema deberá enviar un email vía SMTP al reformista con todos los artefactos (datos del cliente + transcripción + entidades + URL render + PDF) y crear el registro en su panel. | Test E2E: email recibido en <2 min y nuevo lead visible en panel del reformista. | Alta | F2 |
| RF-C-26 | El sistema deberá tracear en PostHog los eventos del funnel (`b2c_landing_view`, `form_step1_completed`, `form_step2_completed`, `precall_sms_sent`, `precall_whatsapp_sent`, `call_started`, `call_completed`, `call_no_answer`, `render_generated`, `budget_generated`, `whatsapp_delivered`, `client_requested_visit`). | Inspección PostHog: los 12 eventos disparan en el flujo correspondiente con sus propiedades. | Alta | F2 |
#### C.6 — Upsell (path alternativo)
| ID | Requisito (EARS) | Criterio de aceptación (binario) | Prioridad | Fase |
|---|---|---|---|---|
| RF-C-27 | Donde el cliente solicite *"callback inmediato"* desde la landing, el sistema deberá omitir la subida de fotos, disparar la llamada del agente y permitirle peticiones libres que se canalizan directamente al sistema de presupuestos. | Test E2E con callback inmediato: llamada disparada sin fotos, presupuesto generado solo a partir de la conversación. | Media | F2 |
### Superficie D — Panel del reformista
Objetivo: dar al reformista visibilidad de leads, capacidad de marcarlos y de cerrar el bucle de precisión introduciendo el precio final firmado.
| ID | Requisito (EARS) | Criterio de aceptación (binario) | Prioridad | Fase |
|---|---|---|---|---|
| RF-D-01 | El sistema deberá mostrar al reformista una lista de sus leads con columnas: fecha/hora, nombre cliente, teléfono, estado actual, presupuesto estimado, miniatura del render. | UI muestra tabla/cards con esas 6 columnas, ordenadas por fecha descendente por defecto. | Alta | F2 |
| RF-D-02 | Cuando el reformista abra un lead, el sistema deberá mostrar todos los artefactos: datos personales, transcripción de la llamada, JSON de entidades extraídas, render generado, PDF descargable, audio reproducible. | UI de detalle muestra todos los 6 artefactos y todos son interactivos (descargar/reproducir). | Alta | F2 |
| RF-D-03 | El sistema deberá permitir al reformista marcar el estado del lead entre: `Nuevo`, `Contactado`, `Visita agendada`, `Presupuesto enviado`, `Ganado`, `Perdido`. | Cambio de estado se persiste en DB y se refleja en la lista sin recargar página. | Alta | F2 |
| RF-D-04 | Cuando el reformista marque un lead como `Ganado`, el sistema deberá pedirle el **precio final firmado** y calcular la delta vs estimado, almacenándolo en la tabla `precision_history`. | Test E2E: marcar `Ganado` abre modal de precio final; al guardar, registro creado con `estimated`, `final`, `delta_pct`. | Alta | F2 |
| RF-D-05 | El sistema deberá proteger el panel mediante token único firmado (JWT) enviado por email tras la creación del lead o cuenta, con expiración 7 días renovable. | Test: acceso sin token devuelve 401; con token válido devuelve panel; con token expirado pide renovación por email. | Alta | F2 |
| RF-D-06 | El sistema deberá notificar al reformista por email (SMTP) cada vez que se cree un nuevo lead, en <2 min desde la finalización de la llamada. | Test E2E: tiempo entre `whatsapp_delivered` y recepción de email < 2 min p95. | Alta | F2 |
| RF-D-07 | El sistema deberá ofrecer al reformista un configurador de perfil con: nombre de empresa, logo, provincia/zona, tipos de reforma ofrecidos, opciones disponibles por tipo, tabla de precios editable, número WhatsApp Business propio (opcional). | UI con formulario completo; submit persiste en DB y regenera el script del agente. | Alta | F2 |
| RF-D-08 | Cuando el reformista modifique la configuración, el sistema deberá regenerar el script del agente en <5 s y ofrecer una demo de prueba de la llamada con su nuevo script. | Test E2E: cambio de tipo de reforma de "baño" a "cocina" → primer prompt del agente cambia en <5 s; botón "Probar llamada" hace ringing al móvil del reformista. | Media | F2 |
---
## Non-Functional Requirements (RNF)
### Performance
| ID | Requisito (EARS) | Métrica |
|---|---|---|
| RNF-PERF-01 | El sistema deberá servir las landings con First Contentful Paint < 2 s. | FCP p95 < 2 s en red 3G throttled (Lighthouse mobile). |
| RNF-PERF-02 | El sistema deberá obtener score Lighthouse Performance ≥ 85 en las dos landings. | Lighthouse Performance score ≥ 85 (mobile y desktop). |
| RNF-PERF-03 | Cuando el cliente complete el formulario y subida de fotos, el sistema deberá disparar la llamada en ≤ 2 minutos. | Tiempo `form_step2_completed``call_started` < 120 s p95. |
| RNF-PERF-04 | Mientras se ejecute el pipeline post-llamada, el sistema deberá entregar render + presupuesto + PDF al WhatsApp del cliente en < 60 s tras colgar. | Tiempo `call_completed``whatsapp_delivered` < 60 s p95. |
| RNF-PERF-05 | El sistema deberá completar el flujo end-to-end del cliente (landing → recibir WhatsApp con render) en < 7 minutos. | Tiempo `b2c_landing_view``whatsapp_delivered` < 7 min p95. |
### Security
| ID | Requisito (EARS) | Métrica |
|---|---|---|
| RNF-SEC-01 | El sistema deberá forzar HTTPS en todas las rutas (HSTS activado). | Inspección de headers: `Strict-Transport-Security: max-age=31536000`. |
| RNF-SEC-02 | El sistema deberá rate-limitar el formulario público de la landing B2C a 5 envíos/minuto por IP. | Test: 6 envíos en 60 s desde misma IP → 6º devuelve HTTP 429. |
| RNF-SEC-03 | El sistema deberá almacenar todas las grabaciones de audio y fotos del cliente en S3 con cifrado at-rest AES-256. | Inspección S3: `ServerSideEncryption=AES256` en todos los objetos. |
| RNF-SEC-04 | El sistema deberá almacenar secretos (API keys de Retell, ElevenLabs, OpenAI, etc.) en un secret manager, nunca en código ni env vars compartidas. | Audit del repo: 0 secretos hardcoded; variables vienen de Vercel env vars / vault. |
| RNF-SEC-05 | Si se detecta intento de SQL injection o XSS en el formulario, entonces el sistema deberá rechazar el input y registrar el intento. | Test con payload conocido: rechazado con HTTP 400 y log de seguridad. |
| RNF-SEC-06 | El sistema deberá proteger el panel del reformista con JWT con expiración 7 días renovable y rotación de secret cada 90 días. | Token expira a los 7 días reales; rotación de secret invalida tokens antiguos. |
### Usability
| ID | Requisito (EARS) | Métrica |
|---|---|---|
| RNF-UX-01 | El sistema deberá ser usable a viewport 375 px (mobile) sin scroll horizontal. | Inspección visual en Chrome DevTools 375 px: ningún elemento sale del viewport. |
| RNF-UX-02 | El sistema deberá cumplir WCAG 2.1 nivel AA en las landings. | Audit con axe-core o Lighthouse Accessibility ≥ 95. |
| RNF-UX-03 | Cuando el cliente envíe el formulario con campos inválidos, el sistema deberá mostrar errores inline por campo en < 200 ms. | Test E2E: submit con email inválido → error visible bajo el campo en < 200 ms. |
| RNF-UX-04 | El sistema deberá usar voces ElevenLabs premium en español con entonación natural y manejo de interrupciones. | Auditoría subjetiva del equipo: ≥ 4/5 en escala "suena humano" sobre 10 llamadas test. |
| RNF-UX-05 | El sistema deberá soportar copia funcional de los datos del lead a portapapeles desde el panel del reformista (botón "Copiar teléfono", "Copiar email"). | UI tiene los botones; click copia el valor al portapapeles. |
### Reliability
| ID | Requisito (EARS) | Métrica |
|---|---|---|
| RNF-REL-01 | El sistema deberá mantener uptime ≥ 99,5 % de las landings y del endpoint de captura de leads. | Status page tipo BetterStack reporta ≥ 99,5 % mensual. |
| RNF-REL-02 | Si Nano Banana 2 / Image 2 falla, entonces el sistema deberá conmutar automáticamente a Replicate (SDXL + ControlNet) sin intervención. | Test simulando fallo: pipeline completa con fallback en < 90 s. |
| RNF-REL-03 | Si Retell.ai cae, entonces el sistema deberá enviar al cliente un SMS/WhatsApp ofreciendo el formulario asíncrono y registrar el lead en estado `pending_retry`. | Test simulando fallo: cliente recibe mensaje y lead queda en cola. |
| RNF-REL-04 | El sistema deberá ejecutar backups automáticos diarios de Postgres con retención 30 días. | Cron de backup configurado; restauración test ejecutada al menos 1 vez antes del lanzamiento. |
| RNF-REL-05 | El sistema deberá usar una cola con reintentos exponenciales (1 s, 5 s, 30 s, 5 min) para todas las tareas asíncronas del pipeline. | Inspección de código: cola implementada con esta política. |
### Maintainability
| ID | Requisito (EARS) | Métrica |
|---|---|---|
| RNF-MAINT-01 | El sistema deberá tener cobertura de tests ≥ 70 % en el motor de cálculo de presupuestos. | `vitest --coverage` sobre `src/budget/*` reporta ≥ 70 %. |
| RNF-MAINT-02 | El sistema deberá traceaer eventos en PostHog que cubran el 100 % del funnel definido en RF-C-26. | Inspección del dashboard PostHog: los 12 eventos están instrumentados y disparan en producción. |
| RNF-MAINT-03 | El sistema deberá documentar el formato del script del agente generado a partir de la configuración del reformista. | Archivo `docs/agent-script-format.md` describe el formato con ejemplo. |
### Budget
| ID | Requisito (EARS) | Métrica |
|---|---|---|
| RNF-BUD-01 | El coste medio por lead procesado (llamada + render + presupuesto + entrega) deberá ser < 1,50 €. | Medición real sobre 100 leads test: media < 1,50 €. |
| RNF-BUD-02 | El coste fijo de infraestructura mensual en fase 0 deberá ser < 200 €/mes (excluyendo ads). | Suma facturas Vercel + Postgres + S3 + ElevenLabs base + GPT-4o base + Zadarma fijo < 200 €/mes. |
| RNF-BUD-03 | El margen bruto por tier deberá ser ≥ 70 % asumiendo uso completo de leads incluidos. | Cálculo: (Precio COGS por leads incluidos) / Precio ≥ 0,70 para los 3 tiers. |
### Legal / Compliance
| ID | Requisito (EARS) | Métrica |
|---|---|---|
| RNF-LEG-01 | El sistema deberá obtener consentimiento LSSI-CE explícito y separado para la llamada comercial. | Auditoría legal del formulario: opt-in en checkbox independiente, no pre-marcado. |
| RNF-LEG-02 | Cuando se inicie una llamada, el sistema deberá avisar de la grabación al inicio. | Transcripción del primer turno del agente contiene el aviso. |
| RNF-LEG-03 | El sistema deberá consultar la Lista Robinson antes de cada llamada saliente y registrar el resultado de la consulta. | Tabla `robinson_checks` con un registro por llamada intentada. |
| RNF-LEG-04 | El sistema deberá conservar las grabaciones máximo 12 meses y borrarlas automáticamente al cumplir el plazo. | Cron de borrado configurado y verificado con audit. |
| RNF-LEG-05 | Cuando el cliente hable con el agente, el sistema deberá identificarse como asistente virtual / IA (no humano), cumpliendo AI Act EU. | Auditoría del script: primera frase identifica al agente como "asistente virtual". |
| RNF-LEG-06 | El sistema deberá respetar el horario de llamadas permitido en España: lunes-viernes 9-21h, sábados 9-14h, domingos no. | Test E2E: form completado fuera de horario → llamada programada para siguiente slot válido. |
| RNF-LEG-07 | El sistema deberá publicar Política de Privacidad, Política de Cookies, Aviso Legal y T&C accesibles desde el footer de ambas landings. | URLs públicas devuelven HTTP 200 con contenido legal completo. |
| RNF-LEG-08 | El sistema deberá ofrecer al cliente y al reformista mecanismos de ejercer derechos RGPD (acceso, rectificación, supresión, portabilidad) en < 30 días. | Endpoint o email accesible que tramita la solicitud; SLA documentado. |
| RNF-LEG-09 | El sistema deberá firmar contrato de Encargado de Tratamiento con cada reformista antes de procesar leads para él. | Onboarding del reformista incluye paso de aceptación del contrato; registro en DB. |
### Scalability
| ID | Requisito (EARS) | Métrica |
|---|---|---|
| RNF-SCAL-01 | El sistema deberá soportar al menos 50 llamadas simultáneas durante el demo y la fase de validación. | Test de carga: 50 llamadas en paralelo sin degradación de latencia > 20 %. |
| RNF-SCAL-02 | El sistema deberá soportar al menos 500 envíos de formulario por hora. | Test de carga: 500 submits/h sin errores HTTP 5xx. |
---
## Constraints
- **Stack obligado** (decidido):
- Frontend + Backend: Next.js 14 (App Router + Server Actions + API Routes)
- UI: Tailwind + shadcn/ui
- Agente voz: Retell.ai + ElevenLabs (voces premium ES)
- Telefonía: Zadarma (números fijos provinciales España)
- WhatsApp: Evolution API (primario) o WhatsApp Business API (respaldo)
- Render IA: Nano Banana 2 / Image 2 (primario) + Replicate SDXL + ControlNet (fallback)
- IA Texto + Vision: GPT-4o (OpenAI)
- DB: Postgres
- Storage: S3 (AWS / Cloudflare R2 / MinIO)
- Email: SMTP genérico
- Deploy: Vercel
- Analytics: PostHog (+ Meta Pixel + GA en landings)
- **Equipo:** 4 personas (Carlos producto + voz + WhatsApp, Simon backend + IA + WhatsApp, Goyo motor presupuesto + dominio, Antonio UI/UX + creativos).
- **Tiempo:** 3 semanas (24-may → 11-jun) hasta demo MVP.
- **Geografía:** España. Idioma: castellano. Provincias prioritarias: Madrid + Barcelona + capitales > 100K hab.
- **Budget bootstrap inicial:** 2.500-5.000 € entre los 4 fundadores.
- **Demo del 11-jun:** "Reformas Ejemplo" hardcoded como reformista único. Multi-tenant real va a F1.5.
---
## Out of Scope (F1 + F2)
- **Configurador multi-tenant real** del reformista (hardcoded en MVP).
- **Validación opcional del reformista** antes de que el cliente reciba el presupuesto.
- **Nurturing y seguimiento del lead** por WhatsApp hasta concertar cita.
- **3 versiones simultáneas Básico/Medio/Premium** con selección granular por elemento.
- **Slider de presupuesto target** con auto-ajuste.
- **Refinamiento por lenguaje natural** ("quiero ducha en vez de bañera").
- **Cálculo automático preciso de m²** desde foto (en MVP usamos lo que indique el cliente + lo que infiera el agente).
- **Doble nomenclatura** asistida por IA (feature killer B2B, post-hackathon v2).
- **"Valora tu presupuesto justo"** (Fase 2 marketplace B2C, mes 9+).
- **Sello "Precio Justo Certificado"** (puente Fase 1 ↔ Fase 2).
- **App móvil nativa** (todo web responsive).
- **PDF con membrete custom** (MVP entrega PDF genérico con branding básico).
- **Integraciones CRM** (Holded, Stel, etc.).
- **Renders 3D fotorrealistas** de alta fidelidad.
- **Pasarela de pago activa** (en MVP solo waitlist + signup trial, sin cobro real).
- **Verifactu integration** (legal F1.5).
- **Asignación automática de leads en marketplace** (Fase 2).
---
## Traceability Matrix
> Plan, Code y Test se rellenan a medida que el proyecto avanza. Celdas vacías son señales: requirement sin Plan = olvidado en planificación; sin Test = no verificado.
### Landing B2B
| Requirement | Plan | Code | Test |
|---|---|---|---|
| RF-A-01 | — | — | — |
| RF-A-02 | — | — | — |
| RF-A-03 | — | — | — |
| RF-A-04 | — | — | — |
| RF-A-05 | — | — | — |
| RF-A-06 | — | — | — |
| RF-A-07 | — | — | — |
| RF-A-08 | — | — | — |
| RF-A-09 | — | — | — |
| RF-A-10 | — | — | — |
### Landing B2C
| Requirement | Plan | Code | Test |
|---|---|---|---|
| RF-B-01 | — | — | — |
| RF-B-02 | — | — | — |
| RF-B-03 | — | — | — |
| RF-B-04 | — | — | — |
| RF-B-05 | — | — | — |
| RF-B-06 | — | — | — |
| RF-B-07 | — | — | — |
| RF-B-08 | — | — | — |
| RF-B-09 | — | — | — |
| RF-B-10 | — | — | — |
### Funnel B2C
| Requirement | Plan | Code | Test |
|---|---|---|---|
| RF-C-01 | — | — | — |
| RF-C-02 | — | — | — |
| RF-C-03 | — | — | — |
| RF-C-04 | — | — | — |
| RF-C-05 | — | — | — |
| RF-C-06 | — | — | — |
| RF-C-07 | — | — | — |
| RF-C-08 | — | — | — |
| RF-C-09 | — | — | — |
| RF-C-10 | — | — | — |
| RF-C-11 | — | — | — |
| RF-C-12 | — | — | — |
| RF-C-13 | — | — | — |
| RF-C-14 | — | — | — |
| RF-C-15 | — | — | — |
| RF-C-16 | — | — | — |
| RF-C-17 | — | — | — |
| RF-C-18 | — | — | — |
| RF-C-19 | — | — | — |
| RF-C-20 | — | — | — |
| RF-C-21 | — | — | — |
| RF-C-22 | — | — | — |
| RF-C-23 | — | — | — |
| RF-C-24 | — | — | — |
| RF-C-25 | — | — | — |
| RF-C-26 | — | — | — |
| RF-C-27 | — | — | — |
### Panel reformista
| Requirement | Plan | Code | Test |
|---|---|---|---|
| RF-D-01 | — | — | — |
| RF-D-02 | — | — | — |
| RF-D-03 | — | — | — |
| RF-D-04 | — | — | — |
| RF-D-05 | — | — | — |
| RF-D-06 | — | — | — |
| RF-D-07 | — | — | — |
| RF-D-08 | — | — | — |
### Non-Functional
| Requirement | Plan | Code | Test |
|---|---|---|---|
| RNF-PERF-01 | — | — | Lighthouse CI |
| RNF-PERF-02 | — | — | Lighthouse CI |
| RNF-PERF-03 | — | — | — |
| RNF-PERF-04 | — | — | — |
| RNF-PERF-05 | — | — | — |
| RNF-SEC-01 | — | (config) | — |
| RNF-SEC-02 | — | — | — |
| RNF-SEC-03 | — | (config) | — |
| RNF-SEC-04 | — | (config) | audit |
| RNF-SEC-05 | — | — | — |
| RNF-SEC-06 | — | — | — |
| RNF-UX-01 | — | — | — |
| RNF-UX-02 | — | — | axe-core |
| RNF-UX-03 | — | — | — |
| RNF-UX-04 | — | — | review subjetiva |
| RNF-UX-05 | — | — | — |
| RNF-REL-01 | — | (config) | BetterStack |
| RNF-REL-02 | — | — | — |
| RNF-REL-03 | — | — | — |
| RNF-REL-04 | — | (config) | restore test |
| RNF-REL-05 | — | — | — |
| RNF-MAINT-01 | — | — | vitest coverage |
| RNF-MAINT-02 | — | — | — |
| RNF-MAINT-03 | — | — | — |
| RNF-BUD-01 | — | — | medición real |
| RNF-BUD-02 | — | — | audit facturas |
| RNF-BUD-03 | — | — | cálculo manual |
| RNF-LEG-01 | — | — | audit legal |
| RNF-LEG-02 | — | — | — |
| RNF-LEG-03 | — | — | — |
| RNF-LEG-04 | — | (config) | — |
| RNF-LEG-05 | — | — | — |
| RNF-LEG-06 | — | — | — |
| RNF-LEG-07 | — | — | — |
| RNF-LEG-08 | — | — | — |
| RNF-LEG-09 | — | — | — |
| RNF-SCAL-01 | — | — | load test |
| RNF-SCAL-02 | — | — | load test |
---
## Change Log
| Versión | Fecha | Cambio |
|---|---|---|
| 1.0 | 2026-05-24 | Versión inicial. 55 RF + 30 RNF distribuidos en 4 superficies (Landing B2B, Landing B2C, Funnel B2C, Panel reformista). Notación EARS aplicada. Fases F1 (Landings 28-may) + F2 (MVP 11-jun). |