Files
FRASA-CAS/api-gateway/src/controllers/contactos.controller.ts
Consult AS Technology 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

55 lines
2.4 KiB
TypeScript

import type { Request, Response } from 'express'
import { detalleContactoLocal, listarContactosLocal, exportarCSV } from '../services/contactos-local.service.js'
import { perfilCompleto } from '../services/contactos-detalle.service.js'
import { NotFoundError } from '../utils/errors.js'
/**
* GET /api/contactos (Bearer) → contactos locales (tabla Cliente + LeadCaptura:
* nombre, teléfono, email, estado), lo más reciente primero, paginado de 100 en
* 100 (?pagina=N; el front muestra el límite). Filtra por usuario actual:
* clientes capturados por él + leads asignados a él.
*/
export async function listarContactosEndpoint(req: Request, res: Response): Promise<void> {
const paginaParam = Number(req.query['pagina'])
const pagina = Number.isFinite(paginaParam) && paginaParam >= 1 ? Math.floor(paginaParam) : 1
res.json(await listarContactosLocal(req.usuarioToken?.sub, pagina))
}
/**
* GET /api/contactos/:id/detalle (Bearer) → ficha completa del contacto armada
* 100% local: sus datos, la propiedad comprada/en proceso (apartado
* relacionado), quién atiende cada item relacionado (leads, oportunidades,
* apartados) y el historial de atención (capturas, altas, documentos y
* cotizaciones locales).
*/
export async function detalleContactoEndpoint(req: Request, res: Response): Promise<void> {
const detalle = await detalleContactoLocal(String(req.params['id']))
if (detalle === null) throw new NotFoundError('Contacto no encontrado')
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)
}