refactor: hardcode API IDs and coaster lists, remove Playwright discovery

Embed Six Flags API IDs directly in the park registry and snapshot
coaster lists from park-meta.json into a TypeScript module. This
eliminates the Playwright-based discovery script, RCDB scraper, and
runtime dependency on park-meta.json — preparing for the backend
API transition.

- Add apiId field to Park type and all 24 park entries
- Create lib/coaster-data.ts with hardcoded coaster lists
- Update page components to use park.apiId and new getCoasterSet()
- Remove scripts/discover.ts, lib/scrapers/rcdb.ts, lib/park-meta.ts
- Remove data/park-meta.json from shared volume
- Remove playwright devDependency and discover npm script
- Simplify scripts/scrape.ts (no RCDB, no discovery checks)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-23 21:25:53 -04:00
parent 757c2a8d4f
commit 4652a92c29
13 changed files with 381 additions and 866 deletions
+6 -27
View File
@@ -2,12 +2,12 @@ import Link from "next/link";
import { BackToCalendarLink } from "@/components/BackToCalendarLink";
import { notFound } from "next/navigation";
import { PARK_MAP } from "@/lib/parks";
import { openDb, getParkMonthData, getApiId } from "@/lib/db";
import { openDb, getParkMonthData } from "@/lib/db";
import { scrapeRidesForDay } from "@/lib/scrapers/sixflags";
import { fetchLiveRides } from "@/lib/scrapers/queuetimes";
import { fetchToday } from "@/lib/scrapers/sixflags";
import { QUEUE_TIMES_IDS } from "@/lib/queue-times-map";
import { readParkMeta, getCoasterSet } from "@/lib/park-meta";
import { getCoasterSet } from "@/lib/coaster-data";
import { ParkMonthCalendar } from "@/components/ParkMonthCalendar";
import { LiveRidePanel } from "@/components/LiveRidePanel";
import type { RideStatus, RidesFetchResult } from "@/lib/scrapers/sixflags";
@@ -42,13 +42,9 @@ export default async function ParkPage({ params, searchParams }: PageProps) {
const db = openDb();
const monthData = getParkMonthData(db, id, year, month);
const apiId = getApiId(db, id);
db.close();
// Prefer live today data from the Six Flags API (5-min ISR cache) so that
// weather delays and hour changes surface immediately rather than showing
// stale DB values. Fall back to DB if the API call fails.
const liveToday = apiId !== null ? await fetchToday(apiId, 300).catch(() => null) : null;
const liveToday = await fetchToday(park.apiId, 300).catch(() => null);
const todayData = liveToday
? { isOpen: liveToday.isOpen, hoursLabel: liveToday.hoursLabel ?? null, specialType: liveToday.specialType ?? null }
: monthData[today];
@@ -56,8 +52,7 @@ export default async function ParkPage({ params, searchParams }: PageProps) {
// ── Ride data: try live Queue-Times first, fall back to schedule ──────────
const queueTimesId = QUEUE_TIMES_IDS[id];
const parkMeta = readParkMeta();
const coasterSet = getCoasterSet(id, parkMeta);
const coasterSet = getCoasterSet(id);
let liveRides: LiveRidesResult | null = null;
let ridesResult: RidesFetchResult | null = null;
@@ -87,9 +82,8 @@ export default async function ParkPage({ params, searchParams }: PageProps) {
liveRides.rides.length > 0 &&
liveRides.rides.every((r) => !r.isOpen);
// Only hit the schedule API as a fallback when Queue-Times live data is unavailable.
if (!liveRides && apiId !== null) {
ridesResult = await scrapeRidesForDay(apiId, today);
if (!liveRides) {
ridesResult = await scrapeRidesForDay(park.apiId, today);
}
return (
@@ -175,7 +169,6 @@ export default async function ParkPage({ params, searchParams }: PageProps) {
<RideList
ridesResult={ridesResult}
parkOpenToday={!!parkOpenToday}
apiIdMissing={apiId === null && !queueTimesId}
/>
)}
</section>
@@ -256,24 +249,10 @@ function LiveBadge() {
function RideList({
ridesResult,
parkOpenToday,
apiIdMissing,
}: {
ridesResult: RidesFetchResult | null;
parkOpenToday: boolean;
apiIdMissing: boolean;
}) {
if (apiIdMissing) {
return (
<Callout>
Park API ID not discovered yet. Run{" "}
<code style={{ background: "var(--color-surface-2)", padding: "1px 5px", borderRadius: 3, fontSize: "0.8em" }}>
npm run discover
</code>{" "}
to enable ride data.
</Callout>
);
}
if (!parkOpenToday) {
return <Callout>Park is closed today no ride schedule available.</Callout>;
}