[object Object]

← back to Nationalrealestate

TK-16: add CA Ring 4 — Solano (06095) + Butte (06007) + Sacramento (06067) + Stanislaus (06099) — pass 10

dcae6a52b2ca1eecbe150b70dd22e94b5cfd1097 · 2026-08-10 16:33:00 -0700 · Steve Abrams

All COVERAGE-only (AB-1785, priced=0):
- Solano 06095: ~139,708 addressed, richest (value+situs+characteristics), explicit xcentroid/ycentroid.
- Butte 06007: ~190k, SITUS one-line addr (No Address Available->null), explicit Latitude/Longitude, OID=FID.
- Sacramento 06067: 502,081 (biggest Ring-4), street parts+city+zip, centroid latlng.
- Stanislaus 06099: 168,709, situs+zoning, Situs_City 'City ST ZIP' trimmed, centroid latlng.

Verified e2e local (2000 each): 100% latlng all four, addresses populated, Solano valued. tsc clean.
Local master, NOT pushed. FAILED/skip: Kern/Merced/Madera/Shasta (geometry-only or token-gated).

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

Files touched

Diff

commit dcae6a52b2ca1eecbe150b70dd22e94b5cfd1097
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Mon Aug 10 16:33:00 2026 -0700

    TK-16: add CA Ring 4 — Solano (06095) + Butte (06007) + Sacramento (06067) + Stanislaus (06099) — pass 10
    
    All COVERAGE-only (AB-1785, priced=0):
    - Solano 06095: ~139,708 addressed, richest (value+situs+characteristics), explicit xcentroid/ycentroid.
    - Butte 06007: ~190k, SITUS one-line addr (No Address Available->null), explicit Latitude/Longitude, OID=FID.
    - Sacramento 06067: 502,081 (biggest Ring-4), street parts+city+zip, centroid latlng.
    - Stanislaus 06099: 168,709, situs+zoning, Situs_City 'City ST ZIP' trimmed, centroid latlng.
    
    Verified e2e local (2000 each): 100% latlng all four, addresses populated, Solano valued. tsc clean.
    Local master, NOT pushed. FAILED/skip: Kern/Merced/Madera/Shasta (geometry-only or token-gated).
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
 SOURCES.md                         |  9 ++++++-
 src/ingest/parcels/arcgis_sales.ts | 55 ++++++++++++++++++++++++++++++++++++++
 src/ingest/parcels/engine.ts       |  4 +++
 src/jobs/hourly_loop.ts            |  4 +++
 4 files changed, 71 insertions(+), 1 deletion(-)

