docs(01-foundation): create phase plan

This commit is contained in:
2026-03-15 19:42:30 +01:00
parent 71312b1122
commit f2e1d715f4
3 changed files with 620 additions and 2 deletions

View File

@@ -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 | - |

View File

@@ -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"
---
<objective>
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.
</objective>
<execution_context>
@/home/jlmak/.claude/get-shit-done/workflows/execute-plan.md
@/home/jlmak/.claude/get-shit-done/templates/summary.md
</execution_context>
<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
@.planning/phases/01-foundation/1-CONTEXT.md
@.planning/phases/01-foundation/01-RESEARCH.md
</context>
<tasks>
<task type="auto">
<name>Task 1: Create Flutter project and configure all dependencies and tooling</name>
<files>
pubspec.yaml,
analysis_options.yaml,
build.yaml,
l10n.yaml
</files>
<action>
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.
</action>
<verify>
<automated>cd /home/jlmak/Projects/jlmak/HouseHoldKeaper && flutter pub get && echo "PASS: All dependencies resolved"</automated>
</verify>
<done>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.</done>
</task>
<task type="auto">
<name>Task 2: Create core infrastructure — database, providers, theme, and localization strings</name>
<files>
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
</files>
<action>
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.
</action>
<verify>
<automated>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"</automated>
</verify>
<done>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.</done>
</task>
</tasks>
<verification>
- `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)
</verification>
<success_criteria>
- 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
</success_criteria>
<output>
After completion, create `.planning/phases/01-foundation/01-01-SUMMARY.md`
</output>

View File

@@ -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"
---
<objective>
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.
</objective>
<execution_context>
@/home/jlmak/.claude/get-shit-done/workflows/execute-plan.md
@/home/jlmak/.claude/get-shit-done/templates/summary.md
</execution_context>
<context>
@.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
<interfaces>
<!-- Key types and contracts from Plan 01 that this plan consumes. -->
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
```
</interfaces>
</context>
<tasks>
<task type="auto">
<name>Task 1: Create router, navigation shell, and all three screens</name>
<files>
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
</files>
<action>
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<ThemeMode>` 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
</action>
<verify>
<automated>cd /home/jlmak/Projects/jlmak/HouseHoldKeaper && dart analyze 2>&1 | tail -10 && echo "PASS: All screens analyze cleanly"</automated>
</verify>
<done>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.</done>
</task>
<task type="auto">
<name>Task 2: Wire app.dart and main.dart -- launchable app with full integration</name>
<files>
lib/app.dart,
lib/main.dart
</files>
<action>
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
</action>
<verify>
<automated>cd /home/jlmak/Projects/jlmak/HouseHoldKeaper && flutter build apk --debug 2>&1 | tail -5 && echo "PASS: App compiles for Android"</automated>
</verify>
<done>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.</done>
</task>
<task type="checkpoint:human-verify" gate="blocking">
<name>Task 3: Visual and functional verification of complete Phase 1 app</name>
<files>none -- verification only</files>
<action>
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
</action>
<verify>Human visually confirms all 12 checklist items pass</verify>
<done>User has approved the visual appearance and functional behavior of the Phase 1 app, or has provided specific feedback for issues to fix.</done>
<what-built>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.</what-built>
<how-to-verify>
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
</how-to-verify>
<resume-signal>Type "approved" to complete Phase 1, or describe any visual/functional issues to fix</resume-signal>
</task>
</tasks>
<verification>
- `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
</verification>
<success_criteria>
- 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
</success_criteria>
<output>
After completion, create `.planning/phases/01-foundation/01-02-SUMMARY.md`
</output>