docs(04): capture phase context
This commit is contained in:
97
.planning/phases/04-notifications/04-CONTEXT.md
Normal file
97
.planning/phases/04-notifications/04-CONTEXT.md
Normal file
@@ -0,0 +1,97 @@
|
||||
# Phase 4: Notifications - Context
|
||||
|
||||
**Gathered:** 2026-03-16
|
||||
**Status:** Ready for planning
|
||||
|
||||
<domain>
|
||||
## Phase Boundary
|
||||
|
||||
Users receive a daily summary notification reminding them of today's task count, and can control notification behavior from settings. Delivers: daily summary notification with configurable time, enable/disable toggle in Settings, Android POST_NOTIFICATIONS permission handling (API 33+), RECEIVE_BOOT_COMPLETED rescheduling, and graceful degradation when permission is denied.
|
||||
|
||||
Requirements: NOTF-01, NOTF-02
|
||||
|
||||
</domain>
|
||||
|
||||
<decisions>
|
||||
## Implementation Decisions
|
||||
|
||||
### Notification timing
|
||||
- **User-configurable time** via time picker in Settings, stored in SharedPreferences
|
||||
- **Default time: 07:00** — early morning, user sees notification when they wake up
|
||||
- **Notifications disabled by default** on fresh install — user explicitly opts in from Settings
|
||||
- **Skip notification on zero-task days** — no notification fires when there are no tasks due (overdue + today). Only notifies when there's something to do
|
||||
|
||||
### Notification content
|
||||
- **Body shows task count with conditional overdue split**: when overdue tasks exist, body reads e.g. "5 Aufgaben fällig (2 überfällig)". When no overdue, just "5 Aufgaben fällig"
|
||||
- **Overdue count only shown when > 0** — cleaner on days with no overdue tasks
|
||||
- **Tapping the notification opens the daily plan (Home tab)** — direct path to action
|
||||
- All notification text from ARB localization files
|
||||
|
||||
### Permission flow
|
||||
- **Permission requested when user toggles notifications ON** in Settings (Android 13+ / API 33+). Natural flow: user explicitly wants notifications, so the request is contextual
|
||||
- **On permission denial**: Claude's discretion on UX (inline hint vs dialog), but toggle reverts to OFF
|
||||
- **On re-enable after prior denial**: app detects permanently denied state and guides user to system notification settings (not just re-requesting)
|
||||
- **Android 12 and below**: same opt-in flow — user must enable in Settings even though no runtime permission is needed. Consistent UX across all API levels
|
||||
- **RECEIVE_BOOT_COMPLETED**: notifications reschedule after device reboot if enabled
|
||||
|
||||
### Settings UI layout
|
||||
- **New "Benachrichtigungen" section** between Darstellung and Über — follows the existing grouped section pattern
|
||||
- **Toggle + time picker**: SwitchListTile for enable/disable. When enabled, time picker row appears below (progressive disclosure). When disabled, time picker row is hidden
|
||||
- **Material 3 time picker dialog** (`showTimePicker()`) for selecting notification time — consistent with the app's M3 design language
|
||||
- **Section header** styled identically to existing "Darstellung" and "Über" headers (primary-colored titleMedium)
|
||||
|
||||
### Claude's Discretion
|
||||
- Notification title (app name vs contextual like "Dein Tagesplan")
|
||||
- Permission denial UX (inline hint vs dialog — pick best approach)
|
||||
- SwitchListTile + time picker row layout details (progressive disclosure animation, spacing)
|
||||
- Notification channel configuration (importance, sound, vibration)
|
||||
- Exact notification icon
|
||||
- Boot receiver implementation approach
|
||||
|
||||
</decisions>
|
||||
|
||||
<specifics>
|
||||
## Specific Ideas
|
||||
|
||||
- Notification should respect the calm aesthetic — informative, not alarming. Even with overdue count, the tone should be helpful not stressful
|
||||
- The Settings section should feel like a natural extension of the existing screen — same section header style, same spacing, same widget patterns
|
||||
- Skip-on-zero-tasks means the notification is genuinely useful every time it appears — no noise on free days
|
||||
- Permission flow should feel seamless: toggle ON → permission dialog → if granted, schedule immediately. User shouldn't need to toggle twice
|
||||
|
||||
</specifics>
|
||||
|
||||
<code_context>
|
||||
## Existing Code Insights
|
||||
|
||||
### Reusable Assets
|
||||
- `DailyPlanDao` (`lib/features/home/data/daily_plan_dao.dart`): Has `watchAllTasksWithRoomName()` stream query — notification service needs a similar one-shot query for task count (overdue + today)
|
||||
- `ThemeProvider` (`lib/core/theme/theme_provider.dart`): AsyncNotifier with SharedPreferences persistence — template for notification settings provider (enabled boolean + TimeOfDay)
|
||||
- `SettingsScreen` (`lib/features/settings/presentation/settings_screen.dart`): ListView with grouped sections and Dividers — notification section slots in between Darstellung and Über
|
||||
- `app_de.arb` (`lib/l10n/app_de.arb`): 92 existing localization keys — needs notification-related strings (toggle label, time label, permission hint, notification body templates)
|
||||
|
||||
### Established Patterns
|
||||
- **Riverpod 3 code generation**: `@riverpod` annotation + `.g.dart` files. Functional providers for reads, class-based AsyncNotifier for mutations
|
||||
- **SharedPreferences for user settings**: ThemeProvider uses `SharedPreferences` with `ref.onDispose` — same pattern for notification preferences
|
||||
- **Manual StreamProvider**: Used for drift queries that hit riverpod_generator type issues — may apply to notification-related queries
|
||||
- **ARB localization**: All UI strings from `AppLocalizations.of(context)` — notification strings follow same pattern
|
||||
- **Material 3 theming**: All colors via `Theme.of(context).colorScheme`
|
||||
|
||||
### Integration Points
|
||||
- Settings screen: new section added to existing `SettingsScreen` widget between Darstellung and Über sections
|
||||
- Notification service queries same task data as `DailyPlanDao` (tasks table with nextDueDate)
|
||||
- AndroidManifest.xml: needs POST_NOTIFICATIONS permission, RECEIVE_BOOT_COMPLETED permission, and boot receiver declaration
|
||||
- pubspec.yaml: needs `flutter_local_notifications` (or similar) package added
|
||||
|
||||
</code_context>
|
||||
|
||||
<deferred>
|
||||
## Deferred Ideas
|
||||
|
||||
None — discussion stayed within phase scope
|
||||
|
||||
</deferred>
|
||||
|
||||
---
|
||||
|
||||
*Phase: 04-notifications*
|
||||
*Context gathered: 2026-03-16*
|
||||
Reference in New Issue
Block a user