← back to Nationalrealestate
Add Deschutes County OR deed adapter (real grantor/grantee NAMES + price, two sales/parcel)
9a64e4e1a7a253812150b49d9cb058e41d0638f2 · 2026-07-26 08:39:45 -0700 · Steve Abrams
Files touched
M src/ingest/parcels/arcgis_sales.tsM src/ingest/parcels/engine.tsM src/jobs/hourly_loop.ts
Diff
commit 9a64e4e1a7a253812150b49d9cb058e41d0638f2
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Sun Jul 26 08:39:45 2026 -0700
Add Deschutes County OR deed adapter (real grantor/grantee NAMES + price, two sales/parcel)
---
src/ingest/parcels/arcgis_sales.ts | 20 ++++++++++++++++++++
src/ingest/parcels/engine.ts | 1 +
src/jobs/hourly_loop.ts | 1 +
3 files changed, 22 insertions(+)
diff --git a/src/ingest/parcels/arcgis_sales.ts b/src/ingest/parcels/arcgis_sales.ts
index 0c08ad8..8d8c9a2 100644
--- a/src/ingest/parcels/arcgis_sales.ts
+++ b/src/ingest/parcels/arcgis_sales.ts
@@ -97,6 +97,26 @@ const SOURCES: Record<string, Source> = {
return [...byDoc.values()];
},
},
+ deschutes: {
+ key: 'deschutes', label: 'Deschutes County OR (Bend)', cursorKey: 'deschutes', geometry: false, orderBy: 'Taxlot',
+ layer: 'https://maps.deschutes.org/arcgis/rest/services/OpenData/TablesFD/MapServer/9',
+ where: 'Total_Sales_Price_1>1000',
+ outFields: 'Taxlot,Total_Sales_Price_1,Sales_Date_1,Seller_1,Buyer_1,Book_Page_1,Total_Sales_Price_2,Sales_Date_2,Seller_2,Buyer_2,Book_Page_2',
+ // Two sales per row (_1 newest, _2 prior), each with REAL grantor/grantee NAMES.
+ toRecords: (fs) => {
+ const out: Rec[] = [];
+ for (const f of fs) {
+ const a = f.attributes; const apn = s(a.Taxlot); if (!apn) continue;
+ for (const nx of ['1', '2']) {
+ const price = num(a['Total_Sales_Price_' + nx]); const date = epochToISO(a['Sales_Date_' + nx]);
+ if (!price || !date) continue;
+ out.push({ fips: '41017', apn, price, saleDate: date, grantor: clean(a['Seller_' + nx]),
+ grantee: clean(a['Buyer_' + nx]), docNum: s(a['Book_Page_' + nx]) || `${date}-${nx}` } as Rec);
+ }
+ }
+ return out;
+ },
+ },
};
async function fetchPage(src: Source, offset: number): Promise<any[]> {
diff --git a/src/ingest/parcels/engine.ts b/src/ingest/parcels/engine.ts
index 9a98b11..2e89c4f 100644
--- a/src/ingest/parcels/engine.ts
+++ b/src/ingest/parcels/engine.ts
@@ -16,6 +16,7 @@ const ADAPTERS: Record<string, () => Promise<{ run: () => Promise<{ upserted: nu
'oregon-rlis': async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('oregon-rlis') }; },
spokane: async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('spokane') }; },
alameda: async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('alameda') }; },
+ deschutes: async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('deschutes') }; },
};
async function main() {
diff --git a/src/jobs/hourly_loop.ts b/src/jobs/hourly_loop.ts
index d0a9994..dbc3a32 100644
--- a/src/jobs/hourly_loop.ts
+++ b/src/jobs/hourly_loop.ts
@@ -51,6 +51,7 @@ const JOBS: Job[] = [
{ name: 'deeds-or', script: 'src/ingest/parcels/engine.ts', args: ['oregon-rlis'], minIntervalHours: 2, runSources: ['oregon_rlis'] },
{ name: 'deeds-spok', script: 'src/ingest/parcels/engine.ts', args: ['spokane'], minIntervalHours: 3, runSources: ['spokane'] },
{ name: 'deeds-alam', script: 'src/ingest/parcels/engine.ts', args: ['alameda'], minIntervalHours: 2, runSources: ['alameda'] },
+ { name: 'deeds-desc', script: 'src/ingest/parcels/engine.ts', args: ['deschutes'], minIntervalHours: 3, runSources: ['deschutes'] },
];
/** hours since this job's freshest OK run across its runSources (∞ if never). */
← 90f2a67 Spokane: per-source pageSize=500 (slow MapServer); all 3 dee
·
back to Nationalrealestate
·
Deschutes pageSize=1000 (server page cap) so pagination cont 32c8646 →