Files
jamshalat-diary/docs/notification-audit-tasklist.md
Dwindi Ramadhana 4badfb6521 Notification system audit: fix 6 defects, close 5 gaps, add rich notifications (v1.1.0)
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
2026-06-06 22:38:02 +07:00

112 lines
6.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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]`
- [x] **D1.1** Move report reminder ID range from `700000+` to `2000000+` in `_reportReminderId()`
- [x] **D1.2** Update `_cancelPrayerPending()` range guard to exclude the new report range explicitly
- [x] **D1.3** Verify adhan IDs (100k800k), iqamah IDs (800k1.5M), report IDs (2M+), non-prayer IDs (900k980k) are all disjoint
### D2. Streak Risk Only Checks Dzikir Petang, Not Pagi `[SEVERITY: Medium]`
- [x] **D2.1** Fix `emitStreakRiskIfNeeded` to check both `!pagi` and `!petang` in dzikir risk logic
- [x] **D2.2** Emit separate inbox items for pagi vs petang dzikir risk with correct deeplinks
### D3. `_cancelPrayerPending` Cancels Non-Prayer Notifications Too `[SEVERITY: Medium]`
- [x] **D3.1** Narrow the ID range filter to only cancel adhan (100k799k), iqamah (800k1.5M), and report (2M+) IDs
- [x] **D3.2** Exclude non-prayer range (900k980k) from cancellation
### D4. Notification Tap Routes All Non-Prayer to `/notifications` Instead of Deep Link `[SEVERITY: Medium]`
- [x] **D4.1** Update `routeForNotificationPayload` to parse deeplink from payload for `streak_risk` type
- [x] **D4.2** Include deeplink in notification payload through `_pushNonPrayer``showNonPrayerAlert` chain
### D5. Timezone Not Updated on Device TZ Change `[SEVERITY: Medium]`
- [x] **D5.1** Add `reconfigureTimeZoneIfNeeded()` method to detect and apply timezone changes
- [x] **D5.2** Reset `_lastSyncSignature` on TZ change to force prayer notification resync
### D6. `_handleLaunchNotification` May Fire Before Router is Ready `[SEVERITY: Low]`
- [x] **D6.1** Defer launch notification routing — store pending route, consume from `AppState.initState` with 800ms delay
---
## Gaps (Missing or Incomplete)
### G1. No Settings UI for Notification Preferences `[SEVERITY: High]`
- [x] **G1.1** Settings UI already existed — added missing `streakRiskEnabled` toggle to notification group
- [x] **G1.2** Added `weeklySummaryEnabled` toggle to notification group
- [x] **G1.3** All other notification settings (alerts, inbox, checklist reminder, quiet hours, push cap) were already present
### G2. No Device Reboot Reschedule `[SEVERITY: High]`
- [x] **G2.1** Verified `RECEIVE_BOOT_COMPLETED` permission in AndroidManifest.xml — already present
- [x] **G2.2** Verified `ScheduledNotificationReceiver` and `ScheduledNotificationBootReceiver` — already declared
- [x] **G2.3** `flutter_local_notifications` v21 handles reboot natively; `workmanager` periodic task resumes via `ExistingPeriodicWorkPolicy.update`
### G3. `mirrorAdzanToInbox` Setting Exists But Never Used `[SEVERITY: Medium]`
- [x] **G3.1** Removed unused `mirrorAdzanToInbox` field from `AppSettings` and generated adapter
- [x] **G3.2** Removed legacy `removeByType('prayer')` calls from `main.dart` and `notification_center_screen.dart`
### G4. No Analytics for `notif_push_opened` `[SEVERITY: Low]`
- [x] **G4.1** Added `notif_push_opened` tracking in `_handleNotificationResponse` (foreground) and `consumePendingLaunchRoute` (launch)
### G5. No Analytics for `notif_settings_changed` `[SEVERITY: Low]`
- [x] **G5.1** Added `notif_settings_changed` tracking in notification bell quick actions toggle
---
## Opportunities (Enhancements)
### O1. Rich Notification Actions — "Sudah Sholat" Button on Report Reminders
- [x] **O1.1** Added `AndroidNotificationAction` with `action_prayed` / "Sudah Sholat" button to `_scheduleShalatReportReminder`
- [x] **O1.2** Background handler (`notificationTapBackgroundHandler`) opens Hive and logs `ShalatLog(completed: true)` via `_markPrayedFromBackground`
- [x] **O1.3** Foreground handler (`_handleNotificationResponse`) logs prayer via `_markPrayedFromForeground`
- [x] **O1.4** Added `_resolvePrayerKeyFromName` to map display names back to canonical keys in background isolate
### O2. Notification Permission Check on App Resume via WidgetsBindingObserver
- [x] **O2.1** Added `_checkNotificationPermissionOnResume()` with 30-second throttle to `_AppState.didChangeAppLifecycleState`
- [x] **O2.2** Re-checks notification permissions and emits warnings via `emitPermissionWarningsIfNeeded` on resume
### O2b. Fix Stretched Notification Icon
- [x] **O2b.1** Created `@drawable/ic_notification` — white crescent moon vector drawable (Android notification-safe)
- [x] **O2b.2** Changed `AndroidInitializationSettings` from `@mipmap/ic_launcher` to `@drawable/ic_notification`
- [x] **O2b.3** Added `icon: '@drawable/ic_notification'` to all 4 notification channels
### O3. Add Expired Item Cleanup to Background Sync
- [x] **O3.1** Added `removeExpired()` call in `BackgroundSyncService.runSyncPass()`
### O4. Haptic Feedback on Quick Actions
- [x] **O4.1** Added `HapticFeedback.selectionClick()` to all three notification bell quick action taps
---
## Progress Tracker
| Category | Total | Done | Skipped | Remaining |
|----------|-------|------|---------|------------|
| Defects (D1D6) | 11 | 11 | 0 | 0 |
| Gaps (G1G5) | 10 | 10 | 0 | 0 |
| Opportunities (O1O4) | 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 |