Files
time_to_leave/CHECKLIST.md
T
fegger 7abfddd607 Add debounce, theme toggle, and calendar optimization
Implement 400ms debounce with AbortController in useGeocode and
useDestinationStation to prevent excessive API calls. Add dark mode
toggle via new useTheme hook, persisting preference to localStorage
and applying to document root.

Pre-group calendar events by date using a Map in CalendarView to
replace O(n) filter operations with O(1) lookups.
2026-05-10 03:39:30 +02:00

3.8 KiB
Raw Blame History

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 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] 400ms setTimeout + AbortController in useGeocode.ts and useDestinationStation.ts. AbortError silently ignored.
Step 9: Pre-Group Calendar Events by Date (~20 min) [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] useTheme.ts created (localStorage + prefers-color-scheme). Sun/moon toggle button added to Header.tsx.
Step 11: Fix Bike Route Steps (~5 min) [x] steps: "true" already present in BikeRoutingClient.getBikeRoute() query params.

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
  • Step 13: Add Hook Tests (~30 min)

    • Create useJourneys.test.ts and useBikeRoute.test.ts — mock global.fetch, test state transitions (loading → success, loading → error)
    • Files: src/hooks/__tests__/useJourneys.test.ts, src/hooks/__tests__/useBikeRoute.test.ts
  • Step 14: Add Component Tests (~15 min)

    • Create EventCard.test.tsx and CalendarView.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

Summary

Phase Steps Est. Time
1 — Unblock Runtime 13 ~45 min
2 — Deduplicate Code 47 ~2 hours
3 — Performance & UX 811 ~1.5 hours
4 — Monitoring & Testing 1214 ~1 hour
Total 14 ~5 hours