feat: mis clientes en Mi dia + perfilamiento de la afluencia en dashboards

- Cliente.capturadoPorId: el alta (directa y progresiva) registra al
  usuario que la inicio; el panel Mi dia muestra 'Mis clientes' con su
  estado (En captura / Cliente) sin depender de Monday.
- LeadMonday ahora lee las 11 columnas de perfil del tablero Leads
  (estado civil, edad, rango salarial, tipo de empleo/economia,
  califica, credito, modelo, etc.).
- GET /api/reportes/resumen agrega leads.perfil con conteos por
  dimension (valores vacios se omiten; edad en buckets).
- /dash/ gana la seccion 'Perfilamiento de la afluencia' con
  mini-graficas de barras por dimension.
This commit is contained in:
2026-09-02 02:39:19 +00:00
parent 895a831ff8
commit 4030faee25
18 changed files with 551 additions and 14 deletions

View File

@@ -176,6 +176,20 @@ describe('iniciarProgreso (POST /api/clientes/progreso/iniciar)', () => {
expect(status).toHaveBeenCalledWith(201)
expect(json.mock.calls[0]?.[0]).toEqual({ id: 'cli-1', mondayContactoId: null })
})
it('guarda capturadoPorId con el sub del JWT (null sin token)', async () => {
const { iniciarProgreso } = await import('./clientes.controller.js')
const req = reqFake({ datosGenerales: { nombreCompleto: 'Ana Demo' } })
;(req as unknown as { usuarioToken: { sub: string } }).usuarioToken = { sub: 'usr-1' }
await iniciarProgreso(req, resFake().res)
expect(prismaMock.cliente.create).toHaveBeenCalledWith(
expect.objectContaining({ data: expect.objectContaining({ capturadoPorId: 'usr-1' }) }),
)
await iniciarProgreso(reqFake({ datosGenerales: { nombreCompleto: 'Ana Demo' } }), resFake().res)
expect(prismaMock.cliente.create).toHaveBeenLastCalledWith(
expect.objectContaining({ data: expect.objectContaining({ capturadoPorId: null }) }),
)
})
})
describe('actualizarProgreso (PATCH /api/clientes/progreso/:id)', () => {