The Health page is your at-a-glance dashboard: which bikes
need attention, which components are overdue, and how close
everything else is to the next service. It's the single place to
plan a workshop weekend.
Open it from Health in the sidebar, or call up /health
directly.
What the page shows
Three layers, top to bottom:
- Stats bar — live counters across all your bikes:
lifespan alerts, overdue services, due now, upcoming
(≥80% of an interval). Filter by bike with the dropdown to
narrow it down. - Bike health scores — a card per current bike showing a
single 0–100 score and a colour: green = healthy, yellow =
approaching maintenance, red = overdue. Each card also shows
how many components are tracked vs how many are installed —
useful for spotting bikes where you've forgotten to add
components. - Service overview — a grouped list of every interval that's
due, overdue, or upcoming, with a one-click Record Service
button on each row.
How the score is calculated
The score is a weighted average of the health of each tracked
component on the bike. Two ingredients:
1. Per-component health (0–100)
We take the worst progress of each component across two checks:
- Lifespan — how close it is to its expected lifespan (e.g.
3,200 km on a 5,000 km chain → 64% progress). - Service intervals — for each interval defined on the
component, how close it is to the next service.
The worst of those becomes the component's worst progress. We
then map that progress to a 0–100 health score:
| Worst progress | Component health |
|---|---|
| < 80% | 100 (fully healthy) |
| 80–99% | 100 → 30 (linear) |
| 100–149% | 30 → 0 (linear, overdue) |
| ≥ 150% | 0 |
Two intentional design choices: the score doesn't drop until 80%
(everything below that is "fine"), and it bottoms out at 0 even
if you ride 5x past the limit (no negative health to confuse the
weighting).
2. Priority weighting
Not every component matters equally. A worn chain is a bigger
problem than worn bar tape. Each component type has a built-in
maintenance priority:
| Priority | Weight | Examples |
|---|---|---|
| critical | 4 | Chain, brake pads, brake rotors |
| high | 3 | Cassette, tires, cables |
| medium | 2 | Bottom bracket, bar tape, hub bearings |
| low | 1 | Cosmetic / low-wear parts |
The bike's overall score is the priority-weighted average of the
per-component scores: Σ(componentHealth × weight) / Σ(weight).
That way an overdue chain pulls the bike's score down much harder
than overdue bar tape.
What "tracked components" means
A component counts toward the score only if it has at least one
of the following:
- An expected lifespan (so we can compute lifespan progress), or
- A service interval (so we can compute service progress).
Components without either are listed in totalInstalled but
don't contribute to the score. If your tracked-vs-installed ratio
is low, the score is based on a small sample and may swing more
than you'd expect — adding intervals for a few more components
makes the score more meaningful.
If a bike has zero tracked components, it shows no score at all
rather than a misleading 100.
When the score updates
Whenever the underlying data changes:
- A new ride syncs from Strava (the cron or webhook).
- You record a service — the relevant interval and possibly
lifespan reset, the score recovers. - You add or transfer a component.
- You edit a component's lifespan, service interval, or status.
The Health page re-fetches when you load it, so refreshing always
gives you the current truth.
What to do with it
A healthy ritual: open Health every couple of weeks, sort by
overdue, work through the red rows, and record each service from
the same page. Once everything is green, you're ready to ride.
For deeper context on individual alerts and their thresholds, see
Maintenance alerts and
Service intervals.
