Files
HealthLog/prisma/migrations/0249_nutrient_intake_day_source/migration.sql
T
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

20 lines
1.1 KiB
SQL

-- v1.29 — `source` joins the `nutrient_intake_days` primary key so a
-- manual water entry and the Apple-synced day total coexist as two rows
-- instead of the manual write being silently clobbered by the next
-- Apple last-writer-wins sync (the batch route always upserts the
-- (userId, day, nutrient) row with the CURRENT running total, so a
-- manual increment folded into that same row would vanish on the next
-- sync — a data-loss bug by construction, not a rare race).
--
-- No data rewrite: every existing row already carries
-- `source = 'APPLE_HEALTH'` (the column default since migration 0241),
-- so dropping and recreating the PRIMARY KEY over the four columns is a
-- pure constraint change — same rows, same values, wider key. The
-- existing `(user_id, nutrient, day DESC)` index is untouched; it does
-- not reference `source` and continues to serve the window-scan reads.
ALTER TABLE "nutrient_intake_days" DROP CONSTRAINT "nutrient_intake_days_pkey";
ALTER TABLE "nutrient_intake_days"
ADD CONSTRAINT "nutrient_intake_days_pkey"
PRIMARY KEY ("user_id", "day", "nutrient", "source");