diff --git a/SOURCES.md b/SOURCES.md
index 83ca367..f7c43ef 100644
--- a/SOURCES.md
+++ b/SOURCES.md
@@ -108,7 +108,7 @@ incl. 8 gated/blocked states → `BROKER-COVERAGE.md`. Adapters: `src/ingest/bro
 
 ## Free priced-DEED feeds — config-driven ArcGIS (`src/ingest/parcels/arcgis_sales.ts`)
 
-Each entry is a keyless ArcGIS REST layer that publishes real recorded SALE PRICE; one `SOURCES` config maps a page of features → parcel row + `parcel_event(event_type='sale')` with grantor/grantee/doc + a `source_url` deep-link. Registered in `parcel_source`, paginated over time by the hourly loop (`src/jobs/hourly_loop.ts`, `runSources` = the config's `cursorKey`). Live configs: `oregon-rlis` (41051/67/05), `spokane` (53063), `alameda` (06001), `deschutes` (41017), `crook` (41013), `sonoma` (06097), `colorado` (statewide composite `08*`), `maricopa` (04013), `thurston` (53067), `palm-beach` (12099), `klamath` (41035), `marion` (41047), `yakima` (53077), `lane` (41039), `jackson` (41029), `orange-county` (06059, coverage-only — AB-1785, no price), `ventura-county` (06111, coverage-only — address), `santa-barbara` (06083, coverage), `imperial` (06025, coverage), `san-bernardino` (06071, coverage), `san-joaquin` (06077, coverage), `fresno` (06019, coverage), `monterey` (06053, coverage).
+Each entry is a keyless ArcGIS REST layer that publishes real recorded SALE PRICE; one `SOURCES` config maps a page of features → parcel row + `parcel_event(event_type='sale')` with grantor/grantee/doc + a `source_url` deep-link. Registered in `parcel_source`, paginated over time by the hourly loop (`src/jobs/hourly_loop.ts`, `runSources` = the config's `cursorKey`). Live configs: `oregon-rlis` (41051/67/05), `spokane` (53063), `alameda` (06001), `deschutes` (41017), `crook` (41013), `sonoma` (06097), `colorado` (statewide composite `08*`), `maricopa` (04013), `thurston` (53067), `palm-beach` (12099), `klamath` (41035), `marion` (41047), `yakima` (53077), `lane` (41039), `jackson` (41029), `orange-county` (06059, coverage-only — AB-1785, no price), `ventura-county` (06111, coverage-only — address), `santa-barbara` (06083, coverage), `imperial` (06025, coverage), `san-bernardino` (06071, coverage), `san-joaquin` (06077, coverage), `fresno` (06019, coverage), `monterey` (06053, coverage), `solano` (06095, coverage), `butte` (06007, coverage), `sacramento` (06067, coverage), `stanislaus` (06099, coverage).
 
 - **Klamath County OR (41035)** — added 2026-07-27 (TK-16). ArcGIS Online FeatureServer `https://services.arcgis.com/H6Mh1bySxR4oHx6x/arcgis/rest/services/KC_ParcelSales/FeatureServer/0` (item `f6314b12b8cc4c35899157172601bf59`, "KC_ParcelSales" = Klamath County Parcel Sales). `where=SALE_PRICE>1000` → **38,796** priced sales. Rich fields: `SALE_PRICE` (int), `SALE_DATE` (epoch-ms), `OWNER_NAME` (→ grantee), `MIN_SITUS_ADDRESS`+`FIRST_CITY_NAME`, `SUM_FINSQFT`/`SUM_BEDRMS`/`SUM_BATH`, `MIN_YRBLT`, `SUM_Tot_Appr` (total appraised → `total_value`), `SALEBK` (→ doc_number, internal double-spaces collapsed by `clean()`), `FIRST_PROP_ID` (→ apn/source_id), `FIRST_PCLCD` (→ use_desc). Server caps pages at 1000. Verified end-to-end against the local `usre` DB (1,000 parcels + 1,000 sale events + links + source registration on first batch).
 
@@ -135,3 +135,10 @@ Ring 3 out from LA (pass 9, all COVERAGE-only — AB-1785):
 - **San Joaquin County CA (06077)** — `https://services2.arcgis.com/GQhSReJEO6f7tsvy/arcgis/rest/services/Parcels/FeatureServer/0`, **252,719** parcels. Rich: `APN`, `FULL_ADDRESS` (one-line incl city/state/zip → address), `SITUSZIP`, `DESCRIPTION` (use), `LAND_VALUE`/`IMPROVEMENT_VALUE` (STRING, no commas → `anyPrice()`; summed → total_value), `YEAR_BUILT`, `TOTALLIV_AREA` (→ sqft), `BEDROOMS`, `BATHROOM_WHOLE`. `maxRecordCount=2000`, OID `OBJECTID`. lat/lng via `centroid:true` (returnCentroid honored).
 - **Fresno County CA (06019)** — `https://gisprod10.co.fresno.ca.us/server/rest/services/FC_PARCEL_SELECT/MapServer/0`, **~412k** parcels with real APN (`where=APN<>''` skips empty-APN head rows). Enterprise SDE MapServer (a `SHAPE.STArea()` helper exists → always explicit outFields). `APN`, `SITEADDRESS1` (street → address), `SITEADDRESS2` (city+zip packed, e.g. "DOS PALOS 93620" → parsed), `TOTAL_ASSESSED_VALUE` (int), `NAME1` (→ owner_name). `maxRecordCount=2000`, OID `OBJECTID` (works though `objectIdField` reports None). lat/lng via `geometry:true` + ring `centroid()` (returnCentroid unsupported).
 - **Monterey County CA (06053)** — `https://services2.arcgis.com/nOGTdfb4kF4dZljH/arcgis/rest/services/Parcels_Data/FeatureServer/0`, **122,448** parcels. No situs address — qualifies via value. `APN`, `Land_Use` (use desc), `Land_Value`/`Imp_Value` (int, summed → total_value), `City` (often literal "None" → null). `maxRecordCount=2000`, OID `OBJECTID`. lat/lng via `centroid:true`. All three verified end-to-end against the local `usre` DB; `tsc` clean.
