Files
ginnoir b89690a9f2 Initial scaffold: tooling, plan, task briefs
- pnpm 10 workspace + TypeScript strict + ESLint flat + Prettier
- CLAUDE.md as canonical brief
- docs/tasks/ — 22 task briefs broken out by phase for sub-sessions
- docs/decisions/ — ADR scaffold

Implements task 01 (repo-init).
2026-05-06 00:05:50 -05:00

1.2 KiB

41 — Reminders engine

Goal

A generic, entity-agnostic reminder system that fires at fire_at and routes through the notification bus.

Depends on

  • 40 (push), 42 (bus)

Scope

  • Schema: reminders (id, household_id, entity_type, entity_id, fire_at timestamptz, channel text default 'auto', fired_at timestamptz nullable, created_by).
  • Worker: a long-running tick (every 30s) that selects due un-fired reminders, calls notify(...), marks fired_at. Runs in the same Node process via setInterval guarded by a Postgres advisory lock to allow future horizontal scaling.
  • _core/reminders.ts exposes scheduleReminder(...), cancelReminder(id), listReminders(entityType, entityId).
  • Notes module's remind_at field calls scheduleReminder on save and cancelReminder when cleared.
  • Calendar module: optional "remind me" on event create (default 30 min before).

Out of scope

  • Recurring reminders (use rrule later).
  • Snooze.

Acceptance criteria

  • A note with remind_at = now + 1min fires within 90s and triggers a push notification.
  • Editing the note's remind_at updates the existing reminder, not creates duplicates.
  • Worker survives DB blips (caught + logged, not crashed).