diff --git a/API.md b/API.md index e4626a9..3e2f5aa 100644 --- a/API.md +++ b/API.md @@ -433,7 +433,7 @@ Creates a new task. | priority | enum | No | `low`, `medium`, `high`, `urgent` | | due_date | date | No | YYYY-MM-DD | | 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_rule | string | No | RRULE string for custom recurrence | | recurrence_end_date | date | No | End date for recurring tasks | @@ -469,7 +469,7 @@ Creates a new task. **Notes:** - When a recurring task is completed, the next instance is automatically created - `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 @@ -949,6 +949,13 @@ Returns notifications for current user. - `shared` - Task/tag shared with user - `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 **POST** `/api/notifications/{notification_id}/read/` (Authenticated) diff --git a/README.md b/README.md index 36cf610..06c0eb9 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,16 @@ A powerful Django-based task management system with time tracking, tag organizat - **Real-time Updates**: Task changes sync across devices - **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 - **Backend**: Django 5.x, Django REST Framework @@ -830,7 +840,9 @@ sudo systemctl start 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 sudo nano /etc/systemd/system/keepitgoing-celery.service @@ -861,6 +873,37 @@ sudo systemctl enable 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 ```bash @@ -1016,8 +1059,8 @@ Complete this checklist before going live: **Services:** - [ ] Set up Gunicorn systemd service - [ ] Configure nginx as reverse proxy -- [ ] Set up Redis for Celery (if using background tasks) -- [ ] Configure Celery systemd service (if needed) +- [ ] Set up Redis for Celery (required for the daily digest, recurring tasks, and reminders) +- [ ] 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 **Monitoring & Logging:**