chore: archive v1.0 phase directories to milestones/

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-16 20:12:01 +01:00
parent 1a1a10c9ea
commit 8c72403c85
42 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,340 @@
---
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
- test/shell/app_shell_test.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
- path: "test/shell/app_shell_test.dart"
provides: "Navigation shell widget test (FOUND-04)"
contains: "NavigationBar"
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. Create the app shell widget test.
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, with app shell test passing.
</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, all three screens, and app shell test</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,
test/shell/app_shell_test.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 -- "Über" (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
6. Create `test/shell/app_shell_test.dart` (covers FOUND-04):
- Widget test: wrap `MaterialApp.router(routerConfig: router)` in `ProviderScope` with localization delegates and `locale: Locale('de')`
- Pump and settle
- Verify that 3 `NavigationDestination` widgets are rendered
- Verify that the labels match the expected German strings from ARB (with umlauts): "Übersicht", "Räume", "Einstellungen"
- Verify that tapping a different destination changes `selectedIndex`
- Use `SharedPreferences.setMockInitialValues({})` for ThemeNotifier isolation
</action>
<verify>
<automated>cd /home/jlmak/Projects/jlmak/HouseHoldKeaper && dart analyze 2>&1 | tail -10 && flutter test test/shell/app_shell_test.dart 2>&1 | tail -10 && echo "PASS: Screens analyze cleanly, shell test passes"</automated>
</verify>
<done>router.dart defines GoRouter with StatefulShellRoute.indexedStack and 3 branches. app_shell.dart renders NavigationBar with 3 tabs using localized labels (with proper umlauts) 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 "Über" with app name, tagline, and version. All text loaded from AppLocalizations, zero hardcoded German strings in Dart code. app_shell_test.dart passes, verifying 3 navigation destinations with correct labels.</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. Verify the complete integration:
- `dart analyze` passes cleanly
- `flutter test` passes (all tests including Wave 0 tests from Plan 01)
</action>
<verify>
<automated>cd /home/jlmak/Projects/jlmak/HouseHoldKeaper && dart analyze 2>&1 | tail -5 && flutter test 2>&1 | tail -10 && echo "PASS: Analysis clean, all tests pass"</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. `dart analyze` passes cleanly. `flutter test` passes all tests (database, theme, color scheme, localization, app shell). The complete architecture is in place: Drift database + Riverpod providers + GoRouter navigation + Material 3 theme + ARB localization. Final confirmation: `flutter build apk --debug` compiles without errors.</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. "Über" 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: "Übersicht" (checklist icon), "Räume" (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 "Über" 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>
- `dart analyze` reports zero errors/warnings
- `flutter test` passes all tests (Wave 0 + app shell test)
- `flutter build apk --debug` succeeds
- 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
- All automated tests pass (Wave 0 tests from Plan 01 + app shell test)
- Human verification approves the visual appearance and interaction
</success_criteria>
<output>
After completion, create `.planning/phases/01-foundation/01-02-SUMMARY.md`
</output>