feat(practice): flag suspiciously short laps and remove any lap in one click

Practice laps under 85% of the driver's own median (a likely shortcut)
are flagged: counted, but never a best lap, record or training stat
until approved. Timing and Race Day get a one-click Approve/Remove
panel, overlays show a warning mark, and any lap can be removed or
restored from Timing and Judging with undo.

Also sends judge corrections straight to the server so its hot-results
protection can no longer hold back a correction made right after a
passing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
larssand
2026-10-07 19:53:23 +02:00
parent 3cc4fa0845
commit 8601954ea2
24 changed files with 556 additions and 60 deletions

View File

@@ -12,6 +12,7 @@ import { runTtsSettingsSmoke } from "./browser_tts_settings.js";
import { runTrackLayoutsSmoke } from "./browser_track_layouts.js";
import { runPrologueSmoke } from "./browser_prologue.js";
import { runPracticeResetSmoke } from "./browser_practice_reset.js";
import { runSuspectLapsSmoke } from "./browser_suspect_laps.js";
import { runObsPopupSmoke } from "./browser_obs_popup.js";
import { runDecoderReconnectSmoke } from "./browser_decoder_reconnect.js";
import assert from "node:assert/strict";
@@ -154,6 +155,7 @@ try {
await runTrackLayoutsSmoke({ evaluate, navigate, savedState, waitFor, base, dialogs });
await runPrologueSmoke({ evaluate, navigate, savedState, waitFor, base, dialogs });
await runPracticeResetSmoke({ evaluate, navigate, savedState, waitFor, base, dialogs });
await runSuspectLapsSmoke({ evaluate, navigate, savedState, waitFor, base, dialogs });
await runRaceDaySmoke({ evaluate, navigate, fill, savedState, waitFor, pause, base, dialogs });
await runRaceDayStartSequencesSmoke({ evaluate, navigate, waitFor, pause, base, dialogs });
await runObsPopupSmoke({ evaluate, navigate, fill, savedState, waitFor, pause, base, debugPort, dialogs, realClick });