77b8c6db98
Update CHECKLIST.md and REWRITE_PLAN.md to reflect the current post-rewrite status and remaining tasks. - Add input validation to /api/hafas route to enforce request shape and cap results - Fix SSR crash in useBikeRoute by using relative fetch URLs - Wire CalendarPanel to fetch calendar events and merge them into the global events store
4.3 KiB
4.3 KiB
TimeToLeave — Implementation Checklist
Source: 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 4: Consolidate HAFAS Journey Parsing (~40 min)
- Move
parseHafasJourneysfromuseJourneys.tsintohafas-client.tsand export it; import fromuseJourneys.ts(Option A — minimal risk) - Files:
src/lib/hafas-client.ts,src/hooks/useJourneys.ts
- Move
-
Step 5: Wire API Routes to Use Library Clients (~30 min)
- Replace raw
fetch()inapi/geocode/route.tswithGeocodingClient, and inapi/bike-route/route.tswithBikeRoutingClient(module-level singleton, proper error handling) - Files:
src/app/api/geocode/route.ts,src/app/api/bike-route/route.ts
- Replace raw
-
Step 6: Remove Dead Code (~5 min)
- Delete
src/lib/live-status-utils.tsentirely; remove its export fromsrc/lib/index.ts - File:
src/lib/live-status-utils.ts,src/lib/index.ts
- Delete
-
Step 7: Create Missing Test Setup File (~10 min)
- Create
src/test/setup.tswithimport "@testing-library/jest-dom/vitest"so jsdom matchers are registered globally - File:
src/test/setup.ts
- Create
Phase 3 — Performance & UX (~1.5 hours)
-
Step 8: Add Debounce to Lookup Hooks (~25 min)
- Wrap fetch in a 400 ms
setTimeoutwithAbortControllercleanup inuseGeocode.tsanduseDestinationStation.tsto prevent per-keystroke API calls - Files:
src/hooks/useGeocode.ts,src/hooks/useDestinationStation.ts
- Wrap fetch in a 400 ms
-
Step 9: Pre-Group Calendar Events by Date (~20 min)
- Build a
Map<string, Event[]>keyed byYYYY-MM-DDviauseMemoinCalendarView.tsx; replace per-cellfilter()with O(1) map lookup - File:
src/app/calendar/CalendarView.tsx
- Build a
-
Step 10: Add Dark Mode Toggle (~20 min)
- Create
useTheme.tshook (persist tolocalStorage, respectprefers-color-scheme); add sun/moon toggle button toHeader.tsx - Files:
src/hooks/useTheme.ts(new),src/app/layout/Header.tsx
- Create
-
Step 11: Fix Bike Route Steps (~5 min)
- Add
steps: "true"to the query params inBikeRoutingClient.getBikeRoute()so OSRM returns turn-by-turn steps - File:
src/lib/bike-routing-client.ts
- Add
Phase 4 — Monitoring & Testing (~1 hour)
-
Step 12: Add Correlation IDs to API Errors (~15 min)
- Generate a short UUID (
randomUUID().slice(0, 8)) in each API route's catch block; log it server-side and include it in the JSON error response - Files: all
src/app/api/*/route.ts
- Generate a short UUID (
-
Step 13: Add Hook Tests (~30 min)
- Create
useJourneys.test.tsanduseBikeRoute.test.ts— mockglobal.fetch, test state transitions (loading → success, loading → error) - Files:
src/hooks/__tests__/useJourneys.test.ts,src/hooks/__tests__/useBikeRoute.test.ts
- Create
-
Step 14: Add Component Tests (~15 min)
- Create
EventCard.test.tsxandCalendarView.test.tsx— render with mock data, verify key elements are in the document - Files:
src/app/event/__tests__/EventCard.test.tsx,src/app/calendar/__tests__/CalendarView.test.tsx
- Create
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 |