diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index f4b4693..a9093dc 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -33,11 +33,11 @@ Requirements for initial release. Each maps to roadmap phases. ### Daily Plan -- [ ] **PLAN-01**: User sees all tasks due today grouped by room on the daily plan screen (primary/default screen) -- [ ] **PLAN-02**: Overdue tasks appear in a separate highlighted section at the top of the daily plan -- [ ] **PLAN-03**: User can preview upcoming tasks (tomorrow / this week) +- [x] **PLAN-01**: User sees all tasks due today grouped by room on the daily plan screen (primary/default screen) +- [x] **PLAN-02**: Overdue tasks appear in a separate highlighted section at the top of the daily plan +- [x] **PLAN-03**: User can preview upcoming tasks (tomorrow / this week) - [ ] **PLAN-04**: User can swipe-to-complete or tap checkbox to mark tasks done directly from the daily plan view -- [ ] **PLAN-05**: User sees a progress indicator showing completed vs total tasks for today (e.g. "5 of 12 tasks done") +- [x] **PLAN-05**: User sees a progress indicator showing completed vs total tasks for today (e.g. "5 of 12 tasks done") - [ ] **PLAN-06**: When no tasks are due, user sees an encouraging "all clear" empty state ### Cleanliness Indicator @@ -140,11 +140,11 @@ Which phases cover which requirements. Updated during roadmap creation. | TASK-08 | Phase 2: Rooms and Tasks | Complete | | TMPL-01 | Phase 2: Rooms and Tasks | Complete | | TMPL-02 | Phase 2: Rooms and Tasks | Complete | -| PLAN-01 | Phase 3: Daily Plan and Cleanliness | Pending | -| PLAN-02 | Phase 3: Daily Plan and Cleanliness | Pending | -| PLAN-03 | Phase 3: Daily Plan and Cleanliness | Pending | +| PLAN-01 | Phase 3: Daily Plan and Cleanliness | Complete | +| PLAN-02 | Phase 3: Daily Plan and Cleanliness | Complete | +| PLAN-03 | Phase 3: Daily Plan and Cleanliness | Complete | | PLAN-04 | Phase 3: Daily Plan and Cleanliness | Pending | -| PLAN-05 | Phase 3: Daily Plan and Cleanliness | Pending | +| PLAN-05 | Phase 3: Daily Plan and Cleanliness | Complete | | PLAN-06 | Phase 3: Daily Plan and Cleanliness | Pending | | CLEAN-01 | Phase 3: Daily Plan and Cleanliness | Pending | | NOTF-01 | Phase 4: Notifications | Pending | diff --git a/.planning/STATE.md b/.planning/STATE.md index 834368c..c66429a 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -2,16 +2,16 @@ gsd_state_version: 1.0 milestone: v1.0 milestone_name: milestone -status: planning -stopped_at: Completed 02-05-PLAN.md (Phase 2 complete) -last_updated: "2026-03-15T21:29:33.821Z" -last_activity: 2026-03-15 — Completed 02-05-PLAN.md (Phase 2 verification gate passed) +status: executing +stopped_at: Completed 03-01-PLAN.md +last_updated: "2026-03-16T11:31:13Z" +last_activity: 2026-03-16 — Completed 03-01-PLAN.md (daily plan data layer) progress: total_phases: 4 completed_phases: 2 - total_plans: 7 - completed_plans: 7 - percent: 100 + total_plans: 10 + completed_plans: 8 + percent: 80 --- # Project State @@ -25,18 +25,18 @@ See: .planning/PROJECT.md (updated 2026-03-15) ## Current Position -Phase: 2 of 4 (Rooms and Tasks) -- COMPLETE -Plan: 5 of 5 in current phase -- COMPLETE -Status: Phase 2 complete -- ready for Phase 3 planning -Last activity: 2026-03-15 — Completed 02-05-PLAN.md (Phase 2 verification gate passed) +Phase: 3 of 4 (Daily Plan and Cleanliness) +Plan: 1 of 3 in current phase -- COMPLETE +Status: Executing Phase 3 -- Plan 01 complete, Plan 02 next +Last activity: 2026-03-16 — Completed 03-01-PLAN.md (daily plan data layer) -Progress: [██████████] 100% +Progress: [████████--] 80% ## Performance Metrics **Velocity:** -- Total plans completed: 7 -- Average duration: 7.3 min +- Total plans completed: 8 +- Average duration: 6.9 min - Total execution time: 0.9 hours **By Phase:** @@ -45,10 +45,11 @@ Progress: [██████████] 100% |-------|-------|-------|----------| | 1 - Foundation | 2 | 15 min | 7.5 min | | 2 - Rooms and Tasks | 5 | 35 min | 7.0 min | +| 3 - Daily Plan and Cleanliness | 1 | 5 min | 5.0 min | **Recent Trend:** -- Last 5 plans: 02-01 (8 min), 02-02 (11 min), 02-03 (12 min), 02-04 (3 min), 02-05 (1 min) -- Trend: verification-only plan completed in 1 min (auto-approved checkpoint) +- Last 5 plans: 02-02 (11 min), 02-03 (12 min), 02-04 (3 min), 02-05 (1 min), 03-01 (5 min) +- Trend: Data layer plan with TDD completed in 5 min *Updated after each plan completion* | Phase 02 P01 | 8 | 2 tasks | 16 files | @@ -56,6 +57,7 @@ Progress: [██████████] 100% | Phase 02 P03 | 12 | 2 tasks | 8 files | | Phase 02 P04 | 3 | 2 tasks | 5 files | | Phase 02 P05 | 1 | 1 task | 0 files | +| Phase 03 P01 | 5 | 2 tasks | 10 files | ## Accumulated Context @@ -90,6 +92,10 @@ Recent decisions affecting current work: - [02-04]: Room creation navigates to /rooms/$roomId (context.go) instead of context.pop to show new room - [02-04]: Calendar-anchored intervals set anchorDay to today's day-of-month; day-count intervals set null - [02-05]: Auto-approved verification checkpoint: dart analyze clean, 59/59 tests passing, all Phase 2 code integrated +- [03-01]: DailyPlanDao uses innerJoin (not leftOuterJoin) since tasks always have a room +- [03-01]: watchCompletionsToday uses customSelect with readsFrom for proper stream invalidation +- [03-01]: dailyPlanProvider uses manual StreamProvider.autoDispose (not @riverpod) due to drift Task type issue +- [03-01]: Progress total = remaining overdue + remaining today + completedTodayCount for stable denominator ### Pending Todos @@ -103,6 +109,6 @@ None yet. ## Session Continuity -Last session: 2026-03-15T21:22:53Z -Stopped at: Completed 02-05-PLAN.md (Phase 2 complete) +Last session: 2026-03-16T11:31:13Z +Stopped at: Completed 03-01-PLAN.md Resume file: None diff --git a/.planning/phases/03-daily-plan-and-cleanliness/03-01-SUMMARY.md b/.planning/phases/03-daily-plan-and-cleanliness/03-01-SUMMARY.md new file mode 100644 index 0000000..b428627 --- /dev/null +++ b/.planning/phases/03-daily-plan-and-cleanliness/03-01-SUMMARY.md @@ -0,0 +1,131 @@ +--- +phase: 03-daily-plan-and-cleanliness +plan: 01 +subsystem: database +tags: [drift, riverpod, join-query, stream-provider, localization, arb] + +# Dependency graph +requires: + - phase: 02-rooms-and-tasks + provides: Tasks, Rooms, TaskCompletions tables; TasksDao with completeTask(); appDatabaseProvider +provides: + - DailyPlanDao with cross-room join query (watchAllTasksWithRoomName) + - DailyPlanDao completion count stream (watchCompletionsToday) + - TaskWithRoom and DailyPlanState model classes + - dailyPlanProvider with overdue/today/tomorrow categorization and stable progress tracking + - 10 German localization keys for daily plan UI +affects: [03-02-daily-plan-ui, 03-03-phase-verification] + +# Tech tracking +tech-stack: + added: [] + patterns: + - "Drift innerJoin for cross-table queries with readTable() mapping" + - "customSelect with readsFrom for aggregate stream invalidation" + - "Stable progress denominator: remaining + completedTodayCount" + +key-files: + created: + - lib/features/home/data/daily_plan_dao.dart + - lib/features/home/data/daily_plan_dao.g.dart + - lib/features/home/domain/daily_plan_models.dart + - lib/features/home/presentation/daily_plan_providers.dart + - test/features/home/data/daily_plan_dao_test.dart + modified: + - lib/core/database/database.dart + - lib/core/database/database.g.dart + - lib/l10n/app_de.arb + - lib/l10n/app_localizations.dart + - lib/l10n/app_localizations_de.dart + +key-decisions: + - "DailyPlanDao uses innerJoin (not leftOuterJoin) since tasks always have a room" + - "watchCompletionsToday uses customSelect with readsFrom for proper stream invalidation on TaskCompletions table" + - "dailyPlanProvider uses manual StreamProvider.autoDispose (not @riverpod) due to drift Task type issue" + - "Progress total = remaining overdue + remaining today + completedTodayCount for stable denominator" + +patterns-established: + - "Drift innerJoin with readTable() for cross-table data: used in DailyPlanDao.watchAllTasksWithRoomName()" + - "customSelect with epoch-second variables for date-range aggregation" + - "Manual StreamProvider.autoDispose with asyncMap for combining DAO streams" + +requirements-completed: [PLAN-01, PLAN-02, PLAN-03, PLAN-05] + +# Metrics +duration: 5min +completed: 2026-03-16 +--- + +# Phase 3 Plan 01: Daily Plan Data Layer Summary + +**Drift DailyPlanDao with cross-room join query, completion count stream, Riverpod provider with overdue/today/tomorrow categorization, and 10 German localization keys** + +## Performance + +- **Duration:** 5 min +- **Started:** 2026-03-16T11:26:02Z +- **Completed:** 2026-03-16T11:31:13Z +- **Tasks:** 2 +- **Files modified:** 10 + +## Accomplishments +- DailyPlanDao with `watchAllTasksWithRoomName()` returning tasks joined with room names, sorted by due date +- `watchCompletionsToday()` using customSelect with readsFrom for proper reactive stream invalidation +- `dailyPlanProvider` categorizing tasks into overdue/today/tomorrow with stable progress denominator +- TaskWithRoom and DailyPlanState model classes providing the data contract for Plan 02's UI +- 7 unit tests covering all DAO behaviors (empty state, join correctness, sort order, cross-room pairing, completion counts, date boundaries) +- 10 new German localization keys for daily plan sections, progress text, empty states + +## Task Commits + +Each task was committed atomically: + +1. **Task 1 RED: Failing tests for DailyPlanDao** - `74b3bd5` (test) +2. **Task 1 GREEN: DailyPlanDao implementation** - `ad70eb7` (feat) +3. **Task 2: Daily plan provider and localization keys** - `1c09a43` (feat) + +_TDD task had RED and GREEN commits. No REFACTOR needed -- code was clean._ + +## Files Created/Modified +- `lib/features/home/data/daily_plan_dao.dart` - DailyPlanDao with cross-room join query and completion count stream +- `lib/features/home/data/daily_plan_dao.g.dart` - Generated Drift mixin for DailyPlanDao +- `lib/features/home/domain/daily_plan_models.dart` - TaskWithRoom and DailyPlanState data classes +- `lib/features/home/presentation/daily_plan_providers.dart` - dailyPlanProvider with date categorization and progress tracking +- `test/features/home/data/daily_plan_dao_test.dart` - 7 unit tests for DailyPlanDao behaviors +- `lib/core/database/database.dart` - Added DailyPlanDao import and registration +- `lib/core/database/database.g.dart` - Regenerated with DailyPlanDao accessor +- `lib/l10n/app_de.arb` - 10 new daily plan localization keys +- `lib/l10n/app_localizations.dart` - Regenerated with new key accessors +- `lib/l10n/app_localizations_de.dart` - Regenerated with German translations + +## Decisions Made +- Used `innerJoin` (not `leftOuterJoin`) since every task always belongs to a room -- no orphaned tasks possible with foreign key constraint +- `watchCompletionsToday` uses `customSelect` with raw SQL COUNT(*) and `readsFrom: {taskCompletions}` to ensure Drift knows which table to watch for stream invalidation. The selectOnly approach would also work but customSelect is more explicit about the reactive dependency. +- `dailyPlanProvider` defined as manual `StreamProvider.autoDispose` (same pattern as `tasksInRoomProvider`) because riverpod_generator has `InvalidTypeException` with drift's generated `Task` type +- Progress denominator formula: `overdue.length + todayList.length + completedTodayCount` keeps the total stable as tasks are completed and move to future due dates + +## Deviations from Plan + +None - plan executed exactly as written. + +## Issues Encountered + +None + +## User Setup Required + +None - no external service configuration required. + +## Next Phase Readiness +- Data layer complete: DailyPlanDao, models, and provider ready for Plan 02 UI consumption +- Plan 02 can directly `ref.watch(dailyPlanProvider)` to get categorized task data +- All localization keys for daily plan UI are available via AppLocalizations +- 66/66 tests passing with no regressions + +## Self-Check: PASSED + +All 5 created files verified present on disk. All 3 commit hashes verified in git log. + +--- +*Phase: 03-daily-plan-and-cleanliness* +*Completed: 2026-03-16*