← back to Nationalrealestate
src/ingest/parcels/engine.ts
86 lines
/**
* Parcel-ingest dispatcher: npm run ingest:parcels <county>
* Counties: nyc (five boroughs, PLUTO) | nyc-acris (ACRIS deed sales onto PLUTO)
* | king (King WA EXTR) | cook (Cook IL Socrata)
* Per-county adapters own download + parse + upsert + parcel_source registration.
*/
import { pool } from '../../../db/pool.ts';
const ADAPTERS: Record<string, () => Promise<{ run: () => Promise<{ upserted: number }> }>> = {
nyc: async () => ({ run: (await import('./nyc_pluto.ts')).ingestNycPluto }),
'nyc-acris': async () => ({ run: (await import('./nyc_acris.ts')).ingestNycAcris }),
king: async () => ({ run: (await import('./king_wa.ts')).ingestKing }),
'maricopa-bulk': async () => { const m = await import('./maricopa_bulk.ts'); const p = process.argv[3]; return { run: () => m.ingestMaricopaBulk(p) }; },
cook: async () => ({ run: (await import('./cook_il.ts')).ingestCook }),
franklin: async () => ({ run: (await import('./franklin_oh.ts')).ingestFranklin }),
miami: async () => ({ run: (await import('./miami_dade.ts')).ingestMiami }),
wake: async () => ({ run: (await import('./wake_nc.ts')).ingestWake }),
tarrant: async () => ({ run: (await import('./tarrant_tx.ts')).ingestTarrant }),
bexar: async () => ({ run: (await import('./bexar_tx.ts')).ingestBexar }),
dallas: async () => ({ run: (await import('./dallas_tx.ts')).ingestDallas }),
harris: async () => ({ run: (await import('./harris_tx.ts')).ingestHarris }),
clark: async () => ({ run: (await import('./clark_nv.ts')).ingestClark }),
philadelphia: async () => ({ run: (await import('./philadelphia_pa.ts')).ingestPhiladelphia }),
hennepin: async () => ({ run: (await import('./hennepin_mn.ts')).ingestHennepin }),
detroit: async () => ({ run: (await import('./detroit_mi.ts')).ingestDetroit }),
fulton: async () => ({ run: (await import('./fulton_ga.ts')).ingestFulton }),
saltlake: async () => ({ run: (await import('./saltlake_ut.ts')).ingestSaltLake }),
sandiego: async () => { const m = await import('./sandiego_ca.ts'); return { run: () => m.ingestSanDiego('poway') }; },
'sandiego-county': async () => { const m = await import('./sandiego_ca.ts'); return { run: () => m.ingestSanDiego('county') }; },
'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') }; },
crook: async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('crook') }; },
sonoma: async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('sonoma') }; },
colorado: async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('colorado') }; },
maricopa: async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('maricopa') }; },
'la-county': async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('la-county') }; },
'santa-clara': async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('santa-clara') }; },
'san-diego-sandag': async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('san-diego-sandag') }; },
thurston: async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('thurston') }; },
'palm-beach': async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('palm-beach') }; },
klamath: async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('klamath') }; },
marion: async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('marion') }; },
yakima: async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('yakima') }; },
lane: async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('lane') }; },
jackson: async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('jackson') }; },
'orange-county': async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('orange-county') }; },
'ventura-county': async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('ventura-county') }; },
'santa-barbara': async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('santa-barbara') }; },
imperial: async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('imperial') }; },
'san-bernardino': async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('san-bernardino') }; },
'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') }; },
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') }; },
whatcom: async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('whatcom') }; },
// TK-10777: Whatcom historical layers — history-safe (date-guarded) upsert
'whatcom-2021': async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('whatcom-2021') }; },
'whatcom-2020': async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('whatcom-2020') }; },
josephine: async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('josephine') }; }, // TK-16: OR priced-deed (Grants Pass)
snohomish: async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('snohomish') }; }, // TK-16: WA priced-deed (Everett, 53061)
};
async function main() {
const which = (process.argv[2] || '').toLowerCase();
if (!ADAPTERS[which]) {
console.error(`usage: npm run ingest:parcels -- <${Object.keys(ADAPTERS).join('|')}>`);
process.exit(2);
}
const { run } = await ADAPTERS[which]();
const { upserted } = await run();
console.log(`[parcels:${which}] done, ${upserted} upserted`);
await pool.end();
}
main().catch(e => { console.error(e); process.exit(1); });