Skip to content

Notifications ​

Softly uses a combination of local notifications (scheduled on-device) and push notifications (sent from the backend via Expo Push API).

Local Notifications ​

Task reminders are scheduled locally using expo-notifications. When a task has reminder_days set (e.g. [1, 7]), the mobile app schedules local notifications for 1 day and 7 days before the due date.

Local notifications are re-scheduled whenever:

  • A task is created or updated
  • The app returns to foreground
  • A task is completed (cancels its pending notifications)

The scheduling logic lives in services/notifications.ts.

TIP

Local notifications work offline and don't require the backend. They're the primary reminder mechanism for most users.

Push Notifications ​

Push notifications are used for server-initiated messages that can't be scheduled locally, like the weekly digest.

Device Token Registration ​

On app launch (or when push permissions are granted), the app registers its Expo push token with the backend:

POST /api/v1/device_tokens

Tokens are stored per-user and per-platform. When a user logs out, the token is deactivated:

DELETE /api/v1/device_tokens

Expo Push API ​

The backend sends push notifications via ExpoPushService, which calls the Expo Push API. Push delivery is handled asynchronously via SendPushNotificationJob (Solid Queue).

Weekly Digest ​

Every Sunday, WeeklyDigestJob runs via Solid Queue's cron scheduler (config/recurring.yml). For each user with active device tokens, it:

  1. Counts tasks due in the coming week
  2. Counts overdue tasks
  3. Sends a push notification summarizing the week ahead

Example: "You have 5 tasks this week and 2 overdue. Let's get on top of it!"

Reminder Scheduling ​

Tasks support flexible reminder scheduling via the reminder_days array field:

ValueMeaning
[0]Remind on the due date
[1]Remind 1 day before
[1, 7]Remind 1 day and 7 days before
[0, 1, 7]Remind on due date, 1 day before, and 7 days before

If a task has a due_time set, notifications fire at that time. Otherwise, they default to 9:00 AM local time.

Internal documentation — not for public distribution