docs: sync README and docs/ with current codebase
Surfaces features that landed after the last big docs pass: per-ride history pages, Fast Lane wait times, outage shading on the today chart, Tier-5 wait-time sampler, production-hardening pieces (rate limiter, structured logger, env validation, graceful shutdown), and the new rides + ride_wait_samples tables. Also corrects the weather-delay rule to match the "open" vs "closing" gate now in rides.ts.
This commit is contained in:
@@ -52,6 +52,20 @@ The park detail page shows ride open/closed status using a two-tier approach:
|
||||
|
||||
2. **Schedule fallback (Six Flags API)** — when Queue-Times data is unavailable, the app falls back to the nearest upcoming date from the Six Flags schedule API as an approximation.
|
||||
|
||||
### Fast Lane wait times
|
||||
|
||||
A second wait number is fetched from Six Flags' `/wait-times/park/{apiId}` endpoint and joined onto each ride by name. The park page has a **Fast Lane** toggle (persisted in `localStorage.fastLaneMode`) that swaps the displayed wait between regular and Fast Lane. On the today chart, Fast Lane appears as a second line.
|
||||
|
||||
### Per-ride history
|
||||
|
||||
Click any ride name on a park page to open `/park/[id]/ride/[slug]` — a detail page with three tabs:
|
||||
|
||||
- **Today** — 5-minute wait-time samples (regular + Fast Lane) with outage markers
|
||||
- **7 days** — daily average / max wait and uptime percentage
|
||||
- **30 days** — same aggregates over a longer window
|
||||
|
||||
Samples are stored in the `ride_wait_samples` table by a Tier-5 cron job that runs every 5 minutes for parks currently within their operating window. Contiguous "ride closed during park hours" runs are shaded on the today chart with a `#N — Hh Mm` label.
|
||||
|
||||
### Roller Coaster Filter
|
||||
|
||||
When live data is shown, a **Coasters only** toggle filters to roller coasters. Coaster lists are hardcoded in `lib/coaster-data.ts`.
|
||||
@@ -66,8 +80,9 @@ The backend runs a tiered scraping schedule via node-cron:
|
||||
| 2 | Every 6 hours | Current month for all parks |
|
||||
| 3 | Twice daily (3 AM, 3 PM) | Current + next month |
|
||||
| 4 | Daily at 3 AM | Full year (respects 72h staleness window) |
|
||||
| 5 | Every 5 minutes | Wait-time samples for all currently-open parks (writes `ride_wait_samples`) |
|
||||
|
||||
Past dates are never overwritten. The hourly tier compares live data against the database before writing — unchanged data is skipped.
|
||||
Past dates are never overwritten. The hourly tier compares live data against the database before writing — unchanged data is skipped. Each tier has its own concurrency latch — if a tick is still running when the next would fire, the new tick is skipped and logged rather than stacked.
|
||||
|
||||
A manual trigger is available via the backend API:
|
||||
|
||||
@@ -152,7 +167,7 @@ See [`.env.example`](.env.example) for the full list and defaults.
|
||||
| `PORT` | `3001` | Port the Hono server listens on. |
|
||||
| `TZ` | `UTC` | Timezone for cron schedules (e.g. `America/New_York`). |
|
||||
| `PARK_HOURS_STALENESS_HOURS` | `72` | Hours before park schedule data is re-fetched. |
|
||||
| `RATE_LIMIT_PER_MIN` | `60` | Per-IP request limit for the public API, per minute. |
|
||||
| `RATE_LIMIT_PER_MIN` | `60` | Per-IP request limit for the public API, per minute. Enforced by `backend/src/middleware/rate-limit.ts`; over-limit requests get a `429` with a `Retry-After` header. |
|
||||
|
||||
### Updating
|
||||
|
||||
@@ -167,6 +182,7 @@ docker compose pull && docker compose up -d
|
||||
| `GET /api/calendar/week?start=YYYY-MM-DD` | Week calendar for all parks |
|
||||
| `GET /api/calendar/:parkId/month?month=YYYY-MM` | Month calendar for one park |
|
||||
| `GET /api/parks/:id/rides` | Live rides or schedule fallback |
|
||||
| `GET /api/parks/:id/rides/:slug` | Per-ride detail + today/7d/30d wait-time history |
|
||||
| `GET /api/parks` | Park list with metadata |
|
||||
| `GET /api/status` | Health check, scrape timestamps, DB stats |
|
||||
| `POST /api/scrape/trigger?scope=...` | Manual scrape trigger |
|
||||
|
||||
Reference in New Issue
Block a user