diff --git a/CLAUDE.md b/CLAUDE.md index 225140b..f6de625 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -63,6 +63,12 @@ assets/ API base URL: `http://localhost:8090/api/v1/` +## Widget API Patterns +- **Dual-param widgets**: `shared/widgets/` accept both entity param (e.g. `task: TaskEntity?`) AND individual raw params — private getters resolve which to use. Keep backward compat when extending. +- **`PetType` canonical location**: `domain/entities/pet_type.dart` — never redeclare locally. +- **`todayTasksProvider`** is a top-level alias for `tasksProvider` (no date filter in MVP). +- **Pet identity vs. pet state**: `petType`/`petName` belong to `userProvider`; `petStateProvider` tracks energy/streak/rewards only. + ## Naming Conventions - **Files**: `snake_case.dart` - **Classes**: `PascalCase` diff --git a/DocumentSW/widget-api-fixes.md b/DocumentSW/widget-api-fixes.md new file mode 100644 index 0000000..24029ea --- /dev/null +++ b/DocumentSW/widget-api-fixes.md @@ -0,0 +1,126 @@ +# Widget API Mismatches — Fix + +**Branch:** `NDM-App-221-fix-widget-api-mismatches-build-errors-after-merge` +**Commits:** `371e826`, `adc2f72` + +## Overview + +After multiple feature branches were merged independently, the shared widgets and domain entities had diverged APIs causing 8 compilation errors. This fix aligns widget constructors with how `TasksScreen` and `ZenScreen` use them, adds missing entity properties, and resolves provider reference errors. + +--- + +## Problems Fixed + +| # | Error | Location | +|---|-------|----------| +| 1 | `EnergyBar` has no param `energyLevel` | `TasksScreen:65` | +| 2 | `PetBubble` missing required param `petName` | `TasksScreen:69` | +| 3 | `StreakDots` has no param `streakDays` | `TasksScreen:77` | +| 4 | `TaskCard` has no param `task` | `TasksScreen:118,132` | +| 5 | `todayTasksProvider` not defined | `TasksScreen:24` | +| 6 | `PetStateEntity` missing `petType` getter | `TasksScreen:35` | +| 7 | `EnergyBadge` has no param `energyLevel` | `ZenScreen:132` | +| 8 | `PetStateEntity` constructor missing `updatedAt` | `pet_providers.dart:43` | + +--- + +## Files Changed + +### `lib/shared/widgets/energy_bar.dart` +Added optional `energyLevel: int?` parameter alongside the existing `fraction: double?`. +Both are now nullable; an `assert` ensures exactly one is provided. +Private getter `_effectiveFraction` converts `energyLevel` → fraction via `(level / 3.0).clamp(0.0, 1.0)`. + +```dart +EnergyBar(energyLevel: petState.energyToday) // new usage +EnergyBar(fraction: 0.66) // existing usage still works +``` + +### `lib/shared/widgets/energy_badge.dart` +Added optional `energyLevel: int?` parameter alongside the existing `level: EnergyLevel?`. +Private getter `_effectiveLevel` falls back to `EnergyLevel.fromInt(energyLevel ?? 1)`. +Also added `EnergyLevel.fromInt()` static factory (maps 1→low, 2→medium, 3→high). + +```dart +EnergyBadge(energyLevel: task.energyLevel) // new usage +EnergyBadge(level: EnergyLevel.medium) // existing usage still works +EnergyBadge.fromInt(2) // factory convenience +``` + +### `lib/shared/widgets/streak_dots.dart` +Added optional `streakDays: int?` parameter. +`_generateDays(int streak)` computes a `List` from today's weekday index and streak count. +Both `days` and `streakCount` are now optional (default to empty/0 when `streakDays` is provided). + +```dart +StreakDots(streakDays: petState.streakDays) // new +StreakDots(days: myList, streakCount: 3) // existing +``` + +### `lib/shared/widgets/task_card.dart` +Added optional `task: TaskEntity?` and `onComplete: VoidCallback?` parameters. +Private getters (`_title`, `_energyLevel`, `_isDone`, `_isSelfCare`, `_isOverdue`, `_toggleCallback`) delegate to `task` fields when set, falling back to individual params. +`_isOverdue` computes from `task.deadline` when a task is provided. + +```dart +TaskCard(task: entity, onComplete: () => ref.read(...).completeTask(id)) // new +TaskCard(title: 'Buy milk', energyLevel: 1, isDone: false) // existing +``` + +### `lib/shared/widgets/pet_bubble.dart` +Removed local `PetType` enum (was duplicated here and in `domain/entities/pet_type.dart`). +Now imports `PetType` from the domain layer — single source of truth. + +### `lib/domain/entities/task_entity.dart` +Added computed getter: +```dart +bool get isCompleted => status == TaskStatus.done; +``` +Widgets and screens use this instead of manually comparing `status == TaskStatus.done`. + +### `lib/features/tasks/providers/task_providers.dart` +Added `uncompleteTask(int id)` method to `TasksNotifier` — sets status back to `pending`. +Added top-level alias: +```dart +final todayTasksProvider = tasksProvider; +``` +MVP does not filter by date; screens watch `todayTasksProvider` and split pending/completed themselves. + +### `lib/features/tasks/providers/pet_providers.dart` +Fixed `PetStateEntity` constructor: `id`/`userId` are `String` (`'1'`), `updatedAt` is required. +Added `onTaskCompleted()` method as a public alias for `incrementTasksDone()`. + +### `lib/features/tasks/screens/tasks_screen.dart` +- Watches `userProvider` (for `petType`, `petName`) and `petMoodProvider` (for mood string). +- `PetBubble` now receives `petName` from `userState` and `mood` from `petMoodProvider`. +- `_EmptyState` now accepts `PetType` (enum) instead of `String`, uses `petType.emoji`. +- Pet type resolved from `userState.petType`, not `petState.petType` (pet state doesn't own identity). + +--- + +## Key Decisions + +**Dual-param widget pattern**: Widgets accept both an entity param (`task: TaskEntity?`) and individual params (`title`, `energyLevel`, etc.). Private getters resolve which to use. This keeps backward compatibility for any callers passing raw values while enabling entity-driven usage from screens. + +**`PetType` canonical location**: `domain/entities/pet_type.dart` is the single source. `PetBubble` used to redeclare it locally — that local copy is removed. + +**`todayTasksProvider` is an alias**: Not a filtered provider. In MVP all tasks are "today" tasks. Screens handle the pending/completed split via `.where()`. If date-filtering is needed later, only this alias needs to change. + +**Pet identity vs. pet state**: `petType` and `petName` belong to the `User` entity (`userProvider`), not `PetStateEntity`. `PetStateEntity` tracks energy/streak/rewards only. + +--- + +## Tests Added + +83 new tests across 6 files: + +| File | Tests | +|------|-------| +| `test/domain/entities/task_entity_test.dart` | 12 | +| `test/domain/entities/pet_type_test.dart` | 12 | +| `test/domain/entities/pet_state_entity_test.dart` | 8 | +| `test/features/tasks/providers/task_providers_test.dart` | 16 | +| `test/features/tasks/providers/pet_providers_test.dart` | 24 | +| `test/shared/widgets/energy_badge_test.dart` | 13 | + +All 83 new tests pass. 2 pre-existing failures in `test/data/repositories/` require `build_runner` regeneration and are unrelated to this fix.