Docker container datetime.now() returns UTC, but all stored datetimes
are naive local time from the browser. Both /due and /snooze now
accept client_now from the frontend, ensuring snooze computes from
the user's actual current time, not the container's clock.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- S1: Add composite index (is_active, is_dismissed, remind_at) for
/due query performance with multi-user scaling
- W3: Snooze endpoint rejects dismissed/inactive reminders (409)
- W4: Custom field_validator on ReminderSnooze for clear error message
- S2: aria-label on all snooze/dismiss buttons in banner and toasts
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- C1: Replaced duplicate useAlerts() calls with AlertsProvider context
wrapping AppLayout — single hook instance, no double polling/toasts
- C2: Added null guard on remind_at in Active Reminders card format()
- W2: Clear snoozed_until when dismissing a reminder
- W5: Extracted getRelativeTime to shared lib/date-utils.ts
- S3: Replaced inline SVG with Lucide Bell component in toasts
- S4: Clear snoozed_until when remind_at is updated via PUT
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Backend: /due endpoint now matches both NULL and empty string for
recurrence_rule (form was sending '' not null, excluding all reminders)
- Form: sends null instead of '' for empty recurrence_rule
- ReminderForm: replaced datetime-local with date + hour/minute/AM-PM
selects for 12-hour time format
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>