When adaptive timing shifts a late-night dose past midnight (e.g. 23:00
→ 00:42), the scheduler would create a new pending schedule on the next
day even if the dose was already taken. The proximity window was too
narrow to match the take log against the shifted time.
- Skip creating schedules for doses already taken/skipped (checks
today + yesterday logs against base_time)
- Fix midnight wraparound in proximity check for should_send_nag
- Display base_time (actual dose time) in reminders instead of the
internal adjusted_time
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix double notifications: remove redundant check_medication_reminders()
call, use adaptive path as primary with basic as fallback
- Fix nag firing immediately: require nag_interval minutes after scheduled
dose time before first nag
- Fix missing schedules: create on-demand if midnight window was missed
- Fix wrong timezone: use user_now_for() instead of request-context
user_now() in calculate_adjusted_times()
- Fix immutable schedules: recalculate pending schedules on wake event
detection so adaptive timing actually adapts
- Fix take/skip not updating schedule: API endpoints now call
mark_med_taken/skipped so nags stop after logging a dose
- Fix skipped doses still triggering reminders: check both taken and
skipped in adaptive reminder and log queries
- Update README with tasks, AI step generation, auth refresh tokens,
knowledge base improvements, and current architecture
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Make last_nag_at timezone-aware before subtracting from the tz-aware
current_time, and store future nag timestamps with timezone.utc to
prevent the mismatch recurring.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
should_send_nag() was iterating all pending schedules for today without
verifying the scheduled time had actually passed. A dose scheduled for
18:00 would get nagged at 13:15. Add an early return when current_time
is before the scheduled dose time.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The medication_schedules.adjusted_time column is a TIME type, but
med_logs.scheduled_time is VARCHAR. When adjusted_time values were
passed into queries against med_logs, PostgreSQL rejected the
comparison. Add _normalize_time() to convert datetime.time objects
to "HH:MM" strings at the entry points of should_send_nag,
record_nag_sent, and mark_med_taken.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>