# Project Research Summary **Project:** HouseHoldKeaper **Domain:** Local-first Flutter household chore management app (Android-first) **Researched:** 2026-03-15 **Confidence:** HIGH ## Executive Summary HouseHoldKeaper occupies a genuine market gap: every competing chore app (Tody, Sweepy, BeTidy, OurHome) requires either a subscription, cloud sync, or an account to be useful. None are fully private, fully free, and room-organized simultaneously. The recommended approach is a clean-architecture Flutter app using Riverpod 3 for state management and Drift for reactive SQLite — a combination that is now well-documented, has strong community templates, and maps cleanly to the feature requirements. The "local-first" constraint is not a limitation to work around; it is the product's core differentiator and shapes every architectural decision in a positive direction. The recommended build order follows strict feature dependency: rooms must exist before tasks, tasks before auto-scheduling, auto-scheduling before the daily plan view. This dependency chain also defines the phase structure — each phase produces a working increment that can be evaluated. The stack chosen (Flutter 3.41, Riverpod 3.3, Drift 2.32, Freezed 3.2) is current-stable with verified pub.dev versions; all major version combinations are explicitly compatible. The code-generation layer (build_runner, riverpod_generator, drift_dev, freezed) means initial setup is non-trivial but the reward is compile-safe, type-safe, low-boilerplate code throughout. The highest-risk area is not implementation complexity but correctness in two specific subsystems: due-date scheduling (timezone/date arithmetic edge cases) and Android notification permissions (API 33+ runtime permission requirements). Both are well-understood problems with documented solutions, but both fail silently in development and only surface on real devices. Addressing these with unit tests and physical device verification before marking them "done" eliminates the most likely post-ship bugs. ## Key Findings ### Recommended Stack The stack is fully determined by prior project decisions (Riverpod, Drift) plus version research that confirms the correct current-stable versions. The critical compatibility constraint is Flutter 3.41+ (Dart 3.7+) for Riverpod 3.3 — pre-3.41 Flutter has a transitive analyzer conflict that was fixed in 3.41.1. All library pairs with major version coupling (drift/drift_dev, riverpod_generator/riverpod_annotation, freezed/freezed_annotation) have been verified to match. See `.planning/research/STACK.md` for the complete `pubspec.yaml` and alternatives considered. **Core technologies:** - Flutter 3.41 / Dart 3.7: UI framework — minimum required by Riverpod 3.3; current stable - flutter_riverpod 3.3.1: State management and DI — `@riverpod` code-gen is the correct path; start on v3, migrating from v2 is painful - drift 2.32 + drift_flutter 0.3: Reactive SQLite ORM — `.watch()` streams integrate naturally with Riverpod `StreamProvider`; type-safe compile-time queries - freezed 3.2.5: Immutable domain entities — eliminates hand-written `==`/`copyWith`; required for all domain objects - go_router 17.1: Navigation — official Flutter team package; `ShellRoute` handles bottom nav with persistent tab state - flutter_local_notifications 21.0: On-device scheduled notifications — no Firebase needed; requires Android API 24+ - flex_color_scheme 8.4: Material 3 theme generation — fills legacy color sync gaps that `ColorScheme.fromSeed()` misses **What not to use:** Firebase (any service), Provider package, Riverpod legacy providers (StateNotifierProvider/StateProvider), Hive, GetIt, MobX, flutter_bloc alongside Riverpod. ### Expected Features The feature research identified a clear three-tier MVP definition. The core scheduling loop (room → task → auto-schedule → daily plan → mark done → reschedule) must be proven before adding any differentiators. The cleanliness indicator is a P1 because it is derived from existing data with no additional database work — it costs almost nothing to include at MVP. See `.planning/research/FEATURES.md` for the full competitor analysis and feature prioritization matrix. **Must have (table stakes):** - Room CRUD with icons — primary organizational unit; every competitor uses rooms - Task CRUD with recurrence intervals (daily/every N days/weekly/monthly/seasonal) — core scheduling primitive - Auto-scheduling next due date on completion — the "fire and forget" reliability promise - Daily plan view with three-band layout (Overdue / Due Today / Upcoming) — primary answer to "what do I do now?" - Task completion action — the satisfying feedback loop closure - Bundled task templates per room type (German) — eliminates blank-slate setup anxiety - Daily summary notification — single notification sufficient; per-task reminders are scope creep - Light/dark theme (system-default follow) — Material 3 baseline expectation - Cleanliness indicator per room — derived from overdue task ratio; zero marginal database complexity - Task sorting by due date — minimum list usability **Should have (competitive):** - Task history / completion log — couples accountability use case; Drift makes storage trivial once completions are being recorded - Vacation / pause mode — first travel use case will surface this immediately - Data export/import (JSON) — specified in PROJECT.md for v1.1 - Task effort/duration tagging — enables time-based filtering ("I have 20 minutes") - One-time project task type — "Paint the hallway" use case; single model flag, minimal complexity **Defer (v2+):** - Statistics and insights dashboard — high UI complexity; requires historical data volume to be meaningful - Self-hosted sync (CouchDB/SQLite replication) — the principled multi-device answer; complex - Tablet-optimized layout — secondary form factor - Onboarding wizard — overkill for initial personal use - Custom accent color picker — non-core personalization **Anti-features to reject:** Cloud sync, family profiles/user accounts, gamification, in-app purchases, AI task suggestions, per-task push notifications. ### Architecture Approach The recommended architecture is Clean Architecture with a feature-first folder structure: `core/` for the shared `AppDatabase` singleton and `NotificationService`, and `features/rooms/`, `features/tasks/`, `features/daily_plan/`, `features/completions/`, `features/templates/` each with their own `data/domain/presentation` split. This mirrors the standard Flutter/Riverpod community pattern and makes the build order self-evident — domain defines contracts, data implements them, presentation consumes them. See `.planning/research/ARCHITECTURE.md` for the full system diagram, data flow diagrams, and anti-patterns. **Major components:** 1. AppDatabase (Drift singleton) — root database; all DAOs are getters on this single instance; registered via one Riverpod provider at app root 2. Feature DAOs (RoomDao, TaskDao, CompletionDao) — type-safe SQL wrappers; thin, no business logic; expose reactive `.watch()` streams 3. Repository interfaces + implementations — domain defines abstract contracts; data layer implements using DAOs; presentation never imports from `data/` directly 4. Riverpod StreamProviders — expose Drift `.watch()` streams to UI; use `keepAlive: true` for long-lived app-wide state (room list, task list, daily plan) 5. Riverpod AsyncNotifiers — handle all mutations (create/complete/delete); call repository, let Drift streams propagate changes automatically 6. SchedulingService (domain) — all recurrence math lives here, not in DAOs; pure Dart, fully testable 7. NotificationService — wraps `flutter_local_notifications`; fire-and-forget side effect; called from task completion notifier after writes **Key data flow pattern:** Drift `.watch()` → StreamProvider → ConsumerWidget. Mutations go through AsyncNotifier → Repository → DAO → SQLite, then Drift automatically emits updated streams to all watchers. No manual invalidation needed for reads. ### Critical Pitfalls Full prevention strategies, warning signs, and recovery steps in `.planning/research/PITFALLS.md`. 1. **Drift schema changes without migration workflow** — Establish `drift_dev make-migrations` + `schemaVersion` bump as a required step for every table change before writing the first table definition. Failures are silent in development and catastrophic on user updates. 2. **Due dates stored as DateTime (with time) instead of Date (calendar day)** — Store all due dates as date-only from day one. Midnight completions and timezone drift create subtle overdue logic bugs. Policy: rolling schedule, last-completion calendar date + interval. 3. **Android notification runtime permissions on API 33+** — `POST_NOTIFICATIONS` and `SCHEDULE_EXACT_ALARM` must be requested at runtime, not just declared in the manifest. Test on a physical API 33+ device with a fresh install. Call `tz.initializeTimeZones()` at startup. 4. **Riverpod `ref.watch` / `ref.listen` outside `build()`** — Enable `riverpod_lint` before writing any feature code; it catches these at analysis time. Rule: `ref.watch` only in `build()`, `ref.read` in callbacks. 5. **`autoDispose` providers losing state on navigation** — Default `@riverpod` enables autoDispose. Use `@Riverpod(keepAlive: true)` for room list, task list, and daily plan providers to avoid loading flicker on every navigation. ## Implications for Roadmap Feature dependencies discovered in research dictate a clear phase order: rooms before tasks before scheduling before daily plan before notifications. Architecture research confirms a bottom-up build order (database schema → DAOs → domain → repositories → providers → UI). Pitfall research identifies which phases need protective setup work before feature code begins. These constraints combine into a natural 6-phase structure. ### Phase 1: Foundation and Project Setup **Rationale:** All subsequent phases depend on the database schema, Riverpod singleton patterns, linting rules, and localization infrastructure being correct from the start. Technical debt incurred here (hardcoded strings, missing migration workflow, wrong provider lifetimes) has the highest recovery cost of any phase. **Delivers:** Compilable project scaffold with database opened, `riverpod_lint` enforcing correct ref usage, `l10n.yaml` + `AppLocalizations` skeleton in place (even if only German, one locale), `drift_dev make-migrations` workflow established, Drift `schemaVersion` = 1 with empty tables, and Material 3 theme via `flex_color_scheme`. **Addresses:** Light/dark theme (system-default) **Avoids:** Hardcoded German strings (recovery: full codebase refactor), `ref.watch` outside `build` (recovery: hard to find without linting), Drift migration gaps (recovery: data loss on upgrade), multiple AppDatabase instances (recovery: runtime crash) ### Phase 2: Room Management **Rationale:** Rooms are the organizing container for everything else. No tasks, no templates, no cleanliness indicator can exist without rooms. This is also the simplest complete feature slice — ideal for proving the full Clean Architecture stack end-to-end (DAO → repository → provider → UI) before adding the complexity of scheduling. **Delivers:** Room CRUD with icons, room list screen, room detail screen, `RoomDao` + `RoomRepository`, `StreamProvider>` watching all rooms, `AsyncNotifier` for mutations. **Addresses:** Room CRUD with icons (table stakes MVP) **Avoids:** Accessing AppDatabase directly in widgets (anti-pattern), storing room photos as blobs (store file paths only if photos are added) ### Phase 3: Task Management and Auto-Scheduling **Rationale:** This is the largest and most complex phase — it implements the core scheduling primitive and the recurrence logic that everything else derives from. It must be solid before building the daily plan view (which purely consumes scheduled due dates) or the cleanliness indicator (which derives from overdue task counts). Due-date correctness unit tests must be written alongside, not after, the `SchedulingService`. **Delivers:** Task CRUD with recurrence interval settings (daily/every N days/weekly/monthly/seasonal), `SchedulingService` (pure Dart, fully unit tested), auto-scheduling on task completion, `TaskDao` + `TaskRepository`, task list per room, task completion action (mark done + reschedule). Bundled task templates seeded on first launch via `AppDatabase.transaction()`. **Addresses:** Task CRUD, auto-scheduling, task completion, bundled templates, task sorting by due date **Avoids:** Due date timestamp vs. date bug (unit test midnight and month-end edge cases before wiring to UI), one-time tasks conflicting with auto-scheduler (add `isOneTime` flag to task model from the start — easier than migrating later) ### Phase 4: Daily Plan View and Cleanliness Indicator **Rationale:** The daily plan view is the primary user-facing answer to "what do I do now?" It has no implementation complexity of its own — it is entirely a Drift query + rendering concern — but it requires rooms, tasks, and scheduling to be complete. The cleanliness indicator is derived from the same data and costs almost nothing to add alongside the daily plan. Both deliver the core value proposition in one phase. **Delivers:** Daily plan screen with three-band layout (Overdue / Due Today / Upcoming), `DailyPlanService` (cross-room join query in Drift), `StreamProvider` with `keepAlive: true`, cleanliness indicator per room (overdue task ratio, computed in provider — not stored), "Done today" session visibility for completed tasks. **Addresses:** Daily plan view, cleanliness indicator, task sorting **Avoids:** Flattening overdue/today/upcoming into one list (per UX pitfalls), cleanliness indicator divide-by-zero on rooms with no tasks, computing daily plan in UI layer instead of DAO ### Phase 5: Notifications **Rationale:** Notifications depend on the scheduling layer (needs due dates) and are self-contained from the UI perspective. They are separated into their own phase because they require special setup steps (manifest permissions, timezone init, boot receiver registration) and must be verified on a physical Android 13+ device — not just the emulator. Conflating this with Phase 3 would make that phase's scope and verification requirements too large. **Delivers:** `NotificationService` wrapping `flutter_local_notifications`, daily summary notification scheduled at app startup, notification rescheduled after task completion, `tz.initializeTimeZones()` at startup, `RECEIVE_BOOT_COMPLETED` receiver for post-reboot rescheduling, runtime permission request at appropriate moment (first launch or settings toggle), notification suppressed when app is in foreground. **Addresses:** Daily summary notification (table stakes MVP) **Avoids:** Manifest-only permission declaration (runtime request required on API 33+), scheduling exact alarms without checking `canScheduleExactAlarms()`, missing timezone initialization (silent wrong-time bug), scheduling one alarm per future recurrence (hits Samsung 500-alarm limit; schedule next occurrence only) ### Phase 6: Polish and v1.x Features **Rationale:** With the core loop proven (rooms → tasks → schedule → daily plan → mark done → notify), this phase adds the highest-value v1.x features before the first public release. Task history is particularly important because the completion event data has been accumulating since Phase 3 — it only requires a read surface, not new data collection. Vacation mode and data export round out the features listed in PROJECT.md for v1.1. **Delivers:** Task history / completion log (scrollable per-task), vacation / pause mode (freeze due dates, resume on return), data export/import (JSON), additional sort options, any visual polish, dark mode verification on device. **Addresses:** Task history, vacation mode, data export (all v1.x) **Avoids:** Completed tasks disappearing with no trace (show "Done today" section or strikethrough), notification firing while app is in foreground ### Phase Ordering Rationale - **Bottom-up dependency:** Every phase's output is a required input for the next phase. This is not an arbitrary choice — the feature dependency graph in FEATURES.md and the build order in ARCHITECTURE.md both point to this exact sequence. - **Risk-front-loading:** The two highest-recovery-cost pitfalls (hardcoded strings and missing migration workflow) are addressed in Phase 1 before any feature code exists. The scheduling correctness pitfall is addressed in Phase 3 with unit tests before the UI depends on it. The notification pitfall is isolated to Phase 5 where it can be verified independently. - **Deliverable increments:** Each phase produces something evaluable. After Phase 2, rooms work. After Phase 3, the full scheduling loop works. After Phase 4, the app is usable daily. After Phase 5, the app is notification-capable. After Phase 6, it is releasable. - **Cleanliness indicator in Phase 4 (not Phase 3):** The indicator derives from overdue task count per room, which requires the scheduling layer to have computed due dates. Including it in Phase 4 alongside the daily plan is correct — both consume the same underlying data. ### Research Flags Phases likely needing deeper research during planning: - **Phase 5 (Notifications):** Android notification permission flows, exact alarm scheduling, and Doze mode behavior have version-specific variations that merit a focused research phase. The pitfalls research covers the known issues, but verifying against the current `flutter_local_notifications` 21.0 API during planning is worthwhile. - **Phase 3 (Scheduling):** The recurrence policy edge cases (seasonal intervals, what "monthly" means for tasks scheduled on the 31st) are not fully specified and will need decision-making during planning. The domain is understood but the product decisions are not yet made. Phases with standard patterns (skip research-phase): - **Phase 1 (Foundation):** Flutter project setup, `flex_color_scheme` theming, and ARB localization infrastructure are all well-documented with official guides. - **Phase 2 (Room Management):** Standard Drift DAO + Riverpod StreamProvider pattern; fully covered by CodeWithAndrea templates and official Drift docs. - **Phase 4 (Daily Plan / Cleanliness):** The Drift cross-table query pattern and provider derivation are standard; no novel integration needed. - **Phase 6 (Polish):** Task history and export are CRUD extensions of existing patterns; no new architectural territory. ## Confidence Assessment | Area | Confidence | Notes | |------|------------|-------| | Stack | HIGH | All versions verified directly on pub.dev; compatibility constraints cross-checked against GitHub issues and official changelogs | | Features | MEDIUM-HIGH | Competitor apps analyzed directly; user pain points from multiple review sources including MIT Technology Review; feature prioritization reflects documented user behavior | | Architecture | HIGH | Cross-verified across official Flutter docs, CodeWithAndrea (authoritative Flutter architecture resource), official Drift docs, and multiple community templates using the same Riverpod + Drift combination | | Pitfalls | HIGH (Riverpod/Drift specifics), MEDIUM (scheduling edge cases) | Riverpod and Drift pitfalls sourced from official docs and known issues; Android notification permission requirements from official Android developer docs; scheduling midnight edge cases from chore app open-source analysis | **Overall confidence:** HIGH ### Gaps to Address - **Recurrence policy details:** The app needs a documented decision on what "monthly" means for a task that was scheduled on the 31st, and what "seasonal" means in terms of interval days. These are product decisions, not technical ones — address in requirements definition. - **Seasonal interval definition:** "Seasonal" appears in the feature list as a recurrence option but is not defined. Is it 90 days? 3 months? Calendar-season-based? Decide before implementing `SchedulingService`. - **Icon set for rooms:** The feature research specifies rooms need icon support but does not specify the icon source. Flutter's Material Icons are the obvious choice; confirm whether custom icons are in scope before Phase 2. - **First-launch template seeding UX:** The architecture specifies templates are seeded on first launch but does not specify whether this is silent (just seeds the data) or shown to the user (a "set up your rooms" prompt). Decide before Phase 2 planning. - **Notification time configuration:** The daily summary notification needs a configurable time. Whether this is user-adjustable in settings or hardcoded (e.g., 8:00 AM) is not resolved. Decide before Phase 5 planning. ## Sources ### Primary (HIGH confidence) - [pub.dev/packages/flutter_riverpod](https://pub.dev/packages/flutter_riverpod) — version 3.3.1 verified - [pub.dev/packages/drift](https://pub.dev/packages/drift) — version 2.32.0 verified; migration and DAO patterns - [riverpod.dev/docs/whats_new](https://riverpod.dev/docs/whats_new) — Riverpod 3.0 feature list and migration guide - [drift.simonbinder.eu/setup](https://drift.simonbinder.eu/setup/) — official Drift setup; DAOs; migrations - [docs.flutter.dev/app-architecture/design-patterns/sql](https://docs.flutter.dev/app-architecture/design-patterns/sql) — Flutter official SQL architecture pattern - [docs.flutter.dev/app-architecture/design-patterns/offline-first](https://docs.flutter.dev/app-architecture/design-patterns/offline-first) — Flutter official offline-first pattern - [developer.android.com — Notification permission](https://developer.android.com/develop/ui/views/notifications/notification-permission) — POST_NOTIFICATIONS runtime requirements - [developer.android.com — Schedule exact alarms](https://developer.android.com/about/versions/14/changes/schedule-exact-alarms) — SCHEDULE_EXACT_ALARM behavior on API 33+ - [codewithandrea.com — Flutter App Architecture with Riverpod](https://codewithandrea.com/articles/flutter-app-architecture-riverpod-introduction/) — authoritative architecture reference - [codewithandrea.com — Riverpod data caching and provider lifecycle](https://codewithandrea.com/articles/flutter-riverpod-data-caching-providers-lifecycle/) — keepAlive and autoDispose patterns ### Secondary (MEDIUM confidence) - Tody, Sweepy, BeTidy, OurHome, Home Routines app analysis — competitor feature comparison - [technologyreview.com/2022/05/10/1051954/chore-apps](https://www.technologyreview.com/2022/05/10/1051954/chore-apps/) — gamification long-term churn evidence - [github.com/ssoad/flutter_riverpod_clean_architecture](https://github.com/ssoad/flutter_riverpod_clean_architecture) — community clean architecture template - [dinkomarinac.dev — Building Local-First Flutter Apps with Riverpod, Drift, and PowerSync](https://dinkomarinac.dev/blog/building-local-first-flutter-apps-with-riverpod-drift-and-powersync/) — Riverpod + Drift integration patterns - [github.com/rrousselGit/riverpod/issues/4676](https://github.com/rrousselGit/riverpod/issues/4676) — Riverpod 3.2+/stable channel compatibility; resolved in Flutter 3.41.1 ### Tertiary (MEDIUM-LOW confidence) - [ha-chore-helper GitHub](https://github.com/bmcclure/ha-chore-helper) — "every" vs "after" scheduling modes; midnight edge cases - [docs.flexcolorscheme.com](https://docs.flexcolorscheme.com/) — M3 legacy color sync coverage (official docs but implementation details not independently verified) --- *Research completed: 2026-03-15* *Ready for roadmap: yes*