[object Object]

← 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

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 →