mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-14 14:40:52 +00:00
feat(measurements): value-range filter on the management list
Add an optional numeric value-range filter to the measurement list:
readings whose `value` falls within `[valueMin, valueMax]`, either bound
omittable for an open-ended range. Server-authoritative — both bounds are
parsed on `listMeasurementsSchema` (coerced from the query string), an
inverted `valueMin > valueMax` returns 422, and the bounds thread into the
Prisma `where` as a `value: { gte, lte }` range on the raw per-sample list.
The filter rides a new `FilterBarNumberRange` pill that mirrors the existing
date-range control, hidden for the day-grouped and sleep-night types where
the painted value is a synthesised total rather than a stored reading.
This commit is contained in:
1 parent
8920a35d38
commit
cc89695cbd
14 files changed
+286
-4
No files matched your search
@@ -331,6 +331,68 @@ describe("measurement validation", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("listMeasurementsSchema — v1.18.5 value-range filter", () => {
|
||||
it("coerces valueMin / valueMax from query strings", () => {
|
||||
const parsed = listMeasurementsSchema.safeParse({
|
||||
valueMin: "80",
|
||||
valueMax: "120",
|
||||
});
|
||||
expect(parsed.success).toBe(true);
|
||||
if (parsed.success) {
|
||||
expect(parsed.data.valueMin).toBe(80);
|
||||
expect(parsed.data.valueMax).toBe(120);
|
||||
}
|
||||
});
|
||||
|
||||
it("accepts an open-ended min-only range", () => {
|
||||
const parsed = listMeasurementsSchema.safeParse({ valueMin: "100" });
|
||||
expect(parsed.success).toBe(true);
|
||||
if (parsed.success) {
|
||||
expect(parsed.data.valueMin).toBe(100);
|
||||
expect(parsed.data.valueMax).toBeUndefined();
|
||||
}
|
||||
});
|
||||
|
||||
it("accepts an open-ended max-only range", () => {
|
||||
const parsed = listMeasurementsSchema.safeParse({ valueMax: "90" });
|
||||
expect(parsed.success).toBe(true);
|
||||
if (parsed.success) {
|
||||
expect(parsed.data.valueMax).toBe(90);
|
||||
expect(parsed.data.valueMin).toBeUndefined();
|
||||
}
|
||||
});
|
||||
|
||||
it("accepts valueMin == valueMax (exact-value band)", () => {
|
||||
const parsed = listMeasurementsSchema.safeParse({
|
||||
valueMin: "72",
|
||||
valueMax: "72",
|
||||
});
|
||||
expect(parsed.success).toBe(true);
|
||||
});
|
||||
|
||||
it("rejects an inverted range (valueMin > valueMax) with a 422-shaped issue", () => {
|
||||
const parsed = listMeasurementsSchema.safeParse({
|
||||
valueMin: "120",
|
||||
valueMax: "80",
|
||||
});
|
||||
expect(parsed.success).toBe(false);
|
||||
if (!parsed.success) {
|
||||
expect(parsed.error.issues.some((i) => i.path[0] === "valueMin")).toBe(
|
||||
true,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
it("leaves both bounds undefined when omitted", () => {
|
||||
const parsed = listMeasurementsSchema.safeParse({});
|
||||
expect(parsed.success).toBe(true);
|
||||
if (parsed.success) {
|
||||
expect(parsed.data.valueMin).toBeUndefined();
|
||||
expect(parsed.data.valueMax).toBeUndefined();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// v1.4.38 — the per-day drill-down branch always returns at most
|
||||
// 1000 rows (one pathological phone-only stepCount day). Push the
|
||||
// cap into the validator so a caller asking for more sees a 422
|
||||
|
||||
Reference in new issue
Block a user