[object Object]

← back to Rentv

feat(services): Property Management now registry-backed (162 DRE-licensed PM firms)

6574a4ffee211a91d1995ddd3819bc7e3a1fabf0 · 2026-08-06 16:30:54 -0700 · Steve

SERVICE_CATS.property → role 'Property Manager' (was featured-only); serviceSpecialty surfaces
the local-model descriptor; ca_dre_pm → 'CA DRE' source label. Real firms + featured majors, with
verified DRE 'Licensed' status + official DRE public-record links.

Files touched

Diff

commit 6574a4ffee211a91d1995ddd3819bc7e3a1fabf0
Author: Steve <steve@designerwallcoverings.com>
Date:   Thu Aug 6 16:30:54 2026 -0700

    feat(services): Property Management now registry-backed (162 DRE-licensed PM firms)
    
    SERVICE_CATS.property → role 'Property Manager' (was featured-only); serviceSpecialty surfaces
    the local-model descriptor; ca_dre_pm → 'CA DRE' source label. Real firms + featured majors, with
    verified DRE 'Licensed' status + official DRE public-record links.
---
 server.js | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/server.js b/server.js
index 14b300ae..4771e30b 100644
--- a/server.js
+++ b/server.js
@@ -1629,10 +1629,11 @@ const SERVICE_CATS = {
   escrow:       { role: 'Escrow',     label: 'Escrow' },
   developers:   { role: 'Developer',  label: 'Developers' },
   legal:        { role: 'Attorney',   label: 'Legal' },
-  // Title + Property Management have NO public license registry we can read, so they are
-  // FEATURED-only (role:null → 0 registry rows, filled entirely by the curated seed below).
-  title:        { role: null,         label: 'Title' },
-  property:     { role: null,         label: 'Property Management' },
+  // Title has no readable public registry → FEATURED-only. Property Management is now
+  // registry-backed: CA property managers hold a DRE broker license, so the ca_dre_pm scraper
+  // mines the DRE firm registry (local-model-classified to commercial/mixed operators).
+  title:        { role: null,               label: 'Title' },
+  property:     { role: 'Property Manager',  label: 'Property Management' },
 };
 // Curated real-firm seed (data/services-featured.json) — guarantees >=1 vendor per category per
 // metro where the registry is thin/absent (Title, Property Mgmt, Legal). Loaded once at startup.
@@ -1697,6 +1698,9 @@ function normCslb(code) {
   return c;
 }
 function serviceSpecialty(role, licenseType) {
+  // Property Manager license_type carries the local-model descriptor (e.g. "Commercial property
+  // & asset management") — surface it verbatim as the specialty.
+  if (role === 'Property Manager') { const s = String(licenseType || '').trim(); return s && !/^property management$/i.test(s) ? s : null; }
   if (role !== 'Contractor') return null;
   const parts = String(licenseType || '').split(/[|,/]+/).map(s => normCslb(s)).filter(Boolean);
   if (!parts.length) return null;
@@ -1705,7 +1709,7 @@ function serviceSpecialty(role, licenseType) {
 }
 const SOURCE_LABELS = {
   cslb: 'CSLB', dfpi_cfl: 'DFPI · CFL', dfpi_escrow: 'DFPI · Escrow',
-  ca_dre_subdivision: 'CA DRE', ca_state_bar: 'CA State Bar',
+  ca_dre_subdivision: 'CA DRE', ca_state_bar: 'CA State Bar', ca_dre_pm: 'CA DRE',
 };
 const nn = v => { const s = String(v == null ? '' : v).trim(); return s || null; }; // '' → null
 function serviceRow(r) {

← fd1945d5 nav: surface /firm (💼 Active Dealmakers) in the site-wide E  ·  back to Rentv  ·  feat(brief): auto-refresh the Boomer 'Deal of the Day' — pul ab40d2bf →