Commit Graph

118 Commits

Author SHA1 Message Date
ed367582c3 feat(cotizador): tope de mensualidades = meses que faltan para la entrega (UI y API); nunca se rebasa la fecha de entrega 2026-09-29 20:50:25 +00:00
4e3ce67ae7 feat(cotizador): mensualidades del diferimiento = meses faltantes para la entrega estimada de la unidad (captura de obra) 2026-09-29 20:11:24 +00:00
1c1e6b04e4 fix(admin): reasignar mueve toda la cadena del cliente (lead+oportunidad+apartado) y sus actividades pendientes; 404 si el id no existe 2026-09-29 19:42:42 +00:00
9bdd666626 fix(busqueda): telefono por digitos normalizados (espacios/ladas/invisibles) y nombres sin acento 2026-09-29 19:08:51 +00:00
4a3ddd2f35 feat(cotizador): 4 opciones de credito sobre el esquema FRASA (saldo 84.5% con mensualidad estimada)
- Nuevo modulo puro lib/opciones-credito.ts: Bancario, Infonavit-Cofinavit,
  Semi Contado (1%) y Contado (2%), con descuentos del Excel del cliente.
  Cada opcion recalcula el esquema FRASA 2026 sobre el precio final y
  estima la mensualidad del credito (anualidad con tasa y plazo ajustables;
  % de contado para la Semi). Ajustes validados (tasa 0-50%, plazo 1-35).
- Nuevo componente OpcionesCredito: grid de 4 tarjetas con tasa/plazo/% de
  contado editables, mensualidad estimada y boton 'Usar en el PDF'.
- CotizadorPage: estado de ajustes y opcion elegida, memo con try/catch
  (defaults de respaldo), restauracion defensiva al retomar cotizacion.
- PDF: seccion 'PROPUESTA DE FINANCIAMIENTO ELEGIDA' con renglones del
  credito (o pago de contado y ahorro para Contado) + disclaimer.
- API: columna Cotizacion.opcionesCredito (TEXT, JSON {elegida, ajustes})
  con migracion manual aplicada en SQLite; zod max 4000; se persiste crudo
  y los GET devuelven la fila completa.

Tests: cotizador 149/149 (19 nuevos en opciones-credito, 2 en pdf),
API 746/746 (3 nuevos en cotizaciones). Smoke real POST+GET en produccion
local con unidad ATELIER-34 (201 con opcionesCredito; fila de prueba borrada).
2026-09-28 19:56:37 +00:00
61d1b84fc3 feat: esquema unico de cotizacion FRASA 2026 (reemplaza las 4 propuestas)
Flujo aprobado por el cliente (28 sep 2026), porcentajes globales para
todos los desarrollos:
- Apartado: cantidad libre (sin minimo), se acredita dentro del enganche
  de firma; el excedente se descuenta del enganche
- Enganche de firma: 2.5% del precio (saldo a firma = max(0, 2.5% - apartado))
- Enganche: 7.5%, diferible en N mensualidades (N a eleccion del vendedor, 1-36)
- Gastos de escrituracion: 5.5%, pago unico a la firma o diferido con el
  enganche (toggle)

- lib/esquema-frasa.ts (frontend) + cotizacion-esquema.service.ts (backend):
  modulos puros espejo, caso dorado M/apartado 5k/N=14 en tests de ambos
- Migracion 20260928120000: 7 columnas nuevas en Cotizacion (esquema,
  saldoFirma, engancheDiferible, escrituracion, etc.); legacy se rellena
  para compatibilidad de reportes (tipoPropuesta=FRASA_2026)
- UI: panel de linea de tiempo (Hoy -> Firma -> Mensualidades) sustituye a
  propuestas/comparadores; PDF y WhatsApp con el esquema unico
