Files
2026-04-03 21:55:55 +02:00

15 KiB

phase, verified, status, score, re_verification, human_verification
phase verified status score re_verification human_verification
11-issue-3-tasks-management-allow-task-checking-anytime-and-pre-populate-recurring-tasks 2026-04-03T00:00:00Z human_needed 8/8 must-haves verified false
test expected why_human
Open the app on a day that is NOT a task due date for a weekly task (e.g. 3 days before due). Confirm the task appears in a 'Demnächst' section with reduced opacity. Task visible with ~55% opacity in a muted 'Demnächst' section below the regular day tasks. Visual rendering, Opacity widget behavior, and section layout cannot be verified without running the app on a device.
test expected why_human
Navigate to a future calendar day for a weekly task and check its checkbox. Verify the task disappears from that day and does not reappear as pre-populated on other days in the same period. Completion recorded, task removed from pre-populated list on all remaining days within the current interval window. Reactive stream behavior (watchCompletionsInRange filtering prePopulatedTasks) requires a live app session to validate end-to-end.
test expected why_human
Check that an overdue task still shows its coral/terracotta accent colour when viewed on today's date. Overdue tasks render task name in _overdueColor (0xFFE07A5F) with no opacity reduction. Visual color rendering requires a live device/simulator.
test expected why_human
Run flutter test and dart analyze in a Flutter-capable environment. All tests pass; dart analyze reports zero issues. Flutter SDK and dart CLI are not available in the verification shell environment. The SUMMARY notes the same constraint for Plan 01. Both plans document this as an environment limitation, not a code issue.

Phase 11: Allow Task Checking Anytime and Pre-Populate Recurring Tasks — Verification Report

Phase Goal: Users can complete tasks on any day regardless of schedule, and recurring tasks appear on all applicable days within their interval window — making the app feel like a consistent checklist rather than a rigid scheduler Verified: 2026-04-03 Status: human_needed (all automated checks pass; 4 items require live-app or Flutter SDK) Re-verification: No — initial verification


Goal Achievement

Observable Truths

# Truth Status Evidence
1 Checkboxes always enabled on all calendar days and in room task lists ✓ VERIFIED isFuture guard absent from both calendar_day_list.dart and task_row.dart; all canComplete calls pass true; task_row.dart onChanged is unconditional
2 Completing a task on a non-due day recalculates nextDueDate from today ✓ VERIFIED tasks_dao.dart:64final baseDate = todayStart == taskDueDay ? task.nextDueDate : todayStart; — explicit today-base path; calculateNextDueDate receives baseDate
3 A weekly task appears on all 7 days leading up to its due date ✓ VERIFIED _isInCurrentIntervalWindow checks selected.isAfter(prevDay) && selected.isBefore(dueDate); _calculatePreviousDueDate subtracts 7 days for weekly; provider feeds result into prePopulatedTasks
4 A monthly task appears on all days within its current month interval ✓ VERIFIED _calculatePreviousDueDate uses _subtractMonths with corrected total-month arithmetic for monthly/quarterly/yearly intervals
5 Tasks already completed in the current interval do not reappear as pre-populated ✓ VERIFIED watchCompletionsInRange(taskId, prevDue, nextDue+1day) called per candidate task; non-empty result skips the task
6 Pre-populated tasks have muted (reduced opacity) visual appearance ✓ VERIFIED calendar_task_row.dart:92return isPrePopulated ? Opacity(opacity: 0.55, child: tile) : tile;
7 Overdue tasks retain coral accent styling ✓ VERIFIED CalendarTaskRow applies _overdueColor to task name when isOverdue: true; pre-populated tasks are never overdue (excluded by overdueIds set in providers)
8 Tests written for all key behaviors ✓ VERIFIED 4 new tests in tasks_dao_test.dart (on-due-day, before-due-day, daily non-due, monthly-early-with-anchor); 9 new tests in calendar_dao_test.dart covering watchAllActiveRecurringTasks, watchAllActiveRecurringTasksInRoom, watchCompletionsInRange

Score: 8/8 truths verified


Required Artifacts

Plan 01 Artifacts

