feat(ux): 17 mejoras de experiencia de usuario

Backend (10 endpoints nuevos):
- Recordatorios personales (CRUD + tabla RecordatorioVendedor)
- Lead scoring 0-100 (etapa+recencia+datos)
- Dashboard mora (pagos vencidos, monto, días atraso)
- Timeline de pagos (pagado/vence/futuro)
- Perfil completo contacto (pagos+cotizaciones+docs+score)
- Exportar contactos a CSV

Frontend Mi día:
- Resumen matutino (saludo+KPIs)
- Historial visual lead (timeline)
- Score badge 0-100 (verde/amarillo/rojo)
- Vista kanban (drag & drop)

Frontend Cobranza:
- Dashboard mora (tabla+WhatsApp)
- Timeline pagos visual (nodos coloreados)

Frontend Alta Clientes:
- Checklist documentos visual
- Foto cliente (cámara)

Frontend Landing:
- Perfil contacto completo
- Exportar contactos CSV

Frontend Mi día (extras):
- Comparativa mensual
- KPIs dashboard (leads hoy, ventas, conversión)

806 tests, 5 apps construidas.
This commit is contained in:
2026-09-08 07:42:54 +00:00
parent 5063ffe281
commit db18685872
34 changed files with 2950 additions and 33 deletions

View File

@@ -1,7 +1,8 @@
import type { Request, Response } from 'express'
import { mondayService } from '../services/monday.service.js'
import { detalleContacto, claveTelefono } from '../services/contactos-detalle.service.js'
import { detalleContactoLocal, listarContactosLocal } from '../services/contactos-local.service.js'
import { detalleContactoLocal, listarContactosLocal, exportarCSV } from '../services/contactos-local.service.js'
import { perfilCompleto } from '../services/contactos-detalle.service.js'
import { saludMonday } from '../services/salud-monday.service.js'
import { esFalloMonday } from '../services/sync-monday.service.js'
import { prisma } from '../services/prisma.js'
@@ -122,3 +123,28 @@ export async function detalleContactoEndpoint(req: Request, res: Response): Prom
res.json(detalle)
}
}
/**
* GET /api/contactos/:id/completo — perfil completo del contacto:
* datos, historial pagos, cotizaciones, documentos, lead score, última actividad
*/
export async function perfilCompletoEndpoint(req: Request, res: Response): Promise<void> {
const contactoId = String(req.params['id'])
const perfil = await perfilCompleto(contactoId)
if (perfil === null) throw new NotFoundError('Contacto no encontrado')
res.json(perfil)
}
/**
* GET /api/contactos/exportar — exportar contactos a CSV
* Query params: desarrollo, estatus
*/
export async function exportarContactosEndpoint(req: Request, res: Response): Promise<void> {
const csv = await exportarCSV({
desarrollo: (req.query['desarrollo'] as string) ?? undefined,
estatus: (req.query['estatus'] as string) ?? undefined,
})
res.setHeader('Content-Type', 'text/csv; charset=utf-8')
res.setHeader('Content-Disposition', 'attachment; filename="contactos.csv"')
res.send(csv)
}