← back to Nationalrealestate
TK-16: add CA Ring 5 — Napa + Contra Costa + El Dorado + Nevada + Tulare — pass 11
834684ad5850dc59d7b4234ee9fb2823aa107b5f · 2026-08-10 16:53:45 -0700 · Steve Abrams
All COVERAGE-only (AB-1785, priced=0):
- Napa 06055: 51,238, richest (value+situs+characteristics), layer /1 not /0, geometry centroid.
- Contra Costa 06013: 387,862 (largest Ring-5), MapServer, NO ADDRESS->null, geometry centroid.
- El Dorado 06017: 115,731, explicit LAT_Y/LONG_X + owner.
- Nevada 06057: 68,095, MapServer situs+value, geometry centroid.
- Tulare 06107: 159,318, value-only (APN_TXT not numeric APN), geometry centroid.
Verified e2e local (2000 each): 100% latlng all five, values populated. tsc clean.
FAILED/skip: Marin/San Mateo/SF(Socrata not ArcGIS)/Placer/Yolo/Humboldt/Kings — no usable keyless REST.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Files touched
M SOURCES.mdM src/ingest/parcels/arcgis_sales.tsM src/ingest/parcels/engine.tsM src/jobs/hourly_loop.ts
Diff
commit 834684ad5850dc59d7b4234ee9fb2823aa107b5f
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Mon Aug 10 16:53:45 2026 -0700
TK-16: add CA Ring 5 — Napa + Contra Costa + El Dorado + Nevada + Tulare — pass 11
All COVERAGE-only (AB-1785, priced=0):
- Napa 06055: 51,238, richest (value+situs+characteristics), layer /1 not /0, geometry centroid.
- Contra Costa 06013: 387,862 (largest Ring-5), MapServer, NO ADDRESS->null, geometry centroid.
- El Dorado 06017: 115,731, explicit LAT_Y/LONG_X + owner.
- Nevada 06057: 68,095, MapServer situs+value, geometry centroid.
- Tulare 06107: 159,318, value-only (APN_TXT not numeric APN), geometry centroid.
Verified e2e local (2000 each): 100% latlng all five, values populated. tsc clean.
FAILED/skip: Marin/San Mateo/SF(Socrata not ArcGIS)/Placer/Yolo/Humboldt/Kings — no usable keyless REST.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
SOURCES.md | 10 +++++-
src/ingest/parcels/arcgis_sales.ts | 70 ++++++++++++++++++++++++++++++++++++++
src/ingest/parcels/engine.ts | 5 +++
src/jobs/hourly_loop.ts | 5 +++
4 files changed, 89 insertions(+), 1 deletion(-)
diff --git a/SOURCES.md b/SOURCES.md
index f7c43ef..964cd44 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), `solano` (06095, coverage), `butte` (06007, coverage), `sacramento` (06067, coverage), `stanislaus` (06099, 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), `napa` (06055, coverage), `contra-costa` (06013, coverage), `el-dorado` (06017, coverage), `nevada` (06057, coverage), `tulare` (06107, 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).
@@ -142,3 +142,11 @@ Ring 4 out from LA (pass 10, all COVERAGE-only — AB-1785; all `maxRecordCount=
- **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.
+
+Ring 5 out from LA (pass 11, all COVERAGE-only — AB-1785; all `maxRecordCount=2000`, OID `OBJECTID`):
+
+- **Napa County CA (06055)** — `.../Ko5rxt00spOfjMqj/.../Napa_County_Public_Parcels/FeatureServer/1` (layer **/1**, not /0), **51,238** parcels. Richest Ring-5 schema: `ASMTWithDash` (→ apn), `FullSitusAddress1`, `Community` (city), `Zip`, `LandUseDescription`, `TotalLandImprValue`, `YearBuilt`, `Building_Size_SqFt`, `BedroomsCount`, `FullBathsCount`. lat/lng via `geometry:true` + ring `centroid()`.
+- **Contra Costa County CA (06013)** — `https://ccmap.cccounty.us/arcgis/rest/services/CCMAP/Assessment_Parcels_ArcPro/MapServer/0`, **387,862** (largest Ring-5). `APN`, `full_address_display` ("NO ADDRESS - <city>" → null), `s_city`, `S_ZIP` (int), `Description` (use), `LAND_VALUE`+`IMP_VAL` (→ total), `YR_BUILT`, `BLDG_SQFT`. lat/lng via `geometry:true` + ring `centroid()`.
+- **El Dorado County CA (06017)** — `.../5b2oZtu5Eo64aE20/.../wlemp_master_parcels_info/FeatureServer/0`, **115,731**. Has EXPLICIT `LAT_Y`/`LONG_X` (no geometry) + owner. `PRCL_ID` (→ apn), `PRCL_ADDR`, `PO_NAME` (city), `ZIP_CODE`, `USE_CD_LITPRI`, `TOTAL_VAL`, `IMPR_SQ_FT`, `OWNER_NAME`.
+- **Nevada County CA (06057)** — `https://maps.nevadacountyca.gov/arcgis/rest/services/web_public/parcel_mail_situs_external/MapServer/0`, **68,095**. `APN_FORMATTED`, `ADDRESS`, `PostOffice` (city), `ZipCode`, `UseCode`, `TotalLandValue`+`TotalImproveValue` (→ total). lat/lng via `geometry:true` + ring `centroid()`.
+- **Tulare County CA (06107)** — `.../bYBANhmQGwSSLC0l/.../Public_Parcels/FeatureServer/0`, **159,318**. Value-only (no situs). NOTE: use `APN_TXT` (string), NOT `APN` (numeric — drops leading zeros). `USEDSCRP` (use), `LAND_VAL`+`IMP_VAL` (→ total). lat/lng via `geometry:true` + ring `centroid()`. All five 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 d263f2a..15de04c 100644
--- a/src/ingest/parcels/arcgis_sales.ts
+++ b/src/ingest/parcels/arcgis_sales.ts
@@ -564,6 +564,76 @@ const SOURCES: Record<string, Source> = {
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[],
},
+ napa: {
+ // Napa County CA — Ring 5, richest schema (value + situs + characteristics). AB-1785 → COVERAGE.
+ // NOTE: parcel layer is FeatureServer/1 (not /0). lat/lng via geometry ring centroid.
+ key: 'napa', label: 'Napa County CA', cursorKey: 'napa', geometry: true, orderBy: 'OBJECTID', pageSize: 2000,
+ layer: 'https://services1.arcgis.com/Ko5rxt00spOfjMqj/arcgis/rest/services/Napa_County_Public_Parcels/FeatureServer/1',
+ where: 'ASMT IS NOT NULL',
+ outFields: 'ASMTWithDash,FullSitusAddress1,Community,Zip,LandUseDescription,TotalLandImprValue,YearBuilt,Building_Size_SqFt,BedroomsCount,FullBathsCount',
+ fieldMap: { source_id: 'ASMTWithDash', address: 'FullSitusAddress1', city: 'Community', zip: 'Zip', use_desc: 'LandUseDescription',
+ total_value: 'TotalLandImprValue', year_built: 'YearBuilt', sqft: 'Building_Size_SqFt', beds: 'BedroomsCount', baths: 'FullBathsCount' },
+ toRecords: (fs) => fs.map(f => { const a = f.attributes; const apn = s(a.ASMTWithDash); if (!apn) return null;
+ const [lng, lat] = centroid(f.geometry);
+ return { fips: '06055', apn, address: clean(a.FullSitusAddress1), city: clean(a.Community), zip: s(a.Zip),
+ use: clean(a.LandUseDescription), lat, lng, year: num(a.YearBuilt), sqft: num(a.Building_Size_SqFt),
+ beds: num(a.BedroomsCount), baths: num(a.FullBathsCount), totalValue: num(a.TotalLandImprValue), raw: a } as Rec; }).filter(Boolean) as Rec[],
+ },
+ 'contra-costa': {
+ // Contra Costa County CA — Ring 5, largest here (~388k). AB-1785 → COVERAGE. MapServer layer.
+ // full_address_display is sometimes "NO ADDRESS - <CITY>" → nulled. lat/lng via geometry ring centroid.
+ key: 'contra-costa', label: 'Contra Costa County CA', cursorKey: 'contra_costa', geometry: true, orderBy: 'OBJECTID', pageSize: 2000,
+ layer: 'https://ccmap.cccounty.us/arcgis/rest/services/CCMAP/Assessment_Parcels_ArcPro/MapServer/0',
+ where: 'APN IS NOT NULL',
+ outFields: 'APN,full_address_display,s_city,S_ZIP,Description,LAND_VALUE,IMP_VAL,YR_BUILT,BLDG_SQFT',
+ fieldMap: { source_id: 'APN', address: 'full_address_display', city: 's_city', zip: 'S_ZIP', use_desc: 'Description',
+ total_value: 'LAND_VALUE+IMP_VAL', year_built: 'YR_BUILT', sqft: 'BLDG_SQFT' },
+ toRecords: (fs) => fs.map(f => { const a = f.attributes; const apn = s(a.APN); if (!apn) return null;
+ const [lng, lat] = centroid(f.geometry);
+ let addr = clean(a.full_address_display); if (addr && /^NO ADDRESS/i.test(addr)) addr = null;
+ const land = num(a.LAND_VALUE), imp = num(a.IMP_VAL);
+ return { fips: '06013', apn, address: addr, city: clean(a.s_city), zip: num(a.S_ZIP) ? String(num(a.S_ZIP)) : null,
+ use: clean(a.Description), lat, lng, year: num(a.YR_BUILT), sqft: num(a.BLDG_SQFT),
+ totalValue: (land || 0) + (imp || 0) || null, raw: a } as Rec; }).filter(Boolean) as Rec[],
+ },
+ 'el-dorado': {
+ // El Dorado County CA — Ring 5. AB-1785 → COVERAGE. Has EXPLICIT LAT_Y/LONG_X (no geometry needed) + owner.
+ key: 'el-dorado', label: 'El Dorado County CA', cursorKey: 'el_dorado', geometry: false, orderBy: 'OBJECTID', pageSize: 2000,
+ layer: 'https://services1.arcgis.com/5b2oZtu5Eo64aE20/arcgis/rest/services/wlemp_master_parcels_info/FeatureServer/0',
+ where: 'PRCL_ID IS NOT NULL',
+ outFields: 'PRCL_ID,PRCL_ADDR,PO_NAME,ZIP_CODE,USE_CD_LITPRI,TOTAL_VAL,IMPR_SQ_FT,OWNER_NAME,LAT_Y,LONG_X',
+ fieldMap: { source_id: 'PRCL_ID', address: 'PRCL_ADDR', city: 'PO_NAME', zip: 'ZIP_CODE', use_desc: 'USE_CD_LITPRI',
+ total_value: 'TOTAL_VAL', sqft: 'IMPR_SQ_FT', owner_name: 'OWNER_NAME', lat: 'LAT_Y', lng: 'LONG_X' },
+ toRecords: (fs) => fs.map(f => { const a = f.attributes; const apn = s(a.PRCL_ID); if (!apn) return null;
+ return { fips: '06017', apn, address: clean(a.PRCL_ADDR), city: clean(a.PO_NAME), zip: s(a.ZIP_CODE),
+ use: clean(a.USE_CD_LITPRI), lat: num(a.LAT_Y), lng: num(a.LONG_X), sqft: num(a.IMPR_SQ_FT),
+ totalValue: num(a.TOTAL_VAL), grantee: clean(a.OWNER_NAME), raw: a } as Rec; }).filter(Boolean) as Rec[],
+ },
+ nevada: {
+ // Nevada County CA — Ring 5. AB-1785 → COVERAGE. MapServer. lat/lng via geometry ring centroid.
+ key: 'nevada', label: 'Nevada County CA', cursorKey: 'nevada', geometry: true, orderBy: 'OBJECTID', pageSize: 2000,
+ layer: 'https://maps.nevadacountyca.gov/arcgis/rest/services/web_public/parcel_mail_situs_external/MapServer/0',
+ where: 'APN IS NOT NULL',
+ outFields: 'APN_FORMATTED,ADDRESS,PostOffice,ZipCode,UseCode,TotalLandValue,TotalImproveValue',
+ fieldMap: { source_id: 'APN_FORMATTED', address: 'ADDRESS', city: 'PostOffice', zip: 'ZipCode', use_desc: 'UseCode',
+ total_value: 'TotalLandValue+TotalImproveValue' },
+ toRecords: (fs) => fs.map(f => { const a = f.attributes; const apn = s(a.APN_FORMATTED); if (!apn) return null;
+ const [lng, lat] = centroid(f.geometry); const land = num(a.TotalLandValue), imp = num(a.TotalImproveValue);
+ return { fips: '06057', apn, address: clean(a.ADDRESS), city: clean(a.PostOffice), zip: s(a.ZipCode),
+ use: clean(a.UseCode), lat, lng, totalValue: (land || 0) + (imp || 0) || null, raw: a } as Rec; }).filter(Boolean) as Rec[],
+ },
+ tulare: {
+ // Tulare County CA — Ring 5. AB-1785 → COVERAGE. No situs (value-only). NOTE: use APN_TXT (string) not
+ // APN (numeric — drops leading zeros). lat/lng via geometry ring centroid.
+ key: 'tulare', label: 'Tulare County CA', cursorKey: 'tulare', geometry: true, orderBy: 'OBJECTID', pageSize: 2000,
+ layer: 'https://services2.arcgis.com/bYBANhmQGwSSLC0l/ArcGIS/rest/services/Public_Parcels/FeatureServer/0',
+ where: 'APN_TXT IS NOT NULL',
+ outFields: 'APN_TXT,USEDSCRP,LAND_VAL,IMP_VAL',
+ fieldMap: { source_id: 'APN_TXT', use_desc: 'USEDSCRP', total_value: 'LAND_VAL+IMP_VAL' },
+ toRecords: (fs) => fs.map(f => { const a = f.attributes; const apn = s(a.APN_TXT); if (!apn) return null;
+ const [lng, lat] = centroid(f.geometry); const land = num(a.LAND_VAL), imp = num(a.IMP_VAL);
+ return { fips: '06107', apn, use: clean(a.USEDSCRP), lat, lng, totalValue: (land || 0) + (imp || 0) || null, 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 3b72e90..9deedff 100644
--- a/src/ingest/parcels/engine.ts
+++ b/src/ingest/parcels/engine.ts
@@ -51,6 +51,11 @@ const ADAPTERS: Record<string, () => Promise<{ run: () => Promise<{ upserted: nu
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') }; },
+ napa: async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('napa') }; },
+ 'contra-costa': async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('contra-costa') }; },
+ 'el-dorado': async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('el-dorado') }; },
+ nevada: async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('nevada') }; },
+ tulare: async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('tulare') }; },
};
async function main() {
diff --git a/src/jobs/hourly_loop.ts b/src/jobs/hourly_loop.ts
index 7405165..51fa67f 100644
--- a/src/jobs/hourly_loop.ts
+++ b/src/jobs/hourly_loop.ts
@@ -87,6 +87,11 @@ const JOBS: Job[] = [
{ 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'] },
+ { name: 'parcels-napa', script: 'src/ingest/parcels/engine.ts', args: ['napa'], minIntervalHours: 2, runSources: ['napa'] },
+ { name: 'parcels-contracosta',script:'src/ingest/parcels/engine.ts',args: ['contra-costa'], minIntervalHours: 2, runSources: ['contra_costa'] },
+ { name: 'parcels-eldorado',script:'src/ingest/parcels/engine.ts', args: ['el-dorado'], minIntervalHours: 2, runSources: ['el_dorado'] },
+ { name: 'parcels-nevada',script:'src/ingest/parcels/engine.ts', args: ['nevada'], minIntervalHours: 2, runSources: ['nevada'] },
+ { name: 'parcels-tulare',script:'src/ingest/parcels/engine.ts', args: ['tulare'], minIntervalHours: 2, runSources: ['tulare'] },
// 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.
← dcae6a5 TK-16: add CA Ring 4 — Solano (06095) + Butte (06007) + Sacr
·
back to Nationalrealestate
·
TK-16: add Parcel Explorer web viewer (/parcels.html + /api/ d6f64ff →