mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-11 13:52:20 +00:00
v1.7.0 — health-record export (PDF + FHIR), flexible medication schedules, first-paint dashboard snapshot, full HealthKit coverage, offline sync delta feed, Coach data clustering. See CHANGELOG. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
51 lines
2.5 KiB
SQL
51 lines
2.5 KiB
SQL
-- v1.7.0 sync — extend the offline-sync feed to mood + medication intakes.
|
|
--
|
|
-- Adds the same reconciliation columns the measurement feed already
|
|
-- carries (`sync_version` LWW counter + `deleted_at` soft-delete
|
|
-- tombstone) to `mood_entries` and `medication_intake_events`, plus an
|
|
-- `updated_at` column to `medication_intake_events` (which had none) so
|
|
-- the `/api/sync/changes` keyset feed can order on it. `mood_entries`
|
|
-- already has `updated_at`, so it only gains the two sync columns.
|
|
--
|
|
-- Conflict semantics mirror the per-domain rules in the iOS-coord
|
|
-- contract: mood is last-writer-wins by `sync_version`; an intake is an
|
|
-- immutable fact whose correction is a tombstone + re-insert, so its
|
|
-- `sync_version` only bumps on the soft-delete write.
|
|
--
|
|
-- Every add is additive + order-safe:
|
|
-- - `sync_version` defaults to 0 (constant) → metadata-only ADD COLUMN.
|
|
-- - `deleted_at` is nullable, no default → metadata-only.
|
|
-- - `updated_at` on intakes is NOT NULL with `DEFAULT now()` so the
|
|
-- ADD COLUMN backfills existing rows to their migration instant
|
|
-- without a table rewrite (constant-folded default on PG 11+). The
|
|
-- Prisma `@updatedAt` directive maintains it from the app layer on
|
|
-- every subsequent write; the DB default only seeds legacy rows.
|
|
--
|
|
-- Supporting keyset indexes match the measurement feed's
|
|
-- `(user_id, updated_at, id)` index from migration 0096 so the delta
|
|
-- drain reads straight off the index in order rather than sorting the
|
|
-- user's whole set per page.
|
|
--
|
|
-- Reversibility (down):
|
|
-- DROP INDEX IF EXISTS "medication_intake_events_user_id_updated_at_id_idx";
|
|
-- DROP INDEX IF EXISTS "mood_entries_user_id_updated_at_id_idx";
|
|
-- ALTER TABLE "medication_intake_events"
|
|
-- DROP COLUMN "deleted_at", DROP COLUMN "sync_version", DROP COLUMN "updated_at";
|
|
-- ALTER TABLE "mood_entries"
|
|
-- DROP COLUMN "deleted_at", DROP COLUMN "sync_version";
|
|
|
|
ALTER TABLE "mood_entries"
|
|
ADD COLUMN "sync_version" INTEGER NOT NULL DEFAULT 0,
|
|
ADD COLUMN "deleted_at" TIMESTAMP(3);
|
|
|
|
ALTER TABLE "medication_intake_events"
|
|
ADD COLUMN "updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
ADD COLUMN "sync_version" INTEGER NOT NULL DEFAULT 0,
|
|
ADD COLUMN "deleted_at" TIMESTAMP(3);
|
|
|
|
CREATE INDEX IF NOT EXISTS "mood_entries_user_id_updated_at_id_idx"
|
|
ON "mood_entries" ("user_id", "updated_at", "id");
|
|
|
|
CREATE INDEX IF NOT EXISTS "medication_intake_events_user_id_updated_at_id_idx"
|
|
ON "medication_intake_events" ("user_id", "updated_at", "id");
|