Files

11 KiB

phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, must_haves
phase plan type wave depends_on files_modified autonomous requirements must_haves
11-issue-3-tasks-management-allow-task-checking-anytime-and-pre-populate-recurring-tasks 01 execute 1
lib/features/home/presentation/calendar_day_list.dart
lib/features/home/presentation/calendar_task_row.dart
lib/features/tasks/presentation/task_row.dart
lib/features/tasks/data/tasks_dao.dart
test/features/tasks/data/tasks_dao_test.dart
true
TM-01
TM-02
truths artifacts key_links
User can check off a task on any calendar day including future days
When completing a task on a non-due day, nextDueDate recalculates from today not from the original due date
Overdue tasks remain completable (no regression)
path provides contains
lib/features/home/presentation/calendar_day_list.dart Checkbox always enabled for all day tasks canComplete: true
path provides contains
lib/features/home/presentation/calendar_task_row.dart CalendarTaskRow with always-enabled checkbox canComplete
path provides
lib/features/tasks/presentation/task_row.dart TaskRow with always-enabled checkbox
path provides contains
lib/features/tasks/data/tasks_dao.dart completeTask with today-based recalculation calculateNextDueDate
from to via pattern
lib/features/home/presentation/calendar_day_list.dart CalendarTaskRow canComplete: true always passed canComplete: true
from to via pattern
lib/features/tasks/data/tasks_dao.dart scheduling.dart calculateNextDueDate uses today as base when completing on non-due day calculateNextDueDate
Enable anytime task completion: remove all checkbox-disable restrictions so users can mark tasks done on any calendar day (past, today, or future). When completing a task on a non-due day, recalculate nextDueDate from today (per D-02).

Purpose: Users should never be blocked from marking a task as done. The current behavior of disabling checkboxes for future tasks creates friction and confusion. Output: All checkboxes always enabled. completeTask() uses today as base for nextDueDate calculation when task is completed on a non-due day.

<execution_context> @$HOME/.claude/get-shit-done/workflows/execute-plan.md @$HOME/.claude/get-shit-done/templates/summary.md </execution_context>

@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/11-issue-3-tasks-management-allow-task-checking-anytime-and-pre-populate-recurring-tasks/11-CONTEXT.md

From lib/features/home/presentation/calendar_task_row.dart:

class CalendarTaskRow extends StatelessWidget {
  const CalendarTaskRow({
    super.key,
    required this.taskWithRoom,
    required this.onCompleted,
    this.isOverdue = false,
    this.showRoomTag = true,
    this.canComplete = true,  // Currently defaults to true but overridden with !isFuture
  });
  final bool canComplete; // When false, checkbox is disabled
}

From lib/features/tasks/data/tasks_dao.dart:

Future<void> completeTask(int taskId, {DateTime? now}) {
  // Step 3: calculates next due from task.nextDueDate (original due date)
  var nextDue = calculateNextDueDate(
    currentDueDate: task.nextDueDate,  // <-- This is the line to change for non-due-day
    ...
  );
}

From lib/features/tasks/domain/scheduling.dart:

DateTime calculateNextDueDate({
  required DateTime currentDueDate,
  required IntervalType intervalType,
  required int intervalDays,
  int? anchorDay,
});

DateTime catchUpToPresent({
  required DateTime nextDue,
  required DateTime today,
  required IntervalType intervalType,
  required int intervalDays,
  int? anchorDay,
});
Task 1: Remove checkbox-disable restrictions in all three UI files lib/features/home/presentation/calendar_day_list.dart lib/features/home/presentation/calendar_task_row.dart lib/features/tasks/presentation/task_row.dart lib/features/home/presentation/calendar_day_list.dart lib/features/home/presentation/calendar_task_row.dart lib/features/tasks/presentation/task_row.dart **Per D-01: Remove isFuture / canComplete restrictions.**
  1. calendar_day_list.dart (line ~271): In the _buildTaskList method, change the day tasks loop to always pass canComplete: true:

    • Remove the line final isFuture = state.selectedDate.isAfter(today); (line ~245)
    • Change canComplete: !isFuture (line ~271) to canComplete: true
    • The isFuture variable can be removed entirely since it is only used for canComplete
    • Keep the today variable — it is still used for isToday check in _buildContent
  2. calendar_task_row.dart: No changes needed. The canComplete parameter already defaults to true and the widget itself has no internal disable logic. The restriction was applied by the caller (calendar_day_list.dart).

  3. task_row.dart (lines ~45, ~60-62): Remove the isFuture check that disables the checkbox:

    • Remove line final isFuture = dueDate.isAfter(today); (line ~45)
    • Change the onChanged from the ternary isFuture ? null : (_) { ... } to always-enabled:
      onChanged: (_) {
        ref.read(taskActionsProvider.notifier).completeTask(task.id);
      },
      
    • The dueDate and isOverdue variables remain — they are used for styling the relative date text color grep -n "isFuture" lib/features/home/presentation/calendar_day_list.dart lib/features/tasks/presentation/task_row.dart; echo "---"; grep -n "canComplete: true" lib/features/home/presentation/calendar_day_list.dart <acceptance_criteria>
    • calendar_day_list.dart does NOT contain the string isFuture
    • calendar_day_list.dart contains canComplete: true in the _buildAnimatedTaskRow call for dayTasks
    • task_row.dart does NOT contain the string isFuture
    • task_row.dart does NOT contain ? null in the Checkbox onChanged handler
    • calendar_task_row.dart is unchanged (canComplete param still exists with default true) </acceptance_criteria> All checkboxes are always enabled across calendar and task list views. No isFuture guard remains in UI code.
