Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.time2.bike/llms.txt

Use this file to discover all available pages before exploring further.

Every action on a timing session — start, finish, edit, status change, finalize — is an entry in an append-only event log. Materialized results are derived from the log by a reducer that runs identically on client and server.

Event kinds

GroupKinds
Session lifecyclesession_open, finalize, publish
Race clockrace_start, race_pause, race_resume, race_stop
Standard finishesfinish, manual_time, note, status_change, delete
Splits & lapslap, split, prime
Dual slalom laneslane_start, lane_finish, lane_clear, lane_assign, lane_unassign
External hardwareexternal_rfid
Bracketsbracket_init, bracket_rebuild, bracket_set_match_winner, bracket_reset_match, bracket_resolve, bracket_match_forfeit, bracket_swap_match_sides, bracket_set_match_participant, bracket_reseed, bracket_set_leg_time
Each event has a clientEventId (UUID), payload, localTimestamp, clockOffset, deviceId, userId, roleAtRecord, and a server-assigned seq.

Why append-only

  • Audit: nothing is silently lost. Deleting a finish writes a delete event referencing the original; the original stays.
  • Offline merge: two devices recording in parallel can post their events independently and the server can re-project the truth deterministically.
  • Time travel: you can “replay to time T” for debugging without rolling back any data.

Materialized state

The reducer computes per-participant timingResult rows: status, startAt, finishAt, elapsedMs, lane, run, and any flagged reasons (duplicate_finish, orphan_finish). The client computes its own projection from local + server events so the UI is correct even offline.

Conflict policy

  • Finish before start arrives: accept the finish; reducer computes elapsedMs once the matching start lands. The row shows “awaiting start”.
  • Duplicate finish from two devices: keep both events; flag the result with both clientEventIds as candidates. A human resolves it in the review UI.
  • Self-clear in dual slalom: a lane_clear event supersedes its referenced lane_finish; the lane goes back to “live”.
  • Storage precision: always 3 decimal places (ms); display rounds.