- API recalcula server-side; smoke end-to-end verificado contra inventario
- 743 tests API + 128 cotizador en verde
2026-09-28 13:00:22 +00:00
23d288d0aa feat: columna Asesor en export CSV de contactos
Nombre del usuario que dio de alta cada contacto (cliente: capturadoPor;
lead/oportunidad/apartado: usuarioId). Resuelto con un solo findMany de
Usuario a mapa, sin N+1.
2026-09-26 22:00:29 +00:00
ea03e6eeba chore: limpieza de 26 registros duplicados (motivo Duplicado)
Post-fix del dedup telefonoNorm: descarte de los leads/oportunidades/
apartados duplicados acumulados antes del 26/09. Regla: conservar la
cadena mas avanzada por telefono; el resto queda con etapa terminal y
motivo 'Duplicado' (sin borrar, con entrada de auditoria). Script
idempotente con validacion de board+etapa esperados.
2026-09-26 21:37:07 +00:00
db28af1c58 fix: dedup de leads por telefonoNorm + lock anti-carrera (duplicados)
- Migracion: columna LeadCaptura.telefonoNorm (ultimos 10 digitos) con
  backfill de los 873 registros e indice
- buscarPorTelefono usa telefonoNorm exacto: la busqueda anterior
  'telefono contains' fallaba con telefonos guardados con espacios
  ('+52 664 225 7841' no contiene '6642257841') y dejaba pasar duplicados
- Mutex en memoria por telefono/email: dos envios simultaneos ya no pasan
  juntos la validacion
- convertirLead/apartar propagan telefonoNorm; email se guarda en minusculas
- 8 tests nuevos (normalizacion, dedup con espacios, lock)
2026-09-26 21:19:31 +00:00
6435086181 feat(alta-clientes): telefono obligatorio en alta y afluencia, importacion de informacion Enkontrol por ID en pantalla final y campos de obra movidos a la seccion Obra en captura 2026-09-25 21:41:59 +00:00
2400ecf6ff feat(crm): fecha de alta en cards y bitacora, click en kanban abre bitacora, tab Descartados con reasignacion para admin, tareas al calendario, estatus No asistio y edicion de unidades del inventario 2026-09-25 18:28:14 +00:00
7f663208a0 feat(mi-dia): gate de afluencia para apartar, pestana Afluencia en bitacora, cita cliente con fecha en calendario, filtros por desarrollo/origen corregidos, rangos salariales nuevos y soporte como acceso directo 2026-09-25 10:23:24 +00:00
8a5db114ec feat(mi-dia): captura rapida arriba de actividades, filtro admin por vendedor, hora en notas, orden Intento->Contactado y kanban de oportunidades alineado 2026-09-25 09:21:23 +00:00
8a2584438d fix(auditoria general): 25 errores encontrados en la revision modulo por modulo
SEGURIDAD (agente IA):
- Conversaciones: GET /ai/conversations/:id y el reanudar chat verifican
  propiedad (antes cualquier usuario leia/continuaba la conversacion de otro).
- /ai/documents pasa a solo-admin (antes cualquien podia inyectar o borrar
  documentos de la base de conocimiento).

DATOS / CORRUPCION:
- Cotizador: elegir un cliente del maestro en el buscador ya no crea un lead
  fantasma "Registro previo (CRM anterior)" en el embudo.
- Afluencia con oportunidadId inexistente: 404 en vez de crear sombra fantasma.
- Cobranza: los 103 planes importados quedaron con vendedor asignado (7 con su
  asesor real segun el Excel, el resto al admin) y el motor de recordatorios
  cae al admin cuando un plan no tiene vendedor: antes los 411 recordatorios
  se registraban 'sin-destinatario' y no los veia nadie.
- Backups: script reescrito para el host real (sqlite .backup + uploads + env
  en /root/backups) y cron instalado (antes: script que asumia docker y sin
  cron programado = cero respaldos).

REPORTES / METRICAS:
- Mi tablero: el embudo ya excluye cancelaciones reales (Cancelo/Cancelacion
  Apartado) y cuenta como vendidos Firma Cliente/Escriturado/Titulado (antes
  41 "apartados" donde habia 13 activos y vendidos buscaba una etapa que no
  existe); tasa de descarte ya compara el mismo periodo.
