Andra guidade träningsövningen i Open Practice: konfigurera en stegserie (antal varv + lugnt/kontrollerat/snabbt per steg), förvalt till klassiska pyramiden. Training-sidan visar aktuellt steg, kvarvarande varv och en progress-pill per steg. När sekvensen är klar jämförs de två kontrollerade stegens snitt neutralt (t.ex. "+0.90s"), utan att kalla en försämring för trötthet. syncTrainingLedger sprider nu resten av det normaliserade training-objektet istället för att lista fält manuellt, så samma klass av bugg som drabbade Jämna varv inte kan upprepas för framtida fält. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
127 lines
12 KiB
Markdown
127 lines
12 KiB
Markdown
# RC RaceCore Roadmap
|
||
|
||
Track work here with checkboxes. Check off a task only after implementation and verification. Record user-visible changes under `Unreleased` in [CHANGELOG.md](CHANGELOG.md). Priorities below are a working order, not release-date commitments.
|
||
|
||
## Existing foundation
|
||
|
||
- [x] Race Day, preflight checks and heat queue.
|
||
- [x] Automatic SQLite backups and local restore command.
|
||
- [x] Isolated session replay.
|
||
- [x] Training statistics, personal mobile profiles and car-change markers.
|
||
- [x] Interactive list sorting and OBS display modes.
|
||
- [x] Visible application version and changelog.
|
||
|
||
Verified 2026-09-08: 122 logic/API tests and the register/offline browser smoke suite passed on Linux with Chrome. Checked items below describe that coverage; other platforms and workflows remain open.
|
||
|
||
## 1. Reliability and browser regression tests
|
||
|
||
Acceptance: real create/edit/save flows persist after reload; background updates do not discard edits. Tests use isolated data, never the installation's database.
|
||
|
||
- [x] Add a repeatable browser smoke-test command with temporary database/profile.
|
||
- [x] Cover create/edit/save for classes, drivers and cars, including reload verification.
|
||
- [x] Verify register form drafts remain intact during background version polling.
|
||
- [x] Cover sponsor-event creation/editing and endurance race wizard/name edits with reload verification.
|
||
- [x] Cover team creation, membership changes, editing and deletion.
|
||
- [x] Cover Open Practice to team-race conversion, duration/follow-up edits and persisted lap limits.
|
||
- [x] Cover Race Day start/pause/resume/finish controls and switching to the next queued heat, with a simulated decoder socket (no real AMMC hardware).
|
||
- [ ] Cover session-type-specific start sequences (heat/qualification/race/team_race countdown and audio) and other transitions beyond Open Practice.
|
||
- [x] Verify leaderboard/TV/team sorting heading alignment at 390/900/1600 px and preserved race positions.
|
||
- [x] Verify OBS views have no interactive sorting controls.
|
||
- [x] Cover actual popup launching and compact OBS layout automatically.
|
||
- [ ] Add Windows and Linux CI runs for supported runtimes.
|
||
|
||
Verified 2026-09-09: the OBS overlay popup opens via a real click on the admin "Open OBS overlay" button (`window.open`, not a direct URL navigation), renders the compact race-info/standings split layout, and its clock advances live and freezes on pause without a manual reload - polling independently of the admin page (`tests/browser_obs_popup.js`). Found and fixed a real bug in the process: `window.open(..., "noopener,noreferrer,...")` always returns `null` in modern browsers even when the window opens successfully (WHATWG spec), which made the blocked-popup check in `openPrintWindow()` and `openOverlayWindow()` always fire - print/export (start lists, results, heat sheets, team reports) showed a false "popup blocked" error and never wrote any content, and the overlay popup's `.focus()` call was unreachable. Both now open without those flags (same-origin, first-party content, so no security loss).
|
||
|
||
Verified 2026-09-08: Race Day start/pause/resume/finish and next-heat selection pass end to end (`tests/browser_race_day.js`) against a simulated decoder socket, with native-dialog auto-accept added to the browser harness so an unexpected `alert()`/`confirm()` fails the test instead of hanging it. Found and fixed two real bugs in the process: Open Practice sessions on a track-mode (sponsor) event showed a ready/green preflight but were silently blocked from starting by a stricter assignment check; and the Race Day view never refreshed when the decoder connected, disconnected, or errored, so its Start button and preflight checklist could stay stale after a page load.
|
||
|
||
## 2. Connection and save status
|
||
|
||
Acceptance: users can distinguish server contact, pending edits, an active save and a failed save; a health check never falsely confirms a failed write.
|
||
|
||
- [x] Show pending, saving, saved and failed state in the main interface.
|
||
- [x] Show last successful data load/save times.
|
||
- [x] Warn when the server connection is lost or its status becomes stale.
|
||
- [x] Offer manual retry for unsaved changes without discarding local edits.
|
||
- [x] Verify save failure/reconnection in a real browser.
|
||
- [x] Extend stale-data feedback to the personal mobile profile: last applied retrieval, 30-second stale warning, timeout and Retry without discarding loaded data.
|
||
- [ ] Review concurrent writes, reconnect recovery and multiple controllers editing the same race.
|
||
|
||
### Implemented: decoder/socket diagnostics
|
||
|
||
Acceptance: each configured channel distinguishes an open socket from actual received data and successfully parsed passing messages. Inspecting diagnostics must not interrupt timing or rerender an active settings form.
|
||
|
||
- [x] Show Main, Split, Pit entry and Pit exit separately, with the configured WebSocket URL.
|
||
- [x] Show socket state, last connection, last received message and elapsed time since reception.
|
||
- [x] Count received frames, recognized passing messages (not accepted laps), ignored messages and parse errors per channel.
|
||
- [x] Add a bounded live message sample/log with pause, clear and copy controls.
|
||
- [x] Show why an incoming passing was ignored or rejected without changing lap validation.
|
||
- [x] Add simulated-socket tests for receiving, parsing, disconnecting and open status.
|
||
- [x] Verify automatic reconnect against a simulated decoder/network interruption (raw socket drop, not a clean close), checking for duplicate connections and correct reconnect-timer behavior.
|
||
- [x] Document IP/port/channel setup and the difference between decoder connection and incoming data.
|
||
|
||
Verified 2026-09-08: 128 logic/API tests and browser smoke tests passed, including mobile profile retention during network loss and recovery via Retry.
|
||
|
||
Verified 2026-09-09: a browser test (`tests/browser_decoder_reconnect.js`) drops a real TCP connection to a simulated decoder socket and confirms the frontend detects it, waits for the ~2s reconnect timer in `src/decoder_runtime.js`, and settles on exactly one live connection afterward - never two at once. Disabling auto-reconnect through the real Settings form (not a raw state patch, which never reaches an already-loaded page) correctly stops further retries after a drop. Reconnecting against physically real AMMC hardware remains a separate hardware-in-the-loop check this suite cannot cover.
|
||
|
||
## 3. Clearer practice follow-up
|
||
|
||
Acceptance: a driver receives a short, encouraging summary based on their own class-specific data, with one useful next goal.
|
||
|
||
- [ ] Add an end-of-practice summary: pace, consistency, progress and achieved goals.
|
||
- [ ] Suggest one next training goal using existing calculations.
|
||
- [ ] Keep summaries separate by class and explain insufficient sample sizes.
|
||
- [ ] Include the summary in the personal mobile profile.
|
||
- [ ] Add coach/parent reward follow-up without turning practice into a public ranking.
|
||
|
||
### Guided practice exercises
|
||
|
||
Acceptance: two structured, configurable exercises run inside an already-active Open Practice session, per driver and class, without stopping other drivers or creating a new session. Named for what they help a driver do, not for who supposedly likes them - "Jämna varv" ("Even laps", formerly "Konsistens-jakten") and "Stegträning" ("Step training", formerly "Pyramiden") - and focused on succeeding rather than performing perfectly.
|
||
|
||
**Jämna varv (even laps):** implemented 2026-09-09.
|
||
- [x] Driver configures target lap time, tolerance and lap count; suggested default 5 laps / ±0.5s - 15 laps / 0.2s is frustrating for a beginner, but stays adjustable for anyone who wants it stricter.
|
||
- [x] Offer a suggested target derived from the driver's own personal best (best lap × 1.05) when enough data exists, shown as the form's placeholder and a hint, never forced.
|
||
- [x] Tolerance is ± around the target lap time: every lap in the streak must land within `target ± tolerance`, not a spread between the streak's fastest and slowest lap. Decided 2026-09-09 - simpler to understand and to show live ("hit the target"), and matches how a beginner already thinks about it.
|
||
- [x] Show the current streak and today's best streak live, e.g. "4/5 even laps - Best streak today: 7".
|
||
- [x] A lap outside tolerance (or one excluded from pace, e.g. a pit stop) ends the current streak but never erases prior progress; messaged as "New streak - try to beat your best", not as a failure.
|
||
|
||
Verified 2026-09-09: `buildEvenLapsProgress` in `src/training_logic.js` (unit-tested for streak tracking, tolerance, and exclusion handling) plus a manual browser check of the live card, config form and streak reset messaging inside an active Open Practice session. Found and fixed two real bugs in the process: `syncTrainingLedger` rebuilt `state.training` on every save without carrying the new `evenLaps` field through, silently discarding every saved configuration; and the Training page crashed for any driver with fewer than 3 laps in every stint (a very common state - e.g. anyone in their first couple of laps), because a dedup filter read `.id` on a `null` "best stint" entry.
|
||
|
||
**Stegträning (step training):** implemented 2026-09-09.
|
||
- [x] Configurable steps: lap count plus an instruction per step (calm / controlled / fast). The form offers the classic pyramid (calm/controlled/fast/controlled/calm, 5 laps each) as an editable starting point; a step's lap count can be set to 0 to skip it, so shorter or longer sequences are both possible.
|
||
- [x] Show the current step and remaining laps in that step, plus a pill per step showing progress and highlighting the current one.
|
||
- [x] Treat calm/controlled/fast as perceived effort shown to the driver, not an exact lap-time target the system enforces - there is no reliable way to measure how hard a driver is pushing.
|
||
- [x] Compare the two controlled-pace steps afterward without automatically labeling a slower second step as fatigue: shown as a plain pace difference ("Controlled step 1: 0:21.100 · Controlled step 2: 0:22.000 (+0.90s)"), generalized to the first and last "controlled" step in the driver's own configuration rather than assuming exactly the pyramid's two.
|
||
|
||
Verified 2026-09-09: `buildStepTrainingProgress` in `src/training_logic.js` (unit-tested for step advancement, pace-exclusion handling, and the controlled-step comparison) plus a manual browser check covering the default pyramid, mid-exercise progress, reconfiguring to a shorter sequence, and the completed-sequence comparison text.
|
||
|
||
## 4. Results archive
|
||
|
||
- [ ] Search completed sessions by date, class and driver without Race Setup.
|
||
- [ ] Show standings, lap history and penalties together.
|
||
- [ ] Reuse existing PDF/export functions from the archive.
|
||
- [ ] Define what remains available after deleting a race.
|
||
|
||
## 5. More natural race speech
|
||
|
||
- [ ] Optional backend-generated neural speech.
|
||
- [ ] Cache announcements and driver names before race day.
|
||
- [ ] Keep credentials on the backend, outside exports and public responses.
|
||
- [ ] Invalidate cached speech when language, voice or pronunciation changes.
|
||
- [ ] Provide provider status and a pre-generate action.
|
||
- [ ] Verify offline fallback and that playback never delays timing.
|
||
|
||
## 6. Permissions and mobile Race Control
|
||
|
||
- [ ] Define Admin, Race Director, Speaker and Read-only capabilities.
|
||
- [ ] Enforce permissions on server endpoints, not only in the UI.
|
||
- [ ] Keep public overlays and training links restricted.
|
||
- [ ] Build compact mobile controls for start/stop, track call, flags and next heat.
|
||
- [ ] Test concurrent control and accidental repeated commands.
|
||
|
||
## Documentation maintenance
|
||
|
||
- [ ] Update the architecture's module/dependency inventory as modules change.
|
||
- [ ] Complete state/settings/SQLite contracts and critical form-to-controller mappings.
|
||
- [x] Consolidate older future-work notes so this file remains the primary roadmap.
|
||
|
||
Consolidated 2026-09-09: the raw "Träningsstat" brainstorm notes (Pyramiden, Konsistens-jakten) were folded into section 3's "Guided practice exercises" as a proper specification and removed from here. |