Backend tasks A→B→C→F→E→D from the Track Map Implementation plan:
A. PCARS V1 position data: read world_position (3×i16) and current_lap_distance
from viewed participant entry, compute derived spline_position, add unit tests.
B. Dual position mode: auto-detect spline vs coordinate mode in track map analysis,
compute cumulative 2D distance as pseudo-spline for PCARS/future games.
C. Persistent TrackModel: Corner, Sector, TrackModel data structures with serde,
TrackModelStore with async CRUD at data/tracks/<game>/<track_name>.json.
F. Track model building algorithm: resample boundaries, compute center line,
track width, heading, curvature, auto-detect corners (κ > 0.005), 3 sectors,
coordinate normalization to [0,1]².
E. TrackMapping use case: new boundary recording workflow with step-by-step
guidance, session integration.
D. Track API endpoints: GET/DELETE /api/tracks/{game}/{track_name},
GET /api/tracks, GET .../corners, POST /api/tracks/build.
- Add session layer with UseCaseSession, SessionRun, SessionManager
for use-case driven telemetry analysis (shift points, track mapping)
- Add analysis module with shift point detection (gear RPM ranges,
upshift events, recommended shift RPM) and track map reconstruction
(spline-aligned interpolation for center line from boundary runs)
- Add 9 REST API endpoints for session CRUD, run management, and
analysis triggers under /api/sessions/*
- Add RecordingManager with always-on ring buffers (5 min, 18k frames)
replacing raw binary file dumps
- Wire SessionManager in main.rs with Arc<Mutex> shared state
- Add TelemetryFrame Serialize derives for JSON API output
- Fix stop_recording race: hold active lock across flush I/O
- Fix flush: separate ring buffer lock from JSON serialization
- Fix flush failure propagation: errors prevent Stopped status
- Add data_truncated flag on SessionRun for ring buffer wrap detection
- Deduplicate gear_display into shared free function
- Deduplicate session_display into closure
- Mutex poisoning recovery on all session API handlers
- Fix KSUDP clutch field reading fuel at offset 59 (KSUDP has no clutch input)
- Replace Notify with watch::channel for reliable shutdown (no missed wakeups)
- Deduplicate read_u16 from parser_pcars into shared binary_utils
- Remove dead Display impl for FeedSource
- Remove unused read_i8 helper from binary_utils
- Change Vec<Instant> to [Instant; 50] in FeedState (eliminate heap alloc)
- Cache rarely-changing strings by driver_id in Telemetry Tool parser