# TRACEABILITY.yml - MAE-014: CRM Clientes # Matriz completa de trazabilidad: Requerimientos → Especificaciones → Historias → Implementación epic_code: MAE-014 epic_name: CRM Clientes phase: 2 phase_name: Comercialización y Ventas budget_mxn: 85000 story_points: 120 status: planned sprint: 8-11 period: "Semanas 8-11" reused_from_gamilit: 40% # ============================================================================ # DOCUMENTACIÓN # ============================================================================ documentation: requirements: - id: RF-CRM-001 file: requerimientos/RF-CRM-001-gestion-prospectos.md title: Gestión de Prospectos status: planned reused_from: null adaptations: - "Sistema de captura y calificación de leads" - "Scoring de prospectos según criterios de construcción" - "Pipeline de ventas específico para proyectos inmobiliarios" - "Seguimiento de fuentes de captación" - id: RF-CRM-002 file: requerimientos/RF-CRM-002-seguimiento-comercial.md title: Seguimiento Comercial status: planned reused_from: null adaptations: - "Agenda de visitas a desarrollos" - "Registro de interacciones con prospectos" - "Embudo de conversión por proyecto" - "Asignación de vendedores por desarrollo" - "KPIs comerciales por vendedor y proyecto" - id: RF-CRM-003 file: requerimientos/RF-CRM-003-cotizaciones.md title: Sistema de Cotizaciones status: planned reused_from: null adaptations: - "Cotizaciones de viviendas con configuraciones personalizadas" - "Cálculo de financiamiento y esquemas de pago" - "Integración con catálogo de prototipos y acabados" - "Generación de propuestas económicas en PDF" - "Historial de versiones de cotización" - id: RF-CRM-004 file: requerimientos/RF-CRM-004-portal-cliente.md title: Portal del Cliente status: planned reused_from: null adaptations: - "Acceso web para compradores" - "Visualización de avance de obra de su vivienda" - "Consulta de estados de cuenta y pagos" - "Solicitud de servicios post-venta" - "Integración con MOB-005 (Derechohabiente)" - "Notificaciones de hitos de construcción" specifications: - id: ET-CRM-001 file: especificaciones/ET-CRM-001-gestion-prospectos.md rf: RF-CRM-001 title: Implementación de Gestión de Prospectos status: planned reused_from: null adaptations: - "Schema crm.prospectos con campos específicos" - "Sistema de scoring automático" - "Estados del lead: nuevo, contactado, calificado, hot, cold, perdido" - "Asignación automática según reglas de distribución" - id: ET-CRM-002 file: especificaciones/ET-CRM-002-seguimiento-comercial.md rf: RF-CRM-002 title: Implementación de Seguimiento Comercial status: planned reused_from: null adaptations: - "Schema crm.interacciones para registro de contactos" - "Calendario de actividades comerciales" - "Dashboard de pipeline y conversión" - "Reportes de actividad por vendedor" - id: ET-CRM-003 file: especificaciones/ET-CRM-003-cotizaciones.md rf: RF-CRM-003 title: Implementación de Sistema de Cotizaciones status: planned reused_from: null adaptations: - "Schema crm.cotizaciones con versionamiento" - "Motor de cálculo de financiamiento" - "Plantillas de cotización en PDF" - "Integración con catálogos de prototipos y acabados" - id: ET-CRM-004 file: especificaciones/ET-CRM-004-portal-cliente.md rf: RF-CRM-004 title: Implementación de Portal del Cliente status: planned reused_from: null adaptations: - "Frontend separado para clientes (portal-cliente app)" - "Schema crm.clientes_portal para configuración" - "Integración con MOB-005 para datos de derechohabiente" - "API pública para consulta de avance de obra" - "Sistema de notificaciones por email/SMS" user_stories: # RF-CRM-001: Gestión de Prospectos - id: US-CRM-001 file: historias-usuario/US-CRM-001-captura-prospectos.md title: Captura de Prospectos rf: RF-CRM-001 story_points: 8 status: planned reused_from: null adaptations: ["Sistema de captura con origen y scoring inicial"] - id: US-CRM-002 file: historias-usuario/US-CRM-002-calificacion-leads.md title: Calificación y Scoring de Leads rf: RF-CRM-001 story_points: 8 status: planned reused_from: null adaptations: ["Motor de scoring basado en criterios configurables"] - id: US-CRM-003 file: historias-usuario/US-CRM-003-asignacion-prospectos.md title: Asignación de Prospectos a Vendedores rf: RF-CRM-001 story_points: 5 status: planned reused_from: null adaptations: ["Reglas de asignación por proyecto, zona, carga"] # RF-CRM-002: Seguimiento Comercial - id: US-CRM-004 file: historias-usuario/US-CRM-004-agenda-visitas.md title: Agenda de Visitas y Seguimiento rf: RF-CRM-002 story_points: 8 status: planned reused_from: null adaptations: ["Calendario de citas en sala de ventas y obra"] - id: US-CRM-005 file: historias-usuario/US-CRM-005-registro-interacciones.md title: Registro de Interacciones con Clientes rf: RF-CRM-002 story_points: 5 status: planned reused_from: null adaptations: ["Log de llamadas, emails, visitas, WhatsApp"] - id: US-CRM-006 file: historias-usuario/US-CRM-006-pipeline-ventas.md title: Pipeline de Ventas y Embudo rf: RF-CRM-002 story_points: 8 status: planned reused_from: null adaptations: ["Dashboard de embudo por proyecto y vendedor"] - id: US-CRM-007 file: historias-usuario/US-CRM-007-kpis-comerciales.md title: KPIs y Métricas Comerciales rf: RF-CRM-002 story_points: 8 status: planned reused_from: null adaptations: ["Dashboard de conversión, cierre, tiempo promedio"] # RF-CRM-003: Cotizaciones - id: US-CRM-008 file: historias-usuario/US-CRM-008-crear-cotizacion.md title: Creación de Cotizaciones rf: RF-CRM-003 story_points: 13 status: planned reused_from: null adaptations: ["Wizard de cotización con selección de prototipo y extras"] - id: US-CRM-009 file: historias-usuario/US-CRM-009-calculo-financiamiento.md title: Cálculo de Esquemas de Financiamiento rf: RF-CRM-003 story_points: 13 status: planned reused_from: null adaptations: ["Motor de cálculo: contado, crédito, mixto"] - id: US-CRM-010 file: historias-usuario/US-CRM-010-generar-propuesta-pdf.md title: Generación de Propuesta Económica en PDF rf: RF-CRM-003 story_points: 8 status: planned reused_from: null adaptations: ["Template profesional con branding de constructora"] - id: US-CRM-011 file: historias-usuario/US-CRM-011-versiones-cotizacion.md title: Versionamiento de Cotizaciones rf: RF-CRM-003 story_points: 5 status: planned reused_from: null adaptations: ["Historial de cambios y comparación de versiones"] # RF-CRM-004: Portal del Cliente - id: US-CRM-012 file: historias-usuario/US-CRM-012-portal-autenticacion.md title: Autenticación en Portal del Cliente rf: RF-CRM-004 story_points: 8 status: planned reused_from: null adaptations: ["Login con email/teléfono, recuperación de contraseña"] - id: US-CRM-013 file: historias-usuario/US-CRM-013-dashboard-cliente.md title: Dashboard del Cliente rf: RF-CRM-004 story_points: 8 status: planned reused_from: null adaptations: ["Vista general de su vivienda y estatus"] - id: US-CRM-014 file: historias-usuario/US-CRM-014-avance-obra-cliente.md title: Visualización de Avance de Obra rf: RF-CRM-004 story_points: 13 status: planned reused_from: null adaptations: ["Integración con MOB-005, fotos, hitos, % avance"] - id: US-CRM-015 file: historias-usuario/US-CRM-015-estados-cuenta-cliente.md title: Consulta de Estados de Cuenta rf: RF-CRM-004 story_points: 8 status: planned reused_from: null adaptations: ["Saldos, pagos realizados, próximos vencimientos"] - id: US-CRM-016 file: historias-usuario/US-CRM-016-solicitudes-postventa.md title: Solicitudes de Servicio Post-Venta rf: RF-CRM-004 story_points: 8 status: planned reused_from: null adaptations: ["Formulario de garantías y mantenimiento"] # ============================================================================ # IMPLEMENTACIÓN - BASE DE DATOS # ============================================================================ implementation: database: schemas: - name: crm path: apps/database/ddl/schemas/crm/ description: Schema de CRM (prospectos, clientes, cotizaciones) reused_from_gamilit: false note: "Nuevo schema específico de CRM para construcción" - name: crm_comercial path: apps/database/ddl/schemas/crm_comercial/ description: Schema de seguimiento comercial (interacciones, pipeline) reused_from_gamilit: false note: "Nuevo schema para actividades comerciales" - name: crm_portal path: apps/database/ddl/schemas/crm_portal/ description: Schema de portal del cliente reused_from_gamilit: false note: "Nuevo schema para portal de clientes" enums: - name: lead_status schema: crm file: apps/database/ddl/schemas/crm/00-enums.sql lines: "1-10" values: [nuevo, contactado, calificado, hot, cold, perdido, convertido] rf: RF-CRM-001 reused_from: null note: "Estados del prospecto en el pipeline" - name: lead_source schema: crm file: apps/database/ddl/schemas/crm/00-enums.sql lines: "12-22" values: [web, facebook, instagram, referido, evento, stand, llamada, walk_in] rf: RF-CRM-001 reused_from: null note: "Fuentes de captación de prospectos" - name: interaction_type schema: crm_comercial file: apps/database/ddl/schemas/crm_comercial/00-enums.sql lines: "1-10" values: [llamada, email, whatsapp, visita_sala, visita_obra, reunion, video_llamada] rf: RF-CRM-002 reused_from: null note: "Tipos de interacción con clientes" - name: cotizacion_status schema: crm file: apps/database/ddl/schemas/crm/00-enums.sql lines: "24-32" values: [borrador, enviada, en_negociacion, aceptada, rechazada, vencida, facturada] rf: RF-CRM-003 reused_from: null note: "Estados de la cotización" - name: financing_type schema: crm file: apps/database/ddl/schemas/crm/00-enums.sql lines: "34-42" values: [contado, credito_infonavit, credito_bancario, credito_cofinavit, credito_constructora, mixto] rf: RF-CRM-003 reused_from: null note: "Tipos de financiamiento para cotizaciones" - name: portal_user_status schema: crm_portal file: apps/database/ddl/schemas/crm_portal/00-enums.sql lines: "1-8" values: [active, suspended, pending_activation, inactive] rf: RF-CRM-004 reused_from: null note: "Estados de usuario del portal" tables: # RF-CRM-001: Gestión de Prospectos - name: prospectos schema: crm file: apps/database/ddl/schemas/crm/tables/01-prospectos.sql lines: 180 description: Catálogo de prospectos (leads) rf: RF-CRM-001 reused_from_gamilit: false note: "Tabla principal de leads con scoring" columns: - id (UUID, PK) - constructora_id (UUID, FK) - proyecto_id (UUID, FK, nullable) - nombre (TEXT) - apellidos (TEXT) - email (TEXT) - telefono (TEXT) - telefono_secundario (TEXT) - lead_source (lead_source ENUM) - lead_status (lead_status ENUM) - scoring (INTEGER, 0-100) - presupuesto_min (NUMERIC) - presupuesto_max (NUMERIC) - fecha_contacto_inicial (DATE) - fecha_conversion (DATE, nullable) - vendedor_asignado_id (UUID, FK, nullable) - notas (TEXT) - metadata (JSONB) - created_at (TIMESTAMPTZ) - updated_at (TIMESTAMPTZ) indexes: - idx_prospectos_constructora_status (constructora_id, lead_status) - idx_prospectos_vendedor (vendedor_asignado_id) - idx_prospectos_scoring (scoring DESC) - name: criterios_scoring schema: crm file: apps/database/ddl/schemas/crm/tables/02-criterios_scoring.sql lines: 90 description: Configuración de criterios de scoring de prospectos rf: RF-CRM-001 reused_from_gamilit: false note: "Criterios personalizables por constructora" columns: - id (UUID, PK) - constructora_id (UUID, FK) - criterio (TEXT) - peso (INTEGER, 0-100) - condiciones (JSONB) - active (BOOLEAN) - created_at (TIMESTAMPTZ) # RF-CRM-002: Seguimiento Comercial - name: interacciones schema: crm_comercial file: apps/database/ddl/schemas/crm_comercial/tables/01-interacciones.sql lines: 140 description: Registro de interacciones con prospectos/clientes rf: RF-CRM-002 reused_from_gamilit: false note: "Log de todas las comunicaciones" columns: - id (UUID, PK) - constructora_id (UUID, FK) - prospecto_id (UUID, FK, nullable) - cliente_id (UUID, FK, nullable) - tipo (interaction_type ENUM) - fecha (TIMESTAMPTZ) - duracion_minutos (INTEGER) - vendedor_id (UUID, FK) - asunto (TEXT) - notas (TEXT) - resultado (TEXT) - siguiente_accion (TEXT) - fecha_siguiente_accion (TIMESTAMPTZ, nullable) - archivos_adjuntos (JSONB) - created_at (TIMESTAMPTZ) indexes: - idx_interacciones_prospecto (prospecto_id, fecha DESC) - idx_interacciones_cliente (cliente_id, fecha DESC) - idx_interacciones_vendedor (vendedor_id, fecha DESC) - name: pipeline_configuracion schema: crm_comercial file: apps/database/ddl/schemas/crm_comercial/tables/02-pipeline_configuracion.sql lines: 100 description: Configuración de etapas del pipeline de ventas rf: RF-CRM-002 reused_from_gamilit: false note: "Etapas personalizables del embudo" columns: - id (UUID, PK) - constructora_id (UUID, FK) - etapa (TEXT) - orden (INTEGER) - probabilidad_cierre (INTEGER, 0-100) - color (TEXT) - active (BOOLEAN) - name: metas_comerciales schema: crm_comercial file: apps/database/ddl/schemas/crm_comercial/tables/03-metas_comerciales.sql lines: 110 description: Metas de ventas por vendedor y período rf: RF-CRM-002 reused_from_gamilit: false note: "KPIs y objetivos comerciales" columns: - id (UUID, PK) - constructora_id (UUID, FK) - vendedor_id (UUID, FK) - proyecto_id (UUID, FK, nullable) - periodo_inicio (DATE) - periodo_fin (DATE) - meta_prospectos (INTEGER) - meta_visitas (INTEGER) - meta_cotizaciones (INTEGER) - meta_cierres (INTEGER) - meta_monto (NUMERIC) - created_at (TIMESTAMPTZ) # RF-CRM-003: Cotizaciones - name: cotizaciones schema: crm file: apps/database/ddl/schemas/crm/tables/10-cotizaciones.sql lines: 220 description: Cotizaciones de viviendas rf: RF-CRM-003 reused_from_gamilit: false note: "Cotizaciones con versionamiento" columns: - id (UUID, PK) - constructora_id (UUID, FK) - numero_cotizacion (TEXT UNIQUE) - version (INTEGER) - prospecto_id (UUID, FK) - proyecto_id (UUID, FK) - prototipo_id (UUID, FK) - lote_id (UUID, FK, nullable) - vendedor_id (UUID, FK) - status (cotizacion_status ENUM) - fecha_emision (DATE) - fecha_vencimiento (DATE) - precio_base (NUMERIC) - extras (JSONB) - total_extras (NUMERIC) - descuentos (JSONB) - total_descuentos (NUMERIC) - precio_final (NUMERIC) - tipo_financiamiento (financing_type ENUM) - enganche_porcentaje (NUMERIC) - enganche_monto (NUMERIC) - financiado_monto (NUMERIC) - plazo_meses (INTEGER) - tasa_interes (NUMERIC) - mensualidad (NUMERIC) - esquema_pagos (JSONB) - condiciones (TEXT) - notas_internas (TEXT) - pdf_url (TEXT, nullable) - enviada_cliente (BOOLEAN) - fecha_envio (TIMESTAMPTZ, nullable) - aceptada_fecha (TIMESTAMPTZ, nullable) - rechazada_fecha (TIMESTAMPTZ, nullable) - razon_rechazo (TEXT, nullable) - created_at (TIMESTAMPTZ) - updated_at (TIMESTAMPTZ) indexes: - idx_cotizaciones_numero (numero_cotizacion) - idx_cotizaciones_prospecto (prospecto_id) - idx_cotizaciones_proyecto_status (proyecto_id, status) - idx_cotizaciones_vendedor (vendedor_id, fecha_emision DESC) - name: cotizacion_versiones schema: crm file: apps/database/ddl/schemas/crm/tables/11-cotizacion_versiones.sql lines: 90 description: Historial de versiones de cotizaciones rf: RF-CRM-003 reused_from_gamilit: false note: "Auditoría de cambios en cotizaciones" columns: - id (UUID, PK) - cotizacion_id (UUID, FK) - version (INTEGER) - cambios (JSONB) - user_id (UUID, FK) - motivo (TEXT) - snapshot (JSONB) - created_at (TIMESTAMPTZ) - name: plantillas_cotizacion schema: crm file: apps/database/ddl/schemas/crm/tables/12-plantillas_cotizacion.sql lines: 80 description: Plantillas para generación de PDFs de cotización rf: RF-CRM-003 reused_from_gamilit: false note: "Templates HTML/PDF personalizables" columns: - id (UUID, PK) - constructora_id (UUID, FK) - nombre (TEXT) - descripcion (TEXT) - template_html (TEXT) - estilos_css (TEXT) - active (BOOLEAN) - default (BOOLEAN) - created_at (TIMESTAMPTZ) - updated_at (TIMESTAMPTZ) # RF-CRM-004: Portal del Cliente - name: clientes_portal schema: crm_portal file: apps/database/ddl/schemas/crm_portal/tables/01-clientes_portal.sql lines: 150 description: Usuarios del portal de clientes rf: RF-CRM-004 reused_from_gamilit: false note: "Autenticación separada para clientes" columns: - id (UUID, PK) - constructora_id (UUID, FK) - cliente_id (UUID, FK) - derechohabiente_id (UUID, FK, nullable) - email (TEXT UNIQUE) - password_hash (TEXT) - telefono (TEXT) - status (portal_user_status ENUM) - activacion_token (TEXT, nullable) - activacion_fecha (TIMESTAMPTZ, nullable) - ultimo_acceso (TIMESTAMPTZ, nullable) - preferencias (JSONB) - created_at (TIMESTAMPTZ) - updated_at (TIMESTAMPTZ) indexes: - idx_portal_email (email) - idx_portal_cliente (cliente_id) - idx_portal_derechohabiente (derechohabiente_id) - name: portal_notificaciones schema: crm_portal file: apps/database/ddl/schemas/crm_portal/tables/02-portal_notificaciones.sql lines: 120 description: Notificaciones enviadas a clientes del portal rf: RF-CRM-004 reused_from_gamilit: false note: "Sistema de notificaciones por email/SMS" columns: - id (UUID, PK) - cliente_portal_id (UUID, FK) - tipo (TEXT) - titulo (TEXT) - mensaje (TEXT) - canal (TEXT[]) - enviado (BOOLEAN) - fecha_envio (TIMESTAMPTZ, nullable) - leido (BOOLEAN) - fecha_lectura (TIMESTAMPTZ, nullable) - metadata (JSONB) - created_at (TIMESTAMPTZ) indexes: - idx_portal_notif_cliente (cliente_portal_id, created_at DESC) - name: portal_solicitudes_servicio schema: crm_portal file: apps/database/ddl/schemas/crm_portal/tables/03-portal_solicitudes_servicio.sql lines: 140 description: Solicitudes de servicio post-venta desde el portal rf: RF-CRM-004 reused_from_gamilit: false note: "Garantías y mantenimiento solicitados por cliente" columns: - id (UUID, PK) - cliente_portal_id (UUID, FK) - vivienda_id (UUID, FK) - tipo_solicitud (TEXT) - categoria (TEXT) - descripcion (TEXT) - prioridad (TEXT) - status (TEXT) - fecha_solicitud (TIMESTAMPTZ) - fecha_atencion (TIMESTAMPTZ, nullable) - fecha_resolucion (TIMESTAMPTZ, nullable) - tecnico_asignado_id (UUID, FK, nullable) - notas_tecnico (TEXT) - fotos (JSONB) - created_at (TIMESTAMPTZ) - updated_at (TIMESTAMPTZ) functions: - name: calcular_scoring_prospecto schema: crm file: apps/database/ddl/schemas/crm/functions/calcular_scoring_prospecto.sql lines: "1-50" description: Calcula el scoring de un prospecto según criterios configurados rf: RF-CRM-001 reused_from_gamilit: false note: "Motor de scoring automático" parameters: - prospecto_id UUID returns: INTEGER - name: asignar_prospecto_vendedor schema: crm file: apps/database/ddl/schemas/crm/functions/asignar_prospecto_vendedor.sql lines: "1-60" description: Asigna prospectos a vendedores según reglas de distribución rf: RF-CRM-001 reused_from_gamilit: false note: "Asignación automática o manual" parameters: - prospecto_id UUID - vendedor_id UUID (nullable) returns: BOOLEAN - name: calcular_financiamiento schema: crm file: apps/database/ddl/schemas/crm/functions/calcular_financiamiento.sql lines: "1-100" description: Calcula esquema de financiamiento para cotización rf: RF-CRM-003 reused_from_gamilit: false note: "Motor de cálculo de mensualidades y amortización" parameters: - monto NUMERIC - enganche NUMERIC - plazo INTEGER - tasa NUMERIC returns: JSONB - name: generar_numero_cotizacion schema: crm file: apps/database/ddl/schemas/crm/functions/generar_numero_cotizacion.sql lines: "1-30" description: Genera número secuencial único de cotización rf: RF-CRM-003 reused_from_gamilit: false note: "Formato: COT-{CONSTRUCTORA}-{YEAR}-{SEQ}" parameters: - constructora_id UUID returns: TEXT - name: get_avance_obra_cliente schema: crm_portal file: apps/database/ddl/schemas/crm_portal/functions/get_avance_obra_cliente.sql lines: "1-80" description: Obtiene avance de obra para un cliente desde MOB-005 rf: RF-CRM-004 reused_from_gamilit: false note: "Integración con módulo MOB-005 (Derechohabiente)" parameters: - cliente_portal_id UUID returns: JSONB - name: enviar_notificacion_portal schema: crm_portal file: apps/database/ddl/schemas/crm_portal/functions/enviar_notificacion_portal.sql lines: "1-60" description: Envía notificación a cliente del portal rf: RF-CRM-004 reused_from_gamilit: false note: "Dispara email/SMS según preferencias" parameters: - cliente_portal_id UUID - tipo TEXT - titulo TEXT - mensaje TEXT returns: UUID views: - name: vw_pipeline_ventas schema: crm_comercial file: apps/database/ddl/schemas/crm_comercial/views/01-vw_pipeline_ventas.sql lines: 60 description: Vista de pipeline de ventas por etapa rf: RF-CRM-002 reused_from_gamilit: false note: "Dashboard de embudo de conversión" - name: vw_kpis_vendedor schema: crm_comercial file: apps/database/ddl/schemas/crm_comercial/views/02-vw_kpis_vendedor.sql lines: 80 description: Vista de KPIs por vendedor rf: RF-CRM-002 reused_from_gamilit: false note: "Métricas de desempeño comercial" - name: vw_cotizaciones_activas schema: crm file: apps/database/ddl/schemas/crm/views/01-vw_cotizaciones_activas.sql lines: 50 description: Vista de cotizaciones activas con información completa rf: RF-CRM-003 reused_from_gamilit: false note: "Dashboard de cotizaciones pendientes" rls_policies: - table: crm.prospectos policy: prospectos_select_own_constructora description: Usuarios solo ven prospectos de su constructora rf: RF-CRM-001 reused_from_gamilit: false sql: | CREATE POLICY "prospectos_select_own_constructora" ON crm.prospectos FOR SELECT TO authenticated USING ( constructora_id = get_current_constructora_id() ); - table: crm.prospectos policy: vendedores_see_assigned description: Vendedores ven solo sus prospectos asignados rf: RF-CRM-001 reused_from_gamilit: false sql: | CREATE POLICY "vendedores_see_assigned" ON crm.prospectos FOR SELECT TO authenticated USING ( CASE WHEN get_current_user_role() IN ('director', 'post_sales') THEN constructora_id = get_current_constructora_id() ELSE vendedor_asignado_id = get_current_user_id() END ); - table: crm.cotizaciones policy: cotizaciones_select_own_constructora description: Usuarios solo ven cotizaciones de su constructora rf: RF-CRM-003 reused_from_gamilit: false - table: crm_portal.clientes_portal policy: portal_users_own_data description: Usuarios del portal solo ven sus propios datos rf: RF-CRM-004 reused_from_gamilit: false sql: | CREATE POLICY "portal_users_own_data" ON crm_portal.clientes_portal FOR SELECT TO authenticated USING (id = get_current_portal_user_id()); # ============================================================================ # IMPLEMENTACIÓN - BACKEND # ============================================================================ backend: modules: - name: crm path: apps/backend/src/modules/crm/ description: Módulo principal de CRM rf: [RF-CRM-001, RF-CRM-002, RF-CRM-003] reused_from_gamilit: false note: "Nuevo módulo específico de CRM" - name: crm-portal path: apps/backend/src/modules/crm-portal/ description: Módulo de portal del cliente rf: RF-CRM-004 reused_from_gamilit: false note: "API pública para portal de clientes" services: - name: ProspectosService path: apps/backend/src/modules/crm/services/prospectos.service.ts description: Lógica de gestión de prospectos rf: RF-CRM-001 reused_from_gamilit: false methods: - create() - update() - delete() - findAll() - findById() - calcularScoring() - asignarVendedor() - cambiarEstado() - name: ScoringService path: apps/backend/src/modules/crm/services/scoring.service.ts description: Motor de scoring de prospectos rf: RF-CRM-001 reused_from_gamilit: false methods: - calcularScoringAutomatico() - evaluarCriterios() - actualizarCriterios() - name: InteraccionesService path: apps/backend/src/modules/crm/services/interacciones.service.ts description: Gestión de interacciones comerciales rf: RF-CRM-002 reused_from_gamilit: false methods: - registrarInteraccion() - findByProspecto() - findByVendedor() - programarSeguimiento() - name: PipelineService path: apps/backend/src/modules/crm/services/pipeline.service.ts description: Gestión de pipeline de ventas rf: RF-CRM-002 reused_from_gamilit: false methods: - getEmbudoVentas() - getKPIsVendedor() - getMetasComerciales() - getConversionRates() - name: CotizacionesService path: apps/backend/src/modules/crm/services/cotizaciones.service.ts description: Gestión de cotizaciones rf: RF-CRM-003 reused_from_gamilit: false methods: - crear() - actualizar() - calcularPrecio() - calcularFinanciamiento() - generarPDF() - enviarCliente() - aceptar() - rechazar() - duplicar() - name: FinanciamientoService path: apps/backend/src/modules/crm/services/financiamiento.service.ts description: Motor de cálculo de financiamiento rf: RF-CRM-003 reused_from_gamilit: false methods: - calcularMensualidad() - generarTablaAmortizacion() - calcularEnganche() - validarCreditoInfonavit() - name: PDFGeneratorService path: apps/backend/src/modules/crm/services/pdf-generator.service.ts description: Generación de PDFs de cotización rf: RF-CRM-003 reused_from_gamilit: false note: "Usa biblioteca como puppeteer o pdfmake" methods: - generarCotizacionPDF() - generarPropuestaEconomica() - name: PortalClienteService path: apps/backend/src/modules/crm-portal/services/portal-cliente.service.ts description: Lógica del portal del cliente rf: RF-CRM-004 reused_from_gamilit: false methods: - register() - login() - activarCuenta() - recuperarPassword() - getDashboard() - getAvanceObra() - getEstadoCuenta() - solicitarServicio() - name: NotificacionesPortalService path: apps/backend/src/modules/crm-portal/services/notificaciones-portal.service.ts description: Envío de notificaciones a clientes rf: RF-CRM-004 reused_from_gamilit: false methods: - enviarEmail() - enviarSMS() - notificarHitoObra() - notificarPagoProximo() - name: IntegracionMOB005Service path: apps/backend/src/modules/crm-portal/services/integracion-mob005.service.ts description: Integración con módulo MOB-005 (Derechohabiente) rf: RF-CRM-004 reused_from_gamilit: false note: "Consume API de MOB-005 para datos de avance" methods: - getDerechohabienteInfo() - getAvanceObraDerechohabiente() - getFotosObra() - getHitosCompletados() controllers: - name: ProspectosController path: apps/backend/src/modules/crm/controllers/prospectos.controller.ts description: Endpoints de prospectos rf: RF-CRM-001 reused_from_gamilit: false endpoints: - GET /api/crm/prospectos - GET /api/crm/prospectos/:id - POST /api/crm/prospectos - PUT /api/crm/prospectos/:id - DELETE /api/crm/prospectos/:id - POST /api/crm/prospectos/:id/asignar-vendedor - PUT /api/crm/prospectos/:id/estado - name: InteraccionesController path: apps/backend/src/modules/crm/controllers/interacciones.controller.ts description: Endpoints de interacciones rf: RF-CRM-002 reused_from_gamilit: false endpoints: - GET /api/crm/interacciones - POST /api/crm/interacciones - GET /api/crm/interacciones/prospecto/:id - GET /api/crm/interacciones/vendedor/:id - name: PipelineController path: apps/backend/src/modules/crm/controllers/pipeline.controller.ts description: Endpoints de pipeline y KPIs rf: RF-CRM-002 reused_from_gamilit: false endpoints: - GET /api/crm/pipeline - GET /api/crm/pipeline/vendedor/:id - GET /api/crm/kpis/vendedor/:id - GET /api/crm/kpis/proyecto/:id - name: CotizacionesController path: apps/backend/src/modules/crm/controllers/cotizaciones.controller.ts description: Endpoints de cotizaciones rf: RF-CRM-003 reused_from_gamilit: false endpoints: - GET /api/crm/cotizaciones - GET /api/crm/cotizaciones/:id - POST /api/crm/cotizaciones - PUT /api/crm/cotizaciones/:id - POST /api/crm/cotizaciones/:id/generar-pdf - POST /api/crm/cotizaciones/:id/enviar-cliente - POST /api/crm/cotizaciones/:id/aceptar - POST /api/crm/cotizaciones/:id/rechazar - POST /api/crm/cotizaciones/:id/duplicar - GET /api/crm/cotizaciones/:id/versiones - name: PortalClienteController path: apps/backend/src/modules/crm-portal/controllers/portal-cliente.controller.ts description: Endpoints públicos del portal del cliente rf: RF-CRM-004 reused_from_gamilit: false note: "API pública sin autenticación interna" endpoints: - POST /api/portal/register - POST /api/portal/login - POST /api/portal/activar - POST /api/portal/recuperar-password - GET /api/portal/dashboard - GET /api/portal/avance-obra - GET /api/portal/estado-cuenta - POST /api/portal/solicitar-servicio - GET /api/portal/notificaciones enums: - name: LeadStatus path: apps/backend/src/modules/crm/enums/lead-status.enum.ts description: Enum de estados de prospecto rf: RF-CRM-001 reused_from: null values: - NUEVO = 'nuevo' - CONTACTADO = 'contactado' - CALIFICADO = 'calificado' - HOT = 'hot' - COLD = 'cold' - PERDIDO = 'perdido' - CONVERTIDO = 'convertido' - name: InteractionType path: apps/backend/src/modules/crm/enums/interaction-type.enum.ts description: Enum de tipos de interacción rf: RF-CRM-002 reused_from: null - name: CotizacionStatus path: apps/backend/src/modules/crm/enums/cotizacion-status.enum.ts description: Enum de estados de cotización rf: RF-CRM-003 reused_from: null - name: FinancingType path: apps/backend/src/modules/crm/enums/financing-type.enum.ts description: Enum de tipos de financiamiento rf: RF-CRM-003 reused_from: null dtos: - name: CreateProspectoDto path: apps/backend/src/modules/crm/dto/create-prospecto.dto.ts rf: RF-CRM-001 - name: UpdateProspectoDto path: apps/backend/src/modules/crm/dto/update-prospecto.dto.ts rf: RF-CRM-001 - name: CreateInteraccionDto path: apps/backend/src/modules/crm/dto/create-interaccion.dto.ts rf: RF-CRM-002 - name: CreateCotizacionDto path: apps/backend/src/modules/crm/dto/create-cotizacion.dto.ts rf: RF-CRM-003 - name: CalcularFinanciamientoDto path: apps/backend/src/modules/crm/dto/calcular-financiamiento.dto.ts rf: RF-CRM-003 - name: PortalRegisterDto path: apps/backend/src/modules/crm-portal/dto/portal-register.dto.ts rf: RF-CRM-004 - name: PortalLoginDto path: apps/backend/src/modules/crm-portal/dto/portal-login.dto.ts rf: RF-CRM-004 # ============================================================================ # IMPLEMENTACIÓN - FRONTEND # ============================================================================ frontend: features: - name: crm path: apps/frontend/src/features/crm/ description: Feature de CRM (prospectos, cotizaciones) rf: [RF-CRM-001, RF-CRM-002, RF-CRM-003] reused_from_gamilit: false - name: portal-cliente path: apps/portal-cliente/src/ description: Aplicación separada para portal del cliente rf: RF-CRM-004 reused_from_gamilit: false note: "App independiente Next.js para clientes" components: # RF-CRM-001: Gestión de Prospectos - name: ProspectosList path: apps/frontend/src/features/crm/components/ProspectosList.tsx description: Lista de prospectos con filtros rf: RF-CRM-001 reused_from_gamilit: false - name: ProspectoForm path: apps/frontend/src/features/crm/components/ProspectoForm.tsx description: Formulario de captura/edición de prospecto rf: RF-CRM-001 reused_from_gamilit: false - name: ProspectoDetailPanel path: apps/frontend/src/features/crm/components/ProspectoDetailPanel.tsx description: Panel lateral con detalle de prospecto rf: RF-CRM-001 reused_from_gamilit: false - name: ScoringIndicator path: apps/frontend/src/features/crm/components/ScoringIndicator.tsx description: Indicador visual de scoring rf: RF-CRM-001 reused_from_gamilit: false # RF-CRM-002: Seguimiento Comercial - name: InteraccionesList path: apps/frontend/src/features/crm/components/InteraccionesList.tsx description: Timeline de interacciones rf: RF-CRM-002 reused_from_gamilit: false - name: InteraccionForm path: apps/frontend/src/features/crm/components/InteraccionForm.tsx description: Formulario de registro de interacción rf: RF-CRM-002 reused_from_gamilit: false - name: PipelineBoard path: apps/frontend/src/features/crm/components/PipelineBoard.tsx description: Tablero Kanban de pipeline rf: RF-CRM-002 reused_from_gamilit: false note: "Drag & drop de prospectos entre etapas" - name: KPIDashboard path: apps/frontend/src/features/crm/components/KPIDashboard.tsx description: Dashboard de KPIs comerciales rf: RF-CRM-002 reused_from_gamilit: false note: "Gráficas de conversión, embudo, metas" - name: CalendarioActividades path: apps/frontend/src/features/crm/components/CalendarioActividades.tsx description: Calendario de visitas y seguimientos rf: RF-CRM-002 reused_from_gamilit: false # RF-CRM-003: Cotizaciones - name: CotizacionesList path: apps/frontend/src/features/crm/components/CotizacionesList.tsx description: Lista de cotizaciones rf: RF-CRM-003 reused_from_gamilit: false - name: CotizacionWizard path: apps/frontend/src/features/crm/components/CotizacionWizard.tsx description: Wizard de creación de cotización rf: RF-CRM-003 reused_from_gamilit: false note: "5 pasos: Prospecto, Prototipo, Extras, Financiamiento, Resumen" - name: FinanciamientoCalculator path: apps/frontend/src/features/crm/components/FinanciamientoCalculator.tsx description: Calculadora de financiamiento rf: RF-CRM-003 reused_from_gamilit: false - name: CotizacionPDFViewer path: apps/frontend/src/features/crm/components/CotizacionPDFViewer.tsx description: Visor de PDF de cotización rf: RF-CRM-003 reused_from_gamilit: false - name: CotizacionVersiones path: apps/frontend/src/features/crm/components/CotizacionVersiones.tsx description: Historial de versiones de cotización rf: RF-CRM-003 reused_from_gamilit: false # RF-CRM-004: Portal del Cliente - name: PortalLoginPage path: apps/portal-cliente/src/components/PortalLoginPage.tsx description: Página de login del portal rf: RF-CRM-004 reused_from_gamilit: false - name: PortalDashboard path: apps/portal-cliente/src/components/PortalDashboard.tsx description: Dashboard principal del cliente rf: RF-CRM-004 reused_from_gamilit: false - name: AvanceObraViewer path: apps/portal-cliente/src/components/AvanceObraViewer.tsx description: Visualización de avance de obra rf: RF-CRM-004 reused_from_gamilit: false note: "Fotos, hitos, % avance desde MOB-005" - name: EstadoCuentaCliente path: apps/portal-cliente/src/components/EstadoCuentaCliente.tsx description: Estado de cuenta del cliente rf: RF-CRM-004 reused_from_gamilit: false - name: SolicitudServicioForm path: apps/portal-cliente/src/components/SolicitudServicioForm.tsx description: Formulario de solicitud de servicio rf: RF-CRM-004 reused_from_gamilit: false - name: NotificacionesPortal path: apps/portal-cliente/src/components/NotificacionesPortal.tsx description: Centro de notificaciones del portal rf: RF-CRM-004 reused_from_gamilit: false stores: - name: prospectosStore path: apps/frontend/src/stores/prospectosStore.ts description: Store de prospectos rf: RF-CRM-001 reused_from_gamilit: false - name: interaccionesStore path: apps/frontend/src/stores/interaccionesStore.ts description: Store de interacciones rf: RF-CRM-002 reused_from_gamilit: false - name: cotizacionesStore path: apps/frontend/src/stores/cotizacionesStore.ts description: Store de cotizaciones rf: RF-CRM-003 reused_from_gamilit: false - name: portalClienteStore path: apps/portal-cliente/src/stores/portalClienteStore.ts description: Store del portal del cliente rf: RF-CRM-004 reused_from_gamilit: false pages: - name: ProspectosPage path: apps/frontend/src/pages/crm/prospectos/index.tsx rf: RF-CRM-001 - name: PipelinePage path: apps/frontend/src/pages/crm/pipeline/index.tsx rf: RF-CRM-002 - name: KPIsPage path: apps/frontend/src/pages/crm/kpis/index.tsx rf: RF-CRM-002 - name: CotizacionesPage path: apps/frontend/src/pages/crm/cotizaciones/index.tsx rf: RF-CRM-003 - name: NuevaCotizacionPage path: apps/frontend/src/pages/crm/cotizaciones/nueva.tsx rf: RF-CRM-003 - name: PortalHomePage path: apps/portal-cliente/src/pages/index.tsx rf: RF-CRM-004 - name: PortalAvanceObraPage path: apps/portal-cliente/src/pages/avance-obra.tsx rf: RF-CRM-004 # ============================================================================ # TESTING # ============================================================================ testing: unit_tests: - module: ProspectosService file: apps/backend/src/modules/crm/services/prospectos.service.spec.ts coverage_target: 85% reused_from_gamilit: false - module: ScoringService file: apps/backend/src/modules/crm/services/scoring.service.spec.ts coverage_target: 90% reused_from_gamilit: false - module: CotizacionesService file: apps/backend/src/modules/crm/services/cotizaciones.service.spec.ts coverage_target: 85% reused_from_gamilit: false - module: FinanciamientoService file: apps/backend/src/modules/crm/services/financiamiento.service.spec.ts coverage_target: 95% reused_from_gamilit: false note: "Crítico - Cálculos financieros" - module: PortalClienteService file: apps/backend/src/modules/crm-portal/services/portal-cliente.service.spec.ts coverage_target: 85% reused_from_gamilit: false - module: IntegracionMOB005Service file: apps/backend/src/modules/crm-portal/services/integracion-mob005.service.spec.ts coverage_target: 80% reused_from_gamilit: false e2e_tests: - name: CRM Prospectos E2E file: apps/backend/test/crm/prospectos.e2e-spec.ts scenarios: - Crear prospecto y calcular scoring - Asignar prospecto a vendedor - Cambiar estado de prospecto - Buscar prospectos con filtros reused_from_gamilit: false - name: CRM Cotizaciones E2E file: apps/backend/test/crm/cotizaciones.e2e-spec.ts scenarios: - Crear cotización completa - Calcular financiamiento - Generar PDF - Enviar cotización a cliente - Aceptar/rechazar cotización - Crear nueva versión reused_from_gamilit: false - name: Portal Cliente E2E file: apps/backend/test/portal/portal-cliente.e2e-spec.ts scenarios: - Registro de cliente - Activación de cuenta - Login al portal - Consultar avance de obra - Solicitar servicio post-venta reused_from_gamilit: false integration_tests: - name: Integración MOB-005 file: apps/backend/test/integration/mob005-integration.spec.ts scenarios: - Obtener datos de derechohabiente - Consultar avance de obra desde MOB-005 - Sincronizar hitos de construcción reused_from_gamilit: false note: "Requiere MOB-005 implementado o mock" - name: PDF Generation Integration file: apps/backend/test/integration/pdf-generation.spec.ts scenarios: - Generar PDF de cotización - Validar formato y contenido - Enviar PDF por email reused_from_gamilit: false # ============================================================================ # INTEGRATIONS # ============================================================================ integrations: internal_modules: - module: MOB-005 name: Derechohabiente description: Módulo móvil de seguimiento de derechohabiente integration_type: REST API direction: consume rf: RF-CRM-004 endpoints: - GET /api/mob/derechohabiente/:id - GET /api/mob/derechohabiente/:id/avance-obra - GET /api/mob/derechohabiente/:id/fotos-obra - GET /api/mob/derechohabiente/:id/hitos note: "Portal del cliente consume datos de avance de obra desde MOB-005" - module: MAI-002 name: Proyectos y Estructura description: Información de proyectos y prototipos integration_type: Database FK direction: consume rf: [RF-CRM-001, RF-CRM-003] tables: - proyectos.proyectos - proyectos.prototipos - proyectos.lotes - module: MAI-003 name: Contratos y Ventas description: Conversión de cotización a contrato integration_type: REST API + Event direction: provide rf: RF-CRM-003 events: - cotizacion.aceptada - prospecto.convertido note: "MAI-003 consume cotizaciones aceptadas para generar contratos" external_services: - name: Email Service (SendGrid/AWS SES) description: Envío de emails a clientes rf: RF-CRM-004 note: "Notificaciones del portal" - name: SMS Service (Twilio) description: Envío de SMS rf: RF-CRM-004 note: "Notificaciones urgentes a clientes" - name: PDF Generator (Puppeteer) description: Generación de PDFs rf: RF-CRM-003 note: "Cotizaciones en PDF" - name: WhatsApp Business API description: Integración con WhatsApp rf: RF-CRM-002 note: "Opcional: Registro de interacciones por WhatsApp" # ============================================================================ # MÉTRICAS # ============================================================================ metrics: story_points: planned: 120 completed: 0 variance: 0% budget: planned: 85000 actual: 0 variance: 0% reuse_from_gamilit: infrastructure: 20% database: 0% backend: 30% frontend: 25% overall: 19% complexity: database: high backend: high frontend: medium integrations: high time_saved_weeks: 0.5 note: "Baja reutilización - Módulo específico de CRM" # ============================================================================ # ROADMAP # ============================================================================ roadmap: sprint_8: weeks: [8] goal: "RF-CRM-001 - Gestión de Prospectos" tasks: - Diseñar schema crm.prospectos - Implementar ProspectosService y API - Desarrollar motor de scoring - UI de captura y lista de prospectos - Tests unitarios story_points: 26 deliverables: - "Sistema de captura de prospectos funcional" - "Motor de scoring automático" - "Asignación de prospectos a vendedores" sprint_9: weeks: [9] goal: "RF-CRM-002 - Seguimiento Comercial" tasks: - Diseñar schema crm_comercial - Implementar InteraccionesService y PipelineService - Desarrollar tablero de pipeline - Dashboard de KPIs comerciales - Calendario de actividades - Tests E2E story_points: 29 deliverables: - "Pipeline de ventas con Kanban" - "Dashboard de KPIs por vendedor" - "Sistema de registro de interacciones" sprint_10: weeks: [10] goal: "RF-CRM-003 - Sistema de Cotizaciones" tasks: - Diseñar schema cotizaciones - Implementar motor de financiamiento - Desarrollar wizard de cotización - Integrar generación de PDF - Versionamiento de cotizaciones - Tests de cálculos financieros story_points: 39 deliverables: - "Wizard completo de cotización" - "Motor de cálculo de financiamiento certificado" - "Generación de PDF profesional" - "Sistema de versiones" sprint_11: weeks: [11] goal: "RF-CRM-004 - Portal del Cliente" tasks: - Diseñar schema crm_portal - Implementar autenticación de portal - Desarrollar frontend de portal-cliente app - Integrar con MOB-005 - Sistema de notificaciones - Solicitudes de servicio post-venta - Tests E2E del portal story_points: 26 deliverables: - "Portal del cliente funcional" - "Integración con MOB-005 para avance de obra" - "Sistema de notificaciones email/SMS" - "Módulo de solicitudes post-venta" # ============================================================================ # RISKS & CHALLENGES # ============================================================================ risks: - risk: "Complejidad del motor de financiamiento" impact: high probability: medium mitigation: "Validar fórmulas con experto financiero, tests exhaustivos" - risk: "Integración con MOB-005 requiere que esté implementado" impact: high probability: medium mitigation: "Crear mock de API de MOB-005 para desarrollo en paralelo" - risk: "Generación de PDF puede ser lenta" impact: medium probability: high mitigation: "Usar cola de jobs (Bull/BullMQ) para generación asíncrona" - risk: "Seguridad del portal del cliente" impact: high probability: low mitigation: "Autenticación separada, rate limiting, auditoría de accesos" - risk: "Cálculos de financiamiento incorrectos" impact: critical probability: low mitigation: "Coverage 95%+ en tests de FinanciamientoService, validación manual" # ============================================================================ # DEPENDENCIES # ============================================================================ dependencies: prerequisites: - MAI-001: "Fundamentos (autenticación, multi-tenancy)" - MAI-002: "Proyectos y Estructura (catálogo de prototipos)" parallel: - MAI-003: "Contratos y Ventas (integración bidireccional)" - MOB-005: "Derechohabiente (para portal del cliente)" blocking: - "MOB-005 debe exponerse API de avance de obra para RF-CRM-004" # ============================================================================ # NOTAS # ============================================================================ notes: - "Módulo 100% nuevo - Sin reutilización de GAMILIT" - "Motor de financiamiento crítico - Requiere validación contable" - "Portal del cliente es app separada (Next.js standalone)" - "Integración con MOB-005 es feature diferenciadora clave" - "Considerar WhatsApp Business API para seguimiento comercial" - "PDF templates deben ser configurables por constructora" - "Scoring de prospectos debe ser ajustable por reglas de negocio" - "Pipeline debe soportar múltiples embudos por tipo de proyecto" - "Sistema de notificaciones debe ser escalable (miles de clientes)" - "Considerar integración futura con Facebook Leads Ads"