340 lines
16 KiB
Markdown
340 lines
16 KiB
Markdown
---
|
|
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
|
|
- test/core/database/database_test.dart
|
|
- test/core/theme/theme_test.dart
|
|
- test/core/theme/color_scheme_test.dart
|
|
- test/l10n/localization_test.dart
|
|
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"
|
|
- path: "test/core/database/database_test.dart"
|
|
provides: "Database unit and smoke tests (FOUND-01)"
|
|
contains: "schemaVersion"
|
|
- path: "test/core/theme/theme_test.dart"
|
|
provides: "Theme switching widget test (THEME-01)"
|
|
contains: "ThemeMode"
|
|
- path: "test/core/theme/color_scheme_test.dart"
|
|
provides: "ColorScheme unit tests (THEME-02)"
|
|
contains: "ColorScheme"
|
|
- path: "test/l10n/localization_test.dart"
|
|
provides: "Localization widget test (FOUND-03)"
|
|
contains: "AppLocalizations"
|
|
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. Create Wave 0 test scaffolding for database, theme, and localization.
|
|
|
|
Purpose: Establish every foundational dependency and pattern so Plan 02 can build the UI shell without any infrastructure work. Tests provide fast feedback during execution.
|
|
Output: A Flutter project that compiles, has all dependencies resolved, code generation working, database initialized, theme/localization ready for consumption by UI code, and test scaffolding in place.
|
|
</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, localization strings, and Wave 0 test scaffolding</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,
|
|
lib/main.dart,
|
|
test/core/database/database_test.dart,
|
|
test/core/theme/theme_test.dart,
|
|
test/core/theme/color_scheme_test.dart,
|
|
test/l10n/localization_test.dart
|
|
</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": "\u00dcbersicht",
|
|
"tabRooms": "R\u00e4ume",
|
|
"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": "\u00dcber",
|
|
"aboutAppName": "HouseHoldKeaper",
|
|
"aboutTagline": "Dein Haushalt, entspannt organisiert.",
|
|
"aboutVersion": "Version {version}",
|
|
"@aboutVersion": {
|
|
"placeholders": {
|
|
"version": { "type": "String" }
|
|
}
|
|
}
|
|
}
|
|
```
|
|
IMPORTANT: Use proper German umlauts throughout -- "Ubersicht" with umlaut (U+00DC), "Raume" with umlaut (U+00E4), "Uber" with umlaut (U+00DC). Per CONTEXT.md user decision: labels are "Ubersicht", "Raume", "Einstellungen" with umlauts.
|
|
|
|
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. Create Wave 0 test files:
|
|
|
|
a. `test/core/database/database_test.dart` (covers FOUND-01):
|
|
- Test that `AppDatabase(NativeDatabase.memory())` opens successfully
|
|
- Test that `schemaVersion` equals 1
|
|
- Test that the database can be closed without error
|
|
- Use in-memory database (`NativeDatabase.memory()`) for test isolation
|
|
|
|
b. `test/core/theme/color_scheme_test.dart` (covers THEME-02):
|
|
- Test that `AppTheme.lightTheme()` has `Brightness.light`
|
|
- Test that `AppTheme.darkTheme()` has `Brightness.dark`
|
|
- Test that both use sage green seed: verify `primary` color is in the green hue range
|
|
- Test that light surface color is warm (0xFFF5F0E8)
|
|
- Test that dark surface color is warm charcoal (0xFF2A2520), not cold gray
|
|
|
|
c. `test/core/theme/theme_test.dart` (covers THEME-01):
|
|
- Widget test: wrap a `MaterialApp` with `ProviderScope` and verify that `ThemeNotifier` defaults to `ThemeMode.system`
|
|
- Test that calling `setThemeMode(ThemeMode.dark)` updates state
|
|
- Test that calling `setThemeMode(ThemeMode.light)` updates state
|
|
- Use `SharedPreferences.setMockInitialValues({})` for test isolation
|
|
|
|
d. `test/l10n/localization_test.dart` (covers FOUND-03):
|
|
- Widget test: create a `MaterialApp` with `AppLocalizations.localizationsDelegates`, `supportedLocales: [Locale('de')]`, `locale: Locale('de')`
|
|
- Pump a widget that reads `AppLocalizations.of(context)` and displays `tabHome`
|
|
- Verify the rendered text contains the expected German string (with umlaut)
|
|
- Test that all critical keys are non-empty: `appTitle`, `tabHome`, `tabRooms`, `tabSettings`
|
|
|
|
10. Run `dart analyze` to verify riverpod_lint is active and no analysis issues exist.
|
|
|
|
11. Run `flutter test` to verify all Wave 0 tests pass.
|
|
</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 && flutter test 2>&1 | tail -10 && echo "PASS: Codegen, analysis, and tests 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 with proper umlauts (Ubersicht, Raume, Uber). All .g.dart files generated successfully. drift_dev make-migrations has captured schema v1. dart analyze passes cleanly. All 4 Wave 0 test files created and passing: database_test.dart, color_scheme_test.dart, theme_test.dart, localization_test.dart.</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 test` passes (all Wave 0 tests green)
|
|
- `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 using proper umlauts
|
|
- All code generation (.g.dart files) succeeds
|
|
- dart analyze passes cleanly with riverpod_lint active
|
|
- Wave 0 tests pass: database (FOUND-01), localization (FOUND-03), theme switching (THEME-01), color scheme (THEME-02)
|
|
</success_criteria>
|
|
|
|
<output>
|
|
After completion, create `.planning/phases/01-foundation/01-01-SUMMARY.md`
|
|
</output>
|