feat(enchantedparks): add Valleyfair under new Enchanted Parks umbrella#183
Open
cubehouse wants to merge 12 commits into
Open
feat(enchantedparks): add Valleyfair under new Enchanted Parks umbrella#183cubehouse wants to merge 12 commits into
cubehouse wants to merge 12 commits into
Conversation
Base class EnchantedParks extends Destination with @config subdomain/ destinationId/destinationName/timezone plus optional themePark/waterPark ParkConfig blocks. getDestinations returns the DESTINATION entity; buildEntityList / buildSchedules / buildLiveData are stubs that return empty arrays. Valleyfair subclass provides the concrete config. Restores Valleyfair coverage that was dropped in 8d7216a when the unified sixflags class was assumed to cover all former Cedar Fair parks; in fact Valleyfair was divested to Enchanted Parks. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Pure module-scope function that filters The Events Calendar REST response to events whose categories include the requested name (e.g. 'Park Hours' for the theme park, 'Waterpark Hours' for the waterpark) and converts them to operating-hours schedule entries with the correct timezone offset. Skips all_day events (those are group events, not operating hours). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Used when the Tribe REST endpoint is unavailable. Parses VEVENT blocks, filters by CATEGORIES line, skips all-day events (DTSTART;VALUE=DATE). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Walks <a href="…/rides-and-experiences/attractions/{slug}/"> links
and pairs each with the nearest h3 heading. Decodes HTML entities,
deduplicates repeats, ignores dining/etc links.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Cache 1h for the calendar sources (events refresh hourly on the WP side) and 24h for the static rides listing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…back The Tribe REST endpoint caps each page at 50 events. scrapeSchedule pages through until total_pages is reached (with a 30-page safety ceiling), then parses each page's category-filtered events. Falls back to the iCal feed only if Tribe returned zero matches or threw. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Theme-park rides from themePark.ridesPath, waterpark rides from waterPark.ridesPath. The waterpark slugs are claimed first; the master attractions page (which lists everything together) skips those so each ride emits exactly once under the right park. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Theme park reads 'Park Hours' category, waterpark reads 'Waterpark Hours' category. Tribe REST is preferred (paginated); iCal feed is used as fallback if Tribe is unavailable. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| h3 = candidate; | ||
| } | ||
| if (!h3) continue; | ||
| const name = decodeHtmlEntities(h3[1].replace(/<[^>]+>/g, '').trim()); |
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a new enchantedparks destination implementation to restore Valleyfair coverage after the Cedar Fair refactor dropped it, establishing an “Enchanted Parks” umbrella intended to host additional parks in follow-up PRs.
Changes:
- Introduces
EnchantedParksbase class with schedule + attraction scraping (Tribe Events REST + iCal fallback, and HTML parsing). - Adds
Valleyfairconcrete destination under the new umbrella with two PARK entities (theme park + waterpark). - Adds unit tests for the pure parsers and updates entity/registry regression coverage for the new Valleyfair registration.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
src/parks/enchantedparks/valleyfair.ts |
Registers Valleyfair destination and provides default IDs/metadata for destination + two parks |
src/parks/enchantedparks/enchantedparks.ts |
Implements shared Enchanted Parks scraping + entity/schedule builders and exported parsers |
src/parks/enchantedparks/__tests__/enchantedparks.test.ts |
Adds unit tests for parseTribeEvents, parseICalFeed, parseAttractionsPage |
src/__tests__/entityIdRegression.test.ts |
Adds regression assertions for Valleyfair registry id/category and DESTINATION entity id |
Comment on lines
+8
to
+15
| super({ | ||
| ...options, | ||
| config: { | ||
| subdomain: 'https://valleyfair.enchantedparks.com', | ||
| destinationId: 'enchantedparks_valleyfair', | ||
| destinationName: 'Valleyfair', | ||
| timezone: 'America/Chicago', | ||
| ...(options?.config ?? {}), |
| location?: {latitude: number; longitude: number}; | ||
| }; | ||
|
|
||
| @config |
Spec entity-id schema is enchantedparks_attraction_<CODE>_<slug>; the initial implementation dropped the <CODE> segment, which would risk cross-park slug collisions when other Enchanted Parks subclasses land later. Adds 'code' to ParkConfig (e.g. 'VF', 'VFW'), threads it into the id construction, and tightens the regression test to assert the legacy 'valleyfair' id is gone. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Addresses two Copilot review notes on #183: 1. Subdomain was hardcoded in the Valleyfair subclass. CLAUDE.md requires empty defaults configured via .env. The base class's @config subdomain now resolves entirely from VALLEYFAIR_SUBDOMAIN (or ENCHANTEDPARKS_SUBDOMAIN). _init() throws a clear error if neither is set so failure is loud. 2. Class-level @config on the base risks double-wrap with the subclass's @destinationController. Removed the class decorator; property-level @config still resolves through the subclass proxy. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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
Restores Valleyfair coverage in parksapi after the cedarfair-drop refactor (
8d7216ab, 2026-04-20) accidentally dropped it. That refactor assumed every former Cedar Fair park had moved to the unified Six Flags app; in fact Valleyfair was divested to a new operator, Enchanted Parks, and is no longer in the Six Flags Firebase Remote Config.This PR adds an
enchantedparksumbrella destination class withValleyfairas the first concrete subclass. The umbrella shape is ready to host the four other Enchanted Parks (Worlds of Fun,Michigan's Adventure,Six Flags St Louis,Six Flags Great Escape,Schlitterbahn Galveston) in follow-up PRs.What v1 covers
enchantedparks_valleyfairenchantedparks_park_VF(Valleyfair theme park)enchantedparks_park_VFW(Superior Shores Waterpark)/rides-and-experiences/<path>/Live wait-times will plug in when the Enchanted Parks app launches Memorial Day 2026.
Architecture
EnchantedParks(src/parks/enchantedparks/enchantedparks.ts) — shared HTTP fetches, pure scrape parsers (parseTribeEvents,parseICalFeed,parseAttractionsPage),getAttractionRideIds-style filter, and template-methodbuild*implementations.Valleyfair(valleyfair.ts) — config-only (~40 lines).Notable details
per_pageat 50 regardless of what you ask for.scrapeSchedulewalks pages viatotal_pages(30-page safety ceiling)./rides-and-experiences/attractions/page lists every ride (theme park + waterpark together). The waterpark page (/rides-and-experiences/superior-shores-waterpark/) lists only its own rides — those slugs are claimed first, and theme-park-page entries with the same slug are skipped to avoid double-emit.Test plan
npm run buildcleannpm test— full 1107+ test suite passesnpm run dev -- valleyfair4/4 passes:entityIdRegression.test.ts) updated to assert the new registry id and namespaced entity idMigration
After merge, run
npm run migrate -- valleyfair --wiki-slug=valleyfairto retag wiki entities from the oldvalleyfair/*IDs to the newenchantedparks_*IDs.🤖 Generated with Claude Code