feat(measurements): raise the series days cap to ten years

The 365-day cap on /api/measurements/series rejected the iOS app's
"Alle"-range request (days = 3650) with a 422, painting an error
banner on every metric tile. Ten years matches the recurrence
engine's hard cap and the medication course-window upper bound.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Marc-André BombeckandClaude Opus 4.7 committed 2026-05-28 22:32:18 +02:00
1 parent befac0ec65
commit 26f13c5064
2 files changed
+24 -1

No files matched your search

@@ -116,6 +116,23 @@ describe("GET /api/measurements/series", () => {
};
expect(body.data.points[0].secondary).toBeNull();
});
it("accepts the ten-year window (days=3650 — iOS 'Alle'-range)", async () => {
// v1.5.5 — the previous 365-day cap rejected the iOS app's
// "Alle"-range request with a 422, painting an error banner on
// every metric tile. Ten years matches the recurrence engine's
// hard cap and the medication course-window upper bound.
vi.mocked(getSession).mockResolvedValue(SESSION_OK as never);
vi.mocked(prisma.measurement.findMany).mockResolvedValue([] as never);
const res = await GET(req("kind=weight&days=3650"));
expect(res.status).toBe(200);
});
it("rejects a days value above the ten-year cap", async () => {
vi.mocked(getSession).mockResolvedValue(SESSION_OK as never);
const res = await GET(req("kind=weight&days=3651"));
expect(res.status).toBe(422);
});
});
describe("GET /api/measurements/series — 422 multi-issue (v1.4.43 W6)", () => {
+7 -1
View File
@@ -38,7 +38,13 @@ const kindEnum = z.enum([
const querySchema = z.object({
kind: kindEnum,
days: z.coerce.number().int().min(1).max(365).optional().default(30),
// v1.5.5 — the 365-day cap rejected the iOS app's "Alle"-range
// request (days = 3650) with a 422, painting an error banner on
// every metric tile. Ten years matches the recurrence engine's
// nextOccurrenceAfter hard cap and the medication course-window
// upper bound, so the ceiling stays consistent across the surface
// area that the user can wire to a "show me everything" intent.
days: z.coerce.number().int().min(1).max(3650).optional().default(30),
});
const KIND_TO_TYPE: Record<z.infer<typeof kindEnum>, MeasurementType> = {