- Guard advancePlaybackIndex against spuriously advancing when budgetMs <= 0 on duplicate timestamps
- Use monotonic millisecond timestamp in commitGroupRide to eliminate timestamp corruption and collision hazards
- Preserve CreateGroupRideModal form inputs on failed commit so users do not lose typed data
- Add regression tests in vitest suites for zero-budget duplicate timestamps, timestamp fidelity, and input preservation
- Add replay regression test suite covering irregular/jittered timestamps, identical/zero dt, inverted timestamps, large gaps, pause/resume timing reconciliation, manual seek, speed changes, and large datasets (144k points).
- Harden advancePlaybackIndex against non-finite/NaN budget and timestamp delta anomalies.
- Reset lastTimeRef and cap frameDelta in WebTelemetryReplayModal to eliminate sudden jumps on speed switching or background tab resumes.
- Guard group-ride creation with in-flight isSubmitting state and disabled submit button in CreateGroupRideModal; guarantee unique collision-free ride IDs across concurrent submissions.
- Remove obsolete Vercel reference in website/.env.example in favor of Vultr VPS and Caddy; add npm test script.
The replay loop advanced the cursor by one sample every 50 ms / speed, assuming a uniform
20 Hz stream. Recorded telemetry is not always uniform (segment breaks and GPS-loss gaps up
to 5 s), so the rider marker drifted out of sync with the elapsed-time readout — which is
derived from real timestamps — and "1x" did not match real time across gaps.
Make playback timestamp-driven:
- Add advancePlaybackIndex(points, fromIndex, budgetMs): a pure helper that consumes a
budget of virtual recorded time, advancing by the real delta between samples so the
marker tracks the elapsed-time clock. Disconnected transitions (per
areTelemetryPointsConnected) are compressed to a single 50 ms step so playback never
stalls across multi-second dead time. No coordinates are altered.
- Drive the rAF loop with frameDelta * playbackSpeed plus carry-over, resuming from an
index ref so manual scrubs are honored.
Verified sound without changes: SHA-256-checked R2/inline telemetry load, CSV/GPX parse and
export integrity, loading/error/empty overlays, and tile-provider fallback.
Tests: advancePlaybackIndex covers uniform cadence, carry-over, gap compression, end-clamp,
and empty input. Existing replay/export/corner tests remain green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>