mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-11 22:02:16 +00:00
Merge branch 'fix/v1437-review' into release/v1.43.7
# Conflicts: # src/app/api/analytics/route.ts
This commit is contained in:
commit
45c027aee2
217 files changed
+3636
-2127
No files matched your search
@@ -589,7 +589,7 @@ export const listMeasurementsSchema = z
|
||||
// Omitting `aggregate` keeps the raw wire shape (iOS contract); the
|
||||
// chart-data client must opt in explicitly.
|
||||
aggregate: z.enum(["raw", "daily", "weekly", "monthly"]).optional(),
|
||||
// v1.4.36 W1 — opt-in source switch for daily-aggregate reads. When
|
||||
// v1.4.36 — opt-in source switch for daily-aggregate reads. When
|
||||
// `source=rollup` + `aggregate=daily`, the route reads from the
|
||||
// persistent `measurement_rollups` DAY buckets instead of running a
|
||||
// live `date_trunc` GROUP BY scan over the raw `measurements` table.
|
||||
@@ -612,7 +612,7 @@ export const listMeasurementsSchema = z
|
||||
// `value: { gte, lte }` range. Server-authoritative; validated min<=max.
|
||||
valueMin: z.coerce.number().finite().optional(),
|
||||
valueMax: z.coerce.number().finite().optional(),
|
||||
// v1.4.37 W7c — list-view "one row per day" mode for cumulative
|
||||
// v1.4.37 — list-view "one row per day" mode for cumulative
|
||||
// types (steps, active energy, distance, flights, daylight). When
|
||||
// `groupBy=day` is set and `type` is a cumulative HK type, the route
|
||||
// returns one synthesised row per user-TZ day with `value` = SUM
|
||||
@@ -623,18 +623,18 @@ export const listMeasurementsSchema = z
|
||||
// picks the page's local days in Postgres and reports the distinct-day
|
||||
// count as `meta.total` (#1245).
|
||||
groupBy: z.enum(["day"]).optional(),
|
||||
// v1.4.37 W7c — drill-down to per-sample rows for a single day in
|
||||
// v1.4.37 — drill-down to per-sample rows for a single day in
|
||||
// the user's IANA timezone. Format `YYYY-MM-DD`; the route resolves
|
||||
// the day boundary against the user's `User.timezone`. Used by the
|
||||
// expandable list row to reveal the chunks that contributed to the
|
||||
// collapsed daily total.
|
||||
//
|
||||
// v1.4.37 W10 — a drill-down returns one bounded page rather than a
|
||||
// v1.4.37 — a drill-down returns one bounded page rather than a
|
||||
// cursor, so it refuses a non-zero `offset`.
|
||||
dayKey: z
|
||||
.string()
|
||||
.regex(/^\d{4}-\d{2}-\d{2}$/, "dayKey must be YYYY-MM-DD")
|
||||
// v1.4.37 W10 — a `YYYY-MM-DD` string can satisfy the regex while
|
||||
// v1.4.37 — a `YYYY-MM-DD` string can satisfy the regex while
|
||||
// still being an impossible calendar date (`2026-02-30`,
|
||||
// `2026-13-01`). `new Date("2026-02-30T00:00:00Z")` silently
|
||||
// overflows to March 2, so the drill-down would return rows from
|
||||
@@ -665,6 +665,19 @@ export const listMeasurementsSchema = z
|
||||
"limit must be <= 1000 when dayKey is set; drill-down responses are capped at 1000 rows",
|
||||
path: ["limit"],
|
||||
})
|
||||
// A value range filters single readings, and a day-grouped row is the sum
|
||||
// of a whole day: filtering its readings would return partial days summed
|
||||
// as if they were whole. The combination has no honest answer, so it is
|
||||
// refused rather than served.
|
||||
.refine(
|
||||
({ groupBy, valueMin, valueMax }) =>
|
||||
groupBy !== "day" || (valueMin == null && valueMax == null),
|
||||
{
|
||||
message:
|
||||
"valueMin / valueMax filter single readings and cannot be combined with groupBy=day",
|
||||
path: ["groupBy"],
|
||||
},
|
||||
)
|
||||
// v1.18.5 — an inverted value range (`valueMin > valueMax`) is a client
|
||||
// bug, not an empty result set; reject it at the validator with a 422 so
|
||||
// the filter UI can surface the mismatch instead of silently returning
|
||||
|
||||
Reference in new issue
Block a user