Per-day habit reflections
Shipped per-day reflections for mirror-habit: a note, effort, and mood attached to each habit’s daily cell, plus effort trend charts. What shipped Reflection editor (CheckInNoteEditor) on every check-in surface — dashboards, habit detail, private habits, and the daily briefing. A note/effort/mood is attached to the (habit_id, user_id, date) cell, not individual entries rows — so counted habits (many rows/day) get exactly one reflection per day. Effort trend charts on habit detail pages, and reflections surfaced in the yearly heatmap. supabase/migrations/20260913_entry_notes.sql: PK-enforced table, RLS (read-all / write-your-own), indexes, and realtime replication alongside entries. DB design notes effort/mood are CHECK-constrained to 1..5 so the bar charts never get nonsense. PK (habit_id, user_id, date) is what keeps “one reflection per cell” true even when a counted habit logs several entries in a day. Reflections are in the realtime publication like entries, so guild-mate notes stream across devices without a reload. What got tricky Store churn: every writer path (fetch, migration push, realtime channel) had to validate reflections the same way or stale 0% rows leak through the reducer — the same class of bug the challenge tiers had. Fix: validate at every ingest point. Moving the reflection data through store.tsx meant keeping streak math and counts untouched — the store diff is mostly additive. A good “small feature, careful data model” push.