diff --git a/src/treatment/queries.mjs b/src/treatment/queries.mjs index b857c32..c2d8ccb 100644 --- a/src/treatment/queries.mjs +++ b/src/treatment/queries.mjs @@ -2,7 +2,7 @@ // exportacoes: o MESMO objeto de filtro que a tela usa para navegar e o que // define quais leads entram num relatorio/exportacao. -import { getWhatsAppVerification } from '../db.mjs'; +import { getWhatsAppVerification, listSharedNumberGroups } from '../db.mjs'; const SORTS = { 'prioridade:asc': 'prioridade ASC, score DESC, cidade ASC, empresa ASC', @@ -75,6 +75,7 @@ export function listLeads(db, filtro = {}) { const orderBy = SORTS[filtro.sort] || SORTS['prioridade:asc']; const total = db.prepare(`SELECT COUNT(*) AS t FROM leads ${whereSql}`).get(...params).t; + const sharedIndex = sharedNumberIndex(db); const rows = db.prepare( `SELECT leads.id AS id, empresa, legal_name, whatsapp, ddd, cidade, uf, segmento, segmento_label, interesse, cnpj, cnae, score, score_qualidade, score_comercial, classificacao, @@ -84,14 +85,15 @@ export function listLeads(db, filtro = {}) { ${whereSql} ORDER BY ${orderBy} LIMIT ? OFFSET ?` - ).all(...params, pageSize, (page - 1) * pageSize).map((lead) => withWhatsAppState(db, lead)); + ).all(...params, pageSize, (page - 1) * pageSize) + .map((lead) => withSharedNumberState(withWhatsAppState(db, lead), sharedIndex)); return { total, page, pageSize, rows }; } export function getLead(db, id) { const storedLead = db.prepare('SELECT * FROM leads WHERE id = ?').get(id); - const lead = storedLead ? withWhatsAppState(db, storedLead) : null; + const lead = storedLead ? withSharedNumberState(withWhatsAppState(db, storedLead), sharedNumberIndex(db)) : null; if (!lead) return null; const exportHistory = db.prepare( @@ -142,6 +144,26 @@ function withWhatsAppState(db, lead) { }; } +function sharedNumberIndex(db) { + const index = new Map(); + for (const group of listSharedNumberGroups(db)) { + for (const lead of group.leads) { + index.set(lead.id, { total: group.leads.length, liberado: group.liberado }); + } + } + return index; +} + +function withSharedNumberState(lead, index) { + const shared = index.get(lead.id); + return { + ...lead, + numero_compartilhado: Boolean(shared), + numero_compartilhado_total: shared?.total || 0, + numero_compartilhado_liberado: shared?.liberado || false + }; +} + export function countLeads(db, filtro = {}) { const { whereSql, params } = buildLeadFilter(filtro); return db.prepare(`SELECT COUNT(*) AS t FROM leads ${whereSql}`).get(...params).t; diff --git a/tests/personal-backend.test.mjs b/tests/personal-backend.test.mjs index 8768195..938aa50 100644 --- a/tests/personal-backend.test.mjs +++ b/tests/personal-backend.test.mjs @@ -140,3 +140,38 @@ test('lead sem verificacao equivalente permanece nao consultado', async () => { } db.close(); }); + +test('listagem e detalhe marcam numero compartilhado por mais de um lead', async () => { + const { openDb, addSharedNumberOverride } = await import('../src/db.mjs'); + const { getLead, listLeads } = await import('../src/treatment/queries.mjs'); + const db = openDb(':memory:'); + const sharedA = db.prepare( + `INSERT INTO leads (dedup_key, empresa, whatsapp, telefone_valido) + VALUES ('shared-a', 'Contabilidade Cliente A', '5575999091780', 1)` + ).run(); + db.prepare( + `INSERT INTO leads (dedup_key, empresa, whatsapp, telefone_valido) + VALUES ('shared-b', 'Contabilidade Cliente B', '557599091780', 1)` + ).run(); + const solo = db.prepare( + `INSERT INTO leads (dedup_key, empresa, whatsapp, telefone_valido) + VALUES ('solo', 'Empresa Unica', '5511999990001', 1)` + ).run(); + + const rows = listLeads(db).rows; + const shared = rows.find((row) => row.id === Number(sharedA.lastInsertRowid)); + const unique = rows.find((row) => row.id === Number(solo.lastInsertRowid)); + assert.equal(shared.numero_compartilhado, true); + assert.equal(shared.numero_compartilhado_total, 2); + assert.equal(shared.numero_compartilhado_liberado, false); + assert.equal(unique.numero_compartilhado, false); + assert.equal(unique.numero_compartilhado_total, 0); + + const detail = getLead(db, Number(sharedA.lastInsertRowid)); + assert.equal(detail.numero_compartilhado, true); + + addSharedNumberOverride(db, '5575999091780', 'revisado'); + const refreshed = getLead(db, Number(sharedA.lastInsertRowid)); + assert.equal(refreshed.numero_compartilhado_liberado, true); + db.close(); +});