diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index 1a5e3b0..30432e1 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -17,8 +17,8 @@ Requirements for milestone v1.1 Calendar & Polish. Each maps to roadmap phases. ### Task History -- [ ] **HIST-01**: Each task completion is recorded with a timestamp -- [ ] **HIST-02**: User can view past completion dates for any individual task +- [x] **HIST-01**: Each task completion is recorded with a timestamp +- [x] **HIST-02**: User can view past completion dates for any individual task ### Task Sorting @@ -65,8 +65,8 @@ Which phases cover which requirements. Updated during roadmap creation. | CAL-03 | Phase 5 | Complete | | CAL-04 | Phase 5 | Complete | | CAL-05 | Phase 5 | Complete | -| HIST-01 | Phase 6 | Pending | -| HIST-02 | Phase 6 | Pending | +| HIST-01 | Phase 6 | Complete | +| HIST-02 | Phase 6 | Complete | | SORT-01 | Phase 7 | Pending | | SORT-02 | Phase 7 | Pending | | SORT-03 | Phase 7 | Pending | diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 1d8ba41..04d59cc 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -22,7 +22,7 @@ See `milestones/v1.0-ROADMAP.md` for full phase details. **v1.1 Calendar & Polish (Phases 5-7):** - [x] **Phase 5: Calendar Strip** - Replace the stacked daily plan home screen with a horizontal scrollable date-strip and day-task list (completed 2026-03-16) -- [ ] **Phase 6: Task History** - Record every task completion with a timestamp and expose a per-task history view +- [x] **Phase 6: Task History** - Record every task completion with a timestamp and expose a per-task history view (completed 2026-03-16) - [ ] **Phase 7: Task Sorting** - Add alphabetical, interval, and effort sort options to task lists ## Phase Details @@ -50,7 +50,7 @@ Plans: 1. Every task completion (tap done in any view) is recorded in the database with a precise timestamp — data persists across app restarts 2. From a task's detail or context menu the user can open a history view listing all past completion dates for that task in reverse-chronological order 3. The history view shows a meaningful empty state if the task has never been completed -**Plans:** 1 plan +**Plans:** 1/1 plans complete Plans: - [ ] 06-01-PLAN.md — DAO query + history bottom sheet + TaskFormScreen integration + CalendarTaskRow navigation @@ -74,5 +74,5 @@ Plans: | 3. Daily Plan and Cleanliness | v1.0 | 3/3 | Complete | 2026-03-16 | | 4. Notifications | v1.0 | 3/3 | Complete | 2026-03-16 | | 5. Calendar Strip | 2/2 | Complete | 2026-03-16 | - | -| 6. Task History | v1.1 | 0/1 | Planned | - | +| 6. Task History | 1/1 | Complete | 2026-03-16 | - | | 7. Task Sorting | v1.1 | 0/? | Not started | - | diff --git a/.planning/STATE.md b/.planning/STATE.md index be656e4..f3db769 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -1,17 +1,17 @@ --- gsd_state_version: 1.0 -milestone: v1.0 -milestone_name: milestone -status: completed -stopped_at: Phase 6 context gathered -last_updated: "2026-03-16T20:46:23.402Z" -last_activity: 2026-03-16 — Completed Phase 5 Plan 02 (calendar strip UI) +milestone: v1.1 +milestone_name: Calendar & Polish +status: in-progress +stopped_at: Completed Phase 6 Plan 01 (task history) +last_updated: "2026-03-16T20:57:30Z" +last_activity: 2026-03-16 — Completed Phase 6 Plan 01 (task completion history) progress: total_phases: 3 - completed_phases: 1 - total_plans: 2 - completed_plans: 2 - percent: 100 + completed_phases: 2 + total_plans: 3 + completed_plans: 3 + percent: 33 --- # Project State @@ -21,17 +21,17 @@ progress: See: .planning/PROJECT.md (updated 2026-03-16) **Core value:** Users can see what needs doing today, mark it done, and trust the app to schedule the next occurrence — without thinking about it. -**Current focus:** v1.1 Calendar & Polish — Phase 5: Calendar Strip +**Current focus:** v1.1 Calendar & Polish — Phase 6: Task History ## Current Position -Phase: 5 — Calendar Strip -Plan: 2/2 complete (Phase 5 done) +Phase: 6 — Task History +Plan: 1/1 complete (Phase 6 done) Status: Phase Complete -Last activity: 2026-03-16 — Completed Phase 5 Plan 02 (calendar strip UI) +Last activity: 2026-03-16 — Completed Phase 6 Plan 01 (task completion history) ``` -Progress: [██████████] 100% (2/2 plans in Phase 5) +Progress: [██████████] 100% (1/1 plans in Phase 6) ``` ## Performance Metrics @@ -44,6 +44,7 @@ Progress: [██████████] 100% (2/2 plans in Phase 5) | Tests | 89 | TBD | | Phase 05-calendar-strip P01 | 5 | 2 tasks | 10 files | | Phase 05-calendar-strip P02 | 8 | 3 tasks | 9 files | +| Phase 06-task-history P01 | 5 | 2 tasks | 9 files | ## Accumulated Context @@ -60,6 +61,8 @@ Progress: [██████████] 100% (2/2 plans in Phase 5) | watchTasksForDate sorts alphabetically by task name | Same-day tasks have no meaningful time-based order; alpha sort is deterministic and user-friendly | | CalendarStripController as VoidCallback holder | Avoids GlobalKey for single imperative scroll-to-today action — simpler | | Tests use pump()+pump(Duration) instead of pumpAndSettle() | CalendarStrip animation controllers cause pumpAndSettle timeout — fixed-duration pump steps are reliable | +| No separate Riverpod provider for history sheet | ref.read(appDatabaseProvider) directly in ConsumerWidget — one-shot modals do not need a dedicated provider | +| CalendarTaskRow onTap navigates to task edit form | Makes history accessible in one tap from home screen, consistent with GoRouter route patterns | ### Pending Todos @@ -71,7 +74,7 @@ None. ## Session Continuity -Last session: 2026-03-16T20:46:23.400Z -Stopped at: Phase 6 context gathered -Resume file: .planning/phases/06-task-history/06-CONTEXT.md -Next action: `/gsd:plan-phase 5` +Last session: 2026-03-16T20:57:30Z +Stopped at: Completed Phase 6 Plan 01 (task history) +Resume file: .planning/phases/06-task-history/06-01-SUMMARY.md +Next action: Phase 7 (task sorting) or release diff --git a/.planning/phases/06-task-history/06-01-SUMMARY.md b/.planning/phases/06-task-history/06-01-SUMMARY.md new file mode 100644 index 0000000..9d64350 --- /dev/null +++ b/.planning/phases/06-task-history/06-01-SUMMARY.md @@ -0,0 +1,131 @@ +--- +phase: 06-task-history +plan: 01 +subsystem: database, ui +tags: [drift, flutter, riverpod, go_router, intl, bottom-sheet, stream] + +# Dependency graph +requires: + - phase: 05-calendar-strip + provides: CalendarTaskRow widget and CalendarDayList that render tasks in the home screen +provides: + - watchCompletionsForTask(taskId) DAO stream on TasksDao — sorted newest-first + - task_history_sheet.dart with showTaskHistorySheet() function + - Verlauf ListTile in TaskFormScreen (edit mode) opening history bottom sheet + - CalendarTaskRow onTap navigation to TaskFormScreen for the tapped task +affects: [07-task-sorting, future-phases-using-TaskFormScreen] + +# Tech tracking +tech-stack: + added: [] + patterns: + - "Bottom sheet follows icon_picker_sheet pattern: showModalBottomSheet with isScrollControlled, ConsumerWidget inside, SafeArea > Padding > Column(mainAxisSize.min)" + - "StreamBuilder on DAO stream directly accessed via ref.read(appDatabaseProvider).tasksDao.methodName (no separate Riverpod provider for one-shot modals)" + - "TDD: RED test commit followed by GREEN implementation commit" + +key-files: + created: + - lib/features/tasks/presentation/task_history_sheet.dart + - test/features/tasks/data/task_history_dao_test.dart + modified: + - lib/features/tasks/data/tasks_dao.dart + - lib/features/tasks/data/tasks_dao.g.dart + - lib/features/tasks/presentation/task_form_screen.dart + - lib/features/home/presentation/calendar_task_row.dart + - lib/l10n/app_de.arb + - lib/l10n/app_localizations.dart + - lib/l10n/app_localizations_de.dart + +key-decisions: + - "No separate Riverpod provider for history sheet — ref.read(appDatabaseProvider) directly in ConsumerWidget keeps it simple for a one-shot modal" + - "CalendarTaskRow onTap routes to /rooms/:roomId/tasks/:taskId so history is always one tap away from the home screen" + - "Count summary line shown above list when completions > 0; not shown for empty state" + +patterns-established: + - "History sheet: showModalBottomSheet returning Future, ConsumerWidget sheet with StreamBuilder on DAO stream" + - "Edit-mode-only ListTile pattern: if (widget.isEditing) [...] in TaskFormScreen ListView children" + +requirements-completed: [HIST-01, HIST-02] + +# Metrics +duration: 5min +completed: 2026-03-16 +--- + +# Phase 6 Plan 1: Task History Summary + +**Drift DAO stream for task completion history, bottom sheet with reverse-chronological German-formatted dates, wired from CalendarTaskRow tap through TaskFormScreen Verlauf button** + +## Performance + +- **Duration:** 5 min +- **Started:** 2026-03-16T20:52:49Z +- **Completed:** 2026-03-16T20:57:19Z +- **Tasks:** 2 (Task 1 TDD: RED + GREEN + localization; Task 2: sheet + wiring + navigation) +- **Files modified:** 9 + +## Accomplishments +- `watchCompletionsForTask(int taskId)` added to TasksDao: returns `Stream>` sorted by completedAt DESC +- Task history bottom sheet (`task_history_sheet.dart`) with StreamBuilder, empty state, German date/time formatting via intl +- Verlauf ListTile added to TaskFormScreen edit mode, opens history sheet on tap +- CalendarTaskRow gains `onTap` that navigates via GoRouter to the task edit form, making history one tap away from the calendar + +## Task Commits + +Each task was committed atomically: + +1. **RED - Failing DAO tests** - `2687f5e` (test) +2. **Task 1: DAO method, localization** - `ceae7d7` (feat) +3. **Task 2: History sheet, form wiring, navigation** - `9f902ff` (feat) + +**Plan metadata:** (docs commit — see below) + +_Note: TDD tasks have separate RED (test) and GREEN (feat) commits_ + +## Files Created/Modified +- `lib/features/tasks/data/tasks_dao.dart` - Added watchCompletionsForTask stream method +- `lib/features/tasks/data/tasks_dao.g.dart` - Regenerated by build_runner +- `lib/features/tasks/presentation/task_history_sheet.dart` - New: bottom sheet with StreamBuilder, empty state, completion list +- `lib/features/tasks/presentation/task_form_screen.dart` - Added Verlauf ListTile in edit mode +- `lib/features/home/presentation/calendar_task_row.dart` - Added onTap navigation to task edit form +- `lib/l10n/app_de.arb` - Added taskHistoryTitle, taskHistoryEmpty, taskHistoryCount strings +- `lib/l10n/app_localizations.dart` - Regenerated (abstract class updated) +- `lib/l10n/app_localizations_de.dart` - Regenerated (German implementation updated) +- `test/features/tasks/data/task_history_dao_test.dart` - New: 5 tests covering empty state, single/multiple completions, task isolation, stream reactivity + +## Decisions Made +- No separate Riverpod provider for history sheet: `ref.read(appDatabaseProvider).tasksDao.watchCompletionsForTask(taskId)` directly in the ConsumerWidget. One-shot modals do not need a dedicated provider. +- CalendarTaskRow navigation uses `context.go('/rooms/.../tasks/...')` consistent with existing GoRouter route patterns. +- Removed unused `import 'package:drift/drift.dart'` from test file (Rule 1 auto-fix during GREEN verification). + +## Deviations from Plan + +### Auto-fixed Issues + +**1. [Rule 1 - Bug] Removed unused import from test file** +- **Found during:** Task 1 (GREEN phase, flutter analyze) +- **Issue:** `import 'package:drift/drift.dart'` was copied from the existing tasks_dao_test.dart pattern but not needed in the new history test file (no `Value()` usage) +- **Fix:** Removed the unused import line +- **Files modified:** test/features/tasks/data/task_history_dao_test.dart +- **Verification:** flutter analyze reports zero issues +- **Committed in:** ceae7d7 (Task 1 feat commit) + +--- + +**Total deviations:** 1 auto-fixed (1 bug — unused import) +**Impact on plan:** Trivial cleanup. No scope creep. + +## Issues Encountered +None — plan executed smoothly. All 106 tests pass (101 pre-existing + 5 new DAO tests), zero analyze issues. + +## User Setup Required +None - no external service configuration required. + +## Next Phase Readiness +- Phase 6 Plan 1 complete. Task history is fully functional. +- Phase 7 (task sorting) can proceed independently. +- No blockers. + +--- +*Phase: 06-task-history* +*Completed: 2026-03-16*