mirror of
https://github.com/AmanTahiliani/box-box.git
synced 2026-08-07 19:56:18 -04:00
Add local-first refactor foundation
This commit is contained in:
136
documentations/refactor/10-phase-2-store-foundation.md
Normal file
136
documentations/refactor/10-phase-2-store-foundation.md
Normal file
@@ -0,0 +1,136 @@
|
||||
# Phase 2 Store Foundation
|
||||
|
||||
## Purpose
|
||||
|
||||
Phase 2 introduces the local domain database foundation. The current SQLite
|
||||
database is an HTTP response cache. That should remain intact, but it is not the
|
||||
same thing as an app-owned F1 domain store.
|
||||
|
||||
The goal of this phase is to add `internal/store` with schema initialization,
|
||||
migrations, provenance-aware raw payload storage, and a small set of typed
|
||||
domain tables needed by Race Hub v1. This phase should not build ingestion
|
||||
commands or change the Web UI yet.
|
||||
|
||||
## Manager Decision
|
||||
|
||||
Keep this phase boring and structural. Do not try to ingest a full weekend yet.
|
||||
The deliverable is a tested store package that later phases can call.
|
||||
|
||||
Phase 2 should prove:
|
||||
|
||||
- the app can create/open a domain SQLite database;
|
||||
- migrations are repeatable and idempotent;
|
||||
- raw source payloads can be stored with provenance;
|
||||
- basic meeting/session/driver/session result records can be upserted and read;
|
||||
- existing HTTP cache behavior is untouched.
|
||||
|
||||
## Package Boundary
|
||||
|
||||
Add:
|
||||
|
||||
```text
|
||||
internal/store/
|
||||
db.go open/close database, pragmas, transaction helper
|
||||
migrations.go embedded SQL migrations and schema versioning
|
||||
models.go store-layer structs for v1 domain records
|
||||
raw.go raw payload/provenance writes and reads
|
||||
meetings.go typed meeting/session upserts and reads
|
||||
results.go typed driver/result/grid-style records as initial slice
|
||||
store_test.go temp-db migration and CRUD tests
|
||||
```
|
||||
|
||||
The exact file split can change, but `internal/store` should not import
|
||||
`internal/ui` or `internal/web`.
|
||||
|
||||
## Database Location
|
||||
|
||||
Use a conservative default path separate from the existing HTTP cache:
|
||||
|
||||
```text
|
||||
~/.local/share/box-box/boxbox.db
|
||||
```
|
||||
|
||||
Tests must use temporary databases, not the user's real home directory.
|
||||
|
||||
## Initial Schema Scope
|
||||
|
||||
Create tables for:
|
||||
|
||||
- `schema_migrations`
|
||||
- `raw_payloads`
|
||||
- `ingestion_runs`
|
||||
- `meetings`
|
||||
- `sessions`
|
||||
- `drivers`
|
||||
- `session_drivers`
|
||||
- `session_results`
|
||||
- `starting_grid`
|
||||
|
||||
It is acceptable to include additional Race Hub v1 tables if doing so is
|
||||
straightforward, but do not overbuild high-volume telemetry yet.
|
||||
|
||||
## Raw Payload Strategy
|
||||
|
||||
`raw_payloads` should preserve source truth before normalization.
|
||||
|
||||
Recommended columns:
|
||||
|
||||
- source name, such as `openf1`
|
||||
- endpoint or topic
|
||||
- request key or URL
|
||||
- meeting key when known
|
||||
- session key when known
|
||||
- payload JSON text/blob
|
||||
- payload hash
|
||||
- fetched timestamp
|
||||
- provenance metadata JSON
|
||||
|
||||
Raw payload storage should be idempotent by source/request/hash or another
|
||||
clear uniqueness rule.
|
||||
|
||||
## Domain Table Strategy
|
||||
|
||||
Use stable OpenF1 identifiers where available:
|
||||
|
||||
- `meeting_key`
|
||||
- `session_key`
|
||||
- `driver_number`
|
||||
|
||||
Prefer explicit upserts over blind inserts. Completed historical data should be
|
||||
safe to re-run without duplicating rows.
|
||||
|
||||
## Tests
|
||||
|
||||
Minimum tests:
|
||||
|
||||
- opening a temp database applies migrations;
|
||||
- migrations can be run twice;
|
||||
- schema version is recorded;
|
||||
- raw payload insert/read works and preserves provenance;
|
||||
- duplicate raw payload writes do not create accidental duplicates;
|
||||
- meeting/session/driver/result upserts are idempotent;
|
||||
- basic Race Hub read helpers can retrieve inserted meeting/session/result data.
|
||||
|
||||
## Non-Goals
|
||||
|
||||
Do not include these in Phase 2:
|
||||
|
||||
- OpenF1 backfill orchestration.
|
||||
- CLI ingestion commands.
|
||||
- Web UI changes.
|
||||
- React setup.
|
||||
- Replacing existing `internal/api/cache.go`.
|
||||
- High-volume telemetry tables for car data/location.
|
||||
- Live SignalR persistence.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
Phase 2 is complete when:
|
||||
|
||||
- `internal/store` exists with tested migration and CRUD behavior.
|
||||
- The package can create a fresh SQLite domain database.
|
||||
- Running migrations repeatedly is safe.
|
||||
- Store tests pass without internet access.
|
||||
- `go test ./internal/store/...` passes.
|
||||
- `go test ./...` either passes or only fails because existing OpenF1
|
||||
integration tests cannot reach the network/API.
|
||||
Reference in New Issue
Block a user