Evening Checklist — Manifestation Tracker v1
For Agents
Lightweight reflection log keyed off the existing
standup_datapoint_config+standup_datapointtables via a new phase value'EVENING_CHECKLIST'. Both mobile sheet (EveningChecklistSheet) and desktop card (EveningChecklistCard) auto-fetch and persist viauseUpsertDatapoint. Field-level debounced autosave — no Save button.
Schema Approach
Reuses existing standup datapoint plumbing rather than introducing a new table. Lightweight v1, ETL-able later.
Migration 008 — 008_evening_checklist_configs.sql
- Widened
standup_datapoint_config_phase_checkCHECK constraint to include'EVENING_CHECKLIST' - Seeded 3 free-text prompts:
| key | label (sort) |
|---|---|
proud_of | What I’m proud of (1) |
not_proud_of | What I’m not proud of (2) |
other_notes | Other (3) |
Applied to remote mkofmdtdldxgmmolxxhc. Commit 3c3501d.
Migration 009 — 009_evening_checklist_overspent.sql
- Added 4th prompt:
| key | label (sort) |
|---|---|
overspent_today | Shit I overspent on (4) |
All 4 prompts: type=TEXT, required=false, idempotent INSERT + UPDATE so reruns + label edits converge. Commit 2849661.
Frontend Wiring
| Surface | Component |
|---|---|
| Mobile | EveningChecklistSheet (vaul drawer) |
| Desktop | EveningChecklistCard (within pages/standup/index.tsx) |
Both:
- Fetch via
useDatapointConfigs('EVENING_CHECKLIST')+useDatapoints(standupId) - Render one
ChecklistFieldsubcomponent per config - Persist via
useUpsertDatapoint— upserts on(standup, config)so repeated writes update the same row, no duplicates - Field-level debounced autosave (see mobile-autosave) — Save buttons removed
- Aggregate (worst-of) status pill in header
Hook Updates
useDatapointConfigs phase union widened to include 'EVENING_CHECKLIST' alongside the existing morning/evening/lunch phases.
Evening-Checklist Reminder (timed nudge)
Shipped 2026-05-11
A pg_cron SQL function (
process_evening_checklist_reminders, cron'0 * * * *', self-gating to hours 21 & 22 Europe/Budapest) nudges the user to finish the checklist if it’s still incomplete at 21:00 (and re-nudges at 22:00 if still incomplete). “Incomplete” = fewer than X =count(active EVENING_CHECKLIST configs)of this person’sstandup_datapointrows for today have a non-emptyvalue(i.e. filled-in answers, notstandup.evening_completed_at— there’s no “complete” button here, fields autosave). The nudge is aCUSTOM_REMINDERnotification (entity_type='standup'); tapping it (in-app or push) opens/standup. Full design lives in Evening-Checklist Reminder — it reuses the scheduled-reminders pattern (pg_cron SQL fn, direct-INSERTwithorigin='reminder',data->>'source_id'dedup) but does not use theremindertable.
Future Graduation Path
Why not a dedicated
manifestation_entrytable?Today’s data lives flat in
standup_datapoint. When richer needs arise (per-user prompts, attached media, threaded reflections), a small ETL forward to a dedicated table is straightforward — but YAGNI for v1.
Likely v2 features:
- Per-user prompt customization (current configs are global)
- Attached media (photos, voice notes)
- Threaded reflections (multi-day chains)
- Mood tracking, weekly digest
Related
- mobile-day-rituals — Sibling rituals (Morning, Lunch, Evening reflection, Standup notes)
- mobile-autosave — The debounced autosave pattern this checklist uses
- mobile-native-feel — Surrounding mobile architecture
- day-planner — Desktop standup page that hosts the card
- scheduled-reminders — The evening-checklist reminder (
process_evening_checklist_reminderspg_cron job) that nudges the user to finish this checklist; see Evening-Checklist Reminder