Artifact Expected Level 1 Exists Level 2 Substantive Level 3 Wired Status
lib/features/home/presentation/calendar_day_list.dart Checkbox always enabled for all day tasks ✓ — canComplete: true on all three call sites (overdue, day, pre-pop loops) ✓ — consumed by CalendarTaskRow widget ✓ VERIFIED
lib/features/home/presentation/calendar_task_row.dart CalendarTaskRow with always-enabled checkbox ✓ — canComplete param present, defaults true; isPrePopulated param added ✓ — rendered by calendar_day_list.dart ✓ VERIFIED
lib/features/tasks/presentation/task_row.dart TaskRow with always-enabled checkbox ✓ — onChanged: (_) { ref.read(...).completeTask(task.id); } unconditional; isFuture absent ✓ — widget used in room task list ✓ VERIFIED
lib/features/tasks/data/tasks_dao.dart completeTask with today-based recalculation ✓ — baseDate logic at lines 62-67; calculateNextDueDate(currentDueDate: baseDate, ...) ✓ — called by taskActionsProvider ✓ VERIFIED

Plan 02 Artifacts

Artifact Expected Level 1 Exists Level 2 Substantive Level 3 Wired Status
lib/features/home/data/calendar_dao.dart watchAllActiveRecurringTasks + watchCompletionsInRange queries ✓ — three new methods: watchAllActiveRecurringTasks (line 173), watchAllActiveRecurringTasksInRoom (line 193), watchCompletionsInRange (line 214) ✓ — called by calendar_providers.dart ✓ VERIFIED
lib/features/home/presentation/calendar_providers.dart Pre-population logic with isPrePopulated filtering ✓ — _isInCurrentIntervalWindow, _calculatePreviousDueDate, _subtractMonths helper functions; full pre-pop loop in both providers ✓ — CalendarDayState.prePopulatedTasks populated and passed to CalendarDayList ✓ VERIFIED
lib/features/home/domain/calendar_models.dart CalendarDayState with prePopulatedTasks field ✓ — final List<TaskWithRoom> prePopulatedTasks at line 13; isEmpty updated at line 30 ✓ — consumed by calendar_day_list.dart ✓ VERIFIED
lib/features/home/presentation/calendar_task_row.dart Visual distinction for pre-populated tasks ✓ — isPrePopulated param (line 29); Opacity(opacity: 0.55) wrapper (line 92) ✓ — isPrePopulated: true passed from calendar_day_list.dart pre-pop loop ✓ VERIFIED
lib/features/home/presentation/calendar_day_list.dart Renders pre-populated section with muted styling ✓ — "Demnächst" section header (line 280); isPrePopulated: true in loop (line 290); cleanup loop covers prePopulatedTasks (line 62) ✓ — reads from state.prePopulatedTasks ✓ VERIFIED

From To Via Status Evidence
calendar_day_list.dart CalendarTaskRow canComplete: true always passed ✓ WIRED Lines 262, 273, 289 all pass canComplete: true
tasks_dao.dart scheduling.dart calculateNextDueDate uses baseDate ✓ WIRED Line 66-71: currentDueDate: baseDate
calendar_providers.dart calendar_dao.dart watchAllActiveRecurringTasks stream ✓ WIRED Line 156: db.calendarDao.watchAllActiveRecurringTasks()
calendar_providers.dart scheduling.dart calculateNextDueDate determines window boundary ✓ WIRED _calculatePreviousDueDate is the inverse of calculateNextDueDate logic; same interval arithmetic applied in reverse
calendar_day_list.dart CalendarTaskRow isPrePopulated flag passed ✓ WIRED Line 290: isPrePopulated: true in pre-pop loop; line 337: propagated in _buildAnimatedTaskRow

Data-Flow Trace (Level 4)

Artifact Data Variable Source Produces Real Data Status
calendar_day_list.dart (pre-pop section) state.prePopulatedTasks calendarDayProvider / roomCalendarDayProviderwatchAllActiveRecurringTasks() DB stream filtered through _isInCurrentIntervalWindow and watchCompletionsInRange Yes — real DB queries; no hardcoded fallback ✓ FLOWING
calendar_task_row.dart (opacity) isPrePopulated boolean Passed from _buildAnimatedTaskRow with isPrePopulated: true for pre-pop section Yes — prop set from real state.prePopulatedTasks list ✓ FLOWING
tasks_dao.dart (baseDate) baseDate currentTime (injectable now param) vs task.nextDueDate from DB Yes — real DB task record ✓ FLOWING

Behavioral Spot-Checks

Flutter SDK and dart CLI unavailable in the verification shell environment. Static code verification performed in lieu of running tests.

