[object Object]

← back to Nationalrealestate

contractors API: default license_status filter to CLEAR (CSLB good-standing)

2f6c9cd1798da35d368070b8ddef29c3da9d153b · 2026-08-12 10:33:23 -0700 · Steve Abrams

CSLB MasterLicenseData has no 'Active' status value — good standing is 'CLEAR'.
Change the /api/contractors default status (buildFilter) and the
/api/contractors/match endpoint's hardcoded status from 'Active' to 'CLEAR'.
status=all still drops the filter. Backs the 230,964-row CSLB master load into
ca_contractors (220,108 CLEAR).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Files touched

Diff

commit 2f6c9cd1798da35d368070b8ddef29c3da9d153b
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Wed Aug 12 10:33:23 2026 -0700

    contractors API: default license_status filter to CLEAR (CSLB good-standing)
    
    CSLB MasterLicenseData has no 'Active' status value — good standing is 'CLEAR'.
    Change the /api/contractors default status (buildFilter) and the
    /api/contractors/match endpoint's hardcoded status from 'Active' to 'CLEAR'.
    status=all still drops the filter. Backs the 230,964-row CSLB master load into
    ca_contractors (220,108 CLEAR).
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
 src/server/contractors.ts | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/server/contractors.ts b/src/server/contractors.ts
index 75cdc2e..afeab51 100644
--- a/src/server/contractors.ts
+++ b/src/server/contractors.ts
@@ -100,8 +100,8 @@ const r_empty = (s: Set<string>) => s.size === 0;
 function buildFilter(q: Request['query'], opts: { defaultStatus?: string } = {}) {
   const params: unknown[] = [];
   const parts: string[] = [];
-  // status: default 'Active'; status=all (or empty) drops the filter
-  const rawStatus = q.status === undefined ? (opts.defaultStatus ?? 'Active') : String(q.status);
+  // status: default 'CLEAR' (CSLB "good standing"; CSLB has no 'Active' value); status=all (or empty) drops the filter
+  const rawStatus = q.status === undefined ? (opts.defaultStatus ?? 'CLEAR') : String(q.status);
   if (rawStatus && rawStatus.toLowerCase() !== 'all') {
     params.push(rawStatus);
     parts.push(`c.license_status = $${params.length}`);
@@ -167,7 +167,7 @@ export function mountContractors(app: Express) {
       const matches: Record<string, any[]> = {};
       for (const code of groups) {
         // $1 = status, $2 = [code] (used by the && classifications filter)
-        const params: unknown[] = ['Active', [code]];
+        const params: unknown[] = ['CLEAR', [code]];
         // nearest-first ranking: exact zip, then city, then county (each a 0/1 DESC key)
         const rank: string[] = [];
         if (zip) { params.push(zip); rank.push(`(c.zip = $${params.length})::int DESC`); }

← 0ef7a6b ca_contractors: date-everything provenance (source_as_of, cs  ·  back to Nationalrealestate  ·  scripts: Kamatera contractor data-load + deploy runbook (TK- 6d30f1f →