[object Object]

← back to Rentv Licensed Targets

scaffold: rentv-licensed-targets — dw_unified staging schema + source matrix + attorney spec

08d7f1270ced68659fca979ea3293f9eb7fba4d9 · 2026-07-30 21:17:35 -0700 · Steve

Files touched

Diff

commit 08d7f1270ced68659fca979ea3293f9eb7fba4d9
Author: Steve <steve@designerwallcoverings.com>
Date:   Thu Jul 30 21:17:35 2026 -0700

    scaffold: rentv-licensed-targets — dw_unified staging schema + source matrix + attorney spec
---
 .gitignore         |  6 ++++++
 README.md          | 42 ++++++++++++++++++++++++++++++++++++++++++
 schema.sql         | 41 +++++++++++++++++++++++++++++++++++++++++
 specs/attorneys.md | 14 ++++++++++++++
 4 files changed, 103 insertions(+)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..76a248e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,6 @@
+node_modules/
+.env*
+*.log
+tmp/
+.DS_Store
+dist/
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..35029ad
--- /dev/null
+++ b/README.md
@@ -0,0 +1,42 @@
+# rentv-licensed-targets
+
+Real, named **licensed CRE-adjacent professionals** for the RENTV Growth console — the
+roles the CA-DRE broker registry can't see. Turns the console's LinkedIn-search *lenses*
+(title, escrow, contractors, lenders, attorneys) into drillable **real names**, the same
+way the DRE registry backs Brokers/Owners.
+
+## Scope (Steve-confirmed)
+- **Roles:** Title · Escrow · Contractors/Builders · Lenders & Capital Sources · Attorneys (RE).
+- **Geography:** near-term markets — **SoCal (LA/OC/IE/SD/Ventura) + Arizona (Scottsdale/Maricopa)**, within ~300 mi of the LA core + Scottsdale.
+- **Filter:** **commercial-relevant only** (e.g. CSLB class B general-building + relevant C-classes; CRE lenders; commercial title/escrow).
+
+## Sources (per-role authoritative public registries) — status: DISCOVERY IN FLIGHT
+| Role | Source | Status |
+|------|--------|--------|
+| Contractors | CA **CSLB** + **Arizona ROC** | discovery agent running |
+| Title | CA **DOI** (title insurers / UTCs) + AZ DIFI | discovery agent running |
+| Escrow | CA **DFPI** (Escrow Law licensees) + AZ DIFI | discovery agent running |
+| Lenders | CA **DFPI** (CFL/CRMLA) + **NMLS** + AZ DIFI | discovery agent running |
+| Attorneys | reuse local **calbar / lawyer-directory** infra, else CA/AZ **State Bar** | discovery agent running |
+
+data.ca.gov CKAN was checked and does **NOT** host these — each is a per-agency
+download/scrape (that's what the discovery agents are speccing).
+
+## Honesty rules (non-negotiable)
+- Public **license** data = targeting only, **not** a send list. No email/phone unless the
+  source provides it; never imply contact data we don't have (mirrors `/summit-leads`).
+- Respect each source's **robots.txt / ToS** — especially **NMLS** (reuse restrictions).
+  Any source whose ToS forbids bulk reuse is dropped or handled per its terms, and flagged.
+
+## Pipeline
+1. **Discovery** (agents) → per-source access spec (endpoint, fields, filter, volume, ToS).
+2. **Scrapers** (`scrapers/<source>.mjs`) → normalize to `schema.sql` rows (commercial + 300mi filter).
+3. **Stage** → `rentv_licensed_targets` (local mirror first; canonical dw_unified apply is **gated**).
+4. **Feed** → the `/social` console role facets read it (a new `/api/summit/*`-style route) — **gated** (prod).
+
+## Gates (drafted to `~/.claude/yolo-queue/pending-approval/`)
+- Volume scraping each source (per its ToS).
+- Applying the staging table to **canonical Kamatera dw_unified**.
+- Feeding results into the **live** `/social` console.
+
+Reversible/local work (schema, scraper code, sample pulls to the local mirror) proceeds directly.
diff --git a/schema.sql b/schema.sql
new file mode 100644
index 0000000..c3812ed
--- /dev/null
+++ b/schema.sql
@@ -0,0 +1,41 @@
+-- RENTV licensed-professional targeting dataset — SoCal + Arizona, commercial-relevant.
+-- Source-agnostic staging table. Feeds the /social Growth console's role facets
+-- (title/escrow/contractors/lenders/attorneys), the same way the CA-DRE registry
+-- already backs Brokers/Owners.
+--
+-- HONESTY: every row is a PUBLIC government-license record — targeting data, NOT a
+-- send list. No email/phone unless the source itself provides it. Never imply contact
+-- data we don't have. Mirrors the /summit-leads provenance caveat.
+--
+-- APPLYING THIS to canonical Kamatera dw_unified is a gated action — see
+-- ~/.claude/yolo-queue/pending-approval/rentv-licensed-targets-scrape.md
+
+CREATE TABLE IF NOT EXISTS rentv_licensed_targets (
+  id              bigserial PRIMARY KEY,
+  source          text NOT NULL,        -- cslb | az_roc | dfpi_escrow | dfpi_cfl | doi_title | nmls | ca_state_bar | az_state_bar
+  role            text NOT NULL,        -- Contractor | Title | Escrow | Lender | Attorney
+  entity_name     text NOT NULL,        -- business or person name (as licensed)
+  contact_name    text,                 -- person, when the license is personal
+  license_no      text,
+  license_type    text,                 -- classification / license class (e.g. CSLB "B")
+  license_status  text,
+  address         text,
+  city            text,
+  county          text,
+  state           text DEFAULT 'CA',
+  zip             text,
+  phone           text,                 -- only if the source provides it
+  website         text,                 -- only if the source provides it
+  market          text,                 -- resolved RENTV market: Greater LA | Orange County | Inland Empire | San Diego | Ventura | Arizona
+  commercial_flag boolean,              -- passed the commercial-relevant filter
+  within_300mi    boolean,              -- passed the geo radius (LA core + Scottsdale)
+  source_url      text,
+  raw             jsonb,                -- full original source record (provenance)
+  scraped_at      timestamptz DEFAULT now(),
+  UNIQUE (source, license_no)
+);
+
+CREATE INDEX IF NOT EXISTS idx_rlt_role   ON rentv_licensed_targets (role);
+CREATE INDEX IF NOT EXISTS idx_rlt_market ON rentv_licensed_targets (market);
+CREATE INDEX IF NOT EXISTS idx_rlt_city   ON rentv_licensed_targets (city);
+CREATE INDEX IF NOT EXISTS idx_rlt_comm   ON rentv_licensed_targets (commercial_flag, within_300mi);
diff --git a/specs/attorneys.md b/specs/attorneys.md
new file mode 100644
index 0000000..1a4d455
--- /dev/null
+++ b/specs/attorneys.md
@@ -0,0 +1,14 @@
+# Attorneys (RE) — access spec  [discovery: COMPLETE 2026-07-31]
+
+## Primary path = reuse existing local infra ($0, no new CA scraping)
+- Project: `~/Projects/lawyer-directory-builder`; DB `lawyer_professional_directory` (local PG, /tmp socket) — **separate from dw_unified**.
+- **89,390 attorneys / 52,764 Active**; ~**21,700 Active in SoCal ZIPs** (900–935 = LA/OC/Riverside/SB/SD/Ventura).
+- Proven scraper `src/ingest/calbar_full_scrape.ts` (undici fetch of `apps.calbar.ca.gov/attorney/Licensee/Detail/{barNumber}`, regex parse, no browser/captcha, `--resume` checkpoint). Fields: name, bar_number (UNIQUE), license_status, firm_name, address, city/state/zip, phone. No email, no practice area.
+
+## "CRE attorney" approximation
+- CalBar publishes **NO practice area** (`primary_practice_area` = 0/89,390) and Real Estate is NOT a Certified Legal Specialist field → no native filter.
+- **CA proxy:** on Active + SoCal-ZIP set, `firm ~* 'real estate|realty|commercial|property|development|title|escrow|land use|zoning'` → ~55 high-precision core; widen via firm-website scrape / broker-roster cross-match (project has `discover_websites.ts`, `firm_website_contacts.ts`, `ad_signals.ts`).
+- **AZ:** azbar.org member directory HAS a real-estate practice + Maricopa-county filter → filter at source (no proxy). Needs one Playwright submission to capture the `/search-results` POST params, then replay+paginate. Basic search not login-walled.
+
+## Land in dw_unified staging `rentv_licensed_targets` (role='Attorney', source ca_state_bar/az_state_bar).
+## Gates: local mirror ETL = safe; AZ Playwright pass = trivial paid, run polite + log; canonical dw_unified apply + prod console feed = gated.

(oldest)  ·  back to Rentv Licensed Targets  ·  spec: title-escrow (DFPI escrow feed-first proven, DOI/AZ br e3ccf77 →