+
+Ring 4 out from LA (pass 10, all COVERAGE-only — AB-1785; all `maxRecordCount=2000`, integer values):
+
+- **Solano County CA (06095)** — `.../SCn6czzcqKAFwdGU/.../Parcels_Public_Aumentum/FeatureServer/0`, **~139,708** addressed parcels (`where=p_address<>''`). Richest Ring-4 roll: `asmtnum` (→ apn), `p_address`, `sitecity`, `use_desc`, `valland`/`valimp`/`valtv` (total = `valtv` else land+imp), `yrbuilt`, `total_area` (→ sqft), `bedroom`/`bathroom`, explicit `xcentroid`/`ycentroid` (lat/lng). OID `objectid` (lowercase). NOTE: `situs` is a Y/N flag, NOT the address.
+- **Butte County CA (06007)** — `.../3t3QfTXFRFX44zo8/.../Butte_County_Parcel_Public_Data/FeatureServer/0`, **~190k** parcels. No value. `APN`, `SITUS` (one-line address; literal "No Address Available" → null), `LandUse`, explicit `Latitude`/`Longitude`. OID `FID`.
+- **Sacramento County CA (06067)** — `.../5NARefyPVtAeuJPU/.../Parcels/FeatureServer/0`, **502,081** parcels (biggest Ring-4). No value. `APN`, `STREET_NBR`+`STREET_NAM` (→ address), `CITY`, `ZIP` (Double → string), `LU_SPECIF`/`LU_GENERAL` (use). lat/lng via `centroid:true`. OID `OBJECTID`.
+- **Stanislaus County CA (06099)** — `.../EeYBJFxLdUojipYa/.../Public_Parcels/FeatureServer/0`, **168,709** parcels. No value (situs + zoning). `APN`, `Situs_Address`, `Situs_City` (packs "City ST ZIP" → trimmed to city), `Situs_Zip`, `Zoning`. lat/lng via `centroid:true`. OID `OBJECTID`. All four verified end-to-end against the local `usre` DB; `tsc` clean.
diff --git a/src/ingest/parcels/arcgis_sales.ts b/src/ingest/parcels/arcgis_sales.ts
index 9bb77e8..d263f2a 100644
--- a/src/ingest/parcels/arcgis_sales.ts
+++ b/src/ingest/parcels/arcgis_sales.ts
@@ -509,6 +509,61 @@ const SOURCES: Record<string, Source> = {
       return { fips: '06053', apn, city, use: clean(a.Land_Use), lat: num(c.y), lng: num(c.x),
         totalValue: (land || 0) + (imp || 0) || null, raw: a } as Rec; }).filter(Boolean) as Rec[],
   },
