Files
HouseHoldKeaper/.planning/milestones/v1.1-phases/05-calendar-strip/05-02-SUMMARY.md
Jean-Luc Makiola edce11dd78 chore: complete v1.1 milestone
Archive v1.1 Calendar & Polish milestone artifacts (roadmap,
requirements, phase directories) to milestones/. Evolve PROJECT.md
with validated requirements and new key decisions. Update
RETROSPECTIVE.md with v1.1 section and cross-milestone trends.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 23:32:04 +01:00

9.0 KiB

phase, plan, subsystem, tags, requires, provides, affects, tech-stack, key-files, key-decisions, patterns-established, requirements-completed, duration, completed
phase plan subsystem tags requires provides affects tech-stack key-files key-decisions patterns-established requirements-completed duration completed
05-calendar-strip 02 ui
flutter
riverpod
dart
intl
animation
calendar
phase provides
05-calendar-strip plan 01 CalendarDao, CalendarDayState, selectedDateProvider, calendarDayProvider
CalendarStrip widget (181-day horizontal scroll, German abbreviations, month boundary labels)
CalendarTaskRow widget (task name + room tag chip + checkbox, no relative date)
CalendarDayList widget (loading/empty/celebration/tasks states, overdue section today-only)
Rewritten HomeScreen composing strip + day list with floating Today button
totalTaskCount field on CalendarDayState and getTaskCount() on CalendarDao
Updated home screen and app shell tests for new calendar providers
06-task-history (uses CalendarStrip as the navigation surface)
07-task-sorting (task display within CalendarDayList)
added patterns
CalendarStrip uses CalendarStripController (simple VoidCallback holder) for parent-to-child imperative scrolling
CalendarDayList manages _completingTaskIds Set<int> for slide-out animation the same way as old HomeScreen
Tests use tester.pump() + pump(Duration) instead of pumpAndSettle() to avoid timeout from animation controllers
created modified
lib/features/home/presentation/calendar_strip.dart
lib/features/home/presentation/calendar_task_row.dart
lib/features/home/presentation/calendar_day_list.dart
lib/features/home/presentation/home_screen.dart
lib/features/home/domain/calendar_models.dart
lib/features/home/data/calendar_dao.dart
lib/features/home/presentation/calendar_providers.dart
test/features/home/presentation/home_screen_test.dart
test/shell/app_shell_test.dart
CalendarStripController holds a VoidCallback instead of using GlobalKey — simpler for this one-direction imperative call
totalTaskCount fetched via getTaskCount() inside calendarDayProvider asyncMap — avoids a third stream, consistent with existing pattern
Tests use pump() + pump(Duration) instead of pumpAndSettle() — CalendarStrip's ScrollController postFrameCallback and animation controllers cause pumpAndSettle to timeout
month label height always reserved with SizedBox(height:16) on non-boundary cards — prevents strip height jitter as you scroll through months
ImperativeController pattern: class with VoidCallback? _action; void action() => _action?.call(); widget sets _action in initState
CalendarDayList state machine: first-run (totalTaskCount==0) > celebration (isToday + isEmpty + totalTaskCount>0) > emptyDay (isEmpty) > hasTasks
CAL-01
CAL-03
CAL-04
CAL-05
8min 2026-03-16

Phase 5 Plan 02: Calendar Strip UI Summary

Horizontal 181-day calendar strip with German day cards, month boundaries, floating Today button, and day task list with overdue section — replaces the stacked daily-plan HomeScreen

Performance

  • Duration: 8 min
  • Started: 2026-03-16T20:27:39Z
  • Completed: 2026-03-16T20:35:55Z
  • Tasks: 3 (Task 3 auto-approved in auto-advance mode)
  • Files modified: 9

Accomplishments

  • CalendarStrip: horizontal ListView with 181 day cards (90 past + today + 90 future), German abbreviations via DateFormat('E', 'de'), selected card highlighted (stronger primaryContainer + border), today card with bold text + 2px accent underline, month boundary wider gap + month label, auto-scrolls to center today on init, CalendarStripController enables Today-button → strip communication
  • CalendarDayList: five-state machine (loading, first-run empty, celebration, empty day, has tasks) with overdue section when viewing today, slide-out completion animation reusing the same SizeTransition + SlideTransition pattern from the old HomeScreen
  • CalendarTaskRow: simplified from DailyPlanTaskRow — no relative date, name + room chip + checkbox, coral text when isOverdue
  • HomeScreen rewritten: Stack with Column(CalendarStrip + Expanded(CalendarDayList)) and conditionally-visible FloatingActionButton.extended for "Heute" navigation
  • Added totalTaskCount to CalendarDayState and getTaskCount() SELECT COUNT to CalendarDao for first-run vs. celebration disambiguation
  • Updated 2 test files (home_screen_test.dart, app_shell_test.dart) to test new providers; test count grew from 100 to 101

