mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-10 13:22:14 +00:00
feat(mood): add the five level-A columns to the mood entry
- migration 0310 adds mood_a1, stress_a2, energy_a3, connection_a4 and stability_a5, all nullable, no table rewrite - the schema comment states the four things a later reader needs: score keeps its 1-5 axis, the columns are queryable plaintext on purpose, stress is stored literally, and a read delegate sees them by design - the backup guard is red until the carriers land alongside
This commit is contained in:
1 parent
9a390aacea
commit
ad4f5c04f0
2 files changed
+56
No files matched your search
@@ -0,0 +1,21 @@
|
||||
-- v1.37 — the five level-A self-state values on a mood entry.
|
||||
--
|
||||
-- A mood entry has carried one 1-5 value since the first release. That value
|
||||
-- keeps its scale and its meaning; these five ride beside it, each 0-10 with
|
||||
-- its own anchors: pleasantness, stress, energy, connectedness and stability.
|
||||
--
|
||||
-- All five are nullable, which is what makes this an additive change rather
|
||||
-- than a table rewrite, and nullable is also the honest shape: only the first
|
||||
-- one can be derived from what a row already carries, and the other four stay
|
||||
-- empty until somebody answers them. A default would fill a hundred thousand
|
||||
-- historical rows with a number nobody chose.
|
||||
--
|
||||
-- No CHECK constraint on the range. Bounds are enforced server-side, the same
|
||||
-- way `mood_entry_tag_links.rating` documents: a future change to the scale
|
||||
-- must not strand rows written under the old one.
|
||||
ALTER TABLE "mood_entries"
|
||||
ADD COLUMN "mood_a1" INTEGER,
|
||||
ADD COLUMN "stress_a2" INTEGER,
|
||||
ADD COLUMN "energy_a3" INTEGER,
|
||||
ADD COLUMN "connection_a4" INTEGER,
|
||||
ADD COLUMN "stability_a5" INTEGER;
|
||||
@@ -4016,6 +4016,41 @@ model MoodEntry {
|
||||
date String // YYYY-MM-DD — anchored to `tz` when not null, else legacy Europe/Berlin
|
||||
mood String // SUPER_GUT, GUT, OKAY, SCHLECHT, LAUSIG
|
||||
score Int // 1-5
|
||||
/// v1.37 — the five level-A self-state values, each 0-10 with its own
|
||||
/// anchors. `MOOD_DIMENSIONS` (`src/lib/mood/dimensions.ts`) is the one
|
||||
/// table binding a column to its label, its anchors and its orientation.
|
||||
///
|
||||
/// `score` above stays the 1-5 legacy axis and is not re-scaled: eleven
|
||||
/// surfaces derive numbers from it on that assumption, three of them into
|
||||
/// prose an assistant then states as fact. The two axes coexist by design.
|
||||
/// `moodA1` is derived from the five-point label on every write, so a quick
|
||||
/// check-in is a full entry rather than a degraded one; A2 to A5 are only
|
||||
/// ever set by hand, and stay NULL when nobody answered them. Absence reads
|
||||
/// as absence — a fabricated middle value would poison both the trend and
|
||||
/// any later model trained on these columns.
|
||||
///
|
||||
/// Queryable plaintext, deliberately — the same trade `CycleDayLog`
|
||||
/// documents at its `basalBodyTempC`. Encrypting them would remove the
|
||||
/// trend read, the factor crosstab and every aggregate at once, and the
|
||||
/// values are self-ratings on a fixed scale rather than prose. The free-text
|
||||
/// note beside them stays encrypted, because that is where the prose is.
|
||||
///
|
||||
/// `stressA2` is stored literally, exactly as the user set it against the
|
||||
/// anchors they read, so a higher value means more stress and a worse day.
|
||||
/// A surface that needs "up is better" flips the sign through the `inverse`
|
||||
/// flag on the dimension table, never inline. The same rule already governs
|
||||
/// `MoodTag.inverse`, and it exists because a stored value that disagrees
|
||||
/// with the label the user saw cannot be recovered afterwards.
|
||||
///
|
||||
/// A delegate holding a READ grant sees these columns, because a grant is
|
||||
/// whole-record by design and carries no per-domain scope. That is
|
||||
/// deliberate, not an oversight: withholding part of a record from a
|
||||
/// delegate would be a new capability, not a field select.
|
||||
moodA1 Int? @map("mood_a1") // 0-10, pleasantness
|
||||
stressA2 Int? @map("stress_a2") // 0-10, inverse-oriented
|
||||
energyA3 Int? @map("energy_a3") // 0-10
|
||||
connectionA4 Int? @map("connection_a4") // 0-10
|
||||
stabilityA5 Int? @map("stability_a5") // 0-10
|
||||
tags String? // JSON array of tag keys
|
||||
/// v1.4.30 — first-class free-text note. Replaces the
|
||||
/// `tags: ["note:<text>"]` workaround the iOS app shipped through
|
||||
|
||||
Reference in new issue
Block a user