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
This commit is contained in:
2026-03-16 21:21:07 +01:00
parent f5c4b4928f
commit c666f9a1c6
4 changed files with 105 additions and 1 deletions

View File

@@ -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<AppDatabase>
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<List<TaskWithRoom>> 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<List<TaskWithRoom>> 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();
});
}
}