Currently the only proactive notification is notifications.tasks.send_daily_task_email, a once-a-day digest (6-7 AM local time) listing tasks due today and overdue tasks. There is no per-task notification at/near a task's actual due time.
Requested triggers (per user, 2026-09-05):
Reminder before due - X minutes before due_date/due_time, per-user configurable. The schema already has this half-built: User.default_reminder_minutes (users/models.py) is a saved, user-editable preference (profile page: "Default Reminder" - 5/15/30/60/1440 min before) but nothing ever reads it.
Notification at the due time itself - when due_date+due_time arrives.
Notification when a task becomes overdue - a one-time notification fired at the moment a task crosses from "due" into "overdue" (i.e. due time has passed and status is still pending/in_progress), not repeated on every check.
Delivery channel choice: the user should be able to choose whether each of these fires as a push notification, an email, or both. The User model already has independent email_notifications and push_notifications booleans (users/models.py) - reuse these (both can already be enabled simultaneously) rather than adding new fields, unless it turns out these new per-task reminders need to be configurable separately from the existing daily-digest email toggle (e.g. someone wants the daily digest by email only, but instant due/overdue alerts by push only) - that would need its own reminder-specific channel setting(s) in the profile UI (templates/users/profile.html) distinct from the current single email/push toggle pair.
The ScheduledReminder model (notifications/models.py) has task, remind_at, is_sent, sent_at - built for exactly this kind of purpose - but nothing ever creates rows in it, and there's no Celery task or beat-schedule entry that processes them.
Implementation sketch:
Create ScheduledReminder row(s) whenever a task's due_date/due_time is set or changed:
one at due_date/due_time - default_reminder_minutes (skip if the user's setting is 0/"No reminder", or if there's no due_time - needs a decision on date-only due dates)
one at due_date/due_time itself (the "due now" notification)
one at due_date/due_time (or shortly after) for the "now overdue" notification - functionally this fires once the due moment passes, so it may be implementable as the same scheduled check but distinct wording/type, or a follow-up check some short interval later confirming the task is still not completed before sending
Add a Celery task (registered in config/celery.py's beat_schedule, running frequently, e.g. every 1-5 minutes) that finds ScheduledReminder rows where remind_at <= now and is_sent=False, sends email and/or push per the user's chosen channel(s) for these reminders (reusing send_web_push_to_user from notifications/tasks.py for the push side), then marks them is_sent=True.
Clean up/cancel stale/pending reminders when a task's due date changes, is completed, or is deleted, so a reminder doesn't fire for a task that's no longer due (or already done).
Decide behavior for recurring tasks - each new recurrence instance needs its own set of ScheduledReminder rows.
Raised during investigation of a user question: "Should I be getting a notification when tasks are due or before they are due?" - answer today is no, only the daily digest.
Currently the only proactive notification is `notifications.tasks.send_daily_task_email`, a once-a-day digest (6-7 AM local time) listing tasks due today and overdue tasks. There is no per-task notification at/near a task's actual due time.
Requested triggers (per user, 2026-09-05):
1. **Reminder before due** - X minutes before `due_date`/`due_time`, per-user configurable. The schema already has this half-built: `User.default_reminder_minutes` (`users/models.py`) is a saved, user-editable preference (profile page: "Default Reminder" - 5/15/30/60/1440 min before) but nothing ever reads it.
2. **Notification at the due time itself** - when `due_date`+`due_time` arrives.
3. **Notification when a task becomes overdue** - a one-time notification fired at the moment a task crosses from "due" into "overdue" (i.e. due time has passed and status is still pending/in_progress), not repeated on every check.
**Delivery channel choice**: the user should be able to choose whether each of these fires as a push notification, an email, or both. The `User` model already has independent `email_notifications` and `push_notifications` booleans (`users/models.py`) - reuse these (both can already be enabled simultaneously) rather than adding new fields, unless it turns out these new per-task reminders need to be configurable separately from the existing daily-digest email toggle (e.g. someone wants the daily digest by email only, but instant due/overdue alerts by push only) - that would need its own reminder-specific channel setting(s) in the profile UI (`templates/users/profile.html`) distinct from the current single email/push toggle pair.
The `ScheduledReminder` model (`notifications/models.py`) has `task`, `remind_at`, `is_sent`, `sent_at` - built for exactly this kind of purpose - but nothing ever creates rows in it, and there's no Celery task or beat-schedule entry that processes them.
Implementation sketch:
1. Create `ScheduledReminder` row(s) whenever a task's `due_date`/`due_time` is set or changed:
- one at `due_date/due_time - default_reminder_minutes` (skip if the user's setting is 0/"No reminder", or if there's no `due_time` - needs a decision on date-only due dates)
- one at `due_date/due_time` itself (the "due now" notification)
- one at `due_date/due_time` (or shortly after) for the "now overdue" notification - functionally this fires once the due moment passes, so it may be implementable as the same scheduled check but distinct wording/type, or a follow-up check some short interval later confirming the task is still not completed before sending
2. Add a Celery task (registered in `config/celery.py`'s `beat_schedule`, running frequently, e.g. every 1-5 minutes) that finds `ScheduledReminder` rows where `remind_at <= now` and `is_sent=False`, sends email and/or push per the user's chosen channel(s) for these reminders (reusing `send_web_push_to_user` from `notifications/tasks.py` for the push side), then marks them `is_sent=True`.
3. Clean up/cancel stale/pending reminders when a task's due date changes, is completed, or is deleted, so a reminder doesn't fire for a task that's no longer due (or already done).
4. Decide behavior for recurring tasks - each new recurrence instance needs its own set of `ScheduledReminder` rows.
Raised during investigation of a user question: "Should I be getting a notification when tasks are due or before they are due?" - answer today is no, only the daily digest.
Confirmed working in production: before-due, due-now, and overdue reminders all fired correctly across email, web push, and mobile push, including after a couple of live-testing refinements (delayed the overdue notification by an hour so it does not arrive alongside due-now, and made changing the Default Reminder profile setting retroactively reschedule already-due-dated tasks).
Shipped in commits 5359bf2, f92ce7a (plus the unrelated a27fcc4 crash fix for task edits that this testing surfaced along the way).
Closing as complete.
Confirmed working in production: before-due, due-now, and overdue reminders all fired correctly across email, web push, and mobile push, including after a couple of live-testing refinements (delayed the overdue notification by an hour so it does not arrive alongside due-now, and made changing the Default Reminder profile setting retroactively reschedule already-due-dated tasks).
Shipped in commits 5359bf2, f92ce7a (plus the unrelated a27fcc4 crash fix for task edits that this testing surfaced along the way).
Closing as complete.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Currently the only proactive notification is
notifications.tasks.send_daily_task_email, a once-a-day digest (6-7 AM local time) listing tasks due today and overdue tasks. There is no per-task notification at/near a task's actual due time.Requested triggers (per user, 2026-09-05):
due_date/due_time, per-user configurable. The schema already has this half-built:User.default_reminder_minutes(users/models.py) is a saved, user-editable preference (profile page: "Default Reminder" - 5/15/30/60/1440 min before) but nothing ever reads it.due_date+due_timearrives.Delivery channel choice: the user should be able to choose whether each of these fires as a push notification, an email, or both. The
Usermodel already has independentemail_notificationsandpush_notificationsbooleans (users/models.py) - reuse these (both can already be enabled simultaneously) rather than adding new fields, unless it turns out these new per-task reminders need to be configurable separately from the existing daily-digest email toggle (e.g. someone wants the daily digest by email only, but instant due/overdue alerts by push only) - that would need its own reminder-specific channel setting(s) in the profile UI (templates/users/profile.html) distinct from the current single email/push toggle pair.The
ScheduledRemindermodel (notifications/models.py) hastask,remind_at,is_sent,sent_at- built for exactly this kind of purpose - but nothing ever creates rows in it, and there's no Celery task or beat-schedule entry that processes them.Implementation sketch:
ScheduledReminderrow(s) whenever a task'sdue_date/due_timeis set or changed:due_date/due_time - default_reminder_minutes(skip if the user's setting is 0/"No reminder", or if there's nodue_time- needs a decision on date-only due dates)due_date/due_timeitself (the "due now" notification)due_date/due_time(or shortly after) for the "now overdue" notification - functionally this fires once the due moment passes, so it may be implementable as the same scheduled check but distinct wording/type, or a follow-up check some short interval later confirming the task is still not completed before sendingconfig/celery.py'sbeat_schedule, running frequently, e.g. every 1-5 minutes) that findsScheduledReminderrows whereremind_at <= nowandis_sent=False, sends email and/or push per the user's chosen channel(s) for these reminders (reusingsend_web_push_to_userfromnotifications/tasks.pyfor the push side), then marks themis_sent=True.ScheduledReminderrows.Raised during investigation of a user question: "Should I be getting a notification when tasks are due or before they are due?" - answer today is no, only the daily digest.
Confirmed working in production: before-due, due-now, and overdue reminders all fired correctly across email, web push, and mobile push, including after a couple of live-testing refinements (delayed the overdue notification by an hour so it does not arrive alongside due-now, and made changing the Default Reminder profile setting retroactively reschedule already-due-dated tasks).
Shipped in commits
5359bf2,f92ce7a(plus the unrelateda27fcc4crash fix for task edits that this testing surfaced along the way).Closing as complete.