| Commit message (Collapse) | Author | Age |
| | |
|
| | |
|
| |
|
|
| |
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.
|
| | |
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
| |
Official climb matching now returns all non-overlapping occurrences
per ride instead of only the globally nearest pair. Each lap is
detected by clustering contiguous points within the endpoint radius
and pairing each start cluster with the first end cluster inside its
window, preserving direction. The ride analysis aggregates all matches
and sorts claimed ranges before excluding them from auto-detection.
Fixes the case where a looping ride only showed one instance of a
saved climb while the user expected one per repetition.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
A detected climb must now average at least 3.5% slope with re-segmentation:
gentle drags are split into their qualifying steeper parts instead of being
reported wholesale or dropped. Qualifying climbs keep their previous
boundaries exactly; only regions whose classic best climb averages below the
threshold get re-segmented (full-scan for the best qualifying sub-segment,
found=false when none exists).
QA: A/B across data/rides (362 rides) went from 137 to 133 climbs, 23 rides
changed; the 7 fully-dropped rides were audited to contain zero qualifying
sub-segments. Example-ride tests updated for the new behavior; the resolved
"minimum slope" TODO was removed.
|
| | |
|
| | |
|
| | |
|
| | |
|
| |
|
|
|
|
|
| |
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.
|
| | |
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Detected climbs no longer absorb an official climb's range: official climbs
matched to the route by coordinates claim their stored start/end range, and
climb detection now runs only in the free regions around them. On ride 263 a
single absorbed Cat 2 ascent is split so creating a first-half official climb
lets the second half be detected on its own.
- ride: add Range, freeRegions, and DetectClimbs(claimed); exclude claimed
ranges so a climb never overlaps one
- official_climb: MatchClimb now bounds-matches purely by coordinates without
needing a detected climb; extract geo.Nearest shared helper
- rideanalysis: Analyze builds claimed climbs from matched official climbs and
detects only in free regions; render official vs unmatched climbs separately
|
| | |
|
| | |
|
| | |
|
| |
|
|
|
|
|
| |
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.
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| |
|
|
|
|
|
|
| |
Add ride.MovingTime, a speed-threshold algorithm over track timestamps.
Add a -backtest CLI command comparing computed values against Strava's
reference across all stored rides, with a percentile distribution summary.
Baseline: mean err 3.9%, p50 1.6, p75 4.6, p90 8.4, p95 12.1, p99 44.9.
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|