diff --git a/api-gateway/src/services/mi-dia-local.test.ts b/api-gateway/src/services/mi-dia-local.test.ts index 62c055c..6737441 100644 --- a/api-gateway/src/services/mi-dia-local.test.ts +++ b/api-gateway/src/services/mi-dia-local.test.ts @@ -70,7 +70,7 @@ describe('resumenMiDiaLocal (Monday caído)', () => { expect(r.misOportunidades.items.map((o) => o.id)).toEqual(['loc_o1']) expect(r.misOportunidades.items[0]).toMatchObject({ etapa: 'Afluencia', desarrollo: 'SENDA', modeloInteres: '1R' }) expect(r.misApartados.map((a) => a.id)).toEqual(['loc_a1']) - expect(r.misCapturas).toHaveLength(6) + expect(r.misCapturas).toHaveLength(4) // loc_l1 y loc_o1 se excluyen (ya en misLeads/misOportunidades) // Lo que no existe en local va vacío/cero sin romper el front expect(r.misActividadesHoy).toEqual([]) expect(r.apartadosPorVencer).toEqual([]) diff --git a/api-gateway/src/services/mi-dia.service.test.ts b/api-gateway/src/services/mi-dia.service.test.ts index c94d618..cd68061 100644 --- a/api-gateway/src/services/mi-dia.service.test.ts +++ b/api-gateway/src/services/mi-dia.service.test.ts @@ -372,7 +372,7 @@ describe('resumenMiDia (GET /api/mi-dia/resumen)', () => { } }) - it('mis capturas: enriquecidas con la etapa/origen actual de la oportunidad en Monday', async () => { + it('mis capturas: items en misLeads/misOportunidades no se duplican en misCapturas', async () => { const monday = mondayMock({ oportunidades: [oportunidad({ id: '100', nombre: 'Ana López', etapa: 'Contactado', origen: 'WhatsApp', asesorIds: [OTRO_ID] })], }) @@ -380,20 +380,11 @@ describe('resumenMiDia (GET /api/mi-dia/resumen)', () => { { leadId: '100', nombreLead: 'Ana López', telefono: '6641112233', createdAt: new Date('2026-08-27T09:00:00Z') }, ] const r = await resumenMiDia(monday, vendedor, new Map(), capturas, [], AHORA) - // Aunque la afluencia quedó asignada a OTRO por round-robin, la captura es mía - expect(r.misCapturas).toEqual([ - { - leadId: '100', - nombre: 'Ana López', - telefono: '6641112233', - estado: 'Contactado', - origen: 'WhatsApp', - capturadoEn: '2026-08-27T09:00:00.000Z', - }, - ]) + // La captura ya aparece en misLeads (via esMio → idsCapturados), asi que no se duplica + expect(r.misCapturas).toEqual([]) }) - it('mis capturas: capturas rápidas cruzan contra el tablero Leads por id', async () => { + it('mis capturas: captura rapida no se duplica si ya esta en misLeads', async () => { const monday = mondayMock({ leads: [lead({ id: 'lead-9', nombre: 'Pepe Rápido', estado: 'Contactado', origen: 'Web', vendedorIds: [OTRO_ID] })], }) @@ -401,16 +392,8 @@ describe('resumenMiDia (GET /api/mi-dia/resumen)', () => { { leadId: 'lead-9', nombreLead: 'Pepe Rápido', telefono: '4771112233', createdAt: new Date('2026-08-27T09:00:00Z') }, ] const r = await resumenMiDia(monday, vendedor, new Map(), capturas, [], AHORA) - expect(r.misCapturas).toEqual([ - { - leadId: 'lead-9', - nombre: 'Pepe Rápido', - telefono: '4771112233', - estado: 'Contactado', - origen: 'Web', - capturadoEn: '2026-08-27T09:00:00.000Z', - }, - ]) + // La captura ya aparece en misLeads (via esMio → idsCapturados), asi que no se duplica + expect(r.misCapturas).toEqual([]) }) it('mis capturas: si el item ya no existe en ningún tablero, estado y origen van vacíos', async () => { diff --git a/api-gateway/src/services/mi-dia.service.ts b/api-gateway/src/services/mi-dia.service.ts index 94c570e..9920f05 100644 --- a/api-gateway/src/services/mi-dia.service.ts +++ b/api-gateway/src/services/mi-dia.service.ts @@ -400,6 +400,14 @@ export async function resumenMiDia( } }) .sort((a, b) => b.capturadoEn.localeCompare(a.capturadoEn)) + // Excluir de "Mis capturas" los que ya aparecen en "Mis leads" o "Mis + // oportunidades" para no duplicar visualmente cuando el lead existe en + // Monday Y tambien en LeadCaptura (caso creacion con Monday activo). + const idsEnOtrosTabs = new Set([ + ...misLeads.map((l) => l.id), + ...mios.map((o) => o.id), + ]) + const misCapturasSinDuplicados = misCapturas.filter((c) => !idsEnOtrosTabs.has(c.leadId)) // "Mis clientes" es local + cruce con Monday: el alta en progreso lleva // proyecto '', el alta completada lleva el proyecto lleno. estadoApartado @@ -457,7 +465,7 @@ export async function resumenMiDia( generadoEn: ahora.toISOString(), sinMapeoMonday: sinMapeo, misLeads, - misCapturas, + misCapturas: misCapturasSinDuplicados, misClientes, misActividadesHoy, apartadosPorVencer, @@ -661,6 +669,13 @@ export function resumenMiDiaLocal( pendienteSync: c.pendienteSync, })) .sort((a, b) => b.capturadoEn.localeCompare(a.capturadoEn)) + // Excluir de "Mis capturas" los que ya aparecen en "Mis leads" u "Mis + // oportunidades" para no duplicar visualmente. + const idsEnOtrosTabsLocal = new Set([ + ...misLeads.map((l) => l.id), + ...itemsOportunidades.map((o) => o.id), + ]) + const misCapturasSinDuplicadosLocal = misCapturas.filter((c) => !idsEnOtrosTabsLocal.has(c.leadId)) const etapaApartadoPorId = new Map(apartadosLocales.map((a) => [a.leadId, a.etapa])) const misClientes: ClienteMiDia[] = clientes @@ -680,7 +695,7 @@ export function resumenMiDiaLocal( generadoEn: ahora.toISOString(), sinMapeoMonday: usuario.mondayUserId === null, misLeads, - misCapturas, + misCapturas: misCapturasSinDuplicadosLocal, misClientes, misActividadesHoy: [], // no hay tabla local de actividades apartadosPorVencer: [], // los apartados locales aún no guardan fecha límite