Behavior Method Result Status
isFuture guard removed from calendar_day_list.dart grep -n "isFuture" No matches ✓ PASS
isFuture guard removed from task_row.dart grep -n "isFuture" No matches ✓ PASS
canComplete: true present in all day-task loops grep -n "canComplete" Lines 262, 273, 289 all true ✓ PASS
baseDate logic in completeTask grep -n "baseDate" Lines 62-67 match plan spec exactly ✓ PASS
4 new TDD tests present in tasks_dao_test.dart Content search Lines 320, 338, 356, 374 contain all 4 test cases ✓ PASS
9 new DAO tests present in calendar_dao_test.dart Content search watchAllActiveRecurringTasks (3 tests), watchAllActiveRecurringTasksInRoom (2 tests), watchCompletionsInRange (4 tests) ✓ PASS
All 5 plan commits present in git log git log --oneline b00806a, 3398aca, c5ab052, 9a67c51, 8cbe989 all found ✓ PASS
flutter test / dart analyze Not runnable in shell Flutter SDK absent ? SKIP

Requirements Coverage

Requirement Source Plan Description Status Evidence
TM-01 11-01 Checkboxes never disabled for future dates ✓ SATISFIED isFuture removed from calendar_day_list.dart and task_row.dart; canComplete: true hardcoded
TM-02 11-01 nextDueDate recalculated from today on non-due-day completion ✓ SATISFIED baseDate = todayStart when todayStart != taskDueDay in tasks_dao.dart:64
TM-03 11-02 Recurring tasks pre-populated on all days in interval window ✓ SATISFIED _isInCurrentIntervalWindow + _calculatePreviousDueDate in calendar_providers.dart; all interval types covered
TM-04 11-02 Pre-populated tasks already completed in current period hidden ✓ SATISFIED watchCompletionsInRange check in provider loop; task skipped when completions.isNotEmpty
TM-05 11-02 Pre-populated tasks have muted visual distinction ✓ SATISFIED Opacity(opacity: 0.55) wrapping ListTile in calendar_task_row.dart:92

All 5 requirements satisfied. No orphaned requirements detected (all TM-01 through TM-05 appear in plan frontmatter and are covered by code).


Anti-Patterns Found

No anti-patterns detected:

  • No TODO, FIXME, HACK, or placeholder comments in any modified file.
  • No return null, return [], or empty-body handlers that block goal.
  • No isFuture guards remaining anywhere in the modified UI files.
  • onChanged: (_) { ... } in task_row.dart is unconditional with real completeTask call.
  • The "Completing tasks always show full styling" comment at calendar_day_list.dart:327 is a documented design decision, not a stub.

Human Verification Required

1. Pre-populated task visual rendering

Test: Open the app and navigate to a calendar day that is within the interval window of a weekly task (e.g. 3 days before the task's due date). Scroll to see if the task appears below any due-today tasks. Expected: Task visible in a "Demnächst" section with roughly 55% opacity — noticeably dimmer than regular tasks. The section header text "Demnächst" appears in a muted colour. Why human: Opacity(0.55) correctness and the "Demnächst" section header layout can only be confirmed visually in a running app.

2. End-to-end pre-population filtering after completion

Test: On a calendar day within a weekly task's interval window (e.g. Monday, task due Friday), check the task's checkbox. Then navigate to Tuesday through Thursday for the same week. Expected: The task does NOT reappear as pre-populated on any remaining day in the same interval window after being completed. Why human: Requires a live Drift database session with reactive watchCompletionsInRange streams to verify filtering propagates correctly across day navigation.

3. Overdue task coral accent retention

Test: With an overdue task (nextDueDate before today), open today's calendar view. Confirm the overdue task's name text uses the coral/terracotta colour. Expected: Overdue task name in Color(0xFFE07A5F) with no opacity reduction. Pre-populated tasks (if any) appear below with reduced opacity — no style cross-contamination. Why human: Colour rendering and visual separation between sections require live rendering.

4. All tests pass and dart analyze clean

Test: In a shell with Flutter SDK: flutter test && dart analyze Expected: Exit code 0 for both commands. No analyzer warnings or errors. Why human: Flutter SDK (flutter) and Dart CLI (dart) are absent from the CI/verification shell. Both SUMMARY documents note this as an environment constraint. Code was verified correct through static inspection; test logic is substantive and matches the plan's specified expected values exactly.


Gaps Summary

No gaps found. All 8 observable truths are verified through static code analysis and commit presence checks. The phase goal is structurally achieved: checkboxes are unconditionally enabled, the today-base recalculation is implemented and tested, the pre-population provider logic is wired end-to-end from DAO queries through provider filtering to UI rendering, and the muted visual distinction is in place.

The 4 human verification items are confirmatory (not gap-closing) — they validate rendering quality and reactive behavior that cannot be checked without a running Flutter app.


Verified: 2026-04-03 Verifier: Claude (gsd-verifier)