feat(blackpool): add Blackpool Pleasure Beach destination#142
Open
feat(blackpool): add Blackpool Pleasure Beach destination#142
Conversation
Compares live data emitted from the parksapi library against what's
currently published on the wiki, and validates both sides against the
typelib schema. Catches type errors (e.g. waitTime as a string), enum
violations (unknown status/queue types), malformed ISO dates, and
staleness during operating hours.
Three modes: remote (default, audits wiki), --local (audits local
emissions), --diff (runs both for cross-source comparison). --only=X,Y
filters by parksapi id. --json emits machine-readable output.
Remote mode uses the wiki /schedule endpoint to determine open hours,
so it never needs to load park secrets. Local/diff modes call the
park's own getSchedules() instead.
Key validations per live item:
id — string, matches /^[\w.-]+$/
status — one of OPERATING | DOWN | CLOSED | REFURBISHMENT
queue — per-type shape (waitTime finite number, state/allocationStatus
in enum, price.amount numeric for PAID_RETURN_TIME, etc.)
showtimes — array of {type, startTime, endTime} with ISO dates
lastUpdated — parseable ISO string, not in the future
Destination-level checks:
- park is currently within operating hours but freshest item is stale
- destination emits no live data at all
New npm script: `npm run audit:live`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
phlsys returns 403 from /signage-snapshots when the caller IP is briefly rate-limited, while simultaneously accepting the same access token on /park-infos. The old handler treated 401 and 403 identically: clear the token, re-login, retry. On a 403 that path is wasted work — the token is fine — and each retry now fires an extra create-user + login pair, roughly doubling request volume during the exact window the server is rate-limiting. Symptoms matched: ~1% failure overnight (sparse polls, warm cache) vs ~14% during the day (3-min cadence) with clustered bursts of 3 consecutive failed polls before recovery. 403 still triggers a retry (4xx is otherwise non-retryable, so we nullify the response to re-enter the queue). Only 401 invalidates the cached token + user, which remains the recovery path for a genuinely pruned anonymous account. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Covers entities (attractions + restaurants) from the park's app API, live wait times from /queue-times, and the schedule calendar scraped from the public opening-times page. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a new Blackpool Pleasure Beach destination implementation and introduces a new CLI tool to audit live data schema/sanity, alongside a small refinement to Phantasialand’s auth retry behavior.
Changes:
- Added
BlackpoolPleasureBeachdestination with entity discovery (rides/restaurants), live wait times, and schedule scraping. - Introduced
audit:livetool to validate live data shape and detect suspicious/stale emissions (local/remote/diff modes). - Adjusted Phantasialand HTTP 401/403 handling so only 401 invalidates cached auth, while both remain retryable.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/tools/audit/live.ts | New live data audit CLI with schema checks, summaries, and optional local/remote diffing. |
| src/parks/phantasialand/phantasialand.ts | Tweaks retry/token invalidation behavior for 401 vs 403 responses. |
| src/parks/blackpool/blackpoolpleasurebeach.ts | New destination implementation (auth, entities, live data, schedules). |
| package.json | Adds audit:live script entry. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+63
to
+65
| @config apiBase: string = ''; | ||
| @config websiteBase: string = ''; | ||
| @config timezone: string = 'Europe/London'; |
| type WikiDest = {id: string; name: string; slug: string; externalId: string}; | ||
|
|
||
| async function fetchWikiDestinations(): Promise<WikiDest[]> { | ||
| const r = await fetch('https://api.themeparks.wiki/v1/destinations'); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
BlackpoolPleasureBeachdestination undersrc/parks/blackpool//queue-times+/map/get-markers)/queue-times(status maps fromenabled/closed/holding/active)wn_datesJSON (192-day window)BLACKPOOLPLEASUREBEACH_EMAIL/_PASSWORD)Test plan
npm run dev -- blackpoolpleasurebeach --clear-cache— 4/4 tests pass, 29 attractions / 8 restaurants / 29 live / 192 schedule daysnpm run health -- blackpoolpleasurebeach— endpoints OKnpx tsc --noEmitclean.envupdated withBLACKPOOLPLEASUREBEACH_*keys in prod🤖 Generated with Claude Code