Add local navigation API

This commit is contained in:
2026-05-25 02:25:06 -04:00
parent b5d87775a6
commit 1661f8dec3
13 changed files with 637 additions and 91 deletions

View File

@@ -0,0 +1,47 @@
# Phase 10 Navigation UI
## Purpose
Phase 9 added local-first navigation APIs for seasons, weekends, sessions, and
dataset coverage. Phase 10 should use those APIs in the React Web UI so users
can browse ingested data instead of manually typing a `session_key`.
This is a frontend slice. Keep it functional and restrained; full visual polish
can come after the navigation workflow exists.
## Scope
Add React UI for:
- available seasons from `/api/v1/seasons`;
- locally ingested meetings for a selected year;
- one weekend view from `/api/v1/weekend?meeting_key=...`;
- session selection that routes into existing Race Hub views.
The existing Race Hub analytics views should stay intact.
## Product Behavior
- If local data exists, users should be able to reach Race Hub without knowing a
raw session key.
- Empty local database states should be explicit and calm.
- Weekend/session rows should show dataset coverage so users understand why a
session may be partial.
- Race Hub should continue accepting `session_key` in the URL for direct links.
## Guardrails
- Do not fetch OpenF1 directly from React.
- Do not redesign every screen.
- Do not remove the manual session key entry yet; keep it as a fallback.
- Do not add a large UI framework or chart dependency.
- Keep mobile and iPad usable.
## Acceptance Criteria
- Users can select a local year, meeting, and session.
- Selecting a session opens Race Hub for that session.
- Empty states are covered.
- Existing Race Hub e2e tests continue passing.
- Add focused frontend tests for navigation behavior where practical.
- Frontend tests and build pass.

View File

@@ -69,8 +69,10 @@ not implementation tickets yet.
- [17 Phase 9 Navigation Data API](17-phase-9-navigation-data-api.md): backend
slice for local-first season/weekend/session navigation so users do not need
raw session keys.
- [Cursor Phase 9 Prompt](cursor-phase-9-navigation-data-api-prompt.md):
current handoff prompt for the next Cursor backend phase.
- [18 Phase 10 Navigation UI](18-phase-10-navigation-ui.md): frontend slice for
adding local-first season/weekend navigation around Race Hub.
- [Cursor Phase 10 Prompt](cursor-phase-10-navigation-ui-prompt.md): current
handoff prompt for the next frontend phase.
## External References

View File

@@ -0,0 +1,83 @@
# Prompt For Cursor: Phase 10 Navigation UI
You are working in the `box-box` repository on Phase 10. This is a frontend
phase, but keep it pragmatic and low-context: build functional local-first
navigation around the existing Race Hub without redesigning the whole app.
## Read First
Open these files first:
- `documentations/refactor/18-phase-10-navigation-ui.md`
- `frontend/src/pages/RaceHubPage.tsx`
- `frontend/src/api.ts`
- `frontend/src/types.ts`
- `frontend/src/main.tsx`
- `frontend/src/styles.css`
- `tests/race-hub.spec.ts`
Only open older docs if you are blocked.
## Backend APIs Available
- `GET /api/v1/seasons`
- returns local years, newest first, e.g. `[2025]`.
- `GET /api/v1/meetings?year=2025&source=local`
- returns locally ingested meetings for the year.
- `GET /api/v1/weekend?meeting_key=1229`
- returns meeting metadata, sessions, `default_session_key`, and per-session
dataset coverage.
Use `source=local` for meetings so React does not fall back to OpenF1.
## Goal
Let users browse local data into Race Hub without knowing a raw `session_key`.
## Work To Do
1. Add TypeScript types and API functions for seasons, local meetings, and
weekend details.
2. Add a simple local data navigator in the React app:
- year selector/list;
- meetings for selected year;
- sessions for selected weekend;
- dataset coverage hints.
3. Selecting a session should navigate to `/race-hub?session_key=<key>`.
4. Keep the current manual session key entry as a fallback.
5. Preserve the existing Race Hub tabs and analytics views.
6. Add focused tests where practical.
7. Update Playwright coverage if a stable seeded navigation path is easy.
## Design Notes
- Keep it dense and operational, not a marketing page.
- Avoid card-heavy dashboard sludge.
- Reuse existing type, spacing, tab, and table conventions where possible.
- Mobile should remain usable.
## Do Not Do
- Do not fetch OpenF1 from React.
- Do not remove direct `session_key` routing.
- Do not introduce a new UI framework.
- Do not touch backend unless you find a blocking API bug.
## Verification
Run:
```bash
cd frontend && npm test -- --run
cd frontend && npm run build
npm run test:e2e
```
## Report Back
Summarize:
- files changed;
- navigation behavior added;
- tests run and results;
- follow-up polish or data needs.

View File

@@ -1,89 +0,0 @@
# Prompt For Cursor: Phase 9 Navigation Data API
You are working in the `box-box` repository as the backend engineer for Phase
9. Please keep this phase focused: add local-first navigation APIs so the
frontend can later stop requiring users to know raw `session_key` values.
## Read First
Open these files first:
- `documentations/refactor/17-phase-9-navigation-data-api.md`
- `internal/query/racehub.go`
- `internal/web/racehub.go`
- `internal/web/server.go`
- `internal/store/store.go`
- `internal/store/models.go`
- `internal/store/store_test.go`
- `scripts/seed-e2e-db/main.go`
Only open older planning docs if you need context.
## Goal
Implement local-first Web API read models for season/weekend/session
navigation. These endpoints must read from the SQLite domain database only.
They must not fetch OpenF1 on demand.
## Suggested API Shape
Use boring, stable names unless the codebase suggests a better convention:
- `GET /api/v1/seasons`
- returns years available in the local domain DB.
- `GET /api/v1/meetings?year=2025`
- returns locally ingested meetings for that year.
- `GET /api/v1/weekend?meeting_key=1229`
- returns meeting metadata, sessions, and per-session dataset coverage.
Dataset coverage should reuse the Race Hub dataset vocabulary where practical:
- meeting
- session
- drivers
- results
- starting_grid
- stints
- pit_stops
- positions
- race_control
- weather
- laps
## Implementation Notes
- Add query-layer structs/methods in `internal/query`; keep HTTP handlers thin.
- Add store read methods only where needed.
- Empty DB should return valid empty arrays, not 500s.
- Missing meeting should return a clear 404 from the web handler.
- Add tests against temp SQLite databases.
- If you touch the e2e seed, keep session `9472` as full data and `9000` as
core-only data.
## Do Not Do
- Do not build the React navigation UI yet.
- Do not add remote OpenF1 calls to these endpoints.
- Do not change the existing Race Hub response shape.
- Do not add live timing persistence in this phase.
## Verification
Run:
```bash
go test ./internal/store/... ./internal/query/... ./internal/web/...
go build -o /private/tmp/box-box ./cmd/main.go
cd frontend && npm test -- --run
cd frontend && npm run build
npm run test:e2e
```
## Report Back
Summarize:
- files changed;
- endpoint shapes added;
- tests run and results;
- follow-up risks or frontend handoff notes.