Files
tiennm99 6569f095c9 feat(game): serve panorama index from Neon Postgres
- panoramas + pano_provinces tables replace 28MB bundled JSON; pano-index.js
  now draws via cached COUNT + ORDER BY id OFFSET with rejection sampling,
  composite (province,id)/(district,id) indexes support the skip
- scripts/seed-pano-db.mjs validates pipeline artifacts (the old real-data
  vitest invariants, extracted to scripts/lib/pano-artifacts.mjs), stages
  into panoramas_next, verifies, renames into place in one transaction,
  keeps panoramas_old as backup; --province reseeds in place; --check
  validates only
- pipeline writes gitignored data-build/panos/; pano barrel removed
- tests run against PGlite mocked in at the @neondatabase/serverless
  boundary, mirroring the fake-upstash pattern; fixtures replace real data
- infrastructure errors rethrow instead of reading as missing coverage;
  session ids via crypto.randomUUID (uuid package dropped)
2026-08-31 09:44:03 +07:00

31 lines
1.5 KiB
JavaScript

import { describe, it, expect } from 'vitest';
import { readFileSync } from 'node:fs';
import { resolve } from 'node:path';
import { boundaryEntries, renderBarrel } from '../scripts/lib/barrel.mjs';
// Rebuilds the generated boundary barrel from the files actually on disk
// through the emitter in scripts/lib/barrel.mjs, and checks it against the
// committed output byte-for-byte, proving the emitter still writes what the
// build script wrote. The panorama index no longer has a barrel: it lives in
// Postgres, seeded by scripts/seed-pano-db.mjs.
const BOUNDARY_HEADER =
'// Generated by scripts/build-region-boundaries.mjs. Do not edit by hand.\n' +
'//\n' +
'// Lists only the boundaries that have actually been built, so a partial\n' +
'// build still compiles.\n\n';
// Both scripts write with '\n' only, and that is what git stores. A Windows
// checkout with core.autocrlf=true rewrites that to '\r\n' on disk, which is a
// checkout-time detail, not a content difference the scripts produced -- so
// the committed side is normalised back to '\n' before the comparison.
const committed = (path) => readFileSync(path, 'utf8').replace(/\r\n/g, '\n');
describe('generated barrels', () => {
it('rebuilds src/data/boundaries/index.js byte-for-byte', () => {
const dir = resolve('src/data/boundaries');
const rebuilt = renderBarrel(BOUNDARY_HEADER, 'REGION_BOUNDARIES', boundaryEntries(dir));
expect(rebuilt).toBe(committed(`${dir}/index.js`));
});
});