Files
jamshalat-diary/docs/notification-plan.md
2026-03-18 00:07:10 +07:00

7.5 KiB

Notification Plan (Alerts + Inbox)

Last updated: 2026-03-16 Owner: Product + Mobile Scope: jamshalat_diary (Flutter)

Implementation Status (2026-03-17)

  • Phase 1: Implemented.
  • Phase 2: Implemented (Notification Center + unread badge + inbox persistence).
  • Phase 3: Implemented (daily checklist reminder scheduling, streak-risk messages, weekly summary, quiet-hours and daily cap preferences).
  • Phase 4: Partially implemented via remote-content sync and remote-push ingestion bridge.
  • External pending for full Phase 4: SDK/provider wiring (FCM/APNs credentials, token registration, backend push dispatch).

1. Problem Statement

Current app has mixed meaning for "notification":

  • Device push alert (time-sensitive, appears in system drawer)
  • In-app message feed (read-later information)

This causes unclear UX around the bell icon and settings.

2. Product Model

Split into two clear products:

  1. Alerts (Pemberitahuan)
  • Time-sensitive pushes to OS notification drawer.
  • Can ring/vibrate.
  • Expire quickly.
  1. Inbox (Pesan)
  • In-app list of messages user can read later.
  • Has read/unread state.
  • No mandatory sound.

Default rule:

  • Push only: urgent + expiring event.
  • Inbox only: informational/non-urgent event.
  • Push + Inbox: important event that also needs follow-up context.

3. Terminology (User-Facing)

  • Bell icon label/context: Pemberitahuan
  • Notification center tabs:
    • Alarm (alert history + system-triggered items)
    • Pesan (inbox/read-later)

4. Event Policy Matrix

Event Push Drawer Inbox Sound Expiry
Adzan time entered Yes Optional (off by default) Yes At end of prayer window
Iqamah reminder Yes No Yes At iqamah time
Next prayer in 10 minutes Optional No Soft At prayer start
Daily checklist reminder Yes (if enabled) No Optional End of day
Streak at risk (Tilawah/Dzikir) Optional Yes No End of day
Weekly worship summary No Yes No 7 days
Permission blocked (notif/exact alarm/location) Yes Yes No When resolved
Schedule/location stale Yes Yes No When resolved
New app content (Doa/Hadits) No Yes No 30 days

5. Architecture

5.1 Channels

  • Local scheduled alerts (already started in app): Adzan + Iqamah.
  • In-app inbox storage (new): persisted read/unread messages.
  • Remote push (future): FCM/APNs for server-driven campaigns/events.

5.2 Data Sources

  • Prayer schedules: MyQuranSholatService.
  • User prefs: AppSettings + new notification preference model.
  • Device status: notification permission, exact alarm permission, location service.

5.3 Decision Engine

Input:

  • event type
  • urgency
  • TTL
  • user preferences
  • cooldown/frequency cap

Output:

  • deliver to push, inbox, or both.

Pseudo rule:

if event.isTimeCritical && event.ttlShort:
  push
if event.needsFollowUp || event.referenceContent:
  inbox
if event.push && event.inboxPolicy == mirror:
  push + inbox

6. Data Model

6.1 Inbox Item (Hive)

Suggested new box: notification_inbox

{
  "id": "uuid",
  "type": "streak_risk | summary | system | content | prayer",
  "title": "string",
  "body": "string",
  "createdAt": "iso8601",
  "expiresAt": "iso8601|null",
  "readAt": "iso8601|null",
  "isPinned": false,
  "deeplink": "/route/path",
  "meta": {
    "cityId": "string|null",
    "prayerKey": "fajr|dhuhr|asr|maghrib|isha|null",
    "date": "yyyy-MM-dd|null"
  },
  "source": "local|remote",
  "dedupeKey": "string"
}

6.2 Preferences

Use existing AppSettings for:

  • adhanEnabled (per prayer)
  • iqamahOffset (per prayer)

