agnets done
This commit is contained in:
72
scripts/seed-fixture.mjs
Normal file
72
scripts/seed-fixture.mjs
Normal file
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* Writes the backend's seed fixture from the frontend's seed module.
|
||||
*
|
||||
* node scripts/seed-fixture.mjs # check: exits non-zero if stale
|
||||
* node scripts/seed-fixture.mjs --write # regenerate
|
||||
*
|
||||
* `src/api/seed.js` is the authored source: it has the helpers, the reasoning in
|
||||
* comments, and the values a person edits. `seed/fixtures/seed.json` is what the
|
||||
* Go seeder loads. They used to be maintained in parallel with nothing checking
|
||||
* them, which is a duplication that only fails quietly — the demo and the API
|
||||
* would answer the same question differently, and the first symptom would be a
|
||||
* number on a page disagreeing with a number from an agent.
|
||||
*
|
||||
* `ShiftRecord` is deliberately not carried across. Its dates are anchored to
|
||||
* the day the seeder runs rather than to this file's fixed calendar, so the Go
|
||||
* side generates it (internal/seeder/shifts.go, a port of attendanceSeed.js).
|
||||
* A frozen snapshot of it would read as permanently empty a fortnight later.
|
||||
*/
|
||||
import { createServer } from 'vite';
|
||||
import { readFileSync, writeFileSync, existsSync } from 'node:fs';
|
||||
import { join } from 'node:path';
|
||||
import { pathToFileURL } from 'node:url';
|
||||
|
||||
export const FIXTURE_PATH = join(process.cwd(), '..', 'krow-backend', 'seed', 'fixtures', 'seed.json');
|
||||
|
||||
/** The fixture the frontend seed implies. Pure — takes the loaded module. */
|
||||
export const GENERATED_NOTE =
|
||||
'Generated from krow-demo/src/api/seed.js — do not edit by hand. ' +
|
||||
'Regenerate with: npm run seed:fixture';
|
||||
|
||||
export function fixtureFrom(seedModule) {
|
||||
const { ShiftRecord, ...entities } = seedModule.seedData;
|
||||
/* First key, so it is the first thing anyone opening the file reads. The Go
|
||||
loader unmarshals into a struct of demoUser + entities and ignores the
|
||||
rest, so this costs nothing on the reading side. */
|
||||
return { _generated: GENERATED_NOTE, demoUser: seedModule.DEMO_USER, entities };
|
||||
}
|
||||
|
||||
/** Serialised exactly as the committed file is: 2-space indent, no trailing newline. */
|
||||
export const serialise = (fixture) => JSON.stringify(fixture, null, 2);
|
||||
|
||||
export async function buildFixture(server) {
|
||||
return serialise(fixtureFrom(await server.ssrLoadModule('/src/api/seed.js')));
|
||||
}
|
||||
|
||||
/* ── CLI ──────────────────────────────────────────────────────────────────── */
|
||||
/* pathToFileURL, not string concatenation: this repo lives under a path with a
|
||||
space in it, and import.meta.url percent-encodes it while `file://${path}`
|
||||
does not — the guard silently never fires and the script does nothing. */
|
||||
if (import.meta.url === pathToFileURL(process.argv[1]).href) {
|
||||
const server = await createServer({
|
||||
root: process.cwd(), server: { middlewareMode: true }, appType: 'custom', logLevel: 'error',
|
||||
});
|
||||
const built = await buildFixture(server);
|
||||
await server.close();
|
||||
|
||||
if (process.argv.includes('--write')) {
|
||||
writeFileSync(FIXTURE_PATH, built);
|
||||
const { entities } = JSON.parse(built);
|
||||
const n = Object.values(entities).reduce((s, v) => s + v.length, 0);
|
||||
console.log(`seed.json written — ${Object.keys(entities).length} collections, ${n} records.`);
|
||||
} else if (!existsSync(FIXTURE_PATH)) {
|
||||
console.error('seed.json is missing. Run: node scripts/seed-fixture.mjs --write');
|
||||
process.exit(1);
|
||||
} else if (readFileSync(FIXTURE_PATH, 'utf8') !== built) {
|
||||
console.error('seed.json is stale — it no longer matches src/api/seed.js.');
|
||||
console.error('Run: node scripts/seed-fixture.mjs --write');
|
||||
process.exit(1);
|
||||
} else {
|
||||
console.log('seed.json is in step with src/api/seed.js.');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user