Bug: Exercise weight-progression/volume/1RM stats ignore weight units (kg vs lbs)

Author: evan188199-techCreated Jul 7, 2026Updated Jul 7, 2026

Bug

The weight-progression chart (/api/exercises/[id]/statistics/weight-progression) plots raw weight values without normalizing units, so a user who switches between kg and lb (or mixes them) gets a misleading trend line. A set logged at 50 lb and a set logged at 50 kg both appear as "50", and a 110 lb set sits far below a 50 kg set on the same axis.

Root cause

In app/api/exercises/[exerciseId]/statistics/weight-progression/route.ts:

typescript
const weightIndex = set.types.indexOf("WEIGHT");
if (weightIndex !== -1 && set.valuesInt && set.valuesInt[weightIndex]) {
  const weight = set.valuesInt[weightIndex];   // raw value, unit ignored
  ...
}

The set stores its unit at units[weightIndex] ("kg" or "lbs"), but the route never reads it. So:

  • 50 lb and 50 kg are plotted identically (off by ~2.2×)
  • switching units mid-history makes the line jump for no real reason
  • the per-session "max weight" can be reported in whichever unit the heaviest set happened to use

The sibling routes statistics/volume and statistics/one-rep-max have the same gap. The app already has convertWeight() / WEIGHT_CONVERSION in src/shared/lib/weight-conversion.ts, so a fix can normalize to a single unit (kg) before aggregating.

Fix

Normalize each weight to kg before comparing/aggregating:

typescript
import { convertWeight } from "@/shared/lib/weight-conversion";

const weightIndex = set.types.indexOf("WEIGHT");
if (weightIndex !== -1 && set.valuesInt && set.valuesInt[weightIndex]) {
  const raw = set.valuesInt[weightIndex];
  const unit = set.units?.[weightIndex] === "lbs" ? "lbs" : "kg";
  const weight = convertWeight(raw, unit, "kg");
  ...
}

I have a PR ready (covering weight-progression first; volume and one-rep-max share the same root cause).