- Scoring: etapa real 'Agendo Cita' (antes 'AGENDO' nunca aplicaba) y los
  descartados/perdidos ya no reciben score.
- ver_cobranza (IA): ignora planes cancelados y no cuenta como vencido el pago
  que vence hoy.

UI / FLUJOS:
- mi-dia: typo CANCO -> CANCELO (los cancelados reaparecen en Escrituracion);
  confirmar cita ya no retrocede la etapa de Cotizador/Aparto (boton y kanban).
- alta-clientes: la firma ya no se borra al navegar fuera del paso de firmas;
  toast de exito solo cuando el API confirma; prefill de apartado trae
  direccion, estado civil y fecha de nacimiento desde el alta.
- Auditoria: el filtro por usuario funciona (el front enviaba 'usuario' y el
  API esperaba 'usuarioId') y 'hasta' incluye todo el dia.
- Contactos: paginacion aplicada despues de fusionar fuentes (antes saltaban o
  se repetian contactos entre paginas y 'Siguiente' se deshabilitaba antes de
  tiempo).
- Buscador global: leads -> /hoy/, contactos -> /; el cotizador entiende
  ?cotizacion=<id> para retomar desde la liga.
- Export mi-dia: columnas Desarrollo/Origen rellenas y sin duplicados.
- Recibo de cobranza: "Recibio" es FRASA (el cliente paga, no recibe).
- Alta de plan de cobranza: proyecto libre con sugerencias del catalogo real
  (antes limitado a 3 proyectos que no cubrian la cartera).

Verificado en vivo: autorizacion IA (3x 403), filtro de auditoria, 404 de
afluencia. Suites: 717 API + 124 alta-clientes + 115 cotizador + 92 cobranza +
89 landing + 32 mi-dia en verde. Backup de hoy generado en /root/backups.
2026-09-24 10:54:09 +00:00
cfc0acb5d3 fix(crm): re-captura tras limpieza, bitacora compartida, origen en oportunidades y privacidad del buscador
1. Re-captura: el dedup por telefono/email ya no considera etapas cerradas
   (Descartado, Perdido, Cancelo, Cancelacion Apartado). Los restos de la
   ultima limpieza (17 filas de APARTADO cancelados sin contraparte activa)
   bloqueaban a los vendedores al re-capturar; los registros activos siguen
   bloqueando con 409 como siempre.
2. Bitacora compartida: GET /recordatorios con leadId/clienteClave devuelve las
   notas de TODOS los usuarios de ese cliente (antes cada quien solo veia las
   suyas). Mi dia pide la bitacora con esos filtros; la lista personal sigue
   siendo propia.
3. Origen en oportunidades: el resumen de mi-dia ya devuelve origen y la card
   de cada oportunidad lo muestra (telefono · desarrollo · canal · modelo).
4. Privacidad del buscador: /leads/buscar y /buscar filtran por dueno cuando
   el rol es vendedor (leads por usuarioId, contactos por capturadoPorId,
   cotizaciones por vendedorId). Los roles de supervision siguen viendo todo.
   Ya no aparecen leads de otros asesores con nombre y telefono al teclear.

Verificado en vivo contra el API: 10/10 comprobaciones (re-captura del
telefono cancelado 201, duplicado activo 409, nota del admin visible para la
vendedora, origen presente en 27/27 oportunidades, buscador del vendedor sin
datos ajenos y del admin completo). 716 pruebas del API y 32 de mi-dia en verde.
Los tests de roles ahora usan prisma mockeado (la BD viva cambia cuando el
cliente edita permisos desde la UI).
2026-09-24 09:49:41 +00:00
d6548999bf feat(desarrollos): modulo de alta de desarrollos con inventario, reglas del cotizador por desarrollo y micrositio publico
Modulo nuevo (solo admin) para dar de alta desarrollos sin tocar codigo:
- CRUD de la ficha, modelos e inventario (alta manual y generador por rango)
- Reglas del cotizador por desarrollo, editables y persistidas en la BD
- El cotizador consume las reglas desde /desarrollos/reglas-cotizador y cae a
  las constantes con aviso cuando un desarrollo aun no tiene reglas guardadas
