125 lines
5.3 KiB
Markdown
125 lines
5.3 KiB
Markdown
# ÖBB Planner — Implementation Checklist
|
|
|
|
> Phase 2 complete. Moving to Phase 3.
|
|
|
|
---
|
|
|
|
**Checkbox key**
|
|
- `[ ]` pending (required) — blocks the next phase until both ✅ and ✔️ are `[x]`
|
|
- `[x]` done
|
|
- `[~]` optional or deferred — never blocks phase advancement; check `[x]` if completed, leave `[~]` to skip
|
|
|
|
---
|
|
|
|
## Phase 1 — Scaffold Next.js Project (~30 min)
|
|
|
|
| # | Item | ✅ | ✔️ |
|
|
|---|------|----|----|
|
|
| 1 | Initialize Next.js with App Router, TypeScript, Tailwind CSS | [x] | [x] |
|
|
| 2 | Set up `tsconfig.json` with strict mode | [x] | [x] |
|
|
| 3 | Create `.env.example` with `PORT`, `HAFAS_URL`, `NOMINATIM_URL`, `OSRM_URL` | [x] | [x] |
|
|
| 4 | Configure `next.config.ts` (rewrites if needed) _(optional — only required if URL rewrites are actually needed)_ | [~] | [~] |
|
|
| 5 | Configure `vitest.config.ts` _(deferred — must be done before Phase 7 begins, but not required to complete Phase 1)_ | [x] | [~] |
|
|
| 6 | Set up `postcss.config.mjs` | [x] | [x] |
|
|
|
|
---
|
|
|
|
## Phase 2 — Types + Library Layer (~2 hours)
|
|
|
|
| # | Item | ✅ | ✔️ |
|
|
|---|------|----|----|
|
|
| 7 | Define TypeScript types in `src/types/index.ts` | [x] | [x] |
|
|
| 8 | Port `lib/hafas-client.ts` — HAFAS API client functions with proper types | [x] | [x] |
|
|
| 9 | Port `lib/calendar-utils.ts` — `extractEvents` + `cleanLocation` | [x] | [x] |
|
|
| 10 | Port `lib/countdown-utils.ts`, `lib/formatting.ts`, `lib/constants.ts`, `lib/demo.ts` | [x] | [x] |
|
|
| 11 | Create `lib/geocoding-client.ts` — Nominatim client (NEW) | [x] | [x] |
|
|
| 12 | Create `lib/bike-routing-client.ts` — OSRM client (NEW) | [x] | [x] |
|
|
|
|
---
|
|
|
|
## Phase 3 — API Routes (~45 min)
|
|
|
|
| # | Item | ✅ | ✔️ |
|
|
|---|------|----|----|
|
|
| 13 | `src/app/api/hafas/route.ts` — POST handler, same logic as Express | [x] | [x] |
|
|
| 14 | `src/app/api/calendar/route.ts` — GET handler for remote ICS | [x] | [x] |
|
|
| 15 | `src/app/api/calendar/parse/route.ts` — POST handler for ICS body | [x] | [x] |
|
|
| 16 | `src/app/api/geocode/route.ts` — GET handler for Nominatim (NEW) | [x] | [x] |
|
|
| 17 | `src/app/api/bike-route/route.ts` — GET handler for OSRM (NEW) | [x] | [x] |
|
|
| 18 | `src/app/api/health/route.ts` — health check | [x] | [x] |
|
|
|
|
---
|
|
|
|
## Phase 4 — Custom Hooks (~2.5 hours)
|
|
|
|
| # | Item | ✅ | ✔️ |
|
|
|---|------|----|----|
|
|
| 19 | `useServerHealth.ts` — polls `/api/health` every 30s | [ ] | [ ] |
|
|
| 20 | `useClock.ts` — interval that updates `now` every 10s | [ ] | [ ] |
|
|
| 21 | `useGeolocation.ts` — wraps `navigator.geolocation` | [ ] | [ ] |
|
|
| 22 | `useOriginStation.ts` — finds nearest station from geolocation | [ ] | [ ] |
|
|
| 23 | `useJourneys.ts` — the complex `fetchAll` logic, per-event journey fetching | [ ] | [ ] |
|
|
| 24 | `useBikeRoute.ts` — fetches bicycle route for an event (NEW) | [ ] | [ ] |
|
|
| 25 | `useCalendar.ts` — URL/file import with merge logic | [ ] | [ ] |
|
|
| 26 | `useEventsStore.ts` — shared events state via Context (NEW) | [ ] | [ ] |
|
|
|
|
---
|
|
|
|
## Phase 5 — UI Components (~3.5 hours)
|
|
|
|
| # | Item | ✅ | ✔️ |
|
|
|---|------|----|----|
|
|
| 27 | `ui/Chip.tsx` — small badge component | [ ] | [ ] |
|
|
| 28 | `ui/Button.tsx` — styled button | [ ] | [ ] |
|
|
| 29 | `ui/LoadingSpinner.tsx` — loading indicator | [ ] | [ ] |
|
|
| 30 | `event/LeaveByBadge.tsx` — countdown badge | [ ] | [ ] |
|
|
| 31 | `event/JourneyList.tsx` — departure rows | [ ] | [ ] |
|
|
| 32 | `event/TrainSection.tsx` — train data in event card | [ ] | [ ] |
|
|
| 33 | `event/BikeSection.tsx` — bicycle data in event card (NEW) | [ ] | [ ] |
|
|
| 34 | `event/EventCard.tsx` — composes train + bike sections | [ ] | [ ] |
|
|
| 35 | `calendar/UrlTab.tsx` | [ ] | [ ] |
|
|
| 36 | `calendar/FileTab.tsx` | [ ] | [ ] |
|
|
| 37 | `calendar/CalendarPanel.tsx` | [ ] | [ ] |
|
|
| 38 | `add-event/AddEventModal.tsx` | [ ] | [ ] |
|
|
| 39 | `layout/Header.tsx` | [ ] | [ ] |
|
|
| 40 | `layout/Navbar.tsx` (NEW) | [ ] | [ ] |
|
|
|
|
---
|
|
|
|
## Phase 6 — Calendar Page (~1 hour)
|
|
|
|
| # | Item | ✅ | ✔️ |
|
|
|---|------|----|----|
|
|
| 41 | `calendar/CalendarView.tsx` — month grid component (NEW) | [ ] | [ ] |
|
|
| 42 | `calendar/DayEvents.tsx` — events for a selected day (NEW) | [ ] | [ ] |
|
|
| 43 | `app/calendar/page.tsx` — calendar route (NEW) | [ ] | [ ] |
|
|
|
|
---
|
|
|
|
## Phase 7 — Tests (~2 hours)
|
|
|
|
| # | Item | ✅ | ✔️ |
|
|
|---|------|----|----|
|
|
| 44 | Migrate `server/__tests__/*.test.js` → `src/app/api/__tests__/*.test.ts` | [ ] | [ ] |
|
|
| 45 | Add unit tests for `calendar-utils.ts`, `countdown-utils.ts` in `src/lib/__tests__/` | [ ] | [ ] |
|
|
| 46 | Add API tests for `geocode` and `bike-route` in `src/app/api/__tests__/` (NEW) | [ ] | [ ] |
|
|
| 47 | Add component smoke tests with `@testing-library/react` _(optional — valuable but not on the critical path; skip if setup cost outweighs benefit at the time)_ | [~] | [~] |
|
|
|
|
---
|
|
|
|
## Phase 8 — Cleanup (~30 min)
|
|
|
|
| # | Item | ✅ | ✔️ |
|
|
|---|------|----|----|
|
|
| 48 | Delete old `server/` directory | [ ] | [ ] |
|
|
| 49 | Delete old `oebb-planner-app/` directory | [ ] | [ ] |
|
|
| 50 | Delete `oebb-planner.jsx` | [ ] | [ ] |
|
|
| 51 | Update `README.md` with new architecture and instructions | [ ] | [ ] |
|
|
| 52 | Final integration test | [ ] | [ ] |
|
|
|
|
---
|
|
|
|
**✅ Implemented** — Code exists and is in the repo.
|
|
**✔️ Reviewed** — Code has been reviewed for correctness against the plan.
|
|
`[ ]` pending required · `[x]` done · `[~]` optional/deferred (never blocks phase advancement)
|