← 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); });