hoangsonww / hoangsonww/ToDo-App-NextJS-Fullstack
Feature: Recurring Tasks + Smart Reminders (Web Push) + Calendar Export
- Dominant language
- TypeScript
- Stars
- 27
- Forks
- 18
- PR merge metrics
- No merged PRs in 30d
Description
Feature: Recurring Tasks + Smart Reminders (Web Push) + Calendar Export
**Summary**
Add first-class support for **recurring tasks** (daily/weekly/monthly/custom RRULE), **smart date parsing** (“tomorrow 9am”, “next Fri”, “every 2 weeks”), **reminders** with **Web Push notifications**, and **read-only calendar export (ICS)** so users can see todos in Google/Apple/Outlook calendars.
**Why**
* Core to a to-do app: recurring chores & follow-ups without re-creating items.
* Reminders keep users engaged (desktop/mobile push).
* ICS lets power users view tasks on any calendar.
---
## Scope (MVP)
**UX**
* Create/Edit task:
* Fields: `Due date & time`, `Repeat` (None/Daily/Weekly/Monthly/Custom…), `Reminder` (None/At due time/5/10/30/60 min before), `Timezone`.
* Natural language quick-add: “pay rent every month on the 1st at 9am”, “standup weekdays 9:15”.
* Task list badges for recurrence; “Skip this occurrence” from task menu.
* Settings → “Enable desktop notifications” (request permission) + test notification.
* Public ICS URL per user (read-only).
**Data Model**
> Use whichever store is active (SQLite/Mongo). Migrate both if both are supported.
* `tasks` (existing): add
* `due_at` DATETIME/ISO
* `timezone` TEXT (IANA, default browser guessed)
* `recurrence_rule` TEXT (RFC 5545 RRULE string; `NULL` if one-off)
* `remind_minutes_before` INT (nullable, 0 for at due time)
* `parent_task_id` (nullable; for occurrence exceptions like “skip”)
* `push_subscriptions` (per user)
* `id`, `user_id`, `endpoint`, `p256dh`, `auth`, `created_at`
* `ics_tokens`
* `user_id`, `token` (random 32B), `created_at`, `revoked_at`
**APIs (Next.js Route Handlers under `/app/api`)**
* `POST /api/push/subscribe` – save Web Push subscription (VAPID).
* `DELETE /api/push/subscribe` – remove subscription.
* `GET /api/calendar.ics?token=...` – serve user’s tasks as ICS (all open + upcoming).
* Extend `/api/todos` CRUD to accept/return `due_at`, `timezone`, `recurrence_rule`, `remind_minutes_before`.
* Internal scheduled endpoint: `POST /api/_cron/send-reminders` – finds due reminders and delivers Web Push (idempotent, batched).
**Scheduling**
* Use **Vercel Cron** (or your existing Jenkins/NGINX/compose cron if self-hosting) to call `/api/_cron/send-reminders` every minute.
* Reminder query window: now … now+1m; mark sent to avoid duplicates.
**Smart Parsing**
* Client-side parse quick-add text with a lightweight parser (e.g., chrono-node) to suggest `due_at` and common recurrences (Daily/Weekdays/Weekly on X).
* For custom recurrence, store as RRULE (e.g., `FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR`).
* Server validates/normalizes timezone + RRULE.
**Web Push**
* Generate VAPID keys once; store as env:
* `VAPID_PUBLIC_KEY`, `VAPID_PRIVATE_KEY`, `VAPID_SUBJECT`
* Use `web-push` to send notifications.
* Message format: title = task title, body = “Due in X min” or “Due now”, click → app opens task.
**Calendar (ICS)**
* Tokenized, read-only URL (`/api/calendar.ics?token=...`), rotating token in Settings.
* Expand recurring tasks into instances for the next 90 days (server side; avoid huge feeds).
* Include `VALARM` for reminder if set.
**Permissions & Security**
* ICS token scoped to user; no auth header needed; easy revoke/regenerate.
* Push endpoints require auth; store subs per user.
* Server-side validation of RRULE and fencepost times in user timezone.
**Out of Scope (MVP)**
* Mobile native push; snooze from notification (can add later).
* Complex exceptions editing UI (support “skip this occurrence” only).
---
## Acceptance Criteria
* Can create/edit tasks with due date/time, optional recurrence, and reminder.
* Natural language quick-add fills fields correctly for common phrases.
* Reminders fire reliably via Web Push when browser permission granted.
* ICS URL imports in Google/Apple/Outlook and shows future recurring instances.
* “Skip this occurrence” prevents one occurrence without deleting series.
* API & UI validated with unit/integration tests; no duplicate notifications.
* Works with existing WebSockets updates to reflect upcoming due states.
---
## Implementation Notes
**Frontend (Next.js App Router, TS, MUI)**
* New components: `RecurrencePicker`, `ReminderSelect`, `TimezoneSelect`, `QuickAddInput`.
* Store push subscription on login or when toggled in Settings (`Notification.requestPermission()` → `pushManager.subscribe({ applicationServerKey: VAPID_PUBLIC_KEY })`).
* Feature flag if notifications denied.
* Use WebSocket channel to reflect “due soon” badges in real time.
**Backend (Route Handlers)**
* Extend todo DTOs + validation.
* Utilities:
* RRULE parsing (use `rrule` package server-side if allowed)
* Occurrence expansion (next N instances or range)
* Reminder finder: for each task with reminder, compute trigger time = `due_at - remind_minutes_before`.
* `/api/_cron/send-reminders`:
* Query tasks with upcoming triggers in \[now, now+60s] for each timezone correctly.
* Send push to all user subscriptions; mark `reminder_sent_at` per occurrence key (taskId+occurrenceDateTime).
* ICS generator: `text/calendar` response; cache for 60s; expand recurrences 90 days ahead.
**Migrations**
* Add columns to `tasks`; create `push_subscriptions`, `ics_tokens`.
* Backfill: set `timezone` from guessed default for existing tasks (optional).
**Testing**
* Unit: RRULE expansion (daily/weekly/monthly, edge cases like month-end), reminder math, ICS rendering.
* Integration: create recurring task → ICS contains events; cron endpoint sends a push; quick-add parses “next fri 9am”.
* E2E (light): create task with reminder; wait for mock push.
**Perf**
* Index `due_at`, `(user_id, due_at)`, `(user_id, reminder_at)` (if materialized).
* Batch Web Push sends; handle 410 Gone to prune dead subscriptions.
---
## Tasks
* [ ] DB migrations (tasks cols, push\_subscriptions, ics\_tokens)
* [ ] Extend `/api/todos` CRUD + validation
* [ ] Add `/api/push/subscribe` & unsubscribe
* [ ] Add `/api/calendar.ics` + token generation/rotation in Settings
* [ ] Implement `/api/_cron/send-reminders` + Vercel Cron (or alt)
* [ ] Frontend UI (create/edit form, quick-add, settings toggle)
* [ ] Web Push wiring (VAPID keys, service worker registration)
* [ ] “Skip this occurrence” action (store exception)
* [ ] Tests (unit + integration + minimal e2e)
* [ ] Docs update (README + .env examples + screenshots)
**Env Vars**
```
VAPID_PUBLIC_KEY=
VAPID_PRIVATE_KEY=
VAPID_SUBJECT=mailto:you@example.com
ICS_SIGNING_SECRET=
```
---
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.