Task 2: Update completeTask to recalculate nextDueDate from today on non-due-day completion lib/features/tasks/data/tasks_dao.dart test/features/tasks/data/tasks_dao_test.dart lib/features/tasks/data/tasks_dao.dart lib/features/tasks/domain/scheduling.dart test/features/tasks/data/tasks_dao_test.dart - Test: Completing a task ON its due date recalculates nextDueDate from the original due date (existing behavior preserved) - Test: Completing a weekly task 3 days BEFORE its due date recalculates nextDueDate from today (not original due date) — e.g., task due Friday, completed Tuesday, next due = next Tuesday - Test: Completing a daily task on a non-due day still produces tomorrow as next due - Test: Completing a monthly task early recalculates from today with anchor day preserved **Per D-02 and D-03: When completing a task on a non-due day, recalculate nextDueDate from today.**

In lib/features/tasks/data/tasks_dao.dart, method completeTask():

Change step 3 from:

// 3. Calculate next due date (from original due date, not today)
var nextDue = calculateNextDueDate(
  currentDueDate: task.nextDueDate,
  intervalType: task.intervalType,
  intervalDays: task.intervalDays,
  anchorDay: task.anchorDay,
);

To:

// 3. Calculate next due date
// If completing on the due date, use original due date as base (keeps rhythm).
// If completing on a different day (early or late), use today as base (per D-02).
final todayStart = DateTime(currentTime.year, currentTime.month, currentTime.day);
final taskDueDay = DateTime(task.nextDueDate.year, task.nextDueDate.month, task.nextDueDate.day);
final baseDate = todayStart == taskDueDay ? task.nextDueDate : todayStart;

var nextDue = calculateNextDueDate(
  currentDueDate: baseDate,
  intervalType: task.intervalType,
  intervalDays: task.intervalDays,
  anchorDay: task.anchorDay,
);

Note: The existing todayDateOnly variable (line 66-70) can be replaced by todayStart since they are the same. Rename to avoid duplication. The catch-up step (step 4) remains unchanged — it still ensures nextDue is not in the past.

Write 4 new test cases in test/features/tasks/data/tasks_dao_test.dart:

  1. completeTask on due date preserves rhythm — weekly task due 2026-03-24, complete on 2026-03-24, next due = 2026-03-31
  2. completeTask before due date recalculates from today — weekly task due 2026-03-28, complete on 2026-03-24, next due = 2026-03-31 (7 days from today)
  3. completeTask daily task on non-due day — daily task due 2026-03-26, complete on 2026-03-24, next due = 2026-03-25 (tomorrow)
  4. completeTask monthly task early preserves anchor — monthly task due 2026-03-28 anchorDay=28, complete on 2026-03-24, next due = 2026-04-28 cd /home/jean-luc-makiola/Development/projects/HouseHoldKeaper && flutter test test/features/tasks/data/tasks_dao_test.dart --reporter compact <acceptance_criteria>
    • tasks_dao.dart completeTask() contains final baseDate = todayStart == taskDueDay ? task.nextDueDate : todayStart;
    • tasks_dao.dart completeTask() passes currentDueDate: baseDate to calculateNextDueDate
    • tasks_dao_test.dart contains test with name matching completeTask.*before due date.*recalculates from today
    • tasks_dao_test.dart contains test with name matching completeTask.*on due date.*preserves rhythm
    • All tests in tasks_dao_test.dart pass (exit code 0) </acceptance_criteria> completeTask() uses today as base for non-due-day completions. 4 new tests verify the behavior for on-due-day, before-due-day, daily, and monthly scenarios. All existing tests still pass.
1. `flutter test` — all existing + new tests pass 2. `dart analyze` — zero issues 3. `grep -rn "isFuture" lib/features/home/presentation/calendar_day_list.dart lib/features/tasks/presentation/task_row.dart` — no matches 4. `grep -n "canComplete: true" lib/features/home/presentation/calendar_day_list.dart` — found in dayTasks loop

<success_criteria>

  • Checkboxes are always enabled on all calendar days (past, today, future)
  • Checkboxes are always enabled in room task list view
  • Completing a task on its due date preserves the original interval rhythm
  • Completing a task on a non-due day recalculates from today
  • All existing tests pass with zero regressions
  • dart analyze reports zero issues </success_criteria>
After completion, create `.planning/phases/11-issue-3-tasks-management-allow-task-checking-anytime-and-pre-populate-recurring-tasks/11-01-SUMMARY.md`