docs(06-01): complete task history plan

- Create 06-01-SUMMARY.md with full execution documentation
- Update STATE.md: Phase 6 Plan 1 complete, decisions recorded
- Update ROADMAP.md: Phase 6 marked complete (1/1 plans)
- Mark HIST-01 and HIST-02 requirements complete
This commit is contained in:
2026-03-16 21:59:00 +01:00
parent 9f902ff2c7
commit 7344933278
4 changed files with 160 additions and 26 deletions

View File

@@ -17,8 +17,8 @@ Requirements for milestone v1.1 Calendar & Polish. Each maps to roadmap phases.
### Task History ### Task History
- [ ] **HIST-01**: Each task completion is recorded with a timestamp - [x] **HIST-01**: Each task completion is recorded with a timestamp
- [ ] **HIST-02**: User can view past completion dates for any individual task - [x] **HIST-02**: User can view past completion dates for any individual task
### Task Sorting ### Task Sorting
@@ -65,8 +65,8 @@ Which phases cover which requirements. Updated during roadmap creation.
| CAL-03 | Phase 5 | Complete | | CAL-03 | Phase 5 | Complete |
| CAL-04 | Phase 5 | Complete | | CAL-04 | Phase 5 | Complete |
| CAL-05 | Phase 5 | Complete | | CAL-05 | Phase 5 | Complete |
| HIST-01 | Phase 6 | Pending | | HIST-01 | Phase 6 | Complete |
| HIST-02 | Phase 6 | Pending | | HIST-02 | Phase 6 | Complete |
| SORT-01 | Phase 7 | Pending | | SORT-01 | Phase 7 | Pending |
| SORT-02 | Phase 7 | Pending | | SORT-02 | Phase 7 | Pending |
| SORT-03 | Phase 7 | Pending | | SORT-03 | Phase 7 | Pending |

View File

@@ -22,7 +22,7 @@ See `milestones/v1.0-ROADMAP.md` for full phase details.
**v1.1 Calendar & Polish (Phases 5-7):** **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) - [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 7: Task Sorting** - Add alphabetical, interval, and effort sort options to task lists
## Phase Details ## 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 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 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 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: Plans:
- [ ] 06-01-PLAN.md — DAO query + history bottom sheet + TaskFormScreen integration + CalendarTaskRow navigation - [ ] 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 | | 3. Daily Plan and Cleanliness | v1.0 | 3/3 | Complete | 2026-03-16 |
| 4. Notifications | 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 | - | | 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 | - | | 7. Task Sorting | v1.1 | 0/? | Not started | - |

View File

@@ -1,17 +1,17 @@
--- ---
gsd_state_version: 1.0 gsd_state_version: 1.0
milestone: v1.0 milestone: v1.1
milestone_name: milestone milestone_name: Calendar & Polish
status: completed status: in-progress
stopped_at: Phase 6 context gathered stopped_at: Completed Phase 6 Plan 01 (task history)
last_updated: "2026-03-16T20:46:23.402Z" last_updated: "2026-03-16T20:57:30Z"
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: progress:
total_phases: 3 total_phases: 3
completed_phases: 1 completed_phases: 2
total_plans: 2 total_plans: 3
completed_plans: 2 completed_plans: 3
percent: 100 percent: 33
--- ---
# Project State # Project State
@@ -21,17 +21,17 @@ progress:
See: .planning/PROJECT.md (updated 2026-03-16) 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. **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 ## Current Position
Phase: 5Calendar Strip Phase: 6Task History
Plan: 2/2 complete (Phase 5 done) Plan: 1/1 complete (Phase 6 done)
Status: Phase Complete 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 ## Performance Metrics
@@ -44,6 +44,7 @@ Progress: [██████████] 100% (2/2 plans in Phase 5)
| Tests | 89 | TBD | | Tests | 89 | TBD |
| Phase 05-calendar-strip P01 | 5 | 2 tasks | 10 files | | Phase 05-calendar-strip P01 | 5 | 2 tasks | 10 files |
| Phase 05-calendar-strip P02 | 8 | 3 tasks | 9 files | | Phase 05-calendar-strip P02 | 8 | 3 tasks | 9 files |
| Phase 06-task-history P01 | 5 | 2 tasks | 9 files |
## Accumulated Context ## 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 | | 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 | | 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 | | 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 ### Pending Todos
@@ -71,7 +74,7 @@ None.
## Session Continuity ## Session Continuity
Last session: 2026-03-16T20:46:23.400Z Last session: 2026-03-16T20:57:30Z
Stopped at: Phase 6 context gathered Stopped at: Completed Phase 6 Plan 01 (task history)
Resume file: .planning/phases/06-task-history/06-CONTEXT.md Resume file: .planning/phases/06-task-history/06-01-SUMMARY.md
Next action: `/gsd:plan-phase 5` Next action: Phase 7 (task sorting) or release

View File

@@ -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<void>, 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<List<TaskCompletion>>` 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*