fix(nutrients): bound the manual water writes and put nutrient totals in the backup

The water quick-add validated calendar realism but never the upper day bound the
batch route applies, so a far-future day was accepted and — every read filters
`day >= since` with no ceiling — became the permanent latest day on the settings
card and the dashboard tile. Hoist the bound into one shared helper both routes
use.

`mode: "add"` bounded a single request to the catalog's plausible daily max but
nothing across requests, so repeated quick-adds drove the stored total
arbitrarily high while the batch route enforced the same cap strictly. Clamp
after the increment so the write stays atomic.

Thiamin's cap sat at exactly 1000 mg while its PRI is exactly 1.0 mg, so a
microgram-read-as-milligram sample landed on precisely the cap and the `>`
comparison let it through. 500 still clears any real supplement dose.

NutrientIntakeDay was in no export path, which contradicted the schema's own
reason for denormalising the unit column. Carry it in the full backup with its
unit and source — source is part of the composite key, so without it a restore
cannot tell a manual entry from a synced day total.
This commit is contained in:
Marc-André Bombeck committed 2026-07-19 13:40:03 +02:00
1 parent 8ead442d44
commit 94157a50c7
16 files changed
+389 -90

No files matched your search

+3 -2
View File
@@ -13349,8 +13349,9 @@ components:
$ref: "#/components/schemas/NutrientIntakeEntry"
required:
- entries
description: Bulk day-total upsert, max 500 entries. Upsert key is (day, nutrient); a re-post replaces the stored total
(last-writer-wins day-total contract).
description: Bulk day-total upsert, max 500 entries. Upsert key is the composite primary key (userId, day, nutrient,
source); this route always writes the APPLE_HEALTH source row, so a manual water entry is never clobbered. A
re-post replaces the stored total (last-writer-wins day-total contract).
NutrientIntakeEntry:
type: object
properties: