From a0f135aac1aa476a9fb2de415b038968a9cb2560 Mon Sep 17 00:00:00 2001 From: AmanTahiliani Date: Mon, 25 May 2026 11:26:52 -0400 Subject: [PATCH] Update operator documentation --- README.md | 252 +++++++++++++++++++++++------- documentations/refactor/README.md | 6 + 2 files changed, 198 insertions(+), 60 deletions(-) diff --git a/README.md b/README.md index c914914..0032be1 100644 --- a/README.md +++ b/README.md @@ -1,92 +1,224 @@ -# ๐ŸŽ๏ธ box-box +# box-box -![Status-Pre-Beta](https://img.shields.io/badge/Status-Pre--Beta-yellow?style=for-the-badge) +> "Box, box. Box, box." โ€” Every F1 race engineer, ever. -> "Box, box. Box, box." โ€” Every F1 Race Engineer, ever. +**box-box** is a Formula 1 dashboard in Go with two surfaces: -**โš ๏ธ Disclaimer: This project is currently in a pre-beta state.** Features may be incomplete, and you might encounter bugs as we fine-tune the engine. +- **Web UI (primary)** โ€” React + TypeScript SPA for Race Hub analytics, local data coverage, and live timing. +- **TUI (preserved)** โ€” Bubble Tea terminal app with standings, calendar, driver profiles, official live timing, track map, battles, pit window, and replay. -**box-box** is a high-performance Formula 1 Terminal User Interface (TUI) built for fans who live in the command line. Get real-time standings, race calendars, and deep-dive driver stats without ever leaving your terminal. +Historical Web data is **local-first** in a SQLite domain database (ingested from OpenF1). **Live timing** uses the official F1 SignalR feed via the Go server; the React app reads `/api/v1/live/*`, not OpenF1 directly. -![box-box TUI Preview](https://img.shields.io/badge/UI-Bubble%20Tea-00ADD8?style=for-the-badge&logo=go) -![Data-OpenF1](https://img.shields.io/badge/Data-OpenF1-FF1801?style=for-the-badge) +For architecture, phase history, and design rationale, see [documentations/refactor/README.md](documentations/refactor/README.md). -## โœจ Features +## How it fits together -- ๐Ÿ† **Live Standings**: Keep track of the Driver and Constructor Championships. -- ๐Ÿ“… **Race Calendar**: The full 2025 schedule at your fingertips. -- ๐ŸŽ๏ธ **Race Details**: Deep dive into session results, starting grids, and lap data. -- ๐Ÿ‘ค **Driver Profiles**: Detailed stats for every driver on the grid. -- ๐Ÿ”ด **Official Live Timing**: Real-time F1 timing tower via the official SignalR feed โ€” gaps, intervals, tyre age, sector times, DRS, and track status. -- โš”๏ธ **Battle Tracker**: Auto-detects on-track duels within DRS range with gap sparklines and tyre strategy comparison. -- ๐Ÿ”ง **Pit Window Calculator**: Predicts rejoin position if a driver pits now, using per-circuit pit loss times. -- โช **Race Replay**: Lap-by-lap scrubber for completed races โ€” relive the whole field's evolution with pit annotations and race control messages. -- ๐Ÿ—บ๏ธ **ASCII Track Map**: Live car positions on a terminal-rendered track outline, team-coloured. -- ๐Ÿ”Œ **Offline-ish**: Fast, lightweight, and powered by the wonderful [OpenF1 API](https://openf1.org). +| 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 (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. | -## ๐Ÿš€ Quick Start +The Web UI should call **local-first Go APIs** (`/api/v1/...`). Do not add direct OpenF1 reads in the frontend. -### Prerequisites +## Prerequisites -- [Go](https://go.dev/doc/install) 1.21 or higher. +- [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 -### Installation +## Install ```bash -# Clone the repository git clone https://github.com/AmanTahiliani/box-box.git cd box-box -# Build and run -go run cmd/main.go +npm install # Playwright and repo-level test scripts +npm install --prefix frontend # Vite + React app ``` -## ๐ŸŽฎ Controls +## 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` | Switch to **Home** | -| `2` | Switch to **Standings** | -| `3` | Switch to **Calendar** | -| `4` | Switch to **Race Details** | -| `5` | Switch to **Drivers** | -| `6` | Switch to **Live Timing** | -| `7` | Switch to **Track Map** | -| `tab` / `shift+tab` | Next / Previous tab | -| `j`/`โ†“` | Navigate down | -| `k`/`โ†‘` | Navigate up | -| `enter` | Select/Inspect item | -| `b` / `esc` | Go back / collapse | -| `s` | Toggle sector times (Live tab) | -| `b` | Toggle Battle Tracker (Live tab) | -| `p` | Toggle Pit Window Calculator (Live tab) | -| `r` | Enter Race Replay (Race Detail tab, Race sessions) | -| `โ†`/`h` ยท `โ†’`/`l` | Scrub laps in Replay | +| `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` | Exit | +| `q` / `ctrl+c` | Quit | -## ๐Ÿ› ๏ธ Tech Stack +## Run โ€” Web (Go serves API + built React) -- **[Bubble Tea](https://github.com/charmbracelet/bubbletea)**: The TUI engine. -- **[Lipgloss](https://github.com/charmbracelet/lipgloss)**: For that sleek F1 styling. -- **[Bubbles](https://github.com/charmbracelet/bubbles)**: Common TUI components. -- **[OpenF1 API](https://api.openf1.org)**: The data source (Free, no API key needed). - -## ๐Ÿšฅ Development - -Want to tinker under the hood? +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 -# Run tests -go test ./... - -# View API integration tests (requires internet) -go test -v ./internal/api +npm run build --prefix frontend +go run ./cmd/main.go --web +# โ†’ http://localhost:8080 ``` -## ๐Ÿ“œ License +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** โ€” local season/weekend coverage, focus weekend, quick links to Live / Race Hub / Data Library | +| `/race-hub?session_key=` | **Race Hub** โ€” classification, grid, strategy, positions, laps, race control, weather (from local DB) | +| `/data-library` | **Data Library** โ€” ingestion coverage and suggested CLI commands | +| `/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 (OpenF1 โ†’ domain DB) + +Ingestion is a **CLI mode** on the same binary. Only one of `--ingest-year`, `--ingest-meeting`, or `--ingest-session` 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 + +# 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. + +## License MIT ยฉ [Aman Tahiliani](https://github.com/AmanTahiliani) --- -*Disclaimer: This project is unofficial and not associated with Formula 1 or the FIA in any way.* + +*Unofficial project; not associated with Formula 1 or the FIA.* diff --git a/documentations/refactor/README.md b/documentations/refactor/README.md index d1acbf2..dd4acee 100644 --- a/documentations/refactor/README.md +++ b/documentations/refactor/README.md @@ -1,5 +1,11 @@ # box-box Refactor Brief +## Operator guide + +For day-to-day build, run, ingest, test, and Web route commands, use the +top-level [README.md](../../README.md). This directory is for architecture, +phasing, and research โ€” not the first stop for new contributors. + ## Purpose This directory captures the planning baseline for the next major evolution of