mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-13 22:32:04 +00:00
feat(api): add source filter to measurement and mood lists
Add a source filter to both management lists. Mood gains an optional `source` param (validated against the mood source set); measurements gain `sourceEq` (validated against MeasurementSource) — the `source` key on the measurements list is the rollup-tier opt-in, so the filter rides a distinct param. Both thread into the list `where` alongside the pinned `userId` + `deletedAt: null`. Migration 0136 adds two additive indexes — `(userId, source, measuredAt)` on measurements and `(userId, source, moodLoggedAt)` on mood — so a source filter + recency sort is an index range scan rather than a userId scan plus in-memory sort at 100-200k rows per user. Pure `CREATE INDEX IF NOT EXISTS`, no backfill. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
1fd875b83c
commit
0d69611bbf
8 files changed
+117
-1
No files matched your search
@@ -0,0 +1,15 @@
|
||||
-- v1.15.13 — source-filter support indexes for the measurements + mood
|
||||
-- management lists. The new list surfaces add a source filter (and the
|
||||
-- existing source/value sort). No index leads with `(user_id, source)`
|
||||
-- today, so a source filter forces a `user_id` scan + in-memory sort —
|
||||
-- the landmine at 100–200k rows per user. These two additive indexes turn
|
||||
-- a source filter + recency sort into an index range scan.
|
||||
--
|
||||
-- Pure additive `CREATE INDEX IF NOT EXISTS`, no backfill — same low-risk
|
||||
-- shape as migration 0123.
|
||||
|
||||
CREATE INDEX IF NOT EXISTS "measurements_user_id_source_measured_at_idx"
|
||||
ON "measurements" ("user_id", "source", "measured_at" DESC);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS "mood_entries_user_id_source_mood_logged_at_idx"
|
||||
ON "mood_entries" ("user_id", "source", "mood_logged_at" DESC);
|
||||
@@ -850,6 +850,10 @@ model Measurement {
|
||||
// (Postgres semantics) so manual entries don't collide here.
|
||||
@@unique([userId, type, source, externalId])
|
||||
@@index([userId, type, measuredAt])
|
||||
// v1.15.13 — leads with `(userId, source)` so the management list's
|
||||
// source filter + recency sort is an index range scan instead of a
|
||||
// `userId` scan + in-memory sort. See migration 0136.
|
||||
@@index([userId, source, measuredAt])
|
||||
@@index([externalId])
|
||||
// v1.7.0 — supports the `/api/sync/changes` keyset feed, which walks
|
||||
// `where userId` ordered by `(updatedAt asc, id asc)` with `take
|
||||
@@ -2082,6 +2086,10 @@ model MoodEntry {
|
||||
// null, moodLoggedAt: { gte } }` ordered by `moodLoggedAt desc`; this
|
||||
// index turns that into a range scan. See migration 0123.
|
||||
@@index([userId, moodLoggedAt])
|
||||
// v1.15.13 — leads with `(userId, source)` so the mood management
|
||||
// list's source filter + recency sort is an index range scan. See
|
||||
// migration 0136.
|
||||
@@index([userId, source, moodLoggedAt])
|
||||
// v1.7.0 sync — keyset support for the `/api/sync/changes` mood feed
|
||||
// (`where userId` ordered by `(updatedAt asc, id asc)`).
|
||||
@@index([userId, updatedAt, id])
|
||||
|
||||
Reference in new issue
Block a user