Document reminders, offline PWA, and fix missing Celery Beat in deploy guide

API.md: document the reminder/due_soon/overdue notification schedule
(including the due_time-aware is_overdue fix and the 1-hour overdue
delay) and how default_reminder_minutes/reminder_at interact.

README.md: add Offline Support (PWA) and Notifications & Reminders to
the feature list - both were fully functional but never listed. Also
fixes a real gap in the manual systemd deployment guide: it only set
up the Celery worker, never Celery Beat, so the daily digest, recurring
task safety net, and now reminders would never fire for anyone
following that guide.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Keith Smith
2026-09-05 13:27:18 -06:00
co-authored by Claude Sonnet 5
parent f92ce7a3d4
commit 6791f008e9
2 changed files with 55 additions and 5 deletions
+9 -2
View File
@@ -433,7 +433,7 @@ Creates a new task.
| priority | enum | No | `low`, `medium`, `high`, `urgent` | | priority | enum | No | `low`, `medium`, `high`, `urgent` |
| due_date | date | No | YYYY-MM-DD | | due_date | date | No | YYYY-MM-DD |
| due_time | time | No | HH:MM:SS | | due_time | time | No | HH:MM:SS |
| reminder_at | datetime | No | ISO 8601 format | | reminder_at | datetime | No | ISO 8601 format. Overrides the user's `default_reminder_minutes` for this task's "before due" reminder - see Notifications |
| recurrence | enum | No | `none`, `daily`, `weekly`, `biweekly`, `monthly`, `yearly`, `custom` | | recurrence | enum | No | `none`, `daily`, `weekly`, `biweekly`, `monthly`, `yearly`, `custom` |
| recurrence_rule | string | No | RRULE string for custom recurrence | | recurrence_rule | string | No | RRULE string for custom recurrence |
| recurrence_end_date | date | No | End date for recurring tasks | | recurrence_end_date | date | No | End date for recurring tasks |
@@ -469,7 +469,7 @@ Creates a new task.
**Notes:** **Notes:**
- When a recurring task is completed, the next instance is automatically created - When a recurring task is completed, the next instance is automatically created
- `completed_at` is automatically set when `status` changes to `completed` - `completed_at` is automatically set when `status` changes to `completed`
- `is_overdue` is calculated based on user's timezone - `is_overdue` is calculated in the user's timezone; if `due_time` is set, the task becomes overdue once that time passes on `due_date`, otherwise it becomes overdue starting the day after `due_date`
### Get Task Details ### Get Task Details
@@ -949,6 +949,13 @@ Returns notifications for current user.
- `shared` - Task/tag shared with user - `shared` - Task/tag shared with user
- `daily_email` - Daily email digest sent - `daily_email` - Daily email digest sent
**Reminder scheduling:** For any task with `due_date` and `due_time` set, up to three notifications are sent automatically (delivered by email and/or push per the user's `email_notifications`/`push_notifications` settings):
- `reminder` - before due, at `reminder_at` if set on the task, otherwise `default_reminder_minutes` before the due moment
- `due_soon` - exactly at the due moment
- `overdue` - one hour after the due moment (kept separate from `due_soon` so they don't arrive together)
A task with `due_date` but no `due_time` only gets the `overdue` notification, fired at the start of the day after `due_date` (matching `is_overdue`'s day-after rule). Changing `default_reminder_minutes` retroactively reschedules the `reminder` notification on existing active tasks that don't have their own `reminder_at` override; it does not affect tasks whose `reminder_at` was explicitly set.
### Mark Notification as Read ### Mark Notification as Read
**POST** `/api/notifications/{notification_id}/read/` (Authenticated) **POST** `/api/notifications/{notification_id}/read/` (Authenticated)
+46 -3
View File
@@ -43,6 +43,16 @@ A powerful Django-based task management system with time tracking, tag organizat
- **Real-time Updates**: Task changes sync across devices - **Real-time Updates**: Task changes sync across devices
- **Conflict Resolution**: Handles offline changes and syncing - **Conflict Resolution**: Handles offline changes and syncing
### Offline Support (PWA)
- **Installable Web App**: Add to home screen with an offline-capable service worker
- **Full Offline Task Management**: Create, edit, complete tasks, manage subtasks and tags, and track time while offline
- **Automatic Sync**: Offline changes queue locally and sync automatically once back online
### Notifications & Reminders
- **Daily Digest**: Morning email summarizing tasks due today and overdue tasks
- **Per-Task Reminders**: Automatic "before due", "due now", and "overdue" notifications, timed per task
- **Multi-Channel Delivery**: Email, push, or both, per user
## Tech Stack ## Tech Stack
- **Backend**: Django 5.x, Django REST Framework - **Backend**: Django 5.x, Django REST Framework
@@ -830,7 +840,9 @@ sudo systemctl start keepitgoing
sudo systemctl status keepitgoing sudo systemctl status keepitgoing
``` ```
#### Step 6: Celery Service (Optional, for background tasks) #### Step 6: Celery Services (Worker + Beat)
Both services are required - the worker executes tasks, Beat is the scheduler that queues the daily digest, recurring task safety net, and per-task reminders on their configured schedules (see `config/celery.py`).
```bash ```bash
sudo nano /etc/systemd/system/keepitgoing-celery.service sudo nano /etc/systemd/system/keepitgoing-celery.service
@@ -861,6 +873,37 @@ sudo systemctl enable keepitgoing-celery
sudo systemctl start keepitgoing-celery sudo systemctl start keepitgoing-celery
``` ```
Beat runs as its own separate service:
```bash
sudo nano /etc/systemd/system/keepitgoing-celerybeat.service
```
```ini
[Unit]
Description=KeepItGoing Celery Beat
After=network.target redis.service
[Service]
Type=simple
User=keepitgoing
Group=keepitgoing
WorkingDirectory=/home/keepitgoing/KeepItGoingServer
Environment="PATH=/home/keepitgoing/KeepItGoingServer/venv/bin"
Environment="DJANGO_SETTINGS_MODULE=config.settings.production"
EnvironmentFile=/home/keepitgoing/KeepItGoingServer/.env
ExecStart=/home/keepitgoing/KeepItGoingServer/venv/bin/celery -A config beat -l info
[Install]
WantedBy=multi-user.target
```
Enable and start:
```bash
sudo systemctl enable keepitgoing-celerybeat
sudo systemctl start keepitgoing-celerybeat
```
#### Step 7: Nginx Configuration #### Step 7: Nginx Configuration
```bash ```bash
@@ -1016,8 +1059,8 @@ Complete this checklist before going live:
**Services:** **Services:**
- [ ] Set up Gunicorn systemd service - [ ] Set up Gunicorn systemd service
- [ ] Configure nginx as reverse proxy - [ ] Configure nginx as reverse proxy
- [ ] Set up Redis for Celery (if using background tasks) - [ ] Set up Redis for Celery (required for the daily digest, recurring tasks, and reminders)
- [ ] Configure Celery systemd service (if needed) - [ ] Configure both the Celery worker and Celery Beat systemd services - Beat is what fires scheduled tasks, the worker alone won't
- [ ] Verify all services start on boot - [ ] Verify all services start on boot
**Monitoring & Logging:** **Monitoring & Logging:**