fix(attractionsio): trust an explicit IsOpen for attraction live status (Djurs Sommerland mass-CLOSED)#259
Open
TimBroddin wants to merge 1 commit into
Open
Conversation
Djurs Sommerland's live feed only sets IsOperational:true on its ~21 queue-metered headline rides; every other open attraction (playgrounds, the Vandland water park, unmetered family rides) reports IsOperational:false with IsOpen:true and a concrete opening window for the day. The attraction branch of buildLiveData() derived status purely from IsOperational, so 44 open attractions were published as CLOSED. Treat an explicit boolean IsOpen as the authoritative live signal for attractions — mirroring the dining branch, which already worked this way — and fall back to IsOperational when IsOpen is absent (Merlin feeds omit it on non-operating rides). Merlin semantics are preserved: across 8 checkable parks, zero tracked attractions sit in the (IsOperational:false, IsOpen:true) combo, and a live breakdown (Legoland Windsor's Jolly Rocker, "BACK SOON") reports IsOpen:false, so breakdowns still surface as CLOSED. The only other park whose output changes is Legoland Windsor, where 5 unmetered walk-through attractions (4D cinema, Adventure Golf, …) were wrongly CLOSED all day for the same reason.
Contributor
Author
|
Generated with Claude Code but reviewed by me. I double checked for breakages. |
TimBroddin
marked this pull request as ready for review
July 17, 2026 12:47
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.
Problem
Djurs Sommerland publishes most of its attractions as
CLOSEDeven while the park is open. Snapshot from production on 2026-07-17 (park open 10:00–20:00, Aqua Park 12:00–18:00 per djurssommerland.dk): 47 of 100 live entities CLOSED, including the Vandland water park, Water Slides, Junior Aqua Park, and dozens of family rides and playgrounds. Every CLOSED attraction had no wait time; every attraction with a wait time was OPERATING — which pointed at queue metering, not actual closures.Root cause
The Djurs live feed (
live-data.attractions.io/<key>.json) only setsIsOperational: trueon its ~21 queue-metered headline rides. Every other open attraction reports:{"IsOperational": false, "IsOpen": true, "OpeningTimes": "{\"type\":\"range\",\"start\":\"2026-07-17 10:00:00\",\"end\":\"2026-07-17 20:00:00\"}"}At scan time the feed contained 44 tracked attractions in this state (open with today's hours) and exactly 1 genuinely closed attraction (
IsOpen: false— a meet & greet). The attraction branch ofbuildLiveData()derived status purely fromIsOperational(IsOperational ? OPERATING : CLOSED), so all 44 were published as CLOSED. The dining branch already treated an explicit booleanIsOpenas authoritative — attractions just never got the same rule.Fix
For attractions, an explicit boolean
IsOpennow wins;IsOperationalremains the fallback whenIsOpenis absent (Merlin feeds omit it on non-operating rides). Status truth table:IsOperationalIsOpenOnly one combination changes, so a park can only be affected if its feed explicitly asserts
IsOpen: trueon a non-operational attraction.Cross-park impact analysis
Scanned the live feeds of every park on this base class with a publicly recoverable feed key (10 of 16), joined against tracked entities via the production API:
(IsOperational:false, IsOpen:true)Legoland Windsor also gets fixed
Windsor has 5 attractions that flip CLOSED → OPERATING: Pirate Goldwash, LEGO® Studios 4D, The Brick, LEGO Ferrari Build & Race, LEGOLAND® Adventure Golf. These are exactly the Djurs-style unmetered walk-through/experience attractions; their records carried
IsOpen: truewith today's opening hours while the park was open. They appear to have been wrongly CLOSED all day until now — same bug, second park.Breakdown semantics verified live
The main regression worry was Merlin breakdowns being masked as OPERATING. Directly disproven during the scan:
QueueStatusMessage: "BACK SOON") and reportedIsOperational: false, IsOpen: false→ stays CLOSED under the new logic.TEMPORARY DELAY— it keptIsOperational: true."Geöffnet"with both flags true.So no observed attractions.io feed leaves
IsOpen: trueon anything that isn't actually open — including closed-park (California at night) and broken-down states.Verification
an attraction with IsOpen:true but IsOperational:false is OPERATINGfailed before the fix, passes after; two guard tests pin the unchanged combos (IsOpen:falsestill closes, absentIsOpenstill falls back toIsOperational).tscclean.npm run dev -- djurssommerlandwith the park's public app config): 96 OPERATING / 3 CLOSED, all 21 wait times intact — vs 53/47 in production at the same time.Not covered / follow-ups
IsOpen: trueon a closed attraction — behavior no examined feed exhibits in any state. Comparing OPERATING counts before/after deploy for those six would settle it conclusively.IsOpenfield at all (e.g. Alton's Haunted Hollow, CBeebies photo studio) still show CLOSED all day. Fixing that would need theOpeningTimeswindow fallback (like the dining branch) and its own verification pass.🤖 Generated with Claude Code