Evening Checklist — Manifestation Tracker v1

For Agents

Lightweight reflection log keyed off the existing standup_datapoint_config + standup_datapoint tables via a new phase value 'EVENING_CHECKLIST'. Both mobile sheet (EveningChecklistSheet) and desktop card (EveningChecklistCard) auto-fetch and persist via useUpsertDatapoint. 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_check CHECK constraint to include 'EVENING_CHECKLIST'
  • Seeded 3 free-text prompts:
keylabel (sort)
proud_ofWhat I’m proud of (1)
not_proud_ofWhat I’m not proud of (2)
other_notesOther (3)

Applied to remote mkofmdtdldxgmmolxxhc. Commit 3c3501d.

Migration 009 — 009_evening_checklist_overspent.sql

  • Added 4th prompt:
keylabel (sort)
overspent_todayShit I overspent on (4)

All 4 prompts: type=TEXT, required=false, idempotent INSERT + UPDATE so reruns + label edits converge. Commit 2849661.

Frontend Wiring

SurfaceComponent
MobileEveningChecklistSheet (vaul drawer)
DesktopEveningChecklistCard (within pages/standup/index.tsx)

Both:

  1. Fetch via useDatapointConfigs('EVENING_CHECKLIST') + useDatapoints(standupId)
  2. Render one ChecklistField subcomponent per config
  3. Persist via useUpsertDatapoint — upserts on (standup, config) so repeated writes update the same row, no duplicates
  4. Field-level debounced autosave (see mobile-autosave) — Save buttons removed
  5. 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’s standup_datapoint rows for today have a non-empty value (i.e. filled-in answers, not standup.evening_completed_at — there’s no “complete” button here, fields autosave). The nudge is a CUSTOM_REMINDER notification (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-INSERT with origin='reminder', data->>'source_id' dedup) but does not use the reminder table.

Future Graduation Path

Why not a dedicated manifestation_entry table?

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