From c666f9a1c625f5b29e283e4ee09af4e69b38e478 Mon Sep 17 00:00:00 2001 From: Jean-Luc Makiola Date: Mon, 16 Mar 2026 21:21:07 +0100 Subject: [PATCH] feat(05-01): implement CalendarDao with date-parameterized task queries - CalendarDao.watchTasksForDate: returns tasks due on a specific calendar day, sorted by name - CalendarDao.watchOverdueTasks: returns tasks due strictly before reference date, sorted by due date - Registered CalendarDao in AppDatabase @DriftDatabase annotation - Generated calendar_dao.g.dart and updated database.g.dart --- lib/core/database/database.dart | 3 +- lib/core/database/database.g.dart | 1 + lib/features/home/data/calendar_dao.dart | 77 ++++++++++++++++++++++ lib/features/home/data/calendar_dao.g.dart | 25 +++++++ 4 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 lib/features/home/data/calendar_dao.dart create mode 100644 lib/features/home/data/calendar_dao.g.dart diff --git a/lib/core/database/database.dart b/lib/core/database/database.dart index 70ac4a2..4d6708a 100644 --- a/lib/core/database/database.dart +++ b/lib/core/database/database.dart @@ -2,6 +2,7 @@ import 'package:drift/drift.dart'; import 'package:drift_flutter/drift_flutter.dart'; import 'package:path_provider/path_provider.dart'; +import '../../features/home/data/calendar_dao.dart'; import '../../features/home/data/daily_plan_dao.dart'; import '../../features/rooms/data/rooms_dao.dart'; import '../../features/tasks/data/tasks_dao.dart'; @@ -45,7 +46,7 @@ class TaskCompletions extends Table { @DriftDatabase( tables: [Rooms, Tasks, TaskCompletions], - daos: [RoomsDao, TasksDao, DailyPlanDao], + daos: [RoomsDao, TasksDao, DailyPlanDao, CalendarDao], ) class AppDatabase extends _$AppDatabase { AppDatabase([QueryExecutor? executor]) diff --git a/lib/core/database/database.g.dart b/lib/core/database/database.g.dart index bc01a7e..adae5b6 100644 --- a/lib/core/database/database.g.dart +++ b/lib/core/database/database.g.dart @@ -1246,6 +1246,7 @@ abstract class _$AppDatabase extends GeneratedDatabase { late final RoomsDao roomsDao = RoomsDao(this as AppDatabase); late final TasksDao tasksDao = TasksDao(this as AppDatabase); late final DailyPlanDao dailyPlanDao = DailyPlanDao(this as AppDatabase); + late final CalendarDao calendarDao = CalendarDao(this as AppDatabase); @override Iterable> get allTables => allSchemaEntities.whereType>(); diff --git a/lib/features/home/data/calendar_dao.dart b/lib/features/home/data/calendar_dao.dart new file mode 100644 index 0000000..62e515b --- /dev/null +++ b/lib/features/home/data/calendar_dao.dart @@ -0,0 +1,77 @@ +import 'package:drift/drift.dart'; + +import '../../../core/database/database.dart'; +import '../domain/daily_plan_models.dart'; + +part 'calendar_dao.g.dart'; + +/// DAO for calendar-based task queries. +/// +/// Provides date-parameterized queries to answer: +/// - "What tasks are due on date X?" +/// - "What tasks are overdue relative to today?" +@DriftAccessor(tables: [Tasks, Rooms, TaskCompletions]) +class CalendarDao extends DatabaseAccessor + with _$CalendarDaoMixin { + CalendarDao(super.attachedDatabase); + + /// Watch tasks whose [nextDueDate] falls on the given calendar day. + /// + /// Returns tasks sorted alphabetically by name. + /// Does NOT include overdue carry-over — only tasks originally due on [date]. + Stream> watchTasksForDate(DateTime date) { + final startOfDay = DateTime(date.year, date.month, date.day); + final endOfDay = startOfDay.add(const Duration(days: 1)); + + final query = select(tasks).join([ + innerJoin(rooms, rooms.id.equalsExp(tasks.roomId)), + ]); + query.where( + tasks.nextDueDate.isBiggerOrEqualValue(startOfDay) & + tasks.nextDueDate.isSmallerThanValue(endOfDay), + ); + query.orderBy([OrderingTerm.asc(tasks.name)]); + + return query.watch().map((rows) { + return rows.map((row) { + final task = row.readTable(tasks); + final room = row.readTable(rooms); + return TaskWithRoom( + task: task, + roomName: room.name, + roomId: room.id, + ); + }).toList(); + }); + } + + /// Watch tasks whose [nextDueDate] is strictly before [referenceDate]. + /// + /// Returns tasks sorted by [nextDueDate] ascending (oldest first). + /// Does NOT include tasks due on [referenceDate] itself. + Stream> watchOverdueTasks(DateTime referenceDate) { + final startOfReferenceDay = DateTime( + referenceDate.year, + referenceDate.month, + referenceDate.day, + ); + + final query = select(tasks).join([ + innerJoin(rooms, rooms.id.equalsExp(tasks.roomId)), + ]); + query.where(tasks.nextDueDate.isSmallerThanValue(startOfReferenceDay)); + query.orderBy([OrderingTerm.asc(tasks.nextDueDate)]); + + return query.watch().map((rows) { + return rows.map((row) { + final task = row.readTable(tasks); + final room = row.readTable(rooms); + return TaskWithRoom( + task: task, + roomName: room.name, + roomId: room.id, + ); + }).toList(); + }); + } +} diff --git a/lib/features/home/data/calendar_dao.g.dart b/lib/features/home/data/calendar_dao.g.dart new file mode 100644 index 0000000..834f4ab --- /dev/null +++ b/lib/features/home/data/calendar_dao.g.dart @@ -0,0 +1,25 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'calendar_dao.dart'; + +// ignore_for_file: type=lint +mixin _$CalendarDaoMixin on DatabaseAccessor { + $RoomsTable get rooms => attachedDatabase.rooms; + $TasksTable get tasks => attachedDatabase.tasks; + $TaskCompletionsTable get taskCompletions => attachedDatabase.taskCompletions; + CalendarDaoManager get managers => CalendarDaoManager(this); +} + +class CalendarDaoManager { + final _$CalendarDaoMixin _db; + CalendarDaoManager(this._db); + $$RoomsTableTableManager get rooms => + $$RoomsTableTableManager(_db.attachedDatabase, _db.rooms); + $$TasksTableTableManager get tasks => + $$TasksTableTableManager(_db.attachedDatabase, _db.tasks); + $$TaskCompletionsTableTableManager get taskCompletions => + $$TaskCompletionsTableTableManager( + _db.attachedDatabase, + _db.taskCompletions, + ); +}