From b7696c11dedfcad973ba8b014bb4557ac38ce075 Mon Sep 17 00:00:00 2001 From: AmanTahiliani Date: Fri, 3 Jul 2026 03:11:16 -0400 Subject: [PATCH] docs: streamline README and split guides --- README.md | 241 ++++-------------------------------- docs/data-and-operations.md | 75 +++++++++++ docs/getting-started.md | 94 ++++++++++++++ docs/testing.md | 59 +++++++++ 4 files changed, 249 insertions(+), 220 deletions(-) create mode 100644 docs/data-and-operations.md create mode 100644 docs/getting-started.md create mode 100644 docs/testing.md diff --git a/README.md b/README.md index 76171cf..eccd8b0 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Live demo: [box-box.amantahiliani.com](https://box-box.amantahiliani.com/) ![box-box Command Center](docs/assets/command-center.jpg) -## What it does +## What It Does - **Command Center**: current race-weekend home with GP identity, live status, schedule, championship leaders, and direct analysis links. - **Race Hub**: session workspace for overview, race story, strategy, laps, weather, race control, and dataset coverage. @@ -18,248 +18,49 @@ Live demo: [box-box.amantahiliani.com](https://box-box.amantahiliani.com/) - **Local-first history**: OpenF1 data ingested into a SQLite domain database for fast historical browsing. - **Terminal Mode**: Bubble Tea TUI with standings, calendar, driver profiles, live timing, track map, battles, pit window, and replay. -## Status - -Pre-beta and actively developed. The Web UI is the primary surface; the TUI is preserved and still useful for terminal workflows. Live timing depends on F1 broadcasting timing data, so it is only fully active during live sessions. - ## Quickstart ```bash git clone https://github.com/AmanTahiliani/box-box.git cd box-box -npm install # Playwright and repo-level test scripts -npm install --prefix frontend # Vite + React app +npm install +npm install --prefix frontend npm run build --prefix frontend go run ./cmd/main.go --web # http://localhost:8080 ``` -For frontend development with a seeded local database: +For a local frontend development loop with seeded data, see [docs/getting-started.md](docs/getting-started.md). -```bash -go run ./scripts/seed-e2e-db/main.go --db /tmp/boxbox-dev.db -BOXBOX_DISABLE_LIVE=1 go run ./cmd/main.go --web --db /tmp/boxbox-dev.db --port 18080 +## Project Shape -BOXBOX_API_PORT=18080 npm run dev --prefix frontend -# http://localhost:5173 -``` - -## Architecture - -| Layer | Role | +| Area | What lives there | | --- | --- | -| **OpenF1 REST** | Backfill and ingestion source; optional paid tier via `OPENF1_API_KEY`. Also powers the TUI’s on-demand reads and HTTP cache. | -| **Domain SQLite** (`boxbox.db`) | Local store for meetings, sessions, Race Hub datasets, and navigation APIs used by the Web UI. | -| **HTTP cache SQLite** (`cache.db`) | TTL cache for OpenF1 responses (TUI and legacy paths). Separate from the domain DB. | -| **Official F1 SignalR** | Live timing bridge in `internal/live`, exposed to Web (SSE) and TUI. | -| **Go server** | `cmd/main.go`: TUI, `--web` API + static SPA, or CLI ingestion. | -| **React frontend** | `frontend/`: production build served from `frontend/dist` when present. | +| `cmd/main.go` | Entry point for TUI, web server, and ingestion CLI | +| `internal/web/` | Go REST API, SSE live bridge, SPA serving | +| `internal/live/` | Official F1 SignalR client shared by Web and TUI | +| `internal/store/`, `internal/ingest/`, `internal/query/` | Local SQLite domain database, ingestion, and read models | +| `internal/ui/` | Bubble Tea TUI | +| `frontend/` | React + Vite + TypeScript web app | +| `tests/` | Playwright e2e and visual coverage | -The Web UI should call **local-first Go APIs** (`/api/v1/...`). Do not add direct OpenF1 reads in the frontend. +The Web UI is local-first and should call the Go APIs under `/api/v1/...`; it should not read OpenF1 directly. -For architecture, phase history, and design rationale, see [documentations/refactor/README.md](documentations/refactor/README.md). +## Documentation -## Prerequisites +- [Getting Started](docs/getting-started.md): install, build, run modes, TUI keybindings, and web routes. +- [Data and Operations](docs/data-and-operations.md): ingestion, environment variables, local files, and live timing notes. +- [Testing](docs/testing.md): Go, frontend, e2e, and visual regression commands. +- [Architecture Notes](documentations/refactor/README.md): deeper design rationale, data-source decisions, and phase history. -- [Go](https://go.dev/doc/install) (see `go.mod` for the module version) -- [Node.js](https://nodejs.org/) 18+ and npm (Web UI dev, unit tests, Playwright) -- Internet for ingestion and TUI OpenF1 calls -- For E2E / visual tests: `npx playwright install` (Chromium) after `npm install` at the repo root +## Status -## Install - -```bash -git clone https://github.com/AmanTahiliani/box-box.git -cd box-box - -npm install # Playwright and repo-level test scripts -npm install --prefix frontend # Vite + React app -``` - -## Build - -```bash -go build -o box-box ./cmd/main.go -npm run build --prefix frontend # writes frontend/dist (gitignored) -``` - -## Run: TUI (default) - -```bash -go run ./cmd/main.go -# or: ./box-box -``` - -Logs go to `box-box.log` in the project directory so the terminal stays clean. - -### TUI keybindings - -| Key | Action | -| --- | --- | -| `1`-`7` | Home, Standings, Calendar, Race Detail, Drivers, Live, Track Map | -| `tab` / `shift+tab` | Next / previous tab | -| `j`/`k`, `enter`, `b`/`esc` | Navigate, select, back | -| `s`, `b`, `p` | Live: sectors, battles, pit window | -| `r` | Race replay (Race Detail, race sessions) | -| `y` | Cycle season year | -| `q` / `ctrl+c` | Quit | - -## Run: Web (Go serves API + built React) - -Build the frontend first, then start web mode. Go walks up from the cwd to find `frontend/dist/index.html`; if missing, it serves embedded legacy assets. - -```bash -npm run build --prefix frontend -go run ./cmd/main.go --web -# http://localhost:8080 -``` - -Use a specific domain database or port: - -```bash -go run ./cmd/main.go --web --db ~/.local/share/box-box/boxbox.db --port 8080 -``` - -## Run: Web dev (Vite + Go API) - -Vite proxies `/api` to the Go server. Set `BOXBOX_API_PORT` to match the Go `--port`. - -**Terminal 1: API (seeded DB is enough for UI work without ingesting):** - -```bash -go run ./scripts/seed-e2e-db/main.go --db /tmp/boxbox-dev.db -BOXBOX_DISABLE_LIVE=1 go run ./cmd/main.go --web --db /tmp/boxbox-dev.db --port 18080 -``` - -**Terminal 2: frontend:** - -```bash -BOXBOX_API_PORT=18080 npm run dev --prefix frontend -# default Vite port 5173: http://localhost:5173 -``` - -`BOXBOX_DISABLE_LIVE=1` skips starting the SignalR bridge (used in CI and local UI work). - -## Web routes - -| Route | Purpose | -| --- | --- | -| `/` | **Command Center**: fan-facing race-weekend home with GP identity, live status, session schedule, and analysis links | -| `/race-hub?session_key=` | **Race Hub**: weekend workspace with session rail and Overview / Race Story / Strategy / Lap Data / Conditions / Race Control / Data Status tabs. Bare `/race-hub` auto-resolves to the focus session. | -| `/admin` | **Admin / Data Health**: ingestion coverage, local data status, and suggested CLI commands | -| `/data-library` | Legacy alias for Admin / Data Health | -| `/live` | **Live Timing**: timing tower and race control via SSE when a session is live | - -Example after seeding: `http://localhost:5173/race-hub?session_key=9472` - -## Ingest historical data and briefing feeds - -Ingestion is a **CLI mode** on the same binary. Only one of `--ingest-year`, `--ingest-meeting`, `--ingest-session`, or `--ingest-news` may be set per run. - -```bash -# Season: discover and store meeting metadata (2023+) -go run ./cmd/main.go --ingest-year 2025 - -# Full race weekend: all sessions + Race Hub datasets -go run ./cmd/main.go --ingest-meeting 1229 - -# Single session only -go run ./cmd/main.go --ingest-session 9472 - -# Preview without writing -go run ./cmd/main.go --dry-run --ingest-meeting 1229 - -# Refresh Paddock Briefing RSS/Atom feeds -go run ./cmd/main.go --ingest-news - -# Custom DB path (default: ~/.local/share/box-box/boxbox.db) -go run ./cmd/main.go --ingest-meeting 1229 --db /tmp/boxbox.db -``` - -Use **`--ingest-meeting`** for a complete weekend. **`--ingest-year`** lists meetings for the season; ingest meetings individually or by weekend as needed. Optional analytics fetches may partially fail without aborting the whole run. - -## `OPENF1_API_KEY` - -```bash -export OPENF1_API_KEY=your_key_here -go run ./cmd/main.go --web -``` - -Without a key, the free OpenF1 tier is used. A key may be required for paid-tier behavior (e.g. live session access during API lockouts). Ingestion and TUI calls use the same client. - -## Local files - -| Path | Purpose | -| --- | --- | -| `~/.local/share/box-box/boxbox.db` | Domain database (default `--db`) | -| `~/.cache/box-box/cache.db` | OpenF1 HTTP response cache (TUI / client) | -| `box-box.log` | TUI application log (project root) | -| `frontend/dist/` | Production React build (**gitignored**; build locally, do not commit) | -| `.playwright/*.db` | Seeded DBs for automated tests | - -Web mode logs to **stderr**. - -## Tests and QA - -### Go (targeted packages) - -```bash -go test ./internal/live ./internal/models ./internal/store ./internal/ingest ./internal/query ./internal/web -``` - -All packages: `go test ./...` - -OpenF1 integration tests (network, rate-limit aware): `go test -v ./internal/api` - -### Frontend unit tests and build - -```bash -npm --prefix frontend test -- --run -npm --prefix frontend run build -``` - -### E2E (Vite dev proxy + seeded API) - -Starts seeded Go on port `18080` and Vite on `15173` (see `playwright.config.ts`). - -```bash -npx playwright install # first time only -npm run test:e2e -``` - -### E2E production (Go serves `frontend/dist`) - -```bash -npm run test:e2e:prod -``` - -### Visual regression (screenshots) - -```bash -npm run test:visual # dev proxy stack -npm run test:visual:prod # production serving (canonical baselines) - -# after intentional UI changes -npm run test:visual:update -npm run test:visual:prod:update -``` - -Snapshots live under `tests/visual/__snapshots__/`. - -## Known limitations - -- **Live timing** only works when F1 is broadcasting timing data; there is no guaranteed live session for local dev. -- **E2E / visual tests** use `BOXBOX_DISABLE_LIVE=1` and seeded SQLite; they do not exercise full SignalR live behavior. -- **`frontend/dist`** is generated output; build before production web mode or `test:e2e:prod`. -- **TUI historical views** still use OpenF1 on demand with the HTTP cache; the Web UI’s local-first model does not fully replace the TUI yet. -- **`--ingest-year`** stores season meetings, not full session datasets; use `--ingest-meeting` or `--ingest-session` for Race Hub data. +Pre-beta and actively developed. The Web UI is the primary surface; the TUI is preserved and still useful for terminal workflows. Live timing depends on F1 broadcasting timing data, so it is only fully active during live sessions. ## License MIT © [Aman Tahiliani](https://github.com/AmanTahiliani) ---- - *Unofficial project; not associated with Formula 1 or the FIA.* diff --git a/docs/data-and-operations.md b/docs/data-and-operations.md new file mode 100644 index 0000000..6d863f0 --- /dev/null +++ b/docs/data-and-operations.md @@ -0,0 +1,75 @@ +# Data and Operations + +## Data Flow + +| Layer | Role | +| --- | --- | +| OpenF1 REST | Backfill and ingestion source; optional paid tier via `OPENF1_API_KEY`. Also powers the TUI's on-demand reads and HTTP cache. | +| Domain SQLite (`boxbox.db`) | Local store for meetings, sessions, Race Hub datasets, and navigation APIs used by the Web UI. | +| HTTP cache SQLite (`cache.db`) | TTL cache for OpenF1 responses used by the TUI and legacy paths. Separate from the domain DB. | +| Official F1 SignalR | Live timing bridge in `internal/live`, exposed to Web via SSE and to the TUI. | +| Go server | `cmd/main.go`: TUI, `--web` API + static SPA, or CLI ingestion. | +| React frontend | `frontend/`: production build served from `frontend/dist` when present. | + +The Web UI should call local-first Go APIs under `/api/v1/...`; do not add direct OpenF1 reads in the frontend. + +## Ingest Historical Data and Briefing Feeds + +Ingestion is a CLI mode on the same binary. Only one of `--ingest-year`, `--ingest-meeting`, `--ingest-session`, or `--ingest-news` may be set per run. + +```bash +# Season: discover and store meeting metadata for 2023+ +go run ./cmd/main.go --ingest-year 2025 + +# Full race weekend: all sessions + Race Hub datasets +go run ./cmd/main.go --ingest-meeting 1229 + +# Single session only +go run ./cmd/main.go --ingest-session 9472 + +# Preview without writing +go run ./cmd/main.go --dry-run --ingest-meeting 1229 + +# Refresh Paddock Briefing RSS/Atom feeds +go run ./cmd/main.go --ingest-news + +# Custom DB path +go run ./cmd/main.go --ingest-meeting 1229 --db /tmp/boxbox.db +``` + +Use `--ingest-meeting` for a complete weekend. `--ingest-year` stores season meetings, not full session datasets. Optional analytics fetches may partially fail without aborting the whole run. + +## Environment Variables + +| Variable | Purpose | +| --- | --- | +| `OPENF1_API_KEY` | Optional Bearer token for paid OpenF1 behavior. | +| `BOXBOX_DISABLE_LIVE=1` | Skip the background SignalR live feed in web mode. Used by CI and local seeded UI work. | +| `BOXBOX_OPENF1_BASE_URL` | Override the OpenF1 API root. Defaults to `https://api.openf1.org`. | +| `BOXBOX_API_PORT` | Go API port used by the Vite dev proxy. Defaults to `8080`. | + +Example: + +```bash +export OPENF1_API_KEY=your_key_here +go run ./cmd/main.go --web +``` + +## Local Files + +| Path | Purpose | +| --- | --- | +| `~/.local/share/box-box/boxbox.db` | Domain database, default `--db`. | +| `~/.cache/box-box/cache.db` | OpenF1 HTTP response cache for the TUI and client. | +| `box-box.log` | TUI application log in the project root. | +| `frontend/dist/` | Production React build. Generated output, do not commit. | +| `.playwright/*.db` | Seeded databases for automated tests. | + +Web mode logs to stderr. + +## Known Limitations + +- Live timing only works when F1 is broadcasting timing data; there is no guaranteed live session for local development. +- E2E and visual tests use `BOXBOX_DISABLE_LIVE=1` and seeded SQLite, so they do not exercise full SignalR live behavior. +- `frontend/dist` is generated output; build before production web mode or `test:e2e:prod`. +- TUI historical views still use OpenF1 on demand with the HTTP cache; the Web UI's local-first model does not fully replace the TUI yet. diff --git a/docs/getting-started.md b/docs/getting-started.md new file mode 100644 index 0000000..575890e --- /dev/null +++ b/docs/getting-started.md @@ -0,0 +1,94 @@ +# Getting Started + +## Prerequisites + +- [Go](https://go.dev/doc/install), using the module version in `go.mod`. +- [Node.js](https://nodejs.org/) 18+ and npm. +- Internet access for ingestion and TUI OpenF1 calls. +- For e2e and visual tests: `npx playwright install` after `npm install` at the repo root. + +## Install + +```bash +git clone https://github.com/AmanTahiliani/box-box.git +cd box-box + +npm install # Playwright and repo-level test scripts +npm install --prefix frontend # Vite + React app +``` + +## Build + +```bash +go build -o box-box ./cmd/main.go +npm run build --prefix frontend # writes frontend/dist +``` + +## Run: Web + +Build the frontend first, then start web mode. Go walks up from the current directory to find `frontend/dist/index.html`; if missing, it serves embedded legacy assets. + +```bash +npm run build --prefix frontend +go run ./cmd/main.go --web +# http://localhost:8080 +``` + +Use a specific domain database or port: + +```bash +go run ./cmd/main.go --web --db ~/.local/share/box-box/boxbox.db --port 8080 +``` + +## Run: Web Dev + +Vite proxies `/api` to the Go server. Set `BOXBOX_API_PORT` to match the Go `--port`. + +Terminal 1: API with a seeded database: + +```bash +go run ./scripts/seed-e2e-db/main.go --db /tmp/boxbox-dev.db +BOXBOX_DISABLE_LIVE=1 go run ./cmd/main.go --web --db /tmp/boxbox-dev.db --port 18080 +``` + +Terminal 2: frontend: + +```bash +BOXBOX_API_PORT=18080 npm run dev --prefix frontend +# http://localhost:5173 +``` + +`BOXBOX_DISABLE_LIVE=1` skips starting the SignalR bridge, which is useful for CI and local UI work. + +## Run: TUI + +```bash +go run ./cmd/main.go +# or: ./box-box +``` + +Logs go to `box-box.log` in the project directory so the terminal stays clean. + +## TUI Keybindings + +| Key | Action | +| --- | --- | +| `1`-`7` | Home, Standings, Calendar, Race Detail, Drivers, Live, Track Map | +| `tab` / `shift+tab` | Next / previous tab | +| `j`/`k`, `enter`, `b`/`esc` | Navigate, select, back | +| `s`, `b`, `p` | Live: sectors, battles, pit window | +| `r` | Race replay in Race Detail race sessions | +| `y` | Cycle season year | +| `q` / `ctrl+c` | Quit | + +## Web Routes + +| Route | Purpose | +| --- | --- | +| `/` | Command Center: race-weekend home with GP identity, live status, schedule, and analysis links | +| `/race-hub?session_key=` | Race Hub: session workspace with Overview, Race Story, Strategy, Lap Data, Conditions, Race Control, and Data Status tabs | +| `/admin` | Admin / Data Health: ingestion coverage, local data status, and suggested CLI commands | +| `/data-library` | Legacy alias for Admin / Data Health | +| `/live` | Live Timing: timing tower and race control via SSE when a session is live | + +Example after seeding: `http://localhost:5173/race-hub?session_key=9472`. diff --git a/docs/testing.md b/docs/testing.md new file mode 100644 index 0000000..402e0dd --- /dev/null +++ b/docs/testing.md @@ -0,0 +1,59 @@ +# Testing + +## Go + +Targeted offline-ish packages: + +```bash +go test ./internal/live ./internal/models ./internal/store ./internal/ingest ./internal/query ./internal/web +``` + +All packages: + +```bash +go test ./... +``` + +OpenF1 integration tests require network access and are rate-limit aware: + +```bash +go test -v ./internal/api +``` + +## Frontend Unit Tests and Build + +```bash +npm --prefix frontend test -- --run +npm --prefix frontend run build +``` + +## E2E + +The default Playwright config starts a seeded Go server on port `18080` and Vite on `15173`. + +```bash +npx playwright install # first time only +npm run test:e2e +``` + +Production serving mode builds around Go serving `frontend/dist`: + +```bash +npm run test:e2e:prod +``` + +## Visual Regression + +```bash +npm run test:visual +npm run test:visual:prod +``` + +After intentional UI changes: + +```bash +npm run test:visual:update +npm run test:visual:prod:update +``` + +Snapshots live under `tests/visual/__snapshots__/`.