← back to Nationalrealestate

scripts/rentv-feed.mjs

100 lines

// USRealEstate (usre) DATA FEED — read-only, CORS-enabled JSON API sharing the
// national CRE datasets (brokers, firms, commercial parcels, subleases, regions)
// with RENTV & partners. Zero-dep (Node http + psql). Tailnet-reachable (binds *).
// Run: node scripts/rentv-feed.mjs   (PORT env, default 9796)
import { createServer } from "node:http";
import { execFile } from "node:child_process";

const DBURL = "postgresql://macstudio3@localhost/usre?host=/tmp";
const PORT = Number(process.env.PORT || 9796);
const q = (sql) => new Promise((r) => execFile("psql", [DBURL, "-tAc", sql], { maxBuffer: 128 << 20 }, (e, o) => r(e ? "[]" : (o.trim() || "[]"))));
const esc = (s) => String(s ?? "").replace(/'/g, "''").replace(/[;\\]/g, "").slice(0, 60);
const int = (v, d, max) => Math.min(max, Math.max(0, parseInt(v ?? d, 10) || d));
const page = (p) => [int(p.get("limit"), 100, 1000), int(p.get("offset"), 0, 5e6)];

async function list(table, cols, where, order, p) {
  const [limit, offset] = page(p);
  const total = Number((await q(`select count(*) from ${table} where ${where}`)).trim() || 0);
  const rows = await q(`select coalesce(json_agg(t),'[]') from (select ${cols} from ${table} where ${where} order by ${order} limit ${limit} offset ${offset}) t`);
  return { total, count: limit, offset, results: JSON.parse(rows) };
}

async function brokers(p) {
  const w = ["1=1"];
  if (p.get("state")) w.push(`b.state_code='${esc(p.get("state")).toUpperCase()}'`);
  if (p.get("city")) w.push(`b.city ilike '${esc(p.get("city"))}%'`);
  if (p.get("status")) w.push(`b.license_status ilike '${esc(p.get("status"))}%'`);
  if (p.get("q")) w.push(`(b.name ilike '%${esc(p.get("q"))}%' or b.email ilike '%${esc(p.get("q"))}%' or b.license_no='${esc(p.get("q"))}')`);
  const [limit, offset] = page(p);
  const where = w.join(" and ");
  const total = Number((await q(`select count(*) from broker b where ${where}`)).trim() || 0);
  const rows = await q(`select coalesce(json_agg(t),'[]') from (
    select b.name, b.license_no, b.license_state, b.license_type, b.license_status, b.email, b.phone,
           b.city, b.state_code, f.name as firm
    from broker b left join firm f on f.id=b.firm_id where ${where}
    order by b.name limit ${limit} offset ${offset}) t`);
  return { total, count: limit, offset, results: JSON.parse(rows) };
}
async function firms(p) {
  const w = ["1=1"];
  if (p.get("state")) w.push(`hq_state='${esc(p.get("state")).toUpperCase()}'`);
  if (p.get("city")) w.push(`hq_city ilike '${esc(p.get("city"))}%'`);
  if (p.get("min_agents")) w.push(`agent_count >= ${int(p.get("min_agents"), 0, 1e7)}`);
  if (p.get("q")) w.push(`name ilike '%${esc(p.get("q"))}%'`);
  return list("firm", "name, website, phone, hq_city, hq_state, agent_count, license_no", w.join(" and "), "agent_count desc nulls last", p);
}
async function commercial(p) {
  const w = ["1=1"];
  if (p.get("city")) w.push(`city ilike '${esc(p.get("city"))}%'`);
  if (p.get("zip")) w.push(`zip='${esc(p.get("zip"))}'`);
  if (p.get("use")) w.push(`use_desc ilike '%${esc(p.get("use"))}%'`);
  if (p.get("min_assessed")) w.push(`assessed_total >= ${int(p.get("min_assessed"), 0, 1e12)}`);
  return list("commercial_parcel", "address, city, zip, ctype, use_desc, use_class, assessed_total, sqft, year_built, units, recording_date::text",
    w.join(" and "), "assessed_total desc nulls last", p);
}
async function subleases(p) {
  return list("sublease", "address, city, submarket, floor_suite, sqft, asking_rate, rate_period, lease_type, sublandlord, firm_name, broker_name, broker_phone, listing_url, lat, lng, status",
    "1=1", "created_at desc", p);
}
async function regions(p) {
  const w = ["1=1"];
  if (p.get("state")) w.push(`state_code='${esc(p.get("state")).toUpperCase()}'`);
  if (p.get("type")) w.push(`region_type='${esc(p.get("type"))}'`);
  return list("region", "name, region_type, state_code, cbsa_code, lat, lng, population", w.join(" and "), "population desc nulls last", p);
}
async function summary() {
  const counts = {};
  for (const t of ["broker", "firm", "commercial_parcel", "sublease", "region", "listing"])
    counts[t] = Number((await q(`select count(*) from ${t}`)).trim() || 0);
  const byState = JSON.parse(await q(`select coalesce(json_agg(t),'[]') from (select state_code, count(*) brokers from broker where state_code is not null group by state_code order by 2 desc limit 15) t`));
  return { counts, brokers_by_state: byState };
}

const DOCS = {
  service: "USRealEstate (usre) Data Feed",
  description: "Read-only national CRE datasets — brokers (~2M), firms (~214k), commercial parcels (~154k, assessed values), subleases, region metrics. Shared with RENTV & partners.",
  endpoints: {
    "GET /feed/brokers": "params: state, city, status, q, limit(<=1000), offset",
    "GET /feed/firms": "params: state, city, min_agents, q, limit, offset",
    "GET /feed/commercial": "commercial parcels — params: city, zip, use, min_assessed, limit, offset",
    "GET /feed/subleases": "sublease inventory — params: limit, offset",
    "GET /feed/regions": "params: state, type, limit, offset",
    "GET /feed/summary": "dataset counts + brokers by state",
  },
  cors: "enabled",
};

const routes = { "/feed/brokers": brokers, "/feed/firms": firms, "/feed/commercial": commercial, "/feed/subleases": subleases, "/feed/regions": regions };
const server = createServer(async (req, res) => {
  res.setHeader("Access-Control-Allow-Origin", "*");
  res.setHeader("content-type", "application/json");
  const u = new URL(req.url, "http://x");
  try {
    if (u.pathname === "/" || u.pathname === "/feed") return res.end(JSON.stringify(DOCS, null, 2));
    if (u.pathname === "/feed/summary") return res.end(JSON.stringify(await summary()));
    if (routes[u.pathname]) return res.end(JSON.stringify(await routes[u.pathname](u.searchParams)));
  } catch (e) { res.statusCode = 500; return res.end(JSON.stringify({ error: String(e) })); }
  res.statusCode = 404; res.end(JSON.stringify({ error: "not found", see: "/" }));
});
server.listen(PORT, () => console.log(`rentv-feed (usre) on http://127.0.0.1:${PORT}`));