scripts/loaders/miami/abc_book.ts
Served verbatim from the project repository. Internal working document conventions apply: documents may reference file paths, branch names, and findings-ledger anchors from the repo.
// Load the parsed board Attendance Zone Recommendations capacity blocks
// (data/cities/miami/reference/parsed/mdcps_abc_book_<year>.csv) →
// enrollment_abc, fish_capacity_permanent_abc, utilization_permanent_pct_abc
// under the block's current year, and projected_enrollment_y1 / _y2 under the
// projected years.
// Run: npx tsx scripts/loaders/miami/abc_book.ts [source_id]
import fs from "node:fs";
import path from "node:path";
import { parse } from "csv-parse/sync";
import { requireSource, startDataLoad, finishDataLoad, schoolUniverse, upsertFacts, runMain, type Fact } from "./_lib";
const SCRIPT_PATH = "scripts/loaders/miami/abc_book.ts";
const PARSED = path.join(process.cwd(), "data", "cities", "miami", "reference", "parsed");
const num = (v: string | undefined): number | null => {
if (v === undefined || v === "" || v === "nan") return null;
const n = Number.parseFloat(v);
return Number.isFinite(n) ? n : null;
};
async function main() {
const sourceId = process.argv[2] ?? "mdcps_abc_book_2026-27";
const { prov } = requireSource(sourceId);
const gate = JSON.parse(fs.readFileSync(path.join(PARSED, `${sourceId}.gate.json`), "utf-8")) as { pass: boolean };
if (!gate.pass) throw new Error(`${sourceId}: parser gate did not pass`);
const rows = parse(fs.readFileSync(path.join(PARSED, `${sourceId}.csv`), "utf-8"), { columns: true, skip_empty_lines: true }) as Record<string, string>[];
const universe = await schoolUniverse();
const facts: Fact[] = [];
let schools = 0;
for (const r of rows) {
if (!universe.has(r.school_number)) { console.warn(`[abc] ${r.school_number} ${r.school_name} not in directory`); continue; }
schools++;
const y0 = r.year_current;
const e = num(r.enrollment_current), c = num(r.perm_fish_current), u = num(r.util_perm_current);
if (e !== null) facts.push({ schoolNumber: r.school_number, year: y0, metricKey: "enrollment_abc", value: e });
if (c !== null) facts.push({ schoolNumber: r.school_number, year: y0, metricKey: "fish_capacity_permanent_abc", value: c });
if (u !== null) facts.push({ schoolNumber: r.school_number, year: y0, metricKey: "utilization_permanent_pct_abc", value: u, denominator: c });
const p1 = num(r.enrollment_proj1), p2 = num(r.enrollment_proj2);
if (p1 !== null && r.year_proj1) facts.push({ schoolNumber: r.school_number, year: r.year_proj1, metricKey: "projected_enrollment_y1", value: p1 });
if (p2 !== null && r.year_proj2) facts.push({ schoolNumber: r.school_number, year: r.year_proj2, metricKey: "projected_enrollment_y2", value: p2 });
}
const load = await startDataLoad({ sourceId, sourceUrl: prov.url, sha256: prov.sha256, bytes: prov.bytes, yearCovered: rows[0]?.year_current, scriptPath: SCRIPT_PATH,
notes: `parsed capacity blocks (${rows.length} schools; arithmetic gate PASS)` });
const res = await upsertFacts(facts, load.id);
await finishDataLoad(load.id, { inserted: res.written, updated: 0, suppressed: 0 });
console.log(`[abc] ${res.written} facts for ${schools} schools`);
}
runMain(main);