From f2e1d715f4b0addb916db6a9a1c33a2951303dc1 Mon Sep 17 00:00:00 2001 From: Jean-Luc Makiola Date: Sun, 15 Mar 2026 19:42:30 +0100 Subject: [PATCH] docs(01-foundation): create phase plan --- .planning/ROADMAP.md | 7 +- .planning/phases/01-foundation/01-01-PLAN.md | 287 ++++++++++++++++ .planning/phases/01-foundation/01-02-PLAN.md | 328 +++++++++++++++++++ 3 files changed, 620 insertions(+), 2 deletions(-) create mode 100644 .planning/phases/01-foundation/01-01-PLAN.md create mode 100644 .planning/phases/01-foundation/01-02-PLAN.md diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 2788094..08db0ec 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -29,7 +29,10 @@ Decimal phases appear between their surrounding integers in numeric order. 3. All UI strings are loaded from ARB localization files — no hardcoded German text in Dart code 4. The Drift database opens on first launch with schemaVersion 1 and the migration workflow is established (drift_dev make-migrations runs without errors) 5. riverpod_lint is active and flags ref.watch usage outside build() as an analysis error -**Plans**: TBD +**Plans**: 2 plans +Plans: +- [ ] 01-01-PLAN.md — Scaffold Flutter project and build core infrastructure (database, providers, theme, localization) +- [ ] 01-02-PLAN.md — Navigation shell, placeholder screens, Settings, and full app wiring ### Phase 2: Rooms and Tasks **Goal**: Users can create and manage rooms and tasks, mark tasks done, and trust the app to schedule the next occurrence automatically @@ -77,7 +80,7 @@ Note: Phase 4 depends on Phase 2 (needs scheduling data) but can be developed in | Phase | Plans Complete | Status | Completed | |-------|----------------|--------|-----------| -| 1. Foundation | 0/TBD | Not started | - | +| 1. Foundation | 0/2 | Planning complete | - | | 2. Rooms and Tasks | 0/TBD | Not started | - | | 3. Daily Plan and Cleanliness | 0/TBD | Not started | - | | 4. Notifications | 0/TBD | Not started | - | diff --git a/.planning/phases/01-foundation/01-01-PLAN.md b/.planning/phases/01-foundation/01-01-PLAN.md new file mode 100644 index 0000000..37988cb --- /dev/null +++ b/.planning/phases/01-foundation/01-01-PLAN.md @@ -0,0 +1,287 @@ +--- +phase: 01-foundation +plan: 01 +type: execute +wave: 1 +depends_on: [] +files_modified: + - pubspec.yaml + - analysis_options.yaml + - build.yaml + - l10n.yaml + - lib/main.dart + - lib/core/database/database.dart + - lib/core/providers/database_provider.dart + - lib/core/theme/app_theme.dart + - lib/core/theme/theme_provider.dart + - lib/l10n/app_de.arb +autonomous: true +requirements: + - FOUND-01 + - FOUND-02 + - FOUND-03 + - THEME-01 + - THEME-02 + +must_haves: + truths: + - "Drift database opens on first launch with schemaVersion 1" + - "drift_dev make-migrations runs without errors and captures schema v1" + - "Riverpod providers generate via build_runner without errors" + - "riverpod_lint is active and dart analyze reports no issues" + - "ARB localization file exists with all German strings for Phase 1" + - "Light and dark ColorScheme definitions use sage green seed with warm surface overrides" + - "ThemeMode provider defaults to system and supports light/dark/system switching" + artifacts: + - path: "pubspec.yaml" + provides: "All dependencies (flutter_riverpod, drift, go_router, etc.)" + contains: "flutter_riverpod" + - path: "analysis_options.yaml" + provides: "riverpod_lint plugin configuration" + contains: "riverpod_lint" + - path: "build.yaml" + provides: "Drift code generation configuration" + contains: "drift_dev" + - path: "l10n.yaml" + provides: "ARB localization configuration" + contains: "app_de.arb" + - path: "lib/core/database/database.dart" + provides: "AppDatabase class with schemaVersion 1" + contains: "schemaVersion => 1" + - path: "lib/core/providers/database_provider.dart" + provides: "Riverpod provider for AppDatabase" + contains: "@riverpod" + - path: "lib/core/theme/app_theme.dart" + provides: "Light and dark ColorScheme with sage & stone palette" + contains: "ColorScheme.fromSeed" + - path: "lib/core/theme/theme_provider.dart" + provides: "ThemeNotifier with shared_preferences persistence" + contains: "@riverpod" + - path: "lib/l10n/app_de.arb" + provides: "German localization strings" + contains: "tabHome" + key_links: + - from: "lib/core/theme/theme_provider.dart" + to: "shared_preferences" + via: "SharedPreferences for theme persistence" + pattern: "SharedPreferences" + - from: "lib/core/database/database.dart" + to: "drift_flutter" + via: "driftDatabase() for SQLite connection" + pattern: "driftDatabase" + - from: "lib/core/providers/database_provider.dart" + to: "lib/core/database/database.dart" + via: "Riverpod provider exposes AppDatabase" + pattern: "AppDatabase" +--- + + +Scaffold the Flutter project and build all core infrastructure: Drift database with migration workflow, Riverpod providers with code generation, theme definitions (sage & stone palette), and ARB localization strings. + +Purpose: Establish every foundational dependency and pattern so Plan 02 can build the UI shell without any infrastructure work. +Output: A Flutter project that compiles, has all dependencies resolved, code generation working, database initialized, and theme/localization ready for consumption by UI code. + + + +@/home/jlmak/.claude/get-shit-done/workflows/execute-plan.md +@/home/jlmak/.claude/get-shit-done/templates/summary.md + + + +@.planning/PROJECT.md +@.planning/ROADMAP.md +@.planning/STATE.md +@.planning/phases/01-foundation/1-CONTEXT.md +@.planning/phases/01-foundation/01-RESEARCH.md + + + + + + Task 1: Create Flutter project and configure all dependencies and tooling + + pubspec.yaml, + analysis_options.yaml, + build.yaml, + l10n.yaml + + +1. Run `flutter create household_keeper --org com.jlmak --platforms android` inside the project root (the project root IS the repo root `/home/jlmak/Projects/jlmak/HouseHoldKeaper`). Since the repo already has files (LICENSE, README.md, .gitignore, .planning/), use `--project-name household_keeper` and target the current directory: `flutter create . --org com.jlmak --platforms android --project-name household_keeper`. This avoids creating a subdirectory. + +2. Add runtime dependencies: + `flutter pub add flutter_riverpod riverpod_annotation drift drift_flutter go_router path_provider shared_preferences` + +3. Add dev dependencies: + `flutter pub add -d riverpod_generator drift_dev build_runner riverpod_lint` + +4. Add `flutter_localizations` and `intl` manually to `pubspec.yaml` since they use the SDK dependency format: + ```yaml + dependencies: + flutter_localizations: + sdk: flutter + intl: any + ``` + +5. Add `generate: true` under the `flutter:` section in `pubspec.yaml`. + +6. Create `l10n.yaml` in project root: + ```yaml + arb-dir: lib/l10n + template-arb-file: app_de.arb + output-localization-file: app_localizations.dart + nullable-getter: false + ``` + +7. Update `analysis_options.yaml` to include riverpod_lint: + ```yaml + include: package:flutter_lints/flutter.yaml + + plugins: + riverpod_lint: ^3.1.3 + ``` + +8. Create `build.yaml` in project root for Drift configuration: + ```yaml + targets: + $default: + builders: + drift_dev: + options: + databases: + household_keeper: lib/core/database/database.dart + sql: + dialect: sqlite + options: + version: "3.38" + ``` + +9. Run `flutter pub get` to verify all dependencies resolve cleanly. + + + cd /home/jlmak/Projects/jlmak/HouseHoldKeaper && flutter pub get && echo "PASS: All dependencies resolved" + + Flutter project exists with all dependencies in pubspec.yaml (flutter_riverpod, drift, drift_flutter, go_router, path_provider, shared_preferences, flutter_localizations, intl, riverpod_annotation as runtime; riverpod_generator, drift_dev, build_runner, riverpod_lint as dev). l10n.yaml, build.yaml, and analysis_options.yaml configured correctly. `flutter pub get` succeeds. + + + + Task 2: Create core infrastructure — database, providers, theme, and localization strings + + lib/core/database/database.dart, + lib/core/providers/database_provider.dart, + lib/core/theme/app_theme.dart, + lib/core/theme/theme_provider.dart, + lib/l10n/app_de.arb + + +1. Create `lib/core/database/database.dart` — the Drift database class: + - Import `package:drift/drift.dart` and `package:drift_flutter/drift_flutter.dart` + - Add `part 'database.g.dart';` + - Define `@DriftDatabase(tables: [])` with empty tables list (tables added in Phase 2) + - Class `AppDatabase extends _$AppDatabase` + - Constructor accepts optional `QueryExecutor` for testing, defaults to `_openConnection()` + - `@override int get schemaVersion => 1;` + - Static `_openConnection()` returns `driftDatabase(name: 'household_keeper', native: const DriftNativeOptions(databaseDirectory: getApplicationSupportDirectory))` + - Import `package:path_provider/path_provider.dart` for `getApplicationSupportDirectory` + +2. Create `lib/core/providers/database_provider.dart` — Riverpod provider for database: + - Import riverpod_annotation and the database + - Add `part 'database_provider.g.dart';` + - Use `@Riverpod(keepAlive: true)` annotation (database must persist) + - Function `appDatabase(Ref ref)` returns `AppDatabase()` + - The provider creates the singleton database instance + +3. Create `lib/core/theme/app_theme.dart` — light and dark theme definitions: + - Define `AppTheme` class with static methods `lightTheme()` and `darkTheme()` returning `ThemeData` + - Light ColorScheme: `ColorScheme.fromSeed(seedColor: Color(0xFF7A9A6D), brightness: Brightness.light, dynamicSchemeVariant: DynamicSchemeVariant.tonalSpot).copyWith(surface: Color(0xFFF5F0E8), surfaceContainerLowest: Color(0xFFFAF7F2), surfaceContainerLow: Color(0xFFF2EDE4), surfaceContainer: Color(0xFFEDE7DC), surfaceContainerHigh: Color(0xFFE7E0D5), surfaceContainerHighest: Color(0xFFE0D9CE))` + - Dark ColorScheme: Same seed, `Brightness.dark`, `.copyWith(surface: Color(0xFF2A2520), surfaceContainerLowest: Color(0xFF1E1A16), surfaceContainerLow: Color(0xFF322D27), surfaceContainer: Color(0xFF3A342E), surfaceContainerHigh: Color(0xFF433D36), surfaceContainerHighest: Color(0xFF4D463F))` + - Both ThemeData set `useMaterial3: true` and use the respective ColorScheme + +4. Create `lib/core/theme/theme_provider.dart` — Riverpod provider for theme mode: + - Import riverpod_annotation, flutter/material.dart, shared_preferences + - Add `part 'theme_provider.g.dart';` + - `@riverpod class ThemeNotifier extends _$ThemeNotifier` + - `build()` method: read from SharedPreferences key `'theme_mode'`, parse to ThemeMode enum, default to `ThemeMode.system` + - `setThemeMode(ThemeMode mode)` method: update state, persist to SharedPreferences + - Use `ref.read` pattern for async SharedPreferences access (NOT ref.watch — this is a Notifier, not build()) + - Helper: `_themeModeFromString(String? value)` and `_themeModeToString(ThemeMode mode)` for serialization + +5. Create `lib/l10n/app_de.arb` — German localization strings for all Phase 1 UI: + ```json + { + "@@locale": "de", + "appTitle": "HouseHoldKeaper", + "tabHome": "Ubersicht", + "tabRooms": "Raume", + "tabSettings": "Einstellungen", + "homeEmptyTitle": "Noch nichts zu tun!", + "homeEmptyMessage": "Lege zuerst einen Raum an, um Aufgaben zu planen.", + "homeEmptyAction": "Raum erstellen", + "roomsEmptyTitle": "Hier ist noch alles leer!", + "roomsEmptyMessage": "Erstelle deinen ersten Raum, um loszulegen.", + "roomsEmptyAction": "Raum erstellen", + "settingsSectionAppearance": "Darstellung", + "settingsThemeLabel": "Farbschema", + "themeSystem": "System", + "themeLight": "Hell", + "themeDark": "Dunkel", + "settingsSectionAbout": "Uber", + "aboutAppName": "HouseHoldKeaper", + "aboutTagline": "Dein Haushalt, entspannt organisiert.", + "aboutVersion": "Version {version}", + "@aboutVersion": { + "placeholders": { + "version": { "type": "String" } + } + } + } + ``` + Note: Use proper German characters (umlauts) where appropriate. The tab labels "Ubersicht" should be "Ubersicht" and "Raume" should be "Raume" — but check CONTEXT.md which shows them without umlauts. Use umlauts in the ARB file: "Ubersicht", "Raume", "Uber" should actually be with umlauts if the font supports it. Per the CONTEXT.md the user specified "Ubersicht", "Raume", "Einstellungen" — follow exactly as specified there. + +6. Remove the default `lib/main.dart` content and replace with a minimal placeholder that imports ProviderScope (just enough to verify compilation — full wiring happens in Plan 02): + ```dart + import 'package:flutter/material.dart'; + import 'package:flutter_riverpod/flutter_riverpod.dart'; + + void main() { + runApp(const ProviderScope(child: MaterialApp(home: Scaffold()))); + } + ``` + +7. Run code generation: `dart run build_runner build --delete-conflicting-outputs` + This generates: `database.g.dart`, `database_provider.g.dart`, `theme_provider.g.dart` + +8. Run Drift migration capture: `dart run drift_dev make-migrations` + This captures schema version 1 in `drift_schemas/` directory. + +9. Run `dart analyze` to verify riverpod_lint is active and no analysis issues exist. + + + cd /home/jlmak/Projects/jlmak/HouseHoldKeaper && dart run build_runner build --delete-conflicting-outputs 2>&1 | tail -5 && dart analyze 2>&1 | tail -5 && echo "PASS: Codegen and analysis clean" + + database.dart defines AppDatabase with schemaVersion 1. database_provider.dart exposes AppDatabase via @riverpod. app_theme.dart provides lightTheme() and darkTheme() with sage green seed and warm surface overrides. theme_provider.dart provides ThemeNotifier with shared_preferences persistence and ThemeMode.system default. app_de.arb contains all German strings for Phase 1 screens. All .g.dart files generated successfully. drift_dev make-migrations has captured schema v1. dart analyze passes cleanly. + + + + + +- `flutter pub get` succeeds (all dependencies resolve) +- `dart run build_runner build` completes without errors (generates .g.dart files) +- `dart run drift_dev make-migrations` completes (schema v1 captured) +- `dart analyze` reports no errors (riverpod_lint active) +- `flutter build apk --debug` compiles (project structure valid) + + + +- Flutter project scaffolded with all Phase 1 dependencies +- Drift database class exists with schemaVersion 1 and migration workflow established +- Riverpod providers created with @riverpod annotation and code generation +- Light and dark theme definitions with sage & stone ColorScheme palette +- ThemeMode provider with shared_preferences persistence +- ARB localization file with all German strings for Phase 1 +- All code generation (.g.dart files) succeeds +- dart analyze passes cleanly with riverpod_lint active + + + +After completion, create `.planning/phases/01-foundation/01-01-SUMMARY.md` + diff --git a/.planning/phases/01-foundation/01-02-PLAN.md b/.planning/phases/01-foundation/01-02-PLAN.md new file mode 100644 index 0000000..92052b5 --- /dev/null +++ b/.planning/phases/01-foundation/01-02-PLAN.md @@ -0,0 +1,328 @@ +--- +phase: 01-foundation +plan: 02 +type: execute +wave: 2 +depends_on: + - "01-01" +files_modified: + - lib/app.dart + - lib/main.dart + - lib/core/router/router.dart + - lib/shell/app_shell.dart + - lib/features/home/presentation/home_screen.dart + - lib/features/rooms/presentation/rooms_screen.dart + - lib/features/settings/presentation/settings_screen.dart +autonomous: false +requirements: + - FOUND-03 + - FOUND-04 + - THEME-01 + - THEME-02 + +must_haves: + truths: + - "App launches on Android without errors and shows a bottom navigation bar" + - "Bottom navigation has three tabs: Home, Rooms, Settings with thematic icons" + - "Tab labels are loaded from ARB localization files, not hardcoded" + - "Tapping each tab switches to the correct screen with preserved state" + - "Home tab shows playful empty state with action button that navigates to Rooms tab" + - "Rooms tab shows playful empty state with action button" + - "Settings screen shows working theme switcher (System/Hell/Dunkel) and About section" + - "Theme switcher persists selection across app restart" + - "Light and dark themes render correctly with sage & stone palette" + artifacts: + - path: "lib/app.dart" + provides: "MaterialApp.router with theme, localization, and ProviderScope" + contains: "MaterialApp.router" + min_lines: 20 + - path: "lib/main.dart" + provides: "Entry point with ProviderScope" + contains: "ProviderScope" + - path: "lib/core/router/router.dart" + provides: "GoRouter with StatefulShellRoute.indexedStack for 3-tab navigation" + contains: "StatefulShellRoute.indexedStack" + - path: "lib/shell/app_shell.dart" + provides: "Scaffold with NavigationBar receiving StatefulNavigationShell" + contains: "NavigationBar" + min_lines: 30 + - path: "lib/features/home/presentation/home_screen.dart" + provides: "Placeholder with empty state guiding user to Rooms tab" + contains: "AppLocalizations" + - path: "lib/features/rooms/presentation/rooms_screen.dart" + provides: "Placeholder with empty state encouraging room creation" + contains: "AppLocalizations" + - path: "lib/features/settings/presentation/settings_screen.dart" + provides: "Theme switcher (SegmentedButton) + About section with grouped headers" + contains: "SegmentedButton" + min_lines: 40 + key_links: + - from: "lib/app.dart" + to: "lib/core/router/router.dart" + via: "routerConfig parameter" + pattern: "routerConfig" + - from: "lib/app.dart" + to: "lib/core/theme/app_theme.dart" + via: "theme and darkTheme parameters" + pattern: "AppTheme" + - from: "lib/app.dart" + to: "lib/core/theme/theme_provider.dart" + via: "ref.watch for themeMode" + pattern: "themeNotifierProvider" + - from: "lib/shell/app_shell.dart" + to: "lib/l10n/app_de.arb" + via: "AppLocalizations for tab labels" + pattern: "AppLocalizations" + - from: "lib/features/home/presentation/home_screen.dart" + to: "lib/core/router/router.dart" + via: "Cross-tab navigation to Rooms" + pattern: "context.go.*rooms" + - from: "lib/features/settings/presentation/settings_screen.dart" + to: "lib/core/theme/theme_provider.dart" + via: "SegmentedButton reads/writes ThemeNotifier" + pattern: "themeNotifierProvider" +--- + + +Build the navigation shell, all three screens (Home placeholder, Rooms placeholder, Settings with theme switcher), and wire everything into a launchable app with full theme and localization integration. + +Purpose: Deliver a complete, launchable app that demonstrates the architecture established in Plan 01 -- users see the bottom navigation, can switch tabs, change themes, and all text comes from localization. +Output: An Android app that compiles, launches, and satisfies all Phase 1 success criteria. + + + +@/home/jlmak/.claude/get-shit-done/workflows/execute-plan.md +@/home/jlmak/.claude/get-shit-done/templates/summary.md + + + +@.planning/PROJECT.md +@.planning/ROADMAP.md +@.planning/STATE.md +@.planning/phases/01-foundation/1-CONTEXT.md +@.planning/phases/01-foundation/01-RESEARCH.md +@.planning/phases/01-foundation/01-01-SUMMARY.md + + + + +From lib/core/theme/app_theme.dart: +```dart +class AppTheme { + static ThemeData lightTheme(); + static ThemeData darkTheme(); +} +``` + +From lib/core/theme/theme_provider.dart (generated): +```dart +// @riverpod class ThemeNotifier extends _$ThemeNotifier +// Access via: ref.watch(themeNotifierProvider) -> ThemeMode +// Mutate via: ref.read(themeNotifierProvider.notifier).setThemeMode(ThemeMode) +``` + +From lib/core/database/database.dart: +```dart +class AppDatabase extends _$AppDatabase { + // schemaVersion => 1 + // Used via database_provider.dart +} +``` + +From lib/core/providers/database_provider.dart (generated): +```dart +// @riverpod AppDatabase appDatabase(Ref ref) +// Access via: ref.watch(appDatabaseProvider) +``` + +From lib/l10n/app_de.arb (generated AppLocalizations): +```dart +// Access via: AppLocalizations.of(context) +// Keys: appTitle, tabHome, tabRooms, tabSettings, +// homeEmptyTitle, homeEmptyMessage, homeEmptyAction, +// roomsEmptyTitle, roomsEmptyMessage, roomsEmptyAction, +// settingsSectionAppearance, settingsThemeLabel, +// themeSystem, themeLight, themeDark, +// settingsSectionAbout, aboutAppName, aboutTagline, aboutVersion +``` + + + + + + + Task 1: Create router, navigation shell, and all three screens + + lib/core/router/router.dart, + lib/shell/app_shell.dart, + lib/features/home/presentation/home_screen.dart, + lib/features/rooms/presentation/rooms_screen.dart, + lib/features/settings/presentation/settings_screen.dart + + +1. Create `lib/core/router/router.dart` -- GoRouter with StatefulShellRoute: + - Define a top-level `GoRouter router` (or use @riverpod if needed for ref access -- keep it simple with a plain final variable since router doesn't need Riverpod state) + - Use `StatefulShellRoute.indexedStack` with 3 branches: + - Branch 0: `GoRoute(path: '/', builder: ... HomeScreen())` + - Branch 1: `GoRoute(path: '/rooms', builder: ... RoomsScreen())` + - Branch 2: `GoRoute(path: '/settings', builder: ... SettingsScreen())` + - Builder returns `AppShell(navigationShell: navigationShell)` + +2. Create `lib/shell/app_shell.dart` -- Scaffold with NavigationBar: + - `AppShell` is a StatelessWidget receiving `StatefulNavigationShell navigationShell` + - Build method: get `AppLocalizations` via `AppLocalizations.of(context)` + - Scaffold body: `navigationShell` + - bottomNavigationBar: `NavigationBar` with: + - `selectedIndex: navigationShell.currentIndex` + - `onDestinationSelected`: calls `navigationShell.goBranch(index, initialLocation: index == navigationShell.currentIndex)` + - Three `NavigationDestination` items: + - Home: icon `Icons.checklist_outlined`, selectedIcon `Icons.checklist`, label from `l10n.tabHome` + - Rooms: icon `Icons.door_front_door_outlined`, selectedIcon `Icons.door_front_door`, label from `l10n.tabRooms` + - Settings: icon `Icons.tune_outlined`, selectedIcon `Icons.tune`, label from `l10n.tabSettings` + +3. Create `lib/features/home/presentation/home_screen.dart` -- Placeholder with empty state: + - `HomeScreen` extends `StatelessWidget` + - Build method: Center column with: + - Large Material icon (e.g., `Icons.checklist_rounded`, size 80, muted color) + - Text from `l10n.homeEmptyTitle` (styled as headline) + - Text from `l10n.homeEmptyMessage` (styled as body, muted color) + - `FilledButton.tonal` with text from `l10n.homeEmptyAction` + - Button onPressed: `context.go('/rooms')` -- cross-navigates to Rooms tab + - All text comes from AppLocalizations, zero hardcoded strings + +4. Create `lib/features/rooms/presentation/rooms_screen.dart` -- Placeholder with empty state: + - Same visual pattern as HomeScreen: icon + title + message + action button + - Icon: `Icons.door_front_door_rounded` (size 80) + - Text from `l10n.roomsEmptyTitle`, `l10n.roomsEmptyMessage`, `l10n.roomsEmptyAction` + - Action button: `FilledButton.tonal` -- for now it can be a no-op (room creation comes in Phase 2) or show a SnackBar. The button should exist but doesn't need to do anything functional yet. + +5. Create `lib/features/settings/presentation/settings_screen.dart` -- Theme switcher + About: + - `SettingsScreen` extends `ConsumerWidget` (needs ref for theme provider) + - Uses `ListView` with grouped sections: + - **Section 1 -- "Darstellung" (Appearance):** + - Section header: Padding + Text from `l10n.settingsSectionAppearance` styled as titleMedium with primary color + - Theme switcher row: ListTile with title from `l10n.settingsThemeLabel`, subtitle is a `SegmentedButton` with three segments: + - `ThemeMode.system`: label `l10n.themeSystem`, icon `Icons.settings_suggest_outlined` + - `ThemeMode.light`: label `l10n.themeLight`, icon `Icons.light_mode_outlined` + - `ThemeMode.dark`: label `l10n.themeDark`, icon `Icons.dark_mode_outlined` + - `selected: {ref.watch(themeNotifierProvider)}` + - `onSelectionChanged: (s) => ref.read(themeNotifierProvider.notifier).setThemeMode(s.first)` + - **Section 2 -- "Uber" (About):** + - Section header: same style, text from `l10n.settingsSectionAbout` + - ListTile: title from `l10n.aboutAppName`, subtitle from `l10n.aboutTagline` + - ListTile: title "Version", subtitle from `l10n.aboutVersion` with version string (use package_info_plus or hardcode "0.1.0" for now -- package_info_plus can be added later if needed) + - A `Divider` between sections for visual separation + + + cd /home/jlmak/Projects/jlmak/HouseHoldKeaper && dart analyze 2>&1 | tail -10 && echo "PASS: All screens analyze cleanly" + + router.dart defines GoRouter with StatefulShellRoute.indexedStack and 3 branches. app_shell.dart renders NavigationBar with 3 tabs using localized labels and thematic icons (checklist, door, tune). home_screen.dart shows empty state with localized text and a button that navigates to /rooms. rooms_screen.dart shows empty state with localized text and action button. settings_screen.dart shows grouped sections: "Darstellung" with SegmentedButton theme switcher wired to ThemeNotifier, and "Uber" with app name, tagline, and version. All text loaded from AppLocalizations, zero hardcoded German strings in Dart code. + + + + Task 2: Wire app.dart and main.dart -- launchable app with full integration + + lib/app.dart, + lib/main.dart + + +1. Create `lib/app.dart` -- the root App widget: + - `App` extends `ConsumerWidget` + - Build method: + - `final themeMode = ref.watch(themeNotifierProvider);` + - Return `MaterialApp.router()` + - `routerConfig: router` (from router.dart) + - `theme: AppTheme.lightTheme()` + - `darkTheme: AppTheme.darkTheme()` + - `themeMode: themeMode` + - `localizationsDelegates: AppLocalizations.localizationsDelegates` + - `supportedLocales: const [Locale('de')]` + - `locale: const Locale('de')` + - `debugShowCheckedModeBanner: false` + - Import `package:flutter_gen/gen_l10n/app_localizations.dart` + +2. Update `lib/main.dart` -- entry point: + - `void main()` calls `runApp(const ProviderScope(child: App()))` + - Import the App widget and flutter_riverpod + +3. Run `dart run build_runner build --delete-conflicting-outputs` one final time to ensure all generated files are current (router may need regeneration if it uses @riverpod). + +4. Run `flutter build apk --debug` to verify the entire app compiles for Android. + +5. Verify the complete integration: + - `dart analyze` passes cleanly + - `flutter test` passes (default test or any existing tests) + - The app structure matches the architecture from RESEARCH.md + + + cd /home/jlmak/Projects/jlmak/HouseHoldKeaper && flutter build apk --debug 2>&1 | tail -5 && echo "PASS: App compiles for Android" + + app.dart wires MaterialApp.router with GoRouter config, light/dark themes from AppTheme, themeMode from ThemeNotifier provider, and German localization delegates. main.dart wraps App in ProviderScope. The app compiles via `flutter build apk --debug` without errors. The complete architecture is in place: Drift database + Riverpod providers + GoRouter navigation + Material 3 theme + ARB localization. + + + + Task 3: Visual and functional verification of complete Phase 1 app + none -- verification only + +Launch the app with `flutter run` on an Android device or emulator. Walk through the 12-step verification checklist below to confirm all Phase 1 requirements are met visually and functionally. This is a human-only verification step -- no code changes. + +Verification checklist: +1. App launches without errors and shows bottom navigation bar +2. Three tabs visible with correct icons and German labels from ARB +3. Tab switching works with state preservation +4. Home empty state has playful text and cross-navigates to Rooms tab +5. Rooms empty state has playful text and action button +6. Settings has "Darstellung" section with SegmentedButton theme switcher +7. Light theme shows warm stone/beige surfaces +8. Dark theme shows warm charcoal-brown surfaces (not cold gray) +9. System theme follows device setting +10. Theme preference persists across app restart +11. "Uber" section shows app name and tagline +12. Overall sage and stone palette feels calm and warm + + Human visually confirms all 12 checklist items pass + User has approved the visual appearance and functional behavior of the Phase 1 app, or has provided specific feedback for issues to fix. + Complete Phase 1 app: bottom navigation with 3 tabs, sage and stone theme (light/dark), playful German placeholder screens, Settings with working theme switcher and About section. All text from ARB localization. + +1. Launch the app on an Android device/emulator: `flutter run` +2. Verify bottom navigation bar shows 3 tabs with icons and German labels: "Ubersicht" (checklist icon), "Raume" (door icon), "Einstellungen" (sliders icon) +3. Tap each tab -- verify it switches content and the active tab indicator uses sage green +4. On the Home tab: verify playful empty state with icon, German text, and "Raum erstellen" button. Tap the button -- verify it navigates to the Rooms tab. +5. On the Rooms tab: verify playful empty state with door icon and German text +6. On the Settings tab: verify "Darstellung" section header and SegmentedButton with System/Hell/Dunkel options +7. Switch theme to "Hell" (light) -- verify warm stone/beige surface tones +8. Switch theme to "Dunkel" (dark) -- verify warm charcoal-brown backgrounds (NOT cold gray/black) +9. Switch back to "System" -- verify it follows device setting +10. Kill and relaunch the app -- verify theme preference persisted +11. Scroll to "Uber" section -- verify app name "HouseHoldKeaper" and tagline "Dein Haushalt, entspannt organisiert." +12. Overall: confirm the sage and stone palette feels calm and warm, not clinical + + Type "approved" to complete Phase 1, or describe any visual/functional issues to fix + + + + + +- `flutter build apk --debug` succeeds +- `dart analyze` reports zero errors/warnings +- App launches and shows 3-tab bottom navigation +- All UI text comes from ARB localization (no hardcoded German in .dart files) +- Theme switching works (System/Hell/Dunkel) and persists across restart +- Light theme: sage green accents, warm stone surfaces +- Dark theme: sage green accents, warm charcoal-brown surfaces +- Home empty state cross-navigates to Rooms tab +- Settings has grouped sections with theme switcher and About + + + +- App launches on Android without errors showing bottom navigation with Home, Rooms, and Settings tabs +- Light and dark themes work correctly following system setting by default using sage and stone palette +- All UI strings loaded from ARB localization files (zero hardcoded German text in Dart code) +- Settings screen has working theme switcher (System/Hell/Dunkel) that persists and About section +- Placeholder screens show playful empty states with localized text and action buttons +- Human verification approves the visual appearance and interaction + + + +After completion, create `.planning/phases/01-foundation/01-02-SUMMARY.md` +