Files
paliad/internal/db/migrations/022_user_reminder_times.up.sql
m e68ff5b434 feat(reminders): per-user send times + due-today evening sweep (t-paliad-048)
Reminders used to fire whenever the hourly ticker happened to scan after
a user's first eligible event — m got mail at 02:28. We now gate delivery
to a user-chosen hour-of-day in their local timezone.

* Migration 022 adds reminder_morning_time / reminder_evening_time /
  reminder_timezone (defaults 09:00, 16:00, Europe/Berlin).
* New "due_today_evening" reminder kind with its own template — fires only
  for due_date = today AND status = pending, in the evening slot.
* Reminder service computes user-local hour each tick and skips users
  outside their slot. SQL widens to a 3-day band; in-process filter
  narrows to per-user local date.
* Settings → Notifications gains time inputs and a timezone field.
* Tests: pure (inSlot, slotForKind, matchesLocalDueDate) plus a live-DB
  TestReminderSlots covering morning, evening, outside-slot, and the
  completed-deadline case.
2026-04-27 11:47:10 +02:00

20 lines
1007 B
SQL

-- Per-user reminder send times (t-paliad-048).
--
-- Background: the hourly ReminderService used to send mail whenever the
-- ticker found a matching due_date — m got reminders at 02:28. We now gate
-- delivery to a user-chosen hour-of-day in the user's local timezone.
--
-- Three knobs per user:
-- * reminder_morning_time — when to send overdue / tomorrow / weekly
-- * reminder_evening_time — when to send the new "due-today, still pending"
-- evening sweep
-- * reminder_timezone — IANA timezone the two times are interpreted in
--
-- Defaults target the HLC-Munich audience; existing rows pick them up via
-- the column DEFAULT, so no explicit backfill is needed.
ALTER TABLE paliad.users
ADD COLUMN IF NOT EXISTS reminder_morning_time TIME NOT NULL DEFAULT '09:00:00',
ADD COLUMN IF NOT EXISTS reminder_evening_time TIME NOT NULL DEFAULT '16:00:00',
ADD COLUMN IF NOT EXISTS reminder_timezone TEXT NOT NULL DEFAULT 'Europe/Berlin';