Defects fixed: - D1: Fix notification ID range collision (report reminders 700k→2M+) - D2: Streak risk now checks both dzikir pagi & petang - D3: _cancelPrayerPending no longer kills non-prayer notifications - D4: Push notifications carry deeplink in payload for proper routing - D5: Add reconfigureTimeZoneIfNeeded() for TZ change detection - D6: Defer launch notification routing until widget tree is ready Gaps closed: - G1: Add streak risk + weekly summary toggles to settings UI - G2: Verified boot reschedule already in place (flutter_local_notifications v21) - G3: Remove unused mirrorAdzanToInbox field and legacy cleanup calls - G4: Add notif_push_opened analytics tracking - G5: Add notif_settings_changed analytics tracking Enhancements: - O1: Rich notification with Sudah Sholat action button on report reminders - O2: Permission check on app resume via WidgetsBindingObserver (30s throttle) - O2b: Fix stretched notification icon (white crescent moon vector drawable) - O3: Expired inbox cleanup in background sync - O4: Haptic feedback on notification bell quick actions Bump version 1.0.8+9 → 1.1.0+10
6.5 KiB
6.5 KiB
Notification Feature Audit — Tasklist
Source: Full codebase trace of notification system
Date: June 2026
Status legend: [ ] Not started · [~] In progress · [x] Done · [-] Skipped
Defects (Bugs)
D1. Notification ID Range Collision — Adhan vs Report Reminders [SEVERITY: High]
- D1.1 Move report reminder ID range from
700000+to2000000+in_reportReminderId() - D1.2 Update
_cancelPrayerPending()range guard to exclude the new report range explicitly - D1.3 Verify adhan IDs (100k–800k), iqamah IDs (800k–1.5M), report IDs (2M+), non-prayer IDs (900k–980k) are all disjoint
D2. Streak Risk Only Checks Dzikir Petang, Not Pagi [SEVERITY: Medium]
- D2.1 Fix
emitStreakRiskIfNeededto check both!pagiand!petangin dzikir risk logic - D2.2 Emit separate inbox items for pagi vs petang dzikir risk with correct deeplinks
D3. _cancelPrayerPending Cancels Non-Prayer Notifications Too [SEVERITY: Medium]
- D3.1 Narrow the ID range filter to only cancel adhan (100k–799k), iqamah (800k–1.5M), and report (2M+) IDs
- D3.2 Exclude non-prayer range (900k–980k) from cancellation
D4. Notification Tap Routes All Non-Prayer to /notifications Instead of Deep Link [SEVERITY: Medium]
- D4.1 Update
routeForNotificationPayloadto parse deeplink from payload forstreak_risktype - D4.2 Include deeplink in notification payload through
_pushNonPrayer→showNonPrayerAlertchain
D5. Timezone Not Updated on Device TZ Change [SEVERITY: Medium]
- D5.1 Add
reconfigureTimeZoneIfNeeded()method to detect and apply timezone changes - D5.2 Reset
_lastSyncSignatureon TZ change to force prayer notification resync
D6. _handleLaunchNotification May Fire Before Router is Ready [SEVERITY: Low]
- D6.1 Defer launch notification routing — store pending route, consume from
AppState.initStatewith 800ms delay
Gaps (Missing or Incomplete)
G1. No Settings UI for Notification Preferences [SEVERITY: High]
- G1.1 Settings UI already existed — added missing
streakRiskEnabledtoggle to notification group - G1.2 Added
weeklySummaryEnabledtoggle to notification group - G1.3 All other notification settings (alerts, inbox, checklist reminder, quiet hours, push cap) were already present
G2. No Device Reboot Reschedule [SEVERITY: High]
- G2.1 Verified
RECEIVE_BOOT_COMPLETEDpermission in AndroidManifest.xml — already present - G2.2 Verified
ScheduledNotificationReceiverandScheduledNotificationBootReceiver— already declared - G2.3
flutter_local_notificationsv21 handles reboot natively;workmanagerperiodic task resumes viaExistingPeriodicWorkPolicy.update
G3. mirrorAdzanToInbox Setting Exists But Never Used [SEVERITY: Medium]
- G3.1 Removed unused
mirrorAdzanToInboxfield fromAppSettingsand generated adapter - G3.2 Removed legacy
removeByType('prayer')calls frommain.dartandnotification_center_screen.dart
G4. No Analytics for notif_push_opened [SEVERITY: Low]
- G4.1 Added
notif_push_openedtracking in_handleNotificationResponse(foreground) andconsumePendingLaunchRoute(launch)
G5. No Analytics for notif_settings_changed [SEVERITY: Low]
- G5.1 Added
notif_settings_changedtracking in notification bell quick actions toggle
Opportunities (Enhancements)
O1. Rich Notification Actions — "Sudah Sholat" Button on Report Reminders
- O1.1 Added
AndroidNotificationActionwithaction_prayed/ "Sudah Sholat" button to_scheduleShalatReportReminder - O1.2 Background handler (
notificationTapBackgroundHandler) opens Hive and logsShalatLog(completed: true)via_markPrayedFromBackground - O1.3 Foreground handler (
_handleNotificationResponse) logs prayer via_markPrayedFromForeground - O1.4 Added
_resolvePrayerKeyFromNameto map display names back to canonical keys in background isolate
O2. Notification Permission Check on App Resume via WidgetsBindingObserver
- O2.1 Added
_checkNotificationPermissionOnResume()with 30-second throttle to_AppState.didChangeAppLifecycleState - O2.2 Re-checks notification permissions and emits warnings via
emitPermissionWarningsIfNeededon resume
O2b. Fix Stretched Notification Icon
- O2b.1 Created
@drawable/ic_notification— white crescent moon vector drawable (Android notification-safe) - O2b.2 Changed
AndroidInitializationSettingsfrom@mipmap/ic_launcherto@drawable/ic_notification - O2b.3 Added
icon: '@drawable/ic_notification'to all 4 notification channels
O3. Add Expired Item Cleanup to Background Sync
- O3.1 Added
removeExpired()call inBackgroundSyncService.runSyncPass()
O4. Haptic Feedback on Quick Actions
- O4.1 Added
HapticFeedback.selectionClick()to all three notification bell quick action taps
Progress Tracker
| Category | Total | Done | Skipped | Remaining |
|---|---|---|---|---|
| Defects (D1–D6) | 11 | 11 | 0 | 0 |
| Gaps (G1–G5) | 10 | 10 | 0 | 0 |
| Opportunities (O1–O4) | 9 | 9 | 0 | 0 |
| TOTAL | 30 | 30 | 0 | 0 |
Files Changed
| File | Changes |
|---|---|
lib/data/services/notification_service.dart |
D1: ID range fix, D3: cancel range fix, D4: payload routing with deeplink, D5: TZ reconfig, D6: deferred launch routing, O1: rich notification action + background handler, O2b: icon fix |
lib/data/services/notification_event_producer_service.dart |
D2: pagi+petang dzikir streak risk, D4: deeplink threading |
lib/core/widgets/notification_bell_button.dart |
G5: analytics tracking, O4: haptic feedback |
lib/data/services/background_sync_service.dart |
O3: expired inbox cleanup |
lib/features/settings/presentation/settings_screen.dart |
G1: streak risk + weekly summary toggles |
lib/data/local/models/app_settings.dart |
G3: removed mirrorAdzanToInbox field |
lib/data/local/models/app_settings.g.dart |
G3: removed field 32 from adapter |
lib/main.dart |
G3: removed legacy removeByType('prayer') |
lib/features/notifications/presentation/notification_center_screen.dart |
G3: removed legacy cleanup |
lib/app/app.dart |
D6: consume pending launch route on init, O2: permission check on resume |
android/app/src/main/res/drawable/ic_notification.xml |
O2b: white crescent moon vector drawable for notification icon |