Summary
Let users set recurring tasks (daily/weekly/monthly/custom RRULE) with smart reminders and NLP quick-add. Deliver Expo push notifications with actions (Complete / Snooze), sync via Supabase, and respect user time zones.
Why
- Core task app need: habits, bills, routines.
- Reduces churn: timely nudges → completion.
- “Type what you think” quick-add is a delight on mobile.
Scope (MVP)
UX
-
Quick-add understands:
pay rent every month on the 1st at 9am remind 1d
water plants every sat 10am, review PRs daily 5pm remind 15m
(Use chrono-node for parsing date/time; simple keywords for repeats/reminders.)
-
Task editor: Recurrence (None/Daily/Weekly/Monthly/Custom), Time zone, Reminder offsets (e.g., 1d, 1h, 15m).
-
Push notification with actions: Complete, Snooze 1h (deep links to the task).
-
One-off reminders for non-recurring tasks supported with same UI.
Data (Supabase)
-- store Expo push tokens
create table if not exists public.user_devices (
id uuid primary key default gen_random_uuid(),
user_id uuid not null references auth.users(id) on delete cascade,
expo_push_token text not null unique,
platform text check (platform in ('ios','android','web')) default 'ios',
created_at timestamptz not null default now()
);
-- extend tasks
alter table public.tasks
add column if not exists recurrence_rrule text, -- e.g., FREQ=MONTHLY;BYMONTHDAY=1;BYHOUR=9;BYMINUTE=0
add column if not exists tz text not null default 'UTC', -- IANA tz
add column if not exists reminder_offsets_min int[] not null default '{30}', -- minutes before due
add column if not exists snoozed_until timestamptz; -- nullable
RLS
alter table public.user_devices enable row level security;
create policy device_owner
on public.user_devices for all
using (auth.uid() = user_id) with check (auth.uid() = user_id);
-- tasks table already owner-scoped; ensure same pattern for new columns
Server (Supabase Edge Functions + Scheduler)
-
register-device: upsert expo_push_token for current user.
-
dispatch-reminders (runs every minute via Supabase Scheduler):
- Find tasks where any
due_date - offset ∈ now()..now()+1m, considering tz and snoozed_until.
- Send push via Expo API to all
user_devices for that user.
- Include actions payload
{action:'complete'|'snooze', taskId}.
-
notification-action (HTTP): handles action callback updates (complete task / set snoozed_until = now()+interval '1 hour').
Client (React Native / Expo)
- On first launch (and Settings): request notifications permission, get Expo push token, call
register-device.
- Quick-add input: try parser → build
recurrence_rrule, due_date, reminder_offsets_min. Fallback to structured form.
- Deep link handling: navigate to task; apply action if present.
- Stats screen should reflect completions triggered from notifications in real-time.
Acceptance Criteria
- User can create a recurring task with reminders via quick-add or editor.
- Devices receive a push at each reminder time; tapping Complete marks the task done; Snooze 1h sets
snoozed_until and reschedules.
- Time zones honored; changing
tz updates next occurrence correctly.
- Non-recurring tasks can have single reminders.
- Tokens are stored per device; removing app revokes token on next failed send.
- All operations respect RLS (no cross-user leakage).
Implementation Notes
- RRULE: use
rrule JS lib to compute next_due_at client-side; persist canonical RRULE in recurrence_rrule.
- Parsing:
chrono-node for date/time; simple regex for every|daily|weekly|monthly and remind <N><m|h|d>.
- Expo:
expo-notifications for token + handling responses; on Android, add notification categories for actions.
- Scheduler: Supabase Scheduled Functions cron
* * * * * to call dispatch-reminders. Batch sends.
Tasks
Summary
Let users set recurring tasks (daily/weekly/monthly/custom RRULE) with smart reminders and NLP quick-add. Deliver Expo push notifications with actions (Complete / Snooze), sync via Supabase, and respect user time zones.
Why
Scope (MVP)
UX
Quick-add understands:
pay rent every month on the 1st at 9am remind 1dwater plants every sat 10am,review PRs daily 5pm remind 15m(Use
chrono-nodefor parsing date/time; simple keywords for repeats/reminders.)Task editor: Recurrence (None/Daily/Weekly/Monthly/Custom), Time zone, Reminder offsets (e.g., 1d, 1h, 15m).
Push notification with actions: Complete, Snooze 1h (deep links to the task).
One-off reminders for non-recurring tasks supported with same UI.
Data (Supabase)
RLS
Server (Supabase Edge Functions + Scheduler)
register-device: upsertexpo_push_tokenfor current user.dispatch-reminders(runs every minute via Supabase Scheduler):due_date - offset∈ now()..now()+1m, consideringtzandsnoozed_until.user_devicesfor that user.{action:'complete'|'snooze', taskId}.notification-action(HTTP): handles action callback updates (complete task / setsnoozed_until = now()+interval '1 hour').Client (React Native / Expo)
register-device.recurrence_rrule,due_date,reminder_offsets_min. Fallback to structured form.Acceptance Criteria
snoozed_untiland reschedules.tzupdates next occurrence correctly.Implementation Notes
rruleJS lib to computenext_due_atclient-side; persist canonical RRULE inrecurrence_rrule.chrono-nodefor date/time; simple regex forevery|daily|weekly|monthlyandremind <N><m|h|d>.expo-notificationsfor token + handling responses; on Android, add notification categories for actions.* * * * *to calldispatch-reminders. Batch sends.Tasks
user_devices+ RLS).register-device,dispatch-reminders,notification-action.