From c5ab052f9e6c659f5f0b51260f0fb584a0669269 Mon Sep 17 00:00:00 2001 From: Jean-Luc Makiola Date: Tue, 24 Mar 2026 09:47:49 +0100 Subject: [PATCH] feat(11-01): recalculate nextDueDate from today on non-due-day completion - When completing on due date: use original due date as base (preserves rhythm) - When completing on different day: use today as base (per D-02) - Replace todayDateOnly with todayStart used for both base calculation and catch-up - Update doc comment to reflect new behavior --- lib/features/tasks/data/tasks_dao.dart | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/lib/features/tasks/data/tasks_dao.dart b/lib/features/tasks/data/tasks_dao.dart index c9d96c1..4829236 100644 --- a/lib/features/tasks/data/tasks_dao.dart +++ b/lib/features/tasks/data/tasks_dao.dart @@ -35,8 +35,10 @@ class TasksDao extends DatabaseAccessor with _$TasksDaoMixin { /// Mark a task as done: records completion and calculates next due date. /// - /// Uses scheduling utility for date calculation. Next due is calculated - /// from the original due date (not completion date) to keep rhythm stable. + /// Uses scheduling utility for date calculation. If completing on the due + /// date, next due is calculated from the original due date (keeps rhythm). + /// If completing on a different day (early or late), next due is calculated + /// from today (per D-02: matches user mental model "I did it now, schedule next from now"). /// If the calculated next due is in the past, catch-up advances to present. /// /// [now] parameter allows injection of current time for testing. @@ -54,23 +56,24 @@ class TasksDao extends DatabaseAccessor with _$TasksDaoMixin { completedAt: currentTime, )); - // 3. Calculate next due date (from original due date, not today) + // 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: task.nextDueDate, + currentDueDate: baseDate, intervalType: task.intervalType, intervalDays: task.intervalDays, anchorDay: task.anchorDay, ); // 4. Catch up if next due is still in the past - final todayDateOnly = DateTime( - currentTime.year, - currentTime.month, - currentTime.day, - ); nextDue = catchUpToPresent( nextDue: nextDue, - today: todayDateOnly, + today: todayStart, intervalType: task.intervalType, intervalDays: task.intervalDays, anchorDay: task.anchorDay,