fix(universal): stop reporting shows as OPERATING outside park hours - #321
fix(universal): stop reporting shows as OPERATING outside park hours#321cubehouse wants to merge 2 commits into
Conversation
Sampled overnight with the park's own schedule confirming it shut, 25 of
31 externally-shown USH entries carried a live-looking show status ("OPEN",
or CLOSED/CANCELED with a future slot still listed) straight through the
closure. show_times lists the whole day's slots from midnight, so "has a
future performance" never goes false overnight, and the status field
itself isn't reliably live either — the same category of stale-reading bug
already fixed for the ride wait-time feed, just on shows.
Show status is now clock-gated against the park's own venue schedule the
same way: OPERATING (from either an explicit OPEN/RIDE_NOW or a future
showtime) only holds while the park is actually open. Delay and
long-closure signals are untouched — neither claims OPERATING, so there's
nothing to gate. A schedule lookup failure, or a venue with no schedule
(CityWalk), falls back to the old ungated behaviour rather than guessing.
Verified live at 00:26 PDT / 03:26 EDT with both US resorts shut: USH
went from 25 shows frozen OPERATING to all 45 rows CLOSED, and Orlando's
96 rows are CLOSED across all four parks.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…edge cases Three independent reviews of the clock-gate fix (crash risk, real-world regression risk, test coverage) surfaced concrete gaps before merge: - isParkOperatingNow could throw on a malformed-but-successful schedule response (non-array body), taking down buildLiveData for the whole destination rather than degrading gracefully. Now validated and wrapped end to end. - A schedule response with zero usable days (empty array, every day unparseable) was treated the same as a confirmed closure. Now distinguished from a schedule that explicitly says every day is closed (a real signal, e.g. Volcano Bay's off-season) — only the former fails open. - The type declared a `SpecialEntryString` field that isn't real; the actual field is `SpecialEntryUnix`, present on every real day but 0 in every sample checked across ~11 weeks including a would-be Halloween Horror Nights window. Left deliberately unused rather than guessing at undocumented semantics — noted in the code as a known gap. - buildSchedules assumed OpenTimeString/CloseTimeString are always present; real UOR data omits them on some days. Fixed the same way (skip, don't publish an Invalid Date). - Added the missing coverage: Universal Orlando's 4-park case (previously untested — only single-park Hollywood was exercised), the venue reparenting branch end to end, the unmapped-venue fail-open branch, multi-day schedule scanning, and the non-array/empty-array/all-closed response shapes. Full suite (2066 tests) green, typechecks clean, re-verified against both US resorts live while genuinely closed. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Holding this in draft. Found a real, confirmed risk after opening this PR: Halloween Horror Nights runs at both Universal Orlando and Universal Studios Hollywood as a wholly separate ticketed admission (day ticket ≠ HHN ticket, either direction), and the legacy Unresolved: whether HHN-branded shows appear in Verifying live once HHN opens (~2026-08-28) rather than merging on a guess. Tracked as a gate on the internal board; will update here once resolved. |
Summary
Universal show entities were reading OPERATING straight through the overnight
park closure and never getting rewritten, so the last-known status froze.
Sampled overnight with the park's own venue schedule confirming it shut, most
externally-shown show entries carried a live-looking status (either an
explicit
OPEN, orCLOSED/CANCELEDwith a future showtime still listed —show_timeslists the whole day's slots from midnight, so "has a futureperformance" never goes false overnight). Neither signal referenced park
hours at all.
Show status is now clock-gated against the park's own venue schedule the same
way
#317did for SeaWorld: OPERATING (from either an explicitOPEN/RIDE_NOWor a future showtime) only holds while the park is actuallyopen. Delay and long-closure signals are untouched — neither claims
OPERATING, so there's nothing to gate.
Hardening after review
This branch went through three independent reviews (crash/correctness risk,
real-world regression risk, test coverage) before being opened as a PR. They
found real gaps, now fixed:
isParkOperatingNowcould throw on a malformed-but-successful scheduleresponse (a non-array body), taking down
buildLiveDatafor the wholedestination rather than degrading gracefully. Validated and wrapped end to
end now.
treated identically to a confirmed closure. Now distinguished from a
schedule that explicitly marks every day Closed (a real signal — e.g.
Volcano Bay's off-season) — only the former fails open (ungated).
buildSchedulesassumedOpenTimeString/CloseTimeStringare alwayspresent; real UOR data omits them on some days. Fixed the same way (skip
rather than publish an
Invalid Date).untested — only single-park Hollywood was exercised), the venue
reparenting branch end to end, the unmapped-venue fail-open branch,
multi-day schedule scanning, and non-array/empty-array/all-closed
response shapes.
Known residual risk — not fixed, flagged for follow-up
The type declared a
SpecialEntryStringfield that isn't real; the actualfield is
SpecialEntryUnix, present on every real day captured but0inevery sample checked across ~11 weeks (both resorts), including deep into a
would-be Halloween Horror Nights window. Its real meaning is unconfirmed —
possibly unused by this endpoint entirely, possibly only populated close to
an actual special-hours date. Left deliberately unread rather than guessing
at undocumented semantics.
The open question this leaves: does the legacy
/venues/{id}/hoursendpoint this fix relies on cover ticketed after-hours events (e.g. HHN) at
all? No HHN-branded shows exist in the feed yet (event is weeks out), so
this can't be resolved from current data. If such an event's hours aren't
covered by this endpoint, shows tied to it would be wrongly gated CLOSED
during the live event — the opposite failure mode from the one this PR
fixes. Worth a live check once such an event is actually running; will file
a follow-up card for that.
Verification
npm testsuite green (2066 tests).npx tsc --noEmitclean.03:26 EDT, then re-verified after the hardening pass): Universal Studios
Hollywood's 45 live rows and Universal Orlando's 96 live rows across all
four parks are all CLOSED.
Test plan
npm test— full suite passesnpm run build— typechecks cleannpm run dev -- universalstudiosandnpm run dev -- universalorlandoagainst live upstream while both resorts are closed🤖 Generated with Claude Code