diff --git a/src/app/api/measurements/series/__tests__/route.test.ts b/src/app/api/measurements/series/__tests__/route.test.ts index 421908782..982c849de 100644 --- a/src/app/api/measurements/series/__tests__/route.test.ts +++ b/src/app/api/measurements/series/__tests__/route.test.ts @@ -133,6 +133,21 @@ describe("GET /api/measurements/series", () => { const res = await GET(req("kind=weight&days=3651")); expect(res.status).toBe(422); }); + + it.each(["restingHeartRate", "heartRateVariability", "vo2Max"])( + "accepts kind=%s (v1.5.5)", + async (kind) => { + // v1.5.5 — the iOS app surfaces these as series-capable; the + // previous enum rejected them with 422 even though the + // underlying MeasurementType already carried the values. + vi.mocked(getSession).mockResolvedValue(SESSION_OK as never); + vi.mocked(prisma.measurement.findMany).mockResolvedValue([] as never); + const res = await GET(req(`kind=${kind}&days=30`)); + expect(res.status).toBe(200); + const body = (await res.json()) as { data: { kind: string } }; + expect(body.data.kind).toBe(kind); + }, + ); }); describe("GET /api/measurements/series — 422 multi-issue (v1.4.43 W6)", () => { diff --git a/src/app/api/measurements/series/route.ts b/src/app/api/measurements/series/route.ts index 95e7f2fba..02536ac2b 100644 --- a/src/app/api/measurements/series/route.ts +++ b/src/app/api/measurements/series/route.ts @@ -34,6 +34,14 @@ const kindEnum = z.enum([ "totalBodyWater", "boneMass", "oxygenSaturation", + // v1.5.5 — the iOS app surfaces these as series-capable, but + // the route used to reject the trend/detail view request with a + // 422. The underlying MeasurementType enum already carries each + // value; this list extends the camelCase wire shape so the route + // matches the data it can serve. + "restingHeartRate", + "heartRateVariability", + "vo2Max", ]); const querySchema = z.object({ @@ -58,6 +66,9 @@ const KIND_TO_TYPE: Record, MeasurementType> = { totalBodyWater: "TOTAL_BODY_WATER", boneMass: "BONE_MASS", oxygenSaturation: "OXYGEN_SATURATION", + restingHeartRate: "RESTING_HEART_RATE", + heartRateVariability: "HEART_RATE_VARIABILITY", + vo2Max: "VO2_MAX", }; interface SeriesPoint {