Files
2026-03-16 20:12:01 +01:00

18 KiB

phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, must_haves
phase plan type wave depends_on files_modified autonomous requirements must_haves
01-foundation 02 execute 2
01-01
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
false
FOUND-03
FOUND-04
THEME-01
THEME-02
truths artifacts key_links
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
path provides contains min_lines
lib/app.dart MaterialApp.router with theme, localization, and ProviderScope MaterialApp.router 20
path provides contains
lib/main.dart Entry point with ProviderScope ProviderScope
path provides contains
lib/core/router/router.dart GoRouter with StatefulShellRoute.indexedStack for 3-tab navigation StatefulShellRoute.indexedStack
path provides contains min_lines
lib/shell/app_shell.dart Scaffold with NavigationBar receiving StatefulNavigationShell NavigationBar 30
path provides contains
lib/features/home/presentation/home_screen.dart Placeholder with empty state guiding user to Rooms tab AppLocalizations
path provides contains
lib/features/rooms/presentation/rooms_screen.dart Placeholder with empty state encouraging room creation AppLocalizations
path provides contains min_lines
lib/features/settings/presentation/settings_screen.dart Theme switcher (SegmentedButton) + About section with grouped headers SegmentedButton 40
path provides contains
test/shell/app_shell_test.dart Navigation shell widget test (FOUND-04) NavigationBar
from to via pattern
lib/app.dart lib/core/router/router.dart routerConfig parameter routerConfig
from to via pattern
lib/app.dart lib/core/theme/app_theme.dart theme and darkTheme parameters AppTheme
from to via pattern
lib/app.dart lib/core/theme/theme_provider.dart ref.watch for themeMode themeNotifierProvider
from to via pattern
lib/shell/app_shell.dart lib/l10n/app_de.arb AppLocalizations for tab labels AppLocalizations
from to via pattern
lib/features/home/presentation/home_screen.dart lib/core/router/router.dart Cross-tab navigation to Rooms context.go.*rooms
from to via pattern
lib/features/settings/presentation/settings_screen.dart lib/core/theme/theme_provider.dart SegmentedButton reads/writes ThemeNotifier 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. 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.

<execution_context> @/home/jlmak/.claude/get-shit-done/workflows/execute-plan.md @/home/jlmak/.claude/get-shit-done/templates/summary.md </execution_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

From lib/core/theme/app_theme.dart:

class AppTheme {
  static ThemeData lightTheme();
  static ThemeData darkTheme();
}

From lib/core/theme/theme_provider.dart (generated):

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

class AppDatabase extends _$AppDatabase {
  // schemaVersion => 1
  // Used via database_provider.dart
}

From lib/core/providers/database_provider.dart (generated):

// @riverpod AppDatabase appDatabase(Ref ref)
// Access via: ref.watch(appDatabaseProvider)

From lib/l10n/app_de.arb (generated AppLocalizations):

// 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, all three screens, and app shell test 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 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)`
  1. 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
  2. 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
  3. 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.
  4. 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
  5. 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 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" 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.
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`
  1. Update lib/main.dart -- entry point:

    • void main() calls runApp(const ProviderScope(child: App()))
    • Import the App widget and flutter_riverpod
  2. 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).

  3. Verify the complete integration:

    • dart analyze passes cleanly
    • flutter test passes (all tests including Wave 0 tests from Plan 01) 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" 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.
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. "Über" 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.
  13. Launch the app on an Android device/emulator: flutter run
  14. Verify bottom navigation bar shows 3 tabs with icons and German labels: "Übersicht" (checklist icon), "Räume" (door icon), "Einstellungen" (sliders icon)
  15. Tap each tab -- verify it switches content and the active tab indicator uses sage green
  16. 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.
  17. On the Rooms tab: verify playful empty state with door icon and German text
  18. On the Settings tab: verify "Darstellung" section header and SegmentedButton with System/Hell/Dunkel options
  19. Switch theme to "Hell" (light) -- verify warm stone/beige surface tones
  20. Switch theme to "Dunkel" (dark) -- verify warm charcoal-brown backgrounds (NOT cold gray/black)
  21. Switch back to "System" -- verify it follows device setting
  22. Kill and relaunch the app -- verify theme preference persisted
  23. Scroll to "Über" section -- verify app name "HouseHoldKeaper" and tagline "Dein Haushalt, entspannt organisiert."
  24. 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
- `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

<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>
After completion, create `.planning/phases/01-foundation/01-02-SUMMARY.md`