mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-12 06:06:10 +00:00
Squashed merge of the v1.4.39 wave work from develop. The release extends the v1.4.38 fast-path posture to two more endpoints that still walked the source table on every cold mount and folds a cumulative `sum_value` column into the existing rollup tier so step / flight / distance / daylight / active-energy sparklines no longer re-derive their daily totals in Node. Raw measurements / mood_entries / medication_intake_events tables are byte-unchanged. Three new tiers (mood_entry_rollups, medication_compliance_rollups, measurement_rollups.sum_value) are derived caches that self-heal via boot-time backfill on first reach. Migrations 0070, 0071, 0072 are additive only. The sum_value column add is catalog-only DDL on PostgreSQL 11+ — no table rewrite, writes resume in milliseconds. No environment-variable change. No API contract break. No iOS contract change. Expected wins (live perf-verify rides the post-deploy window): - /api/mood/analytics cold 12.7 s -> ~200 ms - /api/medications/intake?scope=compliance cold 3.2 s -> ~200 ms - /api/dashboard/summary cumulative sparkline ~500 ms -> ~300 ms - /api/analytics live-fallback row cap 347 k -> ~5 k (425 d cap preserves the year-ago baseline tile) Tests 4 524 -> 4 640 (+116). Typecheck clean. Lint clean. See CHANGELOG.md for the full v1.4.39 entry.
42 lines
1.8 KiB
SQL
42 lines
1.8 KiB
SQL
-- v1.4.39 W-MOOD — persistent mood rollup table.
|
|
--
|
|
-- Second cache tier behind the 60-s LRU on /api/mood/analytics. Per-
|
|
-- (userId, granularity, bucketStart) stats so the read path skips the
|
|
-- unbounded MoodEntry.findMany walk that drove the 12.7 s cold mount on
|
|
-- power-user accounts.
|
|
--
|
|
-- Granularity reuses the existing `measurement_rollup_granularity` enum
|
|
-- so the worker / cross-granularity readers share a single type.
|
|
--
|
|
-- Additive only — no ALTER on existing tables, no DROP. The primary key
|
|
-- `(user_id, granularity, bucket_start)` guarantees idempotent upserts
|
|
-- under re-run; the IF NOT EXISTS guard makes the migration replay-safe
|
|
-- on partially-applied environments (mirrors 0061 / 0067 / 0068 / 0069).
|
|
|
|
CREATE TABLE IF NOT EXISTS "mood_entry_rollups" (
|
|
"user_id" TEXT NOT NULL,
|
|
"granularity" "measurement_rollup_granularity" NOT NULL,
|
|
"bucket_start" TIMESTAMPTZ(3) NOT NULL,
|
|
"count" INTEGER NOT NULL,
|
|
"mean" DOUBLE PRECISION NOT NULL,
|
|
"min_score" INTEGER NOT NULL,
|
|
"max_score" INTEGER NOT NULL,
|
|
"sd" DOUBLE PRECISION,
|
|
"computed_at" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "mood_entry_rollups_pkey"
|
|
PRIMARY KEY ("user_id", "granularity", "bucket_start")
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS "mood_entry_rollups_user_granularity_bucket_desc_idx"
|
|
ON "mood_entry_rollups" ("user_id", "granularity", "bucket_start" DESC);
|
|
|
|
DO $$ BEGIN
|
|
ALTER TABLE "mood_entry_rollups"
|
|
ADD CONSTRAINT "mood_entry_rollups_user_id_fkey"
|
|
FOREIGN KEY ("user_id") REFERENCES "users"("id")
|
|
ON DELETE CASCADE ON UPDATE CASCADE;
|
|
EXCEPTION
|
|
WHEN duplicate_object THEN NULL;
|
|
END $$;
|