Commit Graph
2 Commits
Author SHA1 Message Date
Marc-André Bombeck da2de015fe feat(nutrients): source-aware day totals; manual water write path
NutrientIntakeDay's composite primary key gains `source` (migration
0249_nutrient_intake_day_source): a manual water entry and the
Apple-synced day total now live as two rows instead of the manual
write being silently clobbered by the next Apple last-writer-wins
sync. Every existing row already defaults to source=APPLE_HEALTH, so
the migration is a pure PK-constraint change with no data rewrite.

- POST /api/nutrients/batch keeps writing the APPLE_HEALTH row,
  byte-identical upsert semantics against the wider key.
- GET /api/nutrients sums amounts within (nutrient, day) across
  sources before folding into the window summary.
- POST /api/nutrients/water (new): manual water quick-add, add/set
  modes against the MANUAL row only, module-gated, rate-limited,
  idempotency-key aware, hard-evicts the dashboard snapshot cache.
- GET /api/nutrients/daily (new): dense per-day series for one
  nutrient (summed across sources) plus the EFSA reference resolved
  against the caller's profile sex — omitted when sex is unknown.
- catalog.ts gains resolveNutrientReference(), the sex-resolution
  helper both new routes and the insights cards share.

docs/api/openapi.yaml regenerated for the two new routes.
2026-07-17 16:08:39 +02:00
Marc-André Bombeck 5445fc67ea chore(release): v1.28.34 — nutrient intake lands as quiet context (server side)
Supplement-style intake written to Apple Health by nutrition apps —
vitamins, minerals, water, caffeine — can now sync as daily totals into a
dedicated NutrientIntakeDay store (migration 0241): composite (user, day,
nutrient) identity, re-post replaces, no soft delete, no rollup coupling.
A code-side catalog carries the 26 nutrient codes with canonical units,
plausibility caps, and EFSA dietary reference values (direction-aware;
chromium cites NIH ODS where EFSA declined a DRV).

Deliberately not a nutrition feature: no diary, no calories, no dashboard
surface. POST /api/nutrients/batch is gated behind the new opt-in
nutrients module (default off — with the module off the server refuses
ingest entirely), rate-limited, idempotency-wrapped, with per-entry
unit-mismatch and out-of-range skips. GET /api/nutrients serves a
catalog-ordered summary; the only visible surface is a read-only card
under Settings → Sources. Coach/correlation access is a later slice; the
iOS reading side is coordinated in the companion-app tracker.
2026-07-14 13:10:47 +02:00