+  solano: {
+    // Solano County CA — Ring 4, richest (value + situs + characteristics). AB-1785 → COVERAGE.
+    // Explicit xcentroid/ycentroid fields (no geometry needed). Integer values. `situs` is a Y/N flag,
+    // NOT the address → use p_address; where filters blank-address govt parcels.
+    key: 'solano', label: 'Solano County CA', cursorKey: 'solano', geometry: false, orderBy: 'objectid', pageSize: 2000,
+    layer: 'https://services2.arcgis.com/SCn6czzcqKAFwdGU/arcgis/rest/services/Parcels_Public_Aumentum/FeatureServer/0',
+    where: "p_address<>''",
+    outFields: 'asmtnum,p_address,sitecity,use_desc,valland,valimp,valtv,yrbuilt,total_area,bedroom,bathroom,xcentroid,ycentroid',
+    fieldMap: { source_id: 'asmtnum', address: 'p_address', city: 'sitecity', use_desc: 'use_desc',
+      total_value: 'valtv|valland+valimp', year_built: 'yrbuilt', sqft: 'total_area', beds: 'bedroom', baths: 'bathroom',
+      lat: 'ycentroid', lng: 'xcentroid' },
+    toRecords: (fs) => fs.map(f => { const a = f.attributes; const apn = s(a.asmtnum); if (!apn) return null;
+      const tv = num(a.valtv) || ((num(a.valland) || 0) + (num(a.valimp) || 0) || null);
+      return { fips: '06095', apn, address: clean(a.p_address), city: clean(a.sitecity), use: clean(a.use_desc),
+        lat: num(a.ycentroid), lng: num(a.xcentroid), year: num(a.yrbuilt), sqft: num(a.total_area),
+        beds: num(a.bedroom), baths: num(a.bathroom), totalValue: tv, raw: a } as Rec; }).filter(Boolean) as Rec[],
+  },
+  butte: {
+    // Butte County CA — Ring 4. AB-1785 → COVERAGE, no value on this roll. SITUS is a one-line address
+    // ("492 G ST, BIGGS CA 95917") or the literal "No Address Available" (→ null). Explicit Latitude/Longitude.
+    key: 'butte', label: 'Butte County CA', cursorKey: 'butte', geometry: false, orderBy: 'FID', pageSize: 2000,
+    layer: 'https://services.arcgis.com/3t3QfTXFRFX44zo8/arcgis/rest/services/Butte_County_Parcel_Public_Data/FeatureServer/0',
+    where: 'APN IS NOT NULL',
+    outFields: 'APN,SITUS,LandUse,Latitude,Longitude',
+    fieldMap: { source_id: 'APN', address: 'SITUS', use_desc: 'LandUse', lat: 'Latitude', lng: 'Longitude' },
+    toRecords: (fs) => fs.map(f => { const a = f.attributes; const apn = s(a.APN); if (!apn) return null;
+      let addr = clean(a.SITUS); if (addr && /^no address available$/i.test(addr)) addr = null;
+      return { fips: '06007', apn, address: addr, use: clean(a.LandUse), lat: num(a.Latitude), lng: num(a.Longitude), raw: a } as Rec; }).filter(Boolean) as Rec[],
+  },
+  sacramento: {
+    // Sacramento County CA — Ring 4, biggest here (~502k). AB-1785 → COVERAGE, no value. Address from
+    // STREET_NBR+STREET_NAM; ZIP is a Double. lat/lng via returnCentroid.
+    key: 'sacramento', label: 'Sacramento County CA', cursorKey: 'sacramento', geometry: false, centroid: true, orderBy: 'OBJECTID', pageSize: 2000,
+    layer: 'https://services1.arcgis.com/5NARefyPVtAeuJPU/arcgis/rest/services/Parcels/FeatureServer/0',
+    where: 'APN IS NOT NULL',
+    outFields: 'APN,STREET_NBR,STREET_NAM,CITY,ZIP,LU_SPECIF,LU_GENERAL',
+    fieldMap: { source_id: 'APN', address: 'STREET_NBR+STREET_NAM', city: 'CITY', zip: 'ZIP', use_desc: 'LU_SPECIF', lat: 'centroid.y', lng: 'centroid.x' },
+    toRecords: (fs) => fs.map(f => { const a = f.attributes; const apn = s(a.APN); if (!apn) return null; const c = f.centroid || {};
+      const addr = [s(a.STREET_NBR), clean(a.STREET_NAM)].filter(Boolean).join(' ').trim() || null;
+      const zip = num(a.ZIP) ? String(num(a.ZIP)) : null;
+      return { fips: '06067', apn, address: addr, city: clean(a.CITY), zip, use: clean(a.LU_SPECIF) || clean(a.LU_GENERAL),
+        lat: num(c.y), lng: num(c.x), raw: a } as Rec; }).filter(Boolean) as Rec[],
+  },
+  stanislaus: {
+    // Stanislaus County CA — Ring 4. AB-1785 → COVERAGE, no value (situs + zoning). Situs_City packs
+    // "City ST ZIP" ("Newman CA 95360") → trimmed to city. lat/lng via returnCentroid.
+    key: 'stanislaus', label: 'Stanislaus County CA', cursorKey: 'stanislaus', geometry: false, centroid: true, orderBy: 'OBJECTID', pageSize: 2000,
+    layer: 'https://services.arcgis.com/EeYBJFxLdUojipYa/arcgis/rest/services/Public_Parcels/FeatureServer/0',
+    where: 'APN IS NOT NULL',
+    outFields: 'APN,Situs_Address,Situs_City,Situs_Zip,Zoning',
+    fieldMap: { source_id: 'APN', address: 'Situs_Address', city: 'Situs_City', zip: 'Situs_Zip', lat: 'centroid.y', lng: 'centroid.x' },
+    toRecords: (fs) => fs.map(f => { const a = f.attributes; const apn = s(a.APN); if (!apn) return null; const c = f.centroid || {};
+      let city = clean(a.Situs_City); if (city) city = city.replace(/\s+[A-Z]{2}\s+\d{5}.*$/, '').trim() || null;   // "Newman CA 95360" -> "Newman"
+      return { fips: '06099', apn, address: clean(a.Situs_Address), city, zip: s(a.Situs_Zip), lat: num(c.y), lng: num(c.x), raw: a } as Rec; }).filter(Boolean) as Rec[],
+  },
 };
 
 const execFileP = promisify(execFile);
