Fix lap limits and five-minute stint statistics

This commit is contained in:
larssand
2026-09-02 19:36:25 +02:00
parent f561dd8feb
commit 483a9dbd5a
14 changed files with 356 additions and 110 deletions

View File

@@ -527,7 +527,7 @@ Owns:
- valid driver-lap aggregation across the training ledger, scoped by personal profile and class
- lifetime/session/day/best-lap/average/consistency calculations
- active Open/Free/regular Practice statistics scoped to one personal profile, one class, and the current session start
- stint splitting after passing gaps greater than `120000 ms`
- stint splitting at persisted decoder `stintBoundary` markers, with gaps greater than `120000 ms` as a legacy fallback
- best N consecutive laps and fixed-duration result calculation
- five-minute (`300000 ms`) results include the final lap when its start is before the cutoff and expose average pace for the counted laps
- daily summaries, controlled-lap streak, and recent personal-best gain
@@ -548,7 +548,7 @@ Rules:
- statistics combine linked driver records only when their `classId` matches the selected class
- 2WD and 4WD lap times, stints, best-three, five-minute results, and recommendations are never combined
- legacy driver records without `profileId` are grouped by normalized driver name until explicitly linked or separated in the Drivers UI
- invalid laps and lap times at or below `500 ms` are excluded
- invalid laps and lap times at or below `500 ms` are excluded; counted max-boundary laps remain in the ledger but are excluded from pace calculations
- anonymous Open Practice transponders are excluded until registered as drivers
- consistency is the P10-to-P90 spread of the latest 30 valid laps divided by their mean
- pace trend is `previous-window mean - current-window mean`, so a positive value means faster recent laps
@@ -561,8 +561,8 @@ Rules:
- ledger rows for a deleted session are retained and become historical records
- `sourceKey` deduplicates repeated saves of the same session passing
- a session change always starts a new stint
- a passing gap strictly greater than 2 minutes starts a new stint; exactly 2 minutes remains in the current stint
- a boundary lap whose `lapMs` contains the full break is excluded from pace metrics
- a passing with `stintBoundary: true` starts a new stint at that passing; a gap strictly greater than 2 minutes is the fallback for old data
- a boundary lap whose `lapMs` contains the full break is counted in race results but excluded from pace and duration metrics
- duration-result ranking compares lap count first and elapsed result time second
- a duration result is valid only after crossing the target and includes a final lap whose start is before the target cutoff
- a stint needs at least 3 valid pace laps for consistency/ranking and at least 10 for Race pace 10
@@ -1030,6 +1030,8 @@ Browser host 192.168.1.100 uses ws://192.168.1.100:9000 through :9003
Invariants:
- only `main` may change `entry.laps`, `entry.lastTimestamp`, or append to `result.passings`
- `minLapMs` is a hard validity threshold: a faster passing is stored as `below_min` and does not increment laps
- `maxLapMs` is a statistics threshold: a slower passing increments race laps, carries `above_max_stint`, and starts a new pace stint
- split timing is measured from the latest main timestamp, or mass-start timestamp before the first completed lap
- a duplicate pit-entry signal while `entry.pitActive` is true is ignored
- pit exit without a prior pit entry is ignored
@@ -1814,6 +1816,9 @@ Practical shape:
manualTimeAdjustmentMs?: number,
invalidPending?: boolean,
invalidReason?: string,
validationWarning?: "above_max_stint" | "",
excludedFromPace?: boolean,
stintBoundary?: boolean,
...runtime-derived leaderboard fields
}
},
@@ -2440,8 +2445,8 @@ npm test
- recommendation branch selection
- custom goal and automatic milestone progress
- selected-profile/class active-practice isolation, current-start filtering, and non-practice rejection
- two-minute stint boundaries, cross-session isolation, and boundary-lap exclusion
- best-three consecutive calculation and five-minute final-lap/average-pace behavior
- configured max-lap and two-minute fallback stint boundaries, cross-session/source isolation, and boundary-lap exclusion
- best-three consecutive calculation and five-minute final-lap/average-pace behavior, including a sanity bound that prevents impossible combined results
- trimmed 30-minute pace buckets and weekday aggregation
- class-isolated setup-marker before/after comparison
- short-stint suppression, 10-lap race pace, and mistake detection
@@ -2482,6 +2487,7 @@ npm test
- split and pit roles never incrementing normal laps
- pit-entry attribution surviving an endurance driver/transponder change
- one WebSocket per enabled decoder role
- minimum-lap shortcut rejection and maximum-lap counted stint boundaries
- decoder lifecycle events not rerendering and replacing the Settings form
`tests/audio_runtime.test.js` covers: