[object Object]

← back to Commercialrealestate

modal drill (Cody fixes): gate broker DRE link on verified dre_license not raw regex (+serve.js SELECT), style .maddr a.dl, drop trailing zip space

5d14bae08fb1c0fa3bdfdc8fc2e8ce5564a6bdb7 · 2026-08-03 10:33:52 -0700 · Steve Abrams

Files touched

Diff

commit 5d14bae08fb1c0fa3bdfdc8fc2e8ce5564a6bdb7
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Mon Aug 3 10:33:52 2026 -0700

    modal drill (Cody fixes): gate broker DRE link on verified dre_license not raw regex (+serve.js SELECT), style .maddr a.dl, drop trailing zip space
---
 public/broker-grid.html | 9 ++++++++-
 public/condos.html      | 4 ++--
 scripts/serve.js        | 2 +-
 3 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/public/broker-grid.html b/public/broker-grid.html
index 400df61..ba6b26e 100644
--- a/public/broker-grid.html
+++ b/public/broker-grid.html
@@ -331,7 +331,14 @@ async function openContact(name,id){
   track('broker_modal',{kind:'broker',id:d.broker&&d.broker.id,name:d.broker&&d.broker.name,active:(d.current||[]).length,closed:(d.closed||[]).length,withdrawn:(d.expired||[]).length});
   const b=d.broker, w=b.website?(/^https?:/.test(b.website)?b.website:'https://'+b.website):null;
   const li=b.linkedin?(/^https?:/.test(b.linkedin)?b.linkedin:'https://'+b.linkedin):null;
-  mb.innerHTML='<h3>'+esc(b.name)+atb(b.agent_type)+'</h3><div class="mfirm">'+esc(b.firm||'—')+(b.title?' · '+esc(b.title):'')+(b.license?(function(){const L=String(b.license).trim();return /^\d{8}$/.test(L)?' · DRE# <a href="https://www2.dre.ca.gov/PublicASP/pplinfo.asp?License_id='+encodeURIComponent(L)+'" target="_blank" rel="noopener noreferrer" title="Full CA DRE license record ↗">'+esc(L)+' ↗</a>':' · DRE/MLS '+esc(L);})():'')+'</div>'
+  mb.innerHTML='<h3>'+esc(b.name)+atb(b.agent_type)+'</h3><div class="mfirm">'+esc(b.firm||'—')+(b.title?' · '+esc(b.title):'')+(function(){
+      // Prefer the VERIFIED dre_license column (clean, cross-referenced) over regex-matching the
+      // raw scraped license (Cody gate) — so the DRE# always hooks the correct full CA DRE record.
+      const dl=b.dre_license?String(b.dre_license).trim():'', L=b.license?String(b.license).trim():'';
+      const dre=(dl&&/^\d{7,8}$/.test(dl))?dl:(/^\d{8}$/.test(L)?L:'');
+      if(dre) return ' · DRE# <a href="https://www2.dre.ca.gov/PublicASP/pplinfo.asp?License_id='+encodeURIComponent(dre)+'" target="_blank" rel="noopener noreferrer" title="Full CA DRE license record ↗">'+esc(dre)+' ↗</a>';
+      return L?' · DRE/MLS '+esc(L):'';
+    })()+'</div>'
     +'<div class="ci">'
     +(b.phone?'<a href="tel:'+esc(b.phone)+'">☎ '+esc(b.phone)+'</a>':'<span class="mut">☎ —</span>')
     +(b.email?'<a href="mailto:'+esc(b.email)+'">✉ '+esc(b.email)+'</a>':'<span class="mut">✉ —</span>')
diff --git a/public/condos.html b/public/condos.html
index c36634c..8cefecc 100644
--- a/public/condos.html
+++ b/public/condos.html
@@ -101,7 +101,7 @@
   #modal .maddr{color:var(--mut);font-size:13px;margin-bottom:10px;}
   #modal .litem{display:flex;justify-content:space-between;gap:10px;padding:5px 0;border-bottom:1px solid #20262f;font-size:13px;}
   #modal .litem .m{color:var(--mut);}
-  #modal .litem a.dl{color:var(--blue);text-decoration:none;} #modal .litem a.dl:hover{text-decoration:underline;}
+  #modal .litem a.dl,#modal .maddr a.dl{color:var(--blue);text-decoration:none;} #modal .litem a.dl:hover,#modal .maddr a.dl:hover{text-decoration:underline;}
   #modal .src{font-size:12px;color:var(--mut);margin-top:12px;border-top:1px solid var(--line);padding-top:10px;}
 </style>
 </head>
@@ -484,7 +484,7 @@ function openDetail(id){
   const line=(l,v)=>v==null||v===''?'':`<div class="litem"><span class="m">${esc(l)}</span><span>${v}</span></div>`;
   const ppsf=c.sqft?Math.round(c.price/c.sqft):null;
   mb.innerHTML='<h3>'+esc(c.project_name||c.address||'Condo')+'</h3>'
-    +'<div class="maddr">'+(function(){const q=[c.address,c.city,c.zip].filter(Boolean).join(', ');const txt=esc(c.address||'')+(c.city?', '+esc(c.city):'')+' '+esc(c.zip||'');return q?`<a class="dl" href="https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(q)}" target="_blank" rel="noopener noreferrer" title="Open in Google Maps">${txt} 🗺️</a>`:txt;})()+'</div>'
+    +'<div class="maddr">'+(function(){const q=[c.address,c.city,c.zip].filter(Boolean).join(', ');const txt=esc(c.address||'')+(c.city?', '+esc(c.city):'')+(c.zip?' '+esc(c.zip):'');return q?`<a class="dl" href="https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(q)}" target="_blank" rel="noopener noreferrer" title="Open in Google Maps">${txt} 🗺️</a>`:txt;})()+'</div>'
     +statusBadge(c.warrantable_status||c.warrant_signal||'—')
     +'<div style="margin-top:12px">'
     +line('Price',money(c.price))
diff --git a/scripts/serve.js b/scripts/serve.js
index da7fc97..a35526d 100644
--- a/scripts/serve.js
+++ b/scripts/serve.js
@@ -991,7 +991,7 @@ app.get('/api/broker', async (req, res) => {
     const q = (s, a) => brokerdb.pool.query(s, a).then(r => r.rows);
     // Prefer id (unambiguous — names collide across commercial/residential). For a name lookup,
     // resolve deterministically: the row with the most listings (commercial edges + condos) wins.
-    const sel = `SELECT b.id, b.name, f.name firm, b.phone, b.email, b.title, b.total_assets, b.website, b.agent_type, b.license`;
+    const sel = `SELECT b.id, b.name, f.name firm, b.phone, b.email, b.title, b.total_assets, b.website, b.agent_type, b.license, b.dre_license, b.dre_match`;
     const brokers = id
       ? await q(`${sel} FROM broker b LEFT JOIN firm f ON f.id=b.firm_id WHERE b.id=$1`, [id])
       : await q(`${sel},

← 0d5ac4f detail-modal drill enrichment: condos modal address→Google M  ·  back to Commercialrealestate  ·  detail-modal drill enrichment (index/sales/mls): index broke a06fde2 →