diff --git a/src/ingest/parcels/engine.ts b/src/ingest/parcels/engine.ts
index 7d421db..3b72e90 100644
--- a/src/ingest/parcels/engine.ts
+++ b/src/ingest/parcels/engine.ts
@@ -47,6 +47,10 @@ const ADAPTERS: Record<string, () => Promise<{ run: () => Promise<{ upserted: nu
   'san-joaquin': async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('san-joaquin') }; },
   fresno: async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('fresno') }; },
   monterey: async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('monterey') }; },
+  solano: async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('solano') }; },
+  butte: async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('butte') }; },
+  sacramento: async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('sacramento') }; },
+  stanislaus: async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('stanislaus') }; },
 };
 
 async function main() {
diff --git a/src/jobs/hourly_loop.ts b/src/jobs/hourly_loop.ts
index 2bbab55..7405165 100644
--- a/src/jobs/hourly_loop.ts
+++ b/src/jobs/hourly_loop.ts
@@ -83,6 +83,10 @@ const JOBS: Job[] = [
   { name: 'parcels-sanjoaquin',script:'src/ingest/parcels/engine.ts', args: ['san-joaquin'],  minIntervalHours: 2, runSources: ['san_joaquin'] },
   { name: 'parcels-fresno',script:'src/ingest/parcels/engine.ts',     args: ['fresno'],        minIntervalHours: 2, runSources: ['fresno'] },
   { name: 'parcels-monterey',script:'src/ingest/parcels/engine.ts',   args: ['monterey'],      minIntervalHours: 2, runSources: ['monterey'] },
+  { name: 'parcels-solano',script:'src/ingest/parcels/engine.ts',     args: ['solano'],        minIntervalHours: 2, runSources: ['solano'] },
+  { name: 'parcels-butte', script: 'src/ingest/parcels/engine.ts',    args: ['butte'],         minIntervalHours: 2, runSources: ['butte'] },
+  { name: 'parcels-sacramento',script:'src/ingest/parcels/engine.ts', args: ['sacramento'],    minIntervalHours: 2, runSources: ['sacramento'] },
+  { name: 'parcels-stanislaus',script:'src/ingest/parcels/engine.ts', args: ['stanislaus'],    minIntervalHours: 2, runSources: ['stanislaus'] },
   // TK-5: full San Diego County (1.09M) via SANDAG — zoning + assessed value; was in engine but missing from rotation.
   { name: 'parcels-sd-sandag', script: 'src/ingest/parcels/engine.ts', args: ['san-diego-sandag'], minIntervalHours: 2, runSources: ['san_diego_sandag'] },
   // TK-5: Santa Clara County CA (San Jose, 493k) — situs address; was in engine but missing from rotation.

← d549281 TK-16: add CA Ring 3 — San Joaquin (06077) + Fresno (06019)  ·  back to Nationalrealestate  ·  TK-16: add CA Ring 5 — Napa + Contra Costa + El Dorado + Nev 834684a →