Add new fields (either in AppSettings or separate box):

  • alertsEnabled (global)
  • inboxEnabled (global)
  • streakRiskEnabled
  • dailyChecklistReminderEnabled
  • weeklySummaryEnabled
  • quietHoursStart / quietHoursEnd
  • maxNonPrayerPushPerDay (default 2)

6.3 Badge Source

  • Bell badge count = unread inbox count only.
  • Do not include "already fired system push" count.

7. Local Notification Spec (Current + Next)

7.1 Channels

  • adhan_channel: max importance, sound on.
  • iqamah_channel: high importance, sound on.
  • Later:
    • habit_channel (streak/checklist)
    • system_channel (permission/location)

7.2 Permission Strategy

  • Request POST_NOTIFICATIONS and exact alarm capability only when needed.
  • If denied:
    • create Inbox warning item
    • show non-blocking UI notice

7.3 Scheduling Rules

  • Keep 2-day rolling window (today + tomorrow).
  • Resync on:
    • app start
    • city change
    • prayer settings change
    • adzan toggle change
    • daily boundary change (00:05 local)
  • Deduplicate by key: cityId + date + prayer + kind(adhan/iqamah).

8. UX Specification

8.1 Bell Icon

  • Tap action: open Notification Center.
  • Badge: unread inbox count.
  • Long-press (optional): quick actions
    • toggle Alarm Sholat
    • open Iqamah settings
    • sync now

8.2 Notification Center Screen

Tabs:

  • Alarm
    • recent fired alerts (read-only timeline, optional v2)
  • Pesan
    • unread/read list with filters (Semua, Belum Dibaca, Sistem)

Item actions:

  • Tap: open deeplink target.
  • Swipe: mark read/unread.
  • Optional: pin important item.

8.3 Copy Guidelines

  • Urgent: concise, action-first.
  • Inbox: context-rich but short (max ~120 chars body preview).
  • Prayer push examples:
    • Adzan • Subuh
    • Waktu sholat Subuh telah masuk.
  • Permission blocked -> /settings (notifications section)
  • Location disabled -> /settings or location setup section
  • Streak risk Tilawah -> /quran
  • Streak risk Dzikir -> /tools/dzikir
  • Weekly summary -> /laporan
  • Prayer event details -> / (Beranda)

10. Analytics

Track:

  • notif_push_scheduled
  • notif_push_fired
  • notif_push_opened
  • notif_inbox_created
  • notif_inbox_opened
  • notif_mark_read
  • notif_settings_changed
  • notif_permission_denied

Dimensions:

  • event_type
  • channel (push|inbox|both)
  • city_id
  • simple_mode

11. Rollout Plan

Phase 1 (Now)

  • Stabilize prayer alerts (Adzan + Iqamah) local scheduling.
  • Working sound toggle in hero card and settings.
  • Permission and exact-alarm checks.

Phase 2

  • Build Notification Center page + unread badge.
  • Add inbox persistence and read/unread actions.
  • Add system warning messages to inbox.

Phase 3

  • Add non-prayer reminders (checklist, streak risk, weekly summary).
  • Add cooldown/frequency cap and quiet hours.

Phase 4

  • Remote push integration (FCM/APNs).
  • Server-defined campaigns/content updates.

12. Acceptance Criteria

  • Toggling adzan off removes all pending adzan/iqamah notifications.
  • Toggling adzan on schedules valid upcoming notifications for enabled prayers.
  • Changing iqamah minutes updates future scheduled iqamah alerts immediately.
  • Bell opens Notification Center (after Phase 2).
  • Unread badge count reflects inbox unread only.
  • No duplicate notifications for same prayer/time/city.

13. QA Checklist

  • Android 13/14: permission denied -> graceful fallback.
  • Exact alarm disabled -> user warning path works.
  • Timezone changes -> schedule recalculates correctly.
  • Day rollover -> next-day notifications still present.
  • City changes -> old city schedules removed; new city schedules added.
  • Device reboot (future): optional reschedule receiver if needed.

14. Open Decisions

  1. Should adzan events be mirrored into inbox by default?
  2. Should quiet hours suppress non-prayer push only, or all push except adzan?
  3. Should Alarm tab show only fired events or also pending schedule preview?