- Micrositio publico en /d/:clave (sin sesion) con ficha, modelos y
  disponibilidad; jamas expone datos de clientes ni cotizaciones

Integracion:
- La landing monta el modulo en el grid (clave 'desarrollos', solo admin) y el
  micrositio fuera del login; el rol manager NO accede (matriz y API con 403)
- La tabla de roles de Configuracion ahora lista todos los modulos
- Se alinea la FK de ReglaCotizadorDesarrollo con la BD viva (Desarrollo.id)

Verificado: 708 pruebas del API, 115 del cotizador y 89 de la landing en verde;
12/12 cotizaciones identicas antes y despues del cambio de reglas; prueba en
vivo del API con alta, modelos, inventario, reglas, micrositio y baja (30/30).
2026-09-21 09:52:47 +00:00
2fc80e7f9e feat(pendientes): cotizador (mensualidades, bloqueo de unidad, totales, numMensualidades), cobranza (recibos, atrasos, mora configurable, recordatorios), soporte (adjuntos, filtros, estados), clientes maestro (catalogos reales), contactos (ficha y duplicados) y permisos de captura por rol 2026-09-21 08:34:53 +00:00
b5a20aed4e fix(mi-dia,captura): exportar en escrituracion y avance real sin contar checkboxes en false 2026-09-21 07:20:34 +00:00
5e9b2ac456 fix(auditoria completa): bloqueos de Mi Dia, cobranza (saldos y fechas), captura (departamento y rol), contactos (privacidad), cotizador (QR) y validaciones de API 2026-09-21 07:18:39 +00:00
75956a709f fix(crm-local): etapa tolerante a null en la actualizacion de afluencia 2026-09-18 16:06:33 +00:00
656116c4e5 fix(auditoria): afluencia (validacion, update sin perder datos ni retroceder etapa, dedup cruzado, notas), alta cliente (registro tras firma, documentos por cliente, aviso de fallos) y reporte de clientes aplanado 2026-09-18 16:05:18 +00:00
4965a4488a feat: rol manager, arreglos de reportes (cancelacion/afluencias), credito unico, cliente enkontrol, vendedor en bitacora y actualizar afluencia existente 2026-09-18 15:25:34 +00:00
84582ce6a2 feat(auditoria): mostrar el nombre del usuario en lugar del id (tabla y filtro) 2026-09-17 08:54:56 +00:00
9643f866cc feat(chat-frasa): acceso total a datos (13 herramientas con escopo por rol), streaming SSE, caché de embeddings, markdown y mantenimiento en Configuraciones 2026-09-17 08:41:21 +00:00
278a79c984 fix(reportes): select con rol/activo para la lista de vendedores 2026-09-17 07:19:45 +00:00
8bcb093fec feat(reportes): módulo de Reportes con 10 reportes, filtros y descarga Excel 2026-09-17 07:18:34 +00:00
31f83b0504 fix(mi-dia): admin reasigna/mueve leads, capturista real en cards, datos en apartados, INE obligatoria y bitácora persistente 2026-09-17 06:54:57 +00:00
b99707689f feat(config): alta de usuarios desde Configuraciones (POST /config/usuarios, solo admin) 2026-09-14 20:21:15 +00:00
31379806be fix(cobranza): invariante engancheTotal=plan completo, pago 0 inicial y abonos al pago correcto 2026-09-12 22:58:23 +00:00
34229f1894 fix(catalogos): SOLE y MUTUO en desarrollos de alta lead/afluencia/cliente y filtros 2026-09-12 22:41:15 +00:00
47b00bb6eb fix(cobranza): reimport del maestro con fechas reales y abonos (AplicacionPago) 2026-09-12 09:32:31 +00:00
411130a127 fix(captura): llenar ubicacion con codigo canonico y modelo faltante desde inventario 2026-09-12 09:13:31 +00:00
6473fb5981 fix(captura): reimport del maestro con mapeo explicito por hoja (unidades canonicas, fechas YYYY-MM-DD) 2026-09-12 08:40:39 +00:00
b2d3287c31 feat(captura): Escrituracion con 3 pares fecha+checkbox y columna Desviacion en dias 2026-09-12 08:03:44 +00:00
d2e97f33f5 feat(captura): fechas de Obra bloqueadas tras establecerse, solo admin las cambia 2026-09-12 07:52:40 +00:00
1791dd69ba feat(captura): fecha junto a checkboxes de Obra con semaforo verde/rojo 2026-09-12 07:30:23 +00:00
852182fabc fix(6-mejoras): subcategoría+apartado libre+PDF+coacreditado+docs+dedup
1. Subcategoría en modal descarte (catálogo completo + select)
2. Apartado sin monto mínimo (eliminada validación de 0,000)
3. PDF solo con propuesta elegida (no las 4)
4. Co-acreditado: checkbox 'no tiene' valida sin campos obligatorios
5. Documentos apartado: previsualizar + descargar (endpoint + frontend)
6. Oportunidades: sin duplicados, orden Confirmar→Afluencia→Cotizar→Aparto(verde)→Descartar
2026-09-12 07:09:15 +00:00
c8357fe582 feat(7-mejoras): notas persisten + soporte + captura visible
1. Notas propagan entre etapas (convertirLead/apartar updateMany)
2. Afluencia: conexión → aviso amarillo
3. Escrituración: click nombre abre bitácora
4. Co-acreditado: opción 'no tiene'
5. Nota del alta de lead → bitácora
6. Módulo Soporte: formulario + listado solicitudes
7. Captura visible para todos
2026-09-11 23:17:25 +00:00
1ba7aa49da feat(mejoras): 22 mejoras UX en todos los módulos
Mi día: cancelación con motivo, conteo escrituración real, cita sin retroceder, calendario completo
Cobranza: MoraDashboard respeta alcance, hoy dinámico, cancelar con motivo
Landing: contactos paginados, error vs vacío diferenciado
Dashboards: KPI renombrado, drill-down planes activos
Chat: historial recarga, preguntas rotativas, error solo toast
Transversal: shadow-sm corrupto corregido en 9 archivos

