[object Object]

← back to Marketing Command Center

clients panel: dedup + field-merge in All Prospects (LA groups overlap; keeps richest contact record)

b1d1fc774c13e61601d4e0b1c6faf1d237b9d525 · 2026-07-16 11:59:29 -0700 · steve

Files touched

Diff

commit b1d1fc774c13e61601d4e0b1c6faf1d237b9d525
Author: steve <steve@designerwallcoverings.com>
Date:   Thu Jul 16 11:59:29 2026 -0700

    clients panel: dedup + field-merge in All Prospects (LA groups overlap; keeps richest contact record)
---
 public/panels/clients.js | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/public/panels/clients.js b/public/panels/clients.js
index 6046c59..272b21a 100644
--- a/public/panels/clients.js
+++ b/public/panels/clients.js
@@ -66,11 +66,19 @@ window.MCC_PANELS['clients'] = {
       $('#cl-grouptitle').textContent = d.label;
       $('#cl-list').innerHTML = '<div class="loading">Loading…</div>';
       let data;
-      if (d.files) {                       // merged "All Prospects" — load every group, tag each with its city
+      if (d.files) {                       // merged "All Prospects" — load every group, dedup, merge contact fields
         const parts = await Promise.all(d.files.map(f => jget('/data/' + f).catch(() => null)));
-        const businesses = [];
-        parts.forEach((p, i) => { if (p) (p.businesses || []).forEach(b => businesses.push(Object.assign({ _group: d.labels[i] }, b))); });
-        data = { businesses, source: 'all prospect groups merged', with_email: businesses.filter(b => b.email).length };
+        const hostOf = u => { try { return new URL(u.startsWith('http') ? u : 'http://' + u).hostname.replace(/^www\./, ''); } catch { return ''; } };
+        const seen = new Map();
+        parts.forEach((p, i) => { if (!p) return; (p.businesses || []).forEach(b => {
+          const key = hostOf(b.website) || ((b.title || '').toLowerCase() + '|' + (b.city || '').toLowerCase());
+          if (!seen.has(key)) { seen.set(key, Object.assign({ _group: d.labels[i] }, b)); }
+          else { const ex = seen.get(key);   // fill gaps from the duplicate
+            ex.email = ex.email || b.email; ex.instagram = ex.instagram || b.instagram;
+            ex.linkedin = ex.linkedin || b.linkedin; ex.phone = ex.phone || b.phone; }
+        }); });
+        const businesses = [...seen.values()];
+        data = { businesses, source: `all prospect groups merged (deduped from ${parts.reduce((n, p) => n + (p ? (p.businesses || []).length : 0), 0).toLocaleString()})`, with_email: businesses.filter(b => b.email).length };
       } else {
         try { data = await jget('/data/' + d.file); } catch { $('#cl-list').innerHTML = '<div class="card muted">Could not load ' + esc(d.file) + '.</div>'; return; }
       }

← d544ba1 clients panel: merged ★ All Prospects group (search/sort/fil  ·  back to Marketing Command Center  ·  clients panel: coverage summary (contacts/emails/IG/LinkedIn 5723126 →