feat(08-01): add isActive column, migration v3, softDeleteTask and getCompletionCount

- Add isActive BoolColumn (default true) to Tasks table
- Bump schema version from 2 to 3 with addColumn migration
- Filter watchTasksInRoom to isActive=true only
- Filter getOverdueTaskCount to isActive=true only
- Add softDeleteTask(taskId) - sets isActive=false without removing data
- Add getCompletionCount(taskId) - counts TaskCompletions for a task
This commit is contained in:
2026-03-18 20:49:45 +01:00
parent a2cef91d7e
commit 4b51f5fa04
3 changed files with 98 additions and 6 deletions

View File

@@ -10,9 +10,10 @@ class TasksDao extends DatabaseAccessor<AppDatabase> with _$TasksDaoMixin {
TasksDao(super.attachedDatabase);
/// Watch tasks in a room sorted by nextDueDate ascending.
/// Only returns active tasks (isActive = true).
Stream<List<Task>> watchTasksInRoom(int roomId) {
return (select(tasks)
..where((t) => t.roomId.equals(roomId))
..where((t) => t.roomId.equals(roomId) & t.isActive.equals(true))
..orderBy([(t) => OrderingTerm.asc(t.nextDueDate)]))
.watch();
}
@@ -90,12 +91,13 @@ class TasksDao extends DatabaseAccessor<AppDatabase> with _$TasksDaoMixin {
}
/// Count overdue tasks in a room (nextDueDate before today).
/// Only counts active tasks (isActive = true).
Future<int> getOverdueTaskCount(int roomId, {DateTime? today}) async {
final now = today ?? DateTime.now();
final todayDateOnly = DateTime(now.year, now.month, now.day);
final taskList = await (select(tasks)
..where((t) => t.roomId.equals(roomId)))
..where((t) => t.roomId.equals(roomId) & t.isActive.equals(true)))
.get();
return taskList.where((task) {
@@ -107,4 +109,21 @@ class TasksDao extends DatabaseAccessor<AppDatabase> with _$TasksDaoMixin {
return dueDate.isBefore(todayDateOnly);
}).length;
}
/// Soft-delete a task by setting isActive to false.
/// The task and its completions remain in the database.
Future<void> softDeleteTask(int taskId) {
return (update(tasks)..where((t) => t.id.equals(taskId)))
.write(const TasksCompanion(isActive: Value(false)));
}
/// Count completions for a task.
Future<int> getCompletionCount(int taskId) async {
final count = taskCompletions.id.count();
final query = selectOnly(taskCompletions)
..addColumns([count])
..where(taskCompletions.taskId.equals(taskId));
final result = await query.getSingle();
return result.read(count) ?? 0;
}
}