553 API tests + 7 apps construidas
2026-09-11 12:48:47 +00:00
89d95eb53b feat(purga): Monday eliminado completamente del sistema
14 servicios eliminados, 7 controllers local-only, crons locales,
config sin MONDAY_*, frontend sin banners/avisos Monday.
552 tests API + 7 apps construidas.
2026-09-11 11:47:17 +00:00
64b01246d6 feat(mejoras): 25 mejoras UX en todos los módulos + purga Monday
Backend: mi-dia siempre local, vocabulario canónico, AplicacionPago con usuario
Mi día: modal español real, cita desde modal, score falso eliminado
Cotizador: barra sticky, persistencia local con folio
Alta Clientes: redirect eliminado, foto conectada, asesor desde sesión, refs dinámicas
Cobranza: contrato Mora arreglado, link a Plan, abono próximo pago, WhatsApp
Landing: contactos locales, ModalContacto eliminado, ModoTrabajo eliminado
Dashboards: MiTablero unificado, funnel con descartados, drill-down, rango fechas
Chat FRASA: corpus 5 desarrollos, 6 herramientas, historial conversaciones

69 archivos, 7 apps construidas
2026-09-11 06:52:37 +00:00
075d47c304 fix(mi-dia): 5 bugs críticos + 8 mejoras UX
Bugs críticos: descartar, kanban drag&drop, escrituración, fases API, export filtros
UX: tel clicable, WhatsApp, filtros por tab, tareas, calendario, estado, notas, navegación
2026-09-11 02:05:25 +00:00
fabf507aa0 fix(citas): aceptar datetime-local en validación de etapa
- Backend: fecha ya no requiere formato YYYY-MM-DD, acepta datetime-local
- El input datetime-local del frontend envía 'YYYY-MM-DDTHH:mm'
2026-09-11 00:36:56 +00:00
b1e408f435 fix(notas): notas persisten entre etapas via clienteClave
- Campo clienteClave en RecordatorioVendedor (hash nombre+telefono)
- Al crear nota: se calcula clienteClave del lead/cliente
- Al buscar notas: busca por leadId O clienteClave (no por nombre suelto)
- Mantiene compatibilidad: notas viejas sin clienteClave siguen por leadId
- Migración SQL aplicada
2026-09-10 22:55:11 +00:00
44360591b0 feat(hermes): 4 herramientas nuevas + índices DB
Hermes ahora puede:
- buscar_leads: buscar leads por nombre/teléfono/email
- ver_cliente: info completa de un cliente
- ver_oportunidades: pipeline de ventas con filtro por etapa
- ver_cobranza: resumen de pagos vencidos

