aboutsummaryrefslogtreecommitdiff
path: root/web
Commit message (Collapse)AuthorAge
* Link ride detail official climbs to climb detailMartin Kagamino Lehoux2026-09-27
|
* Chart power vs time for official climb attemptsMartin Kagamino Lehoux2026-09-25
| | | | Snapshot average power per attempt in a nullable average_power_w column (backfilled from stored rides), plot each powered attempt on the climb page as duration vs average watts with ride hover and click-through, and show avg power in the attempts table.
* Match official climbs against their recorded sampleMartin Kagamino Lehoux2026-09-24
| | | | | | | | | | | | | | | | | | | | | | An official climb matched on endpoint coordinates alone. On a loop ridden the other way the route meets the climb's top before its bottom, so pairing each start with the first end inside its lap window credited a 5.9 km passage as the 850 m Chemin de la Tour Pey Blanc, and a 49 km one on another ride. Climbs now keep the sample of the segment they were created from: the recorded length and elevation gain of the selected route points, captured by the ride detail and preview handlers and stored NOT NULL. Matching takes the whole route and drops any candidate outside ±50% of that sample on either axis, and attempts are refreshed by upsert and prune so re-analyzing a ride keeps the recorded-at stamp of the passages that survive. The backfill leaves the web package: backfill.Run recomputes ride values then official climb attempts as a single `go run . backfill` command (climbs-backfill is gone), rideanalysis owns the attempt snapshot, and the mountain-pass loading margin is shared. Applied to the stored rides it stamps 78 samples, drops the four bogus attempts and leaves ride 800 with its three Pont Rout passages.
* Persist official climb attempts with climbs pagesMartin Kagamino Lehoux2026-09-13
| | | | | | | | | | | | | Record one attempt row per (ride, climb, occurrence) when a ride detail loads, snapshotting distance, elevation gain, slope, cotacol and attempt timestamps; a climbs-backfill CLI command seeds all existing rides. New /climbs list page aggregates attempts (medians computed in Go, best time as min duration) with sortable columns, and /climbs/{id} shows the median scalar stats, a median normalized elevation profile (50 steps over each attempt's own length), the full-precision recorded route of the median-distance attempt on an OSM map, and every attempt with time at second precision.
* Split cli.go into per-domain command filesMartin Kagamino Lehoux2026-09-06
| | | | | Move each CLI command into its owning package (mountain_pass, ride, web) with dispatch and usage in main.go; remove the cli package.
* Preview: analyze a raw GPX or FIT file without persisting itMartin Kagamino Lehoux2026-09-06
|
* Display Cotacol in the ride detail summaryMartin Kagamino Lehoux2026-09-01
|
* feat: Analyse and fix elevation issuesMartin Kagamino Lehoux2026-09-01
|
* Rename rides.type to external_sport_type, infer bike type from Strava sport ↵Martin Kagamino Lehoux2026-08-28
| | | | type and display categories in UI
* Add touring ride type for cyclotourismeMartin Kagamino Lehoux2026-08-28
|
* Add Strava external link to ride detailMartin Kagamino Lehoux2026-08-27
|
* Swap ride read path from GPX to FIT for performanceMartin Kagamino Lehoux2026-08-27
| | | | | | Always use FIT for detail, official climb creation and backtest; keep GPX fallback for legacy rides pending backfill. FIT is 10-20x smaller and parses without XML.
* Add dual GPX/FIT exporter and backfill for ridesMartin Kagamino Lehoux2026-08-27
| | | | | | | Phase 1 writes both .gpx and .fit on Strava import, adds fit_path column, renames storage.gpx_dir to storage.rides_dir, and backfills missing FIT files from existing GPX without breaking CLI progress. FIT files are gitignored.
* Categorise OSM passes by highway and colour them on the ride detail mapMartin Kagamino Lehoux2026-08-27
| | | | | | | | Passes are extracted from OSM PBF nodes (mountain_pass=yes) and linked to containing ways; highway road values map to road, track to track, path/footway to path, plus hiking for rock/climbing. All passes are kept, coloured distinctly (road/track/path/hiking/unknown) for road-bike validation on ride 397. Single squashed migration adds category column, cheap to re-extract.
* Use radio inputs and collapsible curation on ride detailMartin Kagamino Lehoux2026-08-27
| | | | | | Replace dropdowns with vertical radio groups for bike and ride type. Make curation block collapsible (details/summary) collapsed by default and expanded when both categories are empty.
* fix: do not fit passes in mapMartin Kagamino Lehoux2026-08-27
|
* Resync Strava title from list payload via SaveMartin Kagamino Lehoux2026-08-27
| | | | | | | | Context / Problem: Strava titles can be corrected after import. The sync path only handled new rides; existing rides were marked skipped without checking the cheap list metadata, so corrections like ride #789 stayed stale. What: In syncRides reuse the existing Save write path for rare title resyncs (pay GPX parse cost) when existing.Name != list.Name; track progress.Updated and surface it in SSE/TS UI; add tests for resync without stream fetch. Remove the now-obsolete TODO. QA: go test/ vet, tsc, biome/stylelint pass.
* Tame the deadcode gate and remove dead web helpersMartin Kagamino Lehoux2026-08-27
| | | | | | | | | Run deadcode with -test and without the vendored node_modules package so the check reports only genuinely unreachable code instead of test-only helpers and vendored functions. Remove the three web helpers it still flagged (formatBikeType, formatRideType, dataQualityURL) that had no callers. Apply the go fix modernizations the check gate performs (range-over-int loops and embedded-field composite literals) that the gate had rewritten in the working tree.
* Extract climb detection into a dedicated climb packageMartin Kagamino Lehoux2026-08-27
| | | | | | | | | | | | | | | | | | | Move climb detection, slope, and Cotacol scoring out of ride into a new climb package that operates on a geometry-only Route (distances, elevations, coords). Ride embeds climb.Route and keeps its timing and telemetry columns. - climb.Detect returns []DetectedClimb (Climb + ride-absolute Start). - Climb owns its sliced geometry; indices are local, with Start reported at the detection boundary for absolute position. - Detected bounds use core.Interval; freeRegions claim suppression fixed. - ride no longer builds slices: ClimbFromDist/ClimbFromIndexes/climbFrom and ride.Climb/Interval/Range are removed; rideanalysis, mountain_pass MatchClimb, and web views are rewired to climb types. - New internal/routetest builds climb.Route from the ride DSL; ridetest reuses it and adds timestamps and telemetry. - Tests moved to climb (synthetic detection and difficulty) and kept in ride for GPX-example integration; ride.comparison detection coverage retained. - mountain_pass.nearestCrossing now reuses geo.Nearest.
* Lint & fixMartin Kagamino Lehoux2026-08-27
|
* Migrate cross-package ride test fixtures to the ridetest DSLMartin Kagamino Lehoux2026-08-25
| | | | | | | | | | | Replace raw FromColumns 4-array blocks in official_climb, mountain_pass and web test rides with ridetest.MustRide strings. Add a Heading option to ridetest for routes whose points are spaced differently per kilometer (e.g. the mountain_pass expanded-bounds route at 0.1 degrees/km). Lap, direction and cluster tests in official_climb keep FromColumns: the DSL generates monotonic northeast coords and cannot express per-point loops or reversals.
* analytics groupingMartin Kagamino Lehoux2026-08-25
|
* Remove per-index ride accessors now dead after the component migrationMartin Kagamino Lehoux2026-08-25
| | | | | | | | The DistanceM, ElevationM, Coord, Timestamp and optional metric index accessors (HeartRateBpm, CadenceRpm, PowerW) are no longer used by any production code now that algorithms and consumers read ride components. Tests that asserted metric parsing and coordinates now read the component slices (Distances, Coords, HeartRates, Cadences, Powers).
* Make mountain pass and web consumers take ride components instead of a whole ↵Martin Kagamino Lehoux2026-08-25
| | | | | | | | | | Ride rideBounds, nearestCrossing and DetectCrossings now accept the coordinate, distance and elevation component slices they read. LoadMountainPassesAroundRide takes the coords slice only. Web ride view builders and the official climb creation path iterate ride components (Coords, Distances, Elevations) rather than per-index accessors on Ride.
* Ride type multiselect filter with a checkbox group across library and analyticsMartin Kagamino Lehoux2026-08-24
|
* Add type filtering, drop hard-coded filters and route filter, tune backtestMartin Kagamino Lehoux2026-08-24
|
* Add data quality bulk categorisation pageMartin Kagamino Lehoux2026-08-24
|
* Add hardcore ride categorisation with bike and ride typesMartin Kagamino Lehoux2026-08-23
|
* Add on-demand pprof profiling grouped by routeMartin Kagamino Lehoux2026-08-23
| | | | Expose pprof at /debug/pprof via -pprof flag, tag each handler with runtime/pprof route label, add handleRoute helper to avoid repeating patterns, and document UI workflow in README.
* Apply go fix modernizations and refresh TODO listMartin Kagamino Lehoux2026-08-23
|
* Handle Strava rate limiting with abort, retry time and daily usage displayMartin Kagamino Lehoux2026-08-23
| | | | | | | | | | | | | Strava sync for 167 rides exceeds the 100/15-min read limit (2 calls per ride). Previously a 429 was treated as a skipped ride, so every remaining ride also failed silently. Now GetJSON returns a typed RateLimitError with RetryAfter computed from Retry-After/Date and X-RateLimit headers (15-min window resets at :00/:15/:30/:45, daily at midnight UTC) and tracks Read/Overall usage. syncRides aborts on 429 with partial progress instead of skipping, and handleSync emits an SSE error with retry time, daily usage vs limit and structured rateLimit snapshot; progress and complete events also carry the snapshot for the UI to display. Frontend shows Read daily/15-min usage in progress details and on completion.
* Add normalized difficulty versus moving duration to analyticsMartin Kagamino Lehoux2026-08-23
| | | | | | | Extend analytics with a second scatter plotting Cotacol per 100 km against moving hours, keep speed versus Cotacol as first chart, render both canvases from shared points, open ride detail in a new tab on dot click, and keep all website copy in English.
* Merge ride and rides packages into ride/store following mountain_pass structureMartin Kagamino Lehoux2026-08-23
| | | | | | | | Consolidate persistence (Save, List, Backfill) into ride/store.go alongside ride.go/climb.go/moving_time.go, rename rides.Ride to ride.StoredRide to avoid collision with parsed ride.Ride, update all web/cli consumers and RideView to use named Ride field, adjust templates and regenerate templ files, and remove rides directory.
* Add distance filter to analytics and go fix to the check gateMartin Kagamino Lehoux2026-08-21
|
* Componentize and isolate the ride range filterMartin Kagamino Lehoux2026-08-21
|
* Add global analytics scatter chartMartin Kagamino Lehoux2026-08-21
|
* Add global analytics page shell and split server.go by concernMartin Kagamino Lehoux2026-08-21
|
* fix: ride detail summary stats fit on one lineMartin Kagamino Lehoux2026-08-21
| | | | | | | The summary dl used a 3-column grid, so the 4th stat (elevation) wrapped to a second line. Switch to flex with space-around and a smaller gap so all four stats share one line while still wrapping gracefully on very narrow screens.
* Upgrade to Go 1.27 and apply go fix modernizationMartin Kagamino Lehoux2026-08-21
|
* Use OSM as the single source of mountain passesMartin Kagamino Lehoux2026-08-21
| | | | | | | Replace the centcols CSV download/enrichment pipeline with OSM PBF extraction as the primary (only) source: merge osmpass into mountain_pass, drop the centcols table and model fields, filter to named passes with elevation, and remove the centcols CLI flags.
* feat(web): add sortable average speed column to ride libraryMartin Kagamino Lehoux2026-08-21
|
* feat(ride): persist canonical moving time, preserve Strava referenceMartin Kagamino Lehoux2026-08-21
|
* feat(web): add ride library filtersMartin Kagamino Lehoux2026-08-18
|
* feat(web): mark climb boundaries on ride mapsMartin Kagamino Lehoux2026-08-17
|
* feat(web): display nearby passes on ride mapsMartin Kagamino Lehoux2026-08-17
|
* feat(web): add official climb chart gridsMartin Kagamino Lehoux2026-08-17
|
* refactor(web): tidy climb matching controlsMartin Kagamino Lehoux2026-08-17
|
* refactor(web): split ride detail rendering concernsMartin Kagamino Lehoux2026-08-17
|
* feat(web): refine ride profile climb labelsMartin Kagamino Lehoux2026-08-17
|
* chore(web): add Stylelint CSS checksMartin Kagamino Lehoux2026-08-16
|