feat(contactos): detalle completo del cliente con propiedad e historial

- GET /api/contactos/:id/detalle: todas las columnas del contacto, la
  propiedad comprada/en proceso (apartado relacionado por teléfono/email,
  enriquecido con el desarrollo de la unidad), quién atiende cada item
  relacionado (leads/oportunidades/apartados, columna people) y el
  historial completo de atención (activity log de los 4 tableros +
  capturas y alta local con nombre del capturista)
- monday.service: getContactoDetalle (columnas por título),
  getHistorialItems (todos los eventos del activity log por items) y
  ApartadoMonday enriquecido (teléfono, email, precio final, fecha compra)
- Landing: la lista de Contactos abre un modal por cliente con datos,
  propiedad, relaciones CRM (con quién atiende) y timeline de historial
- Tests: 465 API + 12 landing, verde
This commit is contained in:
2026-09-04 23:55:36 +00:00
parent 27ba9ea8fa
commit a4575bb948
8 changed files with 744 additions and 11 deletions

View File

@@ -62,7 +62,7 @@ import {
listarUsuariosMondayEndpoint,
} from '../controllers/usuarios.controller.js'
import { resumenMiDiaEndpoint } from '../controllers/mi-dia.controller.js'
import { listarContactosEndpoint } from '../controllers/contactos.controller.js'
import { listarContactosEndpoint, detalleContactoEndpoint } from '../controllers/contactos.controller.js'
import { webhookMonday } from '../controllers/webhooks.controller.js'
import {
correrRoundRobin,
@@ -150,6 +150,7 @@ apiRouter.post('/apartados/:itemId/documentos', uploadDocumentosApartado.array('
apiRouter.get('/mi-dia/resumen', resumenMiDiaEndpoint)
apiRouter.get('/contactos', listarContactosEndpoint)
apiRouter.get('/contactos/:id/detalle', detalleContactoEndpoint)
// GET estático: va ANTES de /leads/:itemId para no colisionar con el parámetro
apiRouter.get('/leads/buscar', buscarLeadsEndpoint)