new raceday and backup

This commit is contained in:
larssand
2026-09-01 07:07:23 +02:00
parent c2bfa97d30
commit f561dd8feb
21 changed files with 1042 additions and 60 deletions

View File

@@ -33,11 +33,13 @@ The system has four main runtime parts:
- AMMC process control
- PDF export endpoint
- app version endpoint
- bounded SQLite backup API and local-only restore CLI
3. Local persistence
- SQLite via `better-sqlite3`
- main file: `data/rc_timing.sqlite`
- AMMC config JSON: `data/ammc_config.json`
- rotating SQLite snapshots: `data/backups/*.sqlite` plus metadata sidecars
4. Decoder / AMMC runtime
- AMMC process started by backend or manually elsewhere
@@ -52,8 +54,10 @@ flowchart LR
Browser -->|GET/POST /api/ammc/*| Server
Browser -->|POST /api/passings| Server
Browser -->|GET /api/app-version| Server
Browser -->|GET/POST /api/backups| Server
Server -->|persist app state| SQLite[(SQLite)]
Server -->|persist passings| SQLite
Server -->|online backup API| Backups[(data/backups)]
Server -->|read/write config| AMMCConfig[(ammc_config.json)]
Server -->|spawn/stop| AMMC[AMMC process]
Browser -->|WebSocket| DecoderWS[AMMC websocket / decoder feed]
@@ -75,6 +79,7 @@ Backend owns:
- AMMC process management
- PDF generation endpoint
- file-watch based app version bumping
- SQLite online backup creation and bounded retention through `server/backup_service.js`
## 2. Repository JavaScript Inventory
@@ -105,6 +110,7 @@ Scripts:
- `npm restart`
- `npm run verify`
- `npm test`
- `npm run backup:restore -- <backup-file.sqlite> --confirm`
- `npm run setup:windows`
### `server.js`
@@ -119,6 +125,7 @@ Uses:
- `express`
- `better-sqlite3`
- `server/public_training_profile.js`
- `server/backup_service.js`
Owns:
- HTTP server
@@ -136,6 +143,7 @@ Delegates public training token validation and response shaping to `server/publi
Main API groups:
- `/api/health`
- `/api/app-version`
- `/api/backups` (`GET` list, `POST` create only)
- `/api/state`
- `/api/passings`
- `/api/ammc/config`
@@ -159,6 +167,23 @@ Runtime environment variables:
- `PUBLIC_OVERLAY_TOKEN`: optional shared token for public overlay routes
- `RC_ALLOWED_ORIGINS`: optional comma-separated cross-origin UI origins; same-origin is always allowed
### `server/backup_service.js`
Role:
- server-side SQLite snapshot service
Owns:
- `data/backups` creation
- online `better-sqlite3.backup(...)` snapshots that remain consistent while WAL mode is active
- sanitized backup names and JSON metadata sidecars
- newest-first backup listing
- bounded retention of the latest 30 snapshots
Security boundary:
- the HTTP API can create and list metadata but cannot download or restore a database
- destructive restore is available only through `scripts/restore-backup.js` on the backend host
- the restore CLI requires the managed server to be stopped and an explicit `--confirm` flag
- before replacement, restore validates SQLite/application state and creates a `pre_restore` safety snapshot
### `server/public_training_profile.js`
Role:
- pure CommonJS backend helper for tokenized personal training profiles
@@ -244,6 +269,38 @@ Owns:
This is the only file that should know about almost every other frontend module.
### `src/race_day_logic.js`
Role:
- pure Race Day queue and preflight calculations
Owns:
- current/next/after-next ordering within one event
- blocking checks for Main decoder, participants, transponders, duplicates, lap window, and position grid
- warnings for backend backup availability, optional decoder roles, and audio
### `src/race_day_view.js`
Role:
- focused Race Day operator UI
Dependencies injected by `app.js`:
- existing timing/session selectors and formatters
- `buildRaceDayQueue` and `buildRaceDayPreflight`
- centralized start, finish, pause, and resume controllers
- navigation shortcuts to Timing, Judging, and Overlay
The view does not own timing state and does not implement a second race clock.
### `src/session_control.js`
Role:
- small pure mutation helpers for begin, finish, pause, and resume
The same helpers are used by the centralized operational start path so Race Day and Timing cannot drift into separate lifecycle behavior.
Safety backup contract:
- session start synchronizes state and creates a `pre_start` snapshot before the existing audio/start sequence
- full data import and every clear-data scope synchronize state and create a `pre_change` snapshot before mutation
- if backup is unavailable, the operator must explicitly confirm before the existing operation continues
### `src/runtime_services.js`
Type:
- frontend runtime helpers