mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-10 05:12:14 +00:00
Migration 0334, all additive. MeasurementReminder gains snoozedUntil, lastSkippedAt and skipCount; the new MeasurementReminderEvent table is the append-only completion ledger (kind SATISFIED|SKIPPED, occurredAt, write-time onTime, source). CustomMetricEntry gains the deletedAt tombstone for undo parity with every other entry surface. Consumers land in the sibling commits of this branch. Refs #223
55 lines
2.5 KiB
SQL
55 lines
2.5 KiB
SQL
-- Refs #223 + iOS #68 — Vorsorge snooze/skip + the completion ledger.
|
|
-- All additive; every existing reminder keeps its exact behaviour.
|
|
|
|
-- Snooze cursor: non-NULL and in the future = "pushed back until this
|
|
-- instant". The snooze write sets next_due_at to the SAME instant, so every
|
|
-- due-state consumer moves with it; expiry is the clock passing the value.
|
|
ALTER TABLE "measurement_reminders" ADD COLUMN "snoozed_until" TIMESTAMP(3);
|
|
|
|
-- Last honest skip. A skip re-anchors next_due_at at the skip instant but
|
|
-- never moves last_satisfied_at — done and skipped stay distinguishable.
|
|
ALTER TABLE "measurement_reminders" ADD COLUMN "last_skipped_at" TIMESTAMP(3);
|
|
|
|
-- Lifetime skip counter ("skipped N times").
|
|
ALTER TABLE "measurement_reminders" ADD COLUMN "skip_count" INTEGER NOT NULL DEFAULT 0;
|
|
|
|
-- The completion ledger (iOS #68). The engine is single-cursor, so before
|
|
-- this table each satisfy overwrote the last and history was unrecoverable.
|
|
-- Append-only: one row per satisfy / skip, written by the one satisfy
|
|
-- primitive and the skip route. History starts with this release — the
|
|
-- cursor holds nothing to backfill from.
|
|
CREATE TYPE "measurement_reminder_event_kind" AS ENUM ('SATISFIED', 'SKIPPED');
|
|
|
|
CREATE TABLE "measurement_reminder_events" (
|
|
"id" TEXT NOT NULL,
|
|
"user_id" TEXT NOT NULL,
|
|
"reminder_id" TEXT NOT NULL,
|
|
"kind" "measurement_reminder_event_kind" NOT NULL,
|
|
"occurred_at" TIMESTAMP(3) NOT NULL,
|
|
"on_time" BOOLEAN NOT NULL,
|
|
"source" TEXT NOT NULL,
|
|
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "measurement_reminder_events_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
CREATE INDEX "measurement_reminder_events_reminder_id_occurred_at_idx"
|
|
ON "measurement_reminder_events"("reminder_id", "occurred_at");
|
|
|
|
CREATE INDEX "measurement_reminder_events_user_id_idx"
|
|
ON "measurement_reminder_events"("user_id");
|
|
|
|
ALTER TABLE "measurement_reminder_events"
|
|
ADD CONSTRAINT "measurement_reminder_events_user_id_fkey"
|
|
FOREIGN KEY ("user_id") REFERENCES "users"("id")
|
|
ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
ALTER TABLE "measurement_reminder_events"
|
|
ADD CONSTRAINT "measurement_reminder_events_reminder_id_fkey"
|
|
FOREIGN KEY ("reminder_id") REFERENCES "measurement_reminders"("id")
|
|
ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- Custom-metric entries gain the soft-delete tombstone every peer entry
|
|
-- surface already has (undo parity — the one hard delete left).
|
|
ALTER TABLE "custom_metric_entries" ADD COLUMN "deleted_at" TIMESTAMP(3);
|