feat: PWA instalable, cambio de contraseña y dashboards por rol

- POST /api/auth/cambiar-password (bcrypt 12, política ≥8+1 número) +
  modal en las 6 apps con auth
- PWA: manifest + íconos de marca en las 7 apps (sin service worker a
  propósito, documentado); instalable en celular
- Dashboards: 'Mi tablero' para vendedor (sus KPIs y funnel) y sección
  Equipo para coordinador/corporativo/admin
- mi-dia: equipo.porVendedor gana leadsNuevosSemana
- Tests: api 271, cotizador 88, alta 88, cobranza 81, agente-ia 19,
  dashboards 15, mi-dia 11, landing 4
This commit is contained in:
2026-08-28 08:37:41 +00:00
parent aa27e89c75
commit cb86a5190a
80 changed files with 2533 additions and 323 deletions

View File

@@ -166,6 +166,7 @@ describe('resumenMiDia (GET /api/mi-dia/resumen)', () => {
lead({ id: '3', vendedorIds: [MI_ID] }),
lead({ id: '4', vendedorIds: [MI_ID], estado: 'DESCARTADO' }), // terminal: no cuenta
lead({ id: '5', vendedorIds: [OTRO_ID] }),
lead({ id: '6', vendedorIds: [OTRO_ID], createdAt: '2026-08-10T08:00:00' }), // viejo: no es nuevo de la semana
],
})
const nombres = new Map([[MI_ID, 'Martin Zavala']])
@@ -176,8 +177,8 @@ describe('resumenMiDia (GET /api/mi-dia/resumen)', () => {
const rCoord = await resumenMiDia(monday, coordinador, nombres, AHORA)
expect(rCoord.equipo?.leadsNuevosSinAsignar).toBe(1)
expect(rCoord.equipo?.porVendedor).toEqual([
{ mondayUserId: MI_ID, nombre: 'Martin Zavala', leadsAsignados: 1 },
{ mondayUserId: OTRO_ID, nombre: null, leadsAsignados: 1 },
{ mondayUserId: OTRO_ID, nombre: null, leadsAsignados: 2, leadsNuevosSemana: 1 },
{ mondayUserId: MI_ID, nombre: 'Martin Zavala', leadsAsignados: 1, leadsNuevosSemana: 1 },
])
})