Problem
Schedule date ranges currently use inconsistent end-bound semantics. Domain/use-case code and docs describe inclusive-start/exclusive-end ranges, but the local DAO includes endDate. LoadSchedulesForMonthUseCase also computes the month end as midnight on the last calendar day, which can omit schedules later on the final day.
Evidence
lib/domain/use-cases/load_schedules_by_date_use_case.dart documents start inclusive and end exclusive.
lib/domain/use-cases/get_schedules_by_date_use_case.dart filters with >= startDate and < endDate.
plans/backend_alarm_feature_spec.md says the existing schedule range API uses scheduleTime >= startDate && scheduleTime < endDate.
lib/data/daos/schedule_dao.dart uses isSmallerOrEqualValue(endDate), making DAO reads end-inclusive.
lib/domain/use-cases/load_schedules_for_month_use_case.dart passes DateTime(date.year, date.month + 1, 0), midnight at the start of the last day.
- Existing tests cover exact-end exclusion in domain but miss exact-end DAO coverage.
Proposed direction
Use one schedule range contract everywhere: inclusive start, exclusive end. Change the DAO predicate to < endDate, update month loading to request [first day, first day of next month), and adjust tests to lock exact-boundary behavior.
Acceptance criteria
scheduleTime >= startDate && scheduleTime < endDate is the documented and implemented contract; endDate == null still means all schedules at/after startDate.
- Month loading for
DateTime(2026, 2, 14) requests DateTime(2026, 2, 1) through DateTime(2026, 3, 1).
- DAO/local data source tests cover start included, exact end excluded, last day of month included, and next month start excluded.
- Existing domain/calendar tests are updated to match the exclusive-end month boundary.
Source: Codex codebase audit on 2026-06-28.
Problem
Schedule date ranges currently use inconsistent end-bound semantics. Domain/use-case code and docs describe inclusive-start/exclusive-end ranges, but the local DAO includes
endDate.LoadSchedulesForMonthUseCasealso computes the month end as midnight on the last calendar day, which can omit schedules later on the final day.Evidence
lib/domain/use-cases/load_schedules_by_date_use_case.dartdocuments start inclusive and end exclusive.lib/domain/use-cases/get_schedules_by_date_use_case.dartfilters with>= startDateand< endDate.plans/backend_alarm_feature_spec.mdsays the existing schedule range API usesscheduleTime >= startDate && scheduleTime < endDate.lib/data/daos/schedule_dao.dartusesisSmallerOrEqualValue(endDate), making DAO reads end-inclusive.lib/domain/use-cases/load_schedules_for_month_use_case.dartpassesDateTime(date.year, date.month + 1, 0), midnight at the start of the last day.Proposed direction
Use one schedule range contract everywhere: inclusive start, exclusive end. Change the DAO predicate to
< endDate, update month loading to request[first day, first day of next month), and adjust tests to lock exact-boundary behavior.Acceptance criteria
scheduleTime >= startDate && scheduleTime < endDateis the documented and implemented contract;endDate == nullstill means all schedules at/afterstartDate.DateTime(2026, 2, 14)requestsDateTime(2026, 2, 1)throughDateTime(2026, 3, 1).Source: Codex codebase audit on 2026-06-28.