Commit Graph

3 Commits

Author SHA1 Message Date
Developer b61d1ebeec fix(website): monotonic timestamp ride IDs, zero-budget cursor guard, and modal input preservation
- 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
2026-10-14 15:07:00 -04:00
Developer a709b058b3 fix(website): replay edge-case resilience and concurrent ride submission guards
- 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.
2026-10-14 14:45:41 -04:00
Developer dd35b216d1 fix(website): persisted-only ride creation and reconciled replay timing (PR #38 hardening)
Phase 1 — group ride creation (no phantom rides):
- Check authentication and Firestore availability BEFORE touching UI state; an unauthenticated
  user (or unavailable Firestore) now gets an actionable error and no phantom ride, instead of a
  local entry that was never saved.
- Insert the ride into UI state ONLY after batch.commit() confirms the write; on commit failure
  nothing is inserted and an error is shown.
- Prevent duplicate submissions: the create modal disables its submit button while in flight, and
  the hub guards with a ref.
- The join code remains the real Firestore document id (no fabricated ids).
- Extract commitGroupRide (pure, dependency-injected) so every path is unit-testable.

Phase 2 — replay playback timing:
- The elapsed clock and rider marker both derive from the same cursor, so they cannot drift.
- Manual seeks (scrub, restart, corner jump, arrow keys) go through seekTo(), which reconciles
  playback timing (clears carry/last-frame) so no stale budget is applied after a seek.
- Make gap compression explicit: a caption labels the timeline as recorded elapsed time and warns
  that dead time in multi-segment recordings is skipped during playback.

Tests: commitGroupRide (unauthenticated / unavailable / commit-ok / commit-failed); group-rides
hub now uses an authenticated mock with deterministic Firebase — authenticated create persists,
unauthenticated create is blocked with no phantom, a failed commit leaves no phantom, and the
create modal blocks duplicate submits.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-14 13:12:49 -04:00