docs(05-01): complete calendar data layer plan — CalendarDao, providers, l10n
- 05-01-SUMMARY.md: execution results with deviations, decisions, self-check - STATE.md: current position updated to Plan 01 complete, 3 new decisions - ROADMAP.md: Phase 5 in progress (1/2 plans complete) - REQUIREMENTS.md: CAL-02 and CAL-05 marked complete
This commit is contained in:
@@ -10,10 +10,10 @@ Requirements for milestone v1.1 Calendar & Polish. Each maps to roadmap phases.
|
||||
### Calendar UI
|
||||
|
||||
- [ ] **CAL-01**: User sees a horizontal scrollable date-strip with day abbreviation (Mo, Di...) and date number per card
|
||||
- [ ] **CAL-02**: User can tap a day card to see that day's tasks in a list below the strip
|
||||
- [x] **CAL-02**: User can tap a day card to see that day's tasks in a list below the strip
|
||||
- [ ] **CAL-03**: User sees a subtle color shift at month boundaries for visual orientation
|
||||
- [ ] **CAL-04**: Calendar strip auto-scrolls to today on app launch
|
||||
- [ ] **CAL-05**: Undone tasks carry over to the next day with a red/orange color accent marking them as overdue
|
||||
- [x] **CAL-05**: Undone tasks carry over to the next day with a red/orange color accent marking them as overdue
|
||||
|
||||
### Task History
|
||||
|
||||
@@ -61,10 +61,10 @@ Which phases cover which requirements. Updated during roadmap creation.
|
||||
| Requirement | Phase | Status |
|
||||
|-------------|-------|--------|
|
||||
| CAL-01 | Phase 5 | Pending |
|
||||
| CAL-02 | Phase 5 | Pending |
|
||||
| CAL-02 | Phase 5 | Complete |
|
||||
| CAL-03 | Phase 5 | Pending |
|
||||
| CAL-04 | Phase 5 | Pending |
|
||||
| CAL-05 | Phase 5 | Pending |
|
||||
| CAL-05 | Phase 5 | Complete |
|
||||
| HIST-01 | Phase 6 | Pending |
|
||||
| HIST-02 | Phase 6 | Pending |
|
||||
| SORT-01 | Phase 7 | Pending |
|
||||
|
||||
@@ -37,7 +37,7 @@ See `milestones/v1.0-ROADMAP.md` for full phase details.
|
||||
3. On app launch the strip auto-scrolls so today's card is centered and selected by default
|
||||
4. When two adjacent day cards span a month boundary, a subtle color shift or divider makes the boundary visible without extra chrome
|
||||
5. Tasks that were not completed on their due date appear in subsequent days' lists with a red/orange accent marking them as overdue
|
||||
**Plans:** 2 plans
|
||||
**Plans:** 1/2 plans executed
|
||||
Plans:
|
||||
- [ ] 05-01-PLAN.md — Data layer: CalendarDao, CalendarDayState model, Riverpod providers, localization, DAO tests
|
||||
- [ ] 05-02-PLAN.md — UI: CalendarStrip, CalendarDayList, CalendarTaskRow widgets, HomeScreen replacement
|
||||
@@ -71,6 +71,6 @@ Plans:
|
||||
| 2. Rooms and Tasks | v1.0 | 5/5 | Complete | 2026-03-15 |
|
||||
| 3. Daily Plan and Cleanliness | v1.0 | 3/3 | Complete | 2026-03-16 |
|
||||
| 4. Notifications | v1.0 | 3/3 | Complete | 2026-03-16 |
|
||||
| 5. Calendar Strip | v1.1 | 0/2 | Planned | - |
|
||||
| 5. Calendar Strip | 1/2 | In Progress| | - |
|
||||
| 6. Task History | v1.1 | 0/? | Not started | - |
|
||||
| 7. Task Sorting | v1.1 | 0/? | Not started | - |
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
---
|
||||
gsd_state_version: 1.0
|
||||
milestone: v1.1
|
||||
milestone_name: Calendar & Polish
|
||||
status: ready
|
||||
stopped_at: Roadmap created — ready for Phase 5
|
||||
last_updated: "2026-03-16T21:00:00.000Z"
|
||||
last_activity: 2026-03-16 — Roadmap created for v1.1 (phases 5-7)
|
||||
milestone: v1.0
|
||||
milestone_name: milestone
|
||||
status: planning
|
||||
stopped_at: Completed 05-calendar-strip 05-01-PLAN.md
|
||||
last_updated: "2026-03-16T20:25:46.918Z"
|
||||
last_activity: 2026-03-16 — Roadmap for v1.1 written (phases 5-7)
|
||||
progress:
|
||||
total_phases: 3
|
||||
completed_phases: 0
|
||||
total_plans: 0
|
||||
completed_plans: 0
|
||||
total_plans: 2
|
||||
completed_plans: 1
|
||||
percent: 0
|
||||
---
|
||||
|
||||
@@ -26,12 +26,12 @@ See: .planning/PROJECT.md (updated 2026-03-16)
|
||||
## Current Position
|
||||
|
||||
Phase: 5 — Calendar Strip
|
||||
Plan: Not started
|
||||
Status: Ready to plan Phase 5
|
||||
Last activity: 2026-03-16 — Roadmap for v1.1 written (phases 5-7)
|
||||
Plan: 1/2 complete (Plan 01 done)
|
||||
Status: In Progress
|
||||
Last activity: 2026-03-16 — Completed Phase 5 Plan 01 (CalendarDao + providers)
|
||||
|
||||
```
|
||||
Progress: [ ░░░░░░░░░░░░░░░░░░░░ ] 0% (0/3 phases)
|
||||
Progress: [█████░░░░░] 50% (1/2 plans in Phase 5)
|
||||
```
|
||||
|
||||
## Performance Metrics
|
||||
@@ -42,6 +42,7 @@ Progress: [ ░░░░░░░░░░░░░░░░░░░░ ] 0% (0
|
||||
| Plans | 13 | TBD |
|
||||
| LOC (lib) | 7,773 | TBD |
|
||||
| Tests | 89 | TBD |
|
||||
| Phase 05-calendar-strip P01 | 5 | 2 tasks | 10 files |
|
||||
|
||||
## Accumulated Context
|
||||
|
||||
@@ -53,6 +54,9 @@ Progress: [ ░░░░░░░░░░░░░░░░░░░░ ] 0% (0
|
||||
| Phase 5 before Phase 6 and 7 | Calendar strip is the primary UI surface; history and sorting operate within or alongside it |
|
||||
| Phase 6 and 7 both depend on Phase 5 only | History and sorting are independent of each other — could execute in either order |
|
||||
| HIST-01 and HIST-02 in same phase | Data layer (HIST-01) is only 1-2 DAO additions; grouping with the UI (HIST-02) keeps the phase coherent |
|
||||
| Used NotifierProvider<SelectedDateNotifier> instead of deprecated StateProvider | Riverpod 3.x removed StateProvider; NotifierProvider is the correct replacement |
|
||||
| calendarDayProvider fetches overdue tasks with .first in asyncMap when isToday | Consistent with dailyPlanProvider pattern; avoids combining two streams |
|
||||
| watchTasksForDate sorts alphabetically by task name | Same-day tasks have no meaningful time-based order; alpha sort is deterministic and user-friendly |
|
||||
|
||||
### Pending Todos
|
||||
|
||||
@@ -60,12 +64,12 @@ None.
|
||||
|
||||
### Blockers/Concerns
|
||||
|
||||
- The existing HomeScreen (daily plan with overdue/today/upcoming) will be replaced entirely in Phase 5. Verify no other screen references the daily plan provider before deleting it, or migrate references.
|
||||
- CAL-05 (overdue carry-over with color accent) requires a query that returns tasks by their original due date relative to a selected day — confirm the existing DailyPlanDao can be adapted or a new CalendarDao is needed.
|
||||
- The existing HomeScreen (daily plan with overdue/today/upcoming) will be replaced entirely in Phase 5. Plan 02 will handle migrating or removing the dailyPlanProvider reference.
|
||||
- CAL-05 resolved: new CalendarDao created with date-parameterized queries; overdue tasks shown only when viewing today.
|
||||
|
||||
## Session Continuity
|
||||
|
||||
Last session: 2026-03-16
|
||||
Stopped at: Roadmap created, ready for Phase 5 planning
|
||||
Last session: 2026-03-16T20:25:46.916Z
|
||||
Stopped at: Completed 05-calendar-strip 05-01-PLAN.md
|
||||
Resume file: None
|
||||
Next action: `/gsd:plan-phase 5`
|
||||
|
||||
142
.planning/phases/05-calendar-strip/05-01-SUMMARY.md
Normal file
142
.planning/phases/05-calendar-strip/05-01-SUMMARY.md
Normal file
@@ -0,0 +1,142 @@
|
||||
---
|
||||
phase: 05-calendar-strip
|
||||
plan: 01
|
||||
subsystem: database
|
||||
tags: [drift, riverpod, dart, flutter, localization, tdd]
|
||||
|
||||
# Dependency graph
|
||||
requires: []
|
||||
provides:
|
||||
- CalendarDao with watchTasksForDate and watchOverdueTasks date-parameterized queries
|
||||
- CalendarDayState domain model with selectedDate/dayTasks/overdueTasks
|
||||
- selectedDateProvider (NotifierProvider, persists while app is alive)
|
||||
- calendarDayProvider (StreamProvider.autoDispose, overdue only for today)
|
||||
- calendarTodayButton l10n string in ARB and generated dart files
|
||||
- 11 DAO unit tests covering all query behaviors
|
||||
affects:
|
||||
- 05-calendar-strip plan 02 (calendar strip UI uses these providers and state model)
|
||||
|
||||
# Tech tracking
|
||||
tech-stack:
|
||||
added: []
|
||||
patterns:
|
||||
- "CalendarDao follows @DriftAccessor pattern with DatabaseAccessor<AppDatabase>"
|
||||
- "Manual NotifierProvider<SelectedDateNotifier, DateTime> instead of @riverpod (Riverpod 3.x pattern)"
|
||||
- "StreamProvider.autoDispose with asyncMap for combining day + overdue streams"
|
||||
- "TDD: failing test commit, then implementation commit"
|
||||
|
||||
key-files:
|
||||
created:
|
||||
- lib/features/home/data/calendar_dao.dart
|
||||
- lib/features/home/data/calendar_dao.g.dart
|
||||
- lib/features/home/domain/calendar_models.dart
|
||||
- lib/features/home/presentation/calendar_providers.dart
|
||||
- test/features/home/data/calendar_dao_test.dart
|
||||
modified:
|
||||
- lib/core/database/database.dart
|
||||
- lib/core/database/database.g.dart
|
||||
- lib/l10n/app_de.arb
|
||||
- lib/l10n/app_localizations.dart
|
||||
- lib/l10n/app_localizations_de.dart
|
||||
|
||||
key-decisions:
|
||||
- "Used NotifierProvider<SelectedDateNotifier, DateTime> instead of deprecated StateProvider — Riverpod 3.x removed StateProvider in favour of Notifier-based providers"
|
||||
- "calendarDayProvider fetches overdue tasks with .first when isToday, keeping asyncMap pattern consistent with dailyPlanProvider"
|
||||
- "watchTasksForDate sorts alphabetically by name (not by due time) — arbitrary due time on same day has no meaningful sort order"
|
||||
|
||||
patterns-established:
|
||||
- "CalendarDao: @DriftAccessor with join + where filter + orderBy, mapped to TaskWithRoom — same shape as DailyPlanDao"
|
||||
- "Manual Notifier subclass for simple value-holding state provider (not @riverpod) to avoid code gen constraints"
|
||||
|
||||
requirements-completed: [CAL-02, CAL-05]
|
||||
|
||||
# Metrics
|
||||
duration: 5min
|
||||
completed: 2026-03-16
|
||||
---
|
||||
|
||||
# Phase 5 Plan 01: Calendar Data Layer Summary
|
||||
|
||||
**CalendarDao with date-exact and overdue-before-date Drift queries, CalendarDayState model, Riverpod providers for selected date and day state, and "Heute" l10n string — full data foundation for the calendar strip UI**
|
||||
|
||||
## Performance
|
||||
|
||||
- **Duration:** 5 min
|
||||
- **Started:** 2026-03-16T20:18:55Z
|
||||
- **Completed:** 2026-03-16T20:24:12Z
|
||||
- **Tasks:** 2
|
||||
- **Files modified:** 10
|
||||
|
||||
## Accomplishments
|
||||
- CalendarDao registered in AppDatabase with two reactive Drift streams: `watchTasksForDate` (exact day, sorted by name) and `watchOverdueTasks` (strictly before reference date, sorted by due date)
|
||||
- CalendarDayState domain model separating dayTasks and overdueTasks with isEmpty helper
|
||||
- selectedDateProvider (NotifierProvider, keeps alive) + calendarDayProvider (StreamProvider.autoDispose) following existing Riverpod patterns
|
||||
- 11 unit tests passing via TDD red-green cycle; full 100-test suite passes with no regressions
|
||||
|
||||
## Task Commits
|
||||
|
||||
Each task was committed atomically:
|
||||
|
||||
1. **Task 1: RED - CalendarDao tests** - `f5c4b49` (test)
|
||||
2. **Task 1: GREEN - CalendarDao implementation** - `c666f9a` (feat)
|
||||
3. **Task 2: CalendarDayState, providers, l10n** - `68ba7c6` (feat)
|
||||
|
||||
## Files Created/Modified
|
||||
- `lib/features/home/data/calendar_dao.dart` - CalendarDao with watchTasksForDate and watchOverdueTasks
|
||||
- `lib/features/home/data/calendar_dao.g.dart` - Generated Drift mixin for CalendarDao
|
||||
- `lib/features/home/domain/calendar_models.dart` - CalendarDayState model
|
||||
- `lib/features/home/presentation/calendar_providers.dart` - selectedDateProvider and calendarDayProvider
|
||||
- `test/features/home/data/calendar_dao_test.dart` - 11 DAO unit tests (TDD RED phase)
|
||||
- `lib/core/database/database.dart` - Added CalendarDao import and registration in @DriftDatabase
|
||||
- `lib/core/database/database.g.dart` - Regenerated with CalendarDao accessor
|
||||
- `lib/l10n/app_de.arb` - Added calendarTodayButton: "Heute"
|
||||
- `lib/l10n/app_localizations.dart` - Regenerated with calendarTodayButton getter
|
||||
- `lib/l10n/app_localizations_de.dart` - Regenerated with calendarTodayButton implementation
|
||||
|
||||
## Decisions Made
|
||||
- **NotifierProvider instead of StateProvider:** Riverpod 3.x dropped `StateProvider` — replaced with `NotifierProvider<SelectedDateNotifier, DateTime>` pattern (manual, not @riverpod) to keep consistent with the codebase's non-generated providers.
|
||||
- **Overdue fetched with .first inside asyncMap:** When isToday, the overdue tasks stream's first emission is awaited inside asyncMap on the day tasks stream. This avoids combining two streams and stays consistent with the `dailyPlanProvider` pattern.
|
||||
- **watchTasksForDate sorts alphabetically by name:** Tasks due on the same calendar day have no meaningful relative order by time. Alphabetical name sort gives deterministic, user-friendly ordering.
|
||||
|
||||
## Deviations from Plan
|
||||
|
||||
### Auto-fixed Issues
|
||||
|
||||
**1. [Rule 1 - Bug] StateProvider unavailable in Riverpod 3.x**
|
||||
- **Found during:** Task 2 (calendar providers)
|
||||
- **Issue:** Plan specified `StateProvider<DateTime>` but flutter_riverpod 3.3.1 removed StateProvider; analyzer reported `undefined_function`
|
||||
- **Fix:** Replaced with `NotifierProvider<SelectedDateNotifier, DateTime>` using a minimal `Notifier` subclass with a `selectDate(DateTime)` method
|
||||
- **Files modified:** lib/features/home/presentation/calendar_providers.dart
|
||||
- **Verification:** `flutter analyze --no-fatal-infos` reports no issues
|
||||
- **Committed in:** 68ba7c6 (Task 2 commit)
|
||||
|
||||
---
|
||||
|
||||
**Total deviations:** 1 auto-fixed (Rule 1 - Bug)
|
||||
**Impact on plan:** Fix was required for compilation. The API surface is equivalent — consumers call `ref.watch(selectedDateProvider)` to read the date and `ref.read(selectedDateProvider.notifier).selectDate(date)` to update it. No scope creep.
|
||||
|
||||
## Issues Encountered
|
||||
- None beyond the StateProvider API change documented above.
|
||||
|
||||
## User Setup Required
|
||||
None - no external service configuration required.
|
||||
|
||||
## Next Phase Readiness
|
||||
- CalendarDao, CalendarDayState, selectedDateProvider, and calendarDayProvider are all ready for consumption by Plan 02 (calendar strip UI)
|
||||
- The `selectDate` method on SelectedDateNotifier is the correct way to update the selected date from the UI
|
||||
- Existing dailyPlanProvider is unchanged — Plan 02 will decide whether to replace or retain it in the HomeScreen
|
||||
|
||||
---
|
||||
*Phase: 05-calendar-strip*
|
||||
*Completed: 2026-03-16*
|
||||
|
||||
## Self-Check: PASSED
|
||||
|
||||
- FOUND: lib/features/home/data/calendar_dao.dart
|
||||
- FOUND: lib/features/home/domain/calendar_models.dart
|
||||
- FOUND: lib/features/home/presentation/calendar_providers.dart
|
||||
- FOUND: test/features/home/data/calendar_dao_test.dart
|
||||
- FOUND: .planning/phases/05-calendar-strip/05-01-SUMMARY.md
|
||||
- FOUND: commit f5c4b49 (test RED phase)
|
||||
- FOUND: commit c666f9a (feat GREEN phase)
|
||||
- FOUND: commit 68ba7c6 (feat Task 2)
|
||||
Reference in New Issue
Block a user