← back to Commercialrealestate
scripts/export-gov-snapshot.js
37 lines
#!/usr/bin/env node
/*
* export-gov-snapshot.js — write per-metro snapshots of cre.gov_licensed_agent so PROD
* (no Postgres) can serve the government-licensed-agent viewer. One file per metro keeps
* each payload small; the index lists metros + counts for the dropdown.
* data/gov/index.json { metros:[{state,metro,source,count,brokers}], total, exported_at }
* data/gov/<metro>.json [ {name,firm,license_number,license_type,city,county,zip,expiration,state,source}, ... ]
*/
'use strict';
const fs = require('fs');
const path = require('path');
const { pool } = require('./db/brokers-db');
const DIR = path.join(__dirname, '..', 'data', 'gov');
async function main() {
fs.mkdirSync(DIR, { recursive: true });
const metros = (await pool.query(
`SELECT state, metro, source, count(*)::int n,
count(*) FILTER (WHERE license_type ILIKE '%broker%')::int brokers
FROM gov_licensed_agent GROUP BY state, metro, source ORDER BY n DESC`)).rows;
let total = 0;
for (const m of metros) {
const rows = (await pool.query(
`SELECT name, firm, license_number, license_type, city, county, zip,
to_char(expiration,'YYYY-MM-DD') expiration, state, source
FROM gov_licensed_agent WHERE metro=$1 AND source=$2 ORDER BY name`, [m.metro, m.source])).rows;
fs.writeFileSync(path.join(DIR, `${m.metro}.json`), JSON.stringify(rows));
total += rows.length;
console.log(` ${m.metro.padEnd(12)} ${String(m.n).padStart(6)} (${(fs.statSync(path.join(DIR, `${m.metro}.json`)).size/1e6).toFixed(1)}MB)`);
}
fs.writeFileSync(path.join(DIR, 'index.json'),
JSON.stringify({ metros, total, exported_at: new Date().toISOString() }));
console.log(`✔ ${metros.length} metros, ${total} gov-licensed agents → ${DIR}`);
await pool.end();
}
if (require.main === module) main().catch(e => { console.error(e); process.exit(1); });