Add Wiener Linien API integration and departures monitoring
This commit is contained in:
+12
-60
@@ -1,62 +1,14 @@
|
||||
# TimeToLeave — Implementation Checklist
|
||||
|
||||
> **Source:** [REWRITE_PLAN.md](./REWRITE_PLAN.md)
|
||||
> **Total:** 4 phases, 14 steps, ~5 hours estimated effort
|
||||
|
||||
---
|
||||
|
||||
## Phase 1 — Unblock Runtime (~45 min)
|
||||
|
||||
Fix bugs that crash the app or lose user data.
|
||||
|
||||
| Step | ✅ Implemented | ✔️ Reviewed | Notes |
|
||||
|------|:--------------:|:-----------:|-------|
|
||||
| **Step 1: Fix SSR Crash in `useBikeRoute`** (~10 min) | [x] | [x] | Relative URL fetch replaces `window.location.href` — SSR-safe. `isMounted` guard intact. |
|
||||
| **Step 2: Wire Calendar Events into `EventsStore`** (~15 min) | [x] | [x] | `CalendarPanel.tsx` merges via `useEffect` when calendar events arrive. `mergeEvents()` converts `CalendarEvent` (string `eventTime`) → `Event` (Date `eventTime`). Bonus: localStorage persistence with rehydration. |
|
||||
| **Step 3: Add Input Validation to `/api/hafas`** (~20 min) | [x] | [x] | Validates `svcReqL` array shape, method allowlist (TripSearch/LocMatch), caps `numF` at 10. Extra type guard on `svcReq.meth` (`typeof svcReq.meth !== 'string'`) exceeds spec. |
|
||||
|
||||
---
|
||||
|
||||
## Phase 2 — Deduplicate Code (~2 hours)
|
||||
|
||||
Eliminate duplicated logic so each integration has one source of truth.
|
||||
|
||||
| Step | ✅ Implemented | ✔️ Reviewed | Notes |
|
||||
|------|:------:|:------:|-------|
|
||||
| **Step 4: Consolidate HAFAS Journey Parsing** (~40 min) | [x] | [x] | parseHafasJourneys moved to hafas-client.ts, exported, imported by useJourneys.ts. Option A followed. |
|
||||
| **Step 5: Wire API Routes to Use Library Clients** (~30 min) | [x] | [x] | Both routes use module-level singleton clients. Param validation, error handling, and try/catch intact. |
|
||||
| **Step 6: Remove Dead Code** (~5 min) | [x] | [x] | live-status-utils.ts deleted, export removed from index.ts. No remaining references. |
|
||||
| **Step 7: Create Missing Test Setup File** (~10 min) | [x] | [x] | src/test/setup.ts created with jest-dom vitest import. Referenced correctly in vitest.config.ts. |
|
||||
|
||||
---
|
||||
|
||||
## Phase 3 — Performance & UX (~1.5 hours)
|
||||
|
||||
| Step | ✅ Implemented | ✔️ Reviewed | Notes |
|
||||
|------|:------:|:------:|-------|
|
||||
| **Step 8: Add Debounce to Lookup Hooks** (~25 min) | [x] | [x] | 400ms setTimeout + AbortController in `useGeocode.ts` and `useDestinationStation.ts`. AbortError silently ignored. |
|
||||
| **Step 9: Pre-Group Calendar Events by Date** (~20 min) | [x] | [x] | `useMemo` builds `Map<string, Event[]>` keyed by `YYYY-MM-DD`. Per-cell `filter()` replaced with O(1) map lookup. |
|
||||
| **Step 10: Add Dark Mode Toggle** (~20 min) | [x] | [x] | `useTheme.ts` created (localStorage + prefers-color-scheme). Sun/moon toggle button added to `Header.tsx`. |
|
||||
| **Step 11: Fix Bike Route Steps** (~5 min) | [x] | [x] | `steps: "true"` already present in `BikeRoutingClient.getBikeRoute()` query params. |
|
||||
|
||||
---
|
||||
|
||||
## Phase 4 — Monitoring & Testing (~1 hour)
|
||||
|
||||
| Step | ✅ Implemented | ✔️ Reviewed | Notes |
|
||||
|------|:------:|:------:|-------|
|
||||
| **Step 12: Add Correlation IDs to API Errors** (~15 min) | [x] | [x] | `randomUUID().slice(0, 8)` in catch blocks of `bike-route`, `geocode`, `hafas`, `calendar`, `calendar/parse`. Logged server-side, returned in JSON. Existing API tests updated to assert `correlationId`. |
|
||||
| **Step 13: Add Hook Tests** (~30 min) | [x] | [x] | `useJourneys.test.ts` (4 tests: no-op when missing IDs, success, HTTP error, fetch throw). `useBikeRoute.test.ts` (4 tests: no-op when missing coords, success, HTTP error, fetch throw). |
|
||||
| **Step 14: Add Component Tests** (~15 min) | [x] | [x] | `EventCard.test.tsx` (renders title + destination, hooks mocked). `CalendarView.test.tsx` (3 tests: month header, event on correct day, overflow indicator). |
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
| Phase | Steps | Est. Time |
|
||||
|-------|-------|-----------|
|
||||
| 1 — Unblock Runtime | 1–3 | ~45 min |
|
||||
| 2 — Deduplicate Code | 4–7 | ~2 hours |
|
||||
| 3 — Performance & UX | 8–11 | ~1.5 hours |
|
||||
| 4 — Monitoring & Testing | 12–14 | ~1 hour |
|
||||
| **Total** | **14** | **~5 hours** |
|
||||
| # | Step | ✅ | ✔️ |
|
||||
|---|------|----|----|
|
||||
| 1 | Project scaffolding & baseline setup | [x] | [x] |
|
||||
| 2 | Environment config + constants (`src/lib/constants.ts`) | [x] | [x] |
|
||||
| 3 | Types (`src/types/index.ts`) | [x] | [x] |
|
||||
| 4 | Geocode client + route + hook + component | [x] | [x] |
|
||||
| 5 | Journeys client + route + hook + component | [x] | [x] |
|
||||
| 6 | Bike routing client + route + hook + component | [x] | [x] |
|
||||
| 7 | WienerLinien client + route + hook + component | [x] | [x] |
|
||||
| 8 | Wire `useWienerLinien` and `<WienerLinienSection>` into `EventCard.tsx` | [x] | [ ] |
|
||||
| 9 | End-to-end integration test for full event card | [ ] | [ ] |
|
||||
| 10 | Polish: loading skeletons, empty states, dark-mode audit | [ ] | [ ] |
|
||||
|
||||
Reference in New Issue
Block a user