Task Commits

Each task was committed atomically:

  1. Task 1: Build CalendarStrip, CalendarTaskRow, CalendarDayList widgets - f718ee8 (feat)
  2. Task 2: Replace HomeScreen with calendar composition - 88ef248 (feat)
  3. Task 3: Verify calendar strip visually - auto-approved (checkpoint:human-verify in auto-advance mode)

Files Created/Modified

  • lib/features/home/presentation/calendar_strip.dart - 181-day horizontal scrollable strip with German abbreviations, today/selected highlights, month boundary labels
  • lib/features/home/presentation/calendar_task_row.dart - Task row: name + room chip + checkbox, isOverdue coral styling, no relative date
  • lib/features/home/presentation/calendar_day_list.dart - Day task list with 5-state machine, overdue section (today only), slide-out animation
  • lib/features/home/presentation/home_screen.dart - Rewritten: CalendarStrip + CalendarDayList + floating Today FAB
  • lib/features/home/domain/calendar_models.dart - Added totalTaskCount field
  • lib/features/home/data/calendar_dao.dart - Added getTaskCount() query
  • lib/features/home/presentation/calendar_providers.dart - calendarDayProvider now fetches and includes totalTaskCount
  • test/features/home/presentation/home_screen_test.dart - Rewritten for CalendarDayState / calendarDayProvider
  • test/shell/app_shell_test.dart - Updated from dailyPlanProvider to calendarDayProvider

Decisions Made

  • CalendarStripController as simple VoidCallback holder: Avoids GlobalKey complexity for a single imperative scroll-to-today action; parent holds controller, widget registers its implementation in initState.
  • totalTaskCount fetched in asyncMap: Consistent with existing calendarDayProvider asyncMap pattern; avoids a third reactive stream just for a count.
  • Tests use pump() + pump(Duration) instead of pumpAndSettle(): ScrollController's postFrameCallback animation and _completingTaskIds AnimationController keep the tester busy indefinitely; fixed-duration pump steps are reliable.
  • Month label height always reserved: Non-boundary cards get SizedBox(height: 16) to match the label row height — prevents strip height from changing as you scroll across month edges.

Deviations from Plan

Auto-fixed Issues

1. [Rule 1 - Bug] Updated existing tests broken by the HomeScreen rewrite

  • Found during: Task 2 verification (flutter test)
  • Issue: home_screen_test.dart and app_shell_test.dart both imported dailyPlanProvider and DailyPlanState and used pumpAndSettle(), which now times out because CalendarStrip animation controllers never settle
  • Fix: Rewrote both test files to use calendarDayProvider/CalendarDayState and replaced pumpAndSettle() with pump() + pump(Duration(milliseconds: 500)); updated all assertions to match new UI (removed progress card / tomorrow section assertions, added strip-visible assertion)
  • Files modified: test/features/home/presentation/home_screen_test.dart, test/shell/app_shell_test.dart
  • Verification: flutter test — 101 tests all pass; flutter analyze --no-fatal-infos — zero issues
  • Committed in: f718ee8 (Task 1 commit, as tests were fixed alongside widget creation)

Total deviations: 1 auto-fixed (Rule 1 - Bug) Impact on plan: Required to maintain working test suite. The new tests cover the same behaviors (empty state, overdue section, celebration, checkboxes) but against the calendar API. No scope creep.

Issues Encountered

  • None beyond the test migration documented above.

User Setup Required

None - no external service configuration required.

Next Phase Readiness

  • HomeScreen is fully replaced; CalendarStrip and CalendarDayList are composable widgets ready for Phase 6/7 integration
  • The old daily_plan_providers.dart, daily_plan_task_row.dart, and progress_card.dart are now dead code; safe to clean up in a future phase
  • DailyPlanDao is still used by the notification service and must NOT be deleted

Phase: 05-calendar-strip Completed: 2026-03-16

Self-Check: PASSED

  • FOUND: lib/features/home/presentation/calendar_strip.dart
  • FOUND: lib/features/home/presentation/calendar_task_row.dart
  • FOUND: lib/features/home/presentation/calendar_day_list.dart
  • FOUND: lib/features/home/presentation/home_screen.dart (rewritten)
  • FOUND: lib/features/home/domain/calendar_models.dart (updated)
  • FOUND: lib/features/home/data/calendar_dao.dart (updated)
  • FOUND: lib/features/home/presentation/calendar_providers.dart (updated)
  • FOUND: .planning/phases/05-calendar-strip/05-02-SUMMARY.md
  • FOUND: commit f718ee8 (Task 1)
  • FOUND: commit 88ef248 (Task 2)