Índices DB: LeadCaptura.nombreLead, Cliente.nombreCompleto, PlanPago.status
38 tests nuevos pasan.
2026-09-10 21:11:01 +00:00
16cacd5f31 feat(9-mejoras): limpieza leads + admin CRUD + calendario + CRM360 FRASA
1. Leads limpiados (207 eliminados, 18 apartados conservados)
2. Round-robin desactivado (config round_robin_habilitado=false)
3. Admin puede borrar/reasignar/mover leads (DELETE/PATCH/POST)
4. Calendario: fechaCita guardada y pasada correctamente
5. Avisos Monday eliminados (BannerModoLocal, ChipPendienteSync, vinculación)
6. Contactos filtrados por usuario asignado
7. Modal bitácora: notas persisten entre fases
8. Fases oportunidades: Agendo→Afluencia→Cotizar→Aparto
9. Toast de nota eliminado en cambios de status
10. Branding: CRM360 FRASA + logo en todas las apps
11. 7 apps construidas
2026-09-10 07:05:40 +00:00
356bf46216 fix(escrituracion): fases reordenadas según solicitud
- Fases: Venta → Seguimiento → Integración → X Autorizar → Autorizado
  → X Escriturar → Escriturado → Titulado → Cancelo
- Kanban y botones actualizados con el nuevo orden
- obtenerColumnaEscrituracion actualizado
- Backend FASES_APARTADO_PERMITIDAS actualizado
2026-09-09 10:41:38 +00:00
d546460ba4 feat(8-mejoras): cancelar+motivo, brocker, etapas, calendario, modal cliente
1. Cancelar con motivo: Mis apartados y Escrituración piden motivo (modal reutilizado)
2. Origen BROCKER agregado en alta afluencia y captura rápida
3. Etapas oportunidades reordenadas: Agendo Cita → Afluencia → Cotizador
4. Cotizador: mensualidades diferibles (6, 12, 14, 18, 24 meses)
5. Calendario semanal por vendedor en Mi día
6. Hora en citas (datetime-local en vez de solo fecha)
7. Click en nombre → modal DetalleLeadModal (info + notas + historial)
2026-09-09 10:26:36 +00:00
6db9662838 fix(mi-dia): mostrar desarrollo en cards de leads
- LeadMiDia ahora incluye campo 'desarrollo'
- Backend: mapeado desde Monday leads y desde LeadCaptura local
- Frontend: FilaLead muestra teléfono · desarrollo · origen
2026-09-08 18:26:58 +00:00
98fe6dd8bf fix(escrituracion): todosApartados incluido en resumenMiDiaLocal
- resumenMiDiaLocal ahora retorna 'todosApartados' (APARTADO filtrado)
- Incluye terminales como Firma Cliente, Escriturado, Cancelo
- Escrituración filtra sobre estos y solo muestra fases de escrituración
- Admin ahora ve 10 apartados en Escrituración (3 con Firma Cliente)
2026-09-08 10:22:30 +00:00