# County Sprints frontend/leaderboard update Replace these files in the project: - `src/main.rs` - `src/model.rs` - `src/db.rs` - `src/leaderboard.rs` - `src/web.rs` - `migrations/0001_initial.sql` No change is required to the working `src/intervals.rs`. The existing `src/webhook.rs` can keep calling: ```rust crate::process_activity(state_clone, athlete_id, activity_id.clone()).await ``` `process_activity()` now loads the athlete's OAuth access token itself. The development sync uses the explicit API-key client, so the personal development key is not written to the database. ## Database The migration is intentionally a complete replacement because the database can be reset during development. The new schema adds: - `leaderboard_groups` - `leaderboard_group_members` - indexes for activity/crossing queries ## Leaderboard location matching Leaderboard rows are grouped by: - 10-minute time bucket - source county - destination county - spatial cluster with a 10 metre DBSCAN radius The crossing geometry is transformed to EPSG:3857 before the 10 metre clustering calculation so the distance is measured in metres rather than degrees. ## Frontend The frontend now provides: - Leaflet map for each leaderboard group - small map for every individual crossing - activity detail page at `/activity/{activity_id}` - activity map containing all crossings - browser-local timestamp formatting using `Intl.DateTimeFormat` - leaderboard group management at `/groups` - group selection on the main leaderboard The map uses Leaflet and OpenStreetMap tiles. Leaflet's current stable 1.x documentation describes the same map/tile-layer APIs used here. citeturn0search2turn0search9