b4108c5a36
Phase 1 of the maintenance-reminders feature. - notification_kind: + maintenance_due_soon, maintenance_overdue. These are distinct from maintenance_event_recorded (service performed) so the bell list can group/filter reminder vs service cleanly. - New maintenance_reminder_kind enum: due_soon | overdue. - New maintenance_reminders_sent table with UNIQUE(schedule_id, kind, due_at). The cron uses INSERT … ON CONFLICT DO NOTHING on this composite to make the fire-once-per-window guarantee atomic even under concurrent runs. Once the schedule's next_due_at advances after a service event, the tuple is fresh and a new reminder fires. No service code yet — Phase 2 wires the readers and orchestrator. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>