111 lines
4.5 KiB
TypeScript
111 lines
4.5 KiB
TypeScript
|
|
/**
|
||
|
|
* Post-Phase-1a Baseline Capture - diff-only helper
|
||
|
|
*
|
||
|
|
* Queries the renamed tables and writes post-rename JSON fixtures. After running,
|
||
|
|
* diff these against test-fixtures/baselines/*-pre-phase1.json to verify the
|
||
|
|
* rename did not change any data. DO NOT COMMIT THIS FILE OR ITS OUTPUT.
|
||
|
|
*
|
||
|
|
* Usage:
|
||
|
|
* npx dotenv -- tsx scripts/capture-baseline-post.ts
|
||
|
|
*/
|
||
|
|
|
||
|
|
import { drizzle } from "drizzle-orm/postgres-js";
|
||
|
|
import postgres from "postgres";
|
||
|
|
import { sql } from "drizzle-orm";
|
||
|
|
import { writeFileSync, mkdirSync } from "fs";
|
||
|
|
import { join } from "path";
|
||
|
|
import * as schema from "../database/schema.js";
|
||
|
|
|
||
|
|
const OUT_DIR = join(process.cwd(), "test-fixtures", "baselines");
|
||
|
|
|
||
|
|
async function main() {
|
||
|
|
const dbUrl = process.env.DATABASE_URL;
|
||
|
|
if (!dbUrl) {
|
||
|
|
console.error("ERROR: DATABASE_URL is required");
|
||
|
|
process.exit(1);
|
||
|
|
}
|
||
|
|
|
||
|
|
console.log("Connecting to database...");
|
||
|
|
const client = postgres(dbUrl, { max: 1 });
|
||
|
|
const db = drizzle(client, { schema });
|
||
|
|
|
||
|
|
mkdirSync(OUT_DIR, { recursive: true });
|
||
|
|
console.log(`Output directory: ${OUT_DIR}\n`);
|
||
|
|
|
||
|
|
// ─── 1. season_participant_qualifying_totals ──────────────────────────────────
|
||
|
|
|
||
|
|
console.log("Capturing season_participant_qualifying_totals...");
|
||
|
|
const qpTotals = await db.execute(sql`
|
||
|
|
SELECT pqt.*, ss.id as sports_season_id, ss.name as sports_season_name, s.name as sport_name
|
||
|
|
FROM season_participant_qualifying_totals pqt
|
||
|
|
JOIN sports_seasons ss ON ss.id = pqt.sports_season_id
|
||
|
|
JOIN sports s ON s.id = ss.sport_id
|
||
|
|
WHERE ss.scoring_pattern = 'qualifying_points'
|
||
|
|
ORDER BY ss.id, pqt.participant_id
|
||
|
|
`);
|
||
|
|
|
||
|
|
writeFileSync(
|
||
|
|
join(OUT_DIR, "qp-totals-post-phase1a.json"),
|
||
|
|
JSON.stringify(qpTotals, null, 2)
|
||
|
|
);
|
||
|
|
console.log(` Wrote ${qpTotals.length} rows → qp-totals-post-phase1a.json`);
|
||
|
|
|
||
|
|
// ─── 2. event_results with qualifying_points_awarded ─────────────────────────
|
||
|
|
|
||
|
|
console.log("Capturing event_results with qualifying_points_awarded...");
|
||
|
|
const eventResults = await db.execute(sql`
|
||
|
|
SELECT er.*, se.sports_season_id, se.name as event_name
|
||
|
|
FROM event_results er
|
||
|
|
JOIN scoring_events se ON se.id = er.scoring_event_id
|
||
|
|
JOIN sports_seasons ss ON ss.id = se.sports_season_id
|
||
|
|
WHERE ss.scoring_pattern = 'qualifying_points'
|
||
|
|
AND er.qualifying_points_awarded IS NOT NULL
|
||
|
|
ORDER BY se.sports_season_id, er.scoring_event_id, er.season_participant_id
|
||
|
|
`);
|
||
|
|
|
||
|
|
writeFileSync(
|
||
|
|
join(OUT_DIR, "event-results-post-phase1a.json"),
|
||
|
|
JSON.stringify(eventResults, null, 2)
|
||
|
|
);
|
||
|
|
console.log(` Wrote ${eventResults.length} rows → event-results-post-phase1a.json`);
|
||
|
|
|
||
|
|
// ─── 3. season_participant_surface_elos ──────────────────────────────────────
|
||
|
|
|
||
|
|
console.log("Capturing season_participant_surface_elos...");
|
||
|
|
const surfaceElos = await db.execute(sql`
|
||
|
|
SELECT pse.*, ss.sport_id, ss.name as sports_season_name, s.name as sport_name
|
||
|
|
FROM season_participant_surface_elos pse
|
||
|
|
JOIN sports_seasons ss ON ss.id = pse.sports_season_id
|
||
|
|
JOIN sports s ON s.id = ss.sport_id
|
||
|
|
WHERE ss.scoring_pattern = 'qualifying_points'
|
||
|
|
ORDER BY ss.id, pse.participant_id
|
||
|
|
`);
|
||
|
|
|
||
|
|
writeFileSync(
|
||
|
|
join(OUT_DIR, "surface-elos-post-phase1a.json"),
|
||
|
|
JSON.stringify(surfaceElos, null, 2)
|
||
|
|
);
|
||
|
|
console.log(` Wrote ${surfaceElos.length} rows → surface-elos-post-phase1a.json`);
|
||
|
|
|
||
|
|
console.log(`\n✓ Post-rename capture complete!`);
|
||
|
|
console.log(` ${qpTotals.length} QP totals`);
|
||
|
|
console.log(` ${eventResults.length} event results`);
|
||
|
|
console.log(` ${surfaceElos.length} surface elo rows`);
|
||
|
|
console.log(`\nNow diff against the pre-phase1 fixtures:`);
|
||
|
|
console.log(` diff <(jq -S . test-fixtures/baselines/qp-totals-pre-phase1.json) \\`);
|
||
|
|
console.log(` <(jq -S . test-fixtures/baselines/qp-totals-post-phase1a.json)`);
|
||
|
|
console.log(` diff <(jq -S . test-fixtures/baselines/surface-elos-pre-phase1.json) \\`);
|
||
|
|
console.log(` <(jq -S . test-fixtures/baselines/surface-elos-post-phase1a.json)`);
|
||
|
|
console.log(` diff <(jq -S 'map(del(.participant_id))' test-fixtures/baselines/event-results-pre-phase1.json) \\`);
|
||
|
|
console.log(` <(jq -S 'map(del(.season_participant_id))' test-fixtures/baselines/event-results-post-phase1a.json)`);
|
||
|
|
|
||
|
|
await client.end();
|
||
|
|
}
|
||
|
|
|
||
|
|
main()
|
||
|
|
.then(() => process.exit(0))
|
||
|
|
.catch((e) => {
|
||
|
|
console.error("FATAL:", e);
|
||
|
|
process.exit(1);
|
||
|
|
});
|