Household — requirements
Epic. MVP-1 requirements breakdown for the Household people surface (see the feature architecture). The tab is being restructured from the T5 editable-member-list to the T7 read-only tile roster + Family Goals card. T7 is specced but not yet built — every FR here is net-new build. Member management moves to Profile → Account (off this surface).
| Type | Functional |
| Layer (build approach) | Frontend — design_system atoms + app bloc/page + flow-test |
| RICE | R 8 × I 2 × C 80% / E 3 = 4.3 · Tier MVP-1 |
| KPI (summary) | Household-tab DAU; family-goal creation rate |
| Traces to | feature household · C4 components |
| Depends on | Personas / authz · Money (family goals / budget) · Admin |
Success criteria (definitive KPI)
Success = Household-tab reached by ≥ 70% of active households at least once per week AND ≥ 40% of activated households create ≥ 1 family goal within 4 weeks.
- Metric A (reach): households with ≥ 1
chore_completedin the trailing 7 days wherehousehold_viewedfires ≥ once in the same week. Target: ≥ 70%, sustained across weeks 2–4 post-activation. - Metric B (family-goal creation): share of activated households that emit
family_goal_created≥ once within 4 weeks of their firstchore_completed. Target: ≥ 40%. - Why: A is the engagement floor — the tab should feel like a family home screen, not a settings backwater. B measures whether Family Goals triggers household-level motivation, the intended differentiator from a plain chore tracker.
- Baseline: no install base yet; treat these as the launch hypothesis and re-baseline from first-cohort wk-2 data.
Analytics — events to record
All member references are opaque/hashed; no minor PII (see COPPA). Emitted through the consent-gated analytics substrate.
| Event | When | Key properties | Feeds |
|---|---|---|---|
household_viewed | Household tab opened | memberCount, hasFamilyGoals (bool) | reach denominator (Metric A) |
family_goal_created | family goal created or requested | goalStatus (active|requested), targetTokens (bucketed: <100|100–499|500+) | primary KPI → Metric B |
member_tile_opened | member tile tapped | memberRef (opaque), hasPendingGoal (bool) | tile engagement |
budget_recommendation_submitted | non-admin submits recommendation | recommendationType (increase|decrease|maintain) | admin-handoff funnel |
household_viewedandfamily_goal_createdship with the surface — both KPI metrics require these from day one.
Scope
Household is the people surface: read-only member tiles (tap → Member Profile) + Family Goals card + a read-only family budget/goal summary with a non-admin "Recommend a change" CTA and an admin "Edit" link into Admin → Family Budget. Member management (add/edit/ remove/roles/invite) is off this tab — it lives under Profile → Account → Members per the T7 IA decision (2026-06-25).
Functional requirements
FR-HOUSEHOLD-1 — Tab restructure: editable list → read-only member tiles
Priority: P1 · Status: 🔨 to build (T5 → T7) Statement. As any household member, I see a read-only tile roster of my family so I can navigate to any profile at a glance without triggering edits. Acceptance
- Given the current
MembersBloc-driven editable list When T7 ships Then the Household tab shows read-only tiles and all add/edit affordances are absent. - Given a tile When tapped Then the app navigates to that member's
MemberProfilePage. - The inline member-editor bottom sheet is removed from the tab; it relocates under Profile → Account → Members.
FR-HOUSEHOLD-2 — Member tile glance: wallet balance + goal chip
Priority: P1 · Status: 🔨 to build Statement. As a parent or helper, I see each member's spend balance and active goal at a glance so I know who is close to earning a reward without opening each profile. Acceptance
- Given a member with a wallet When their tile renders Then it shows
walletOf(memberId).spendand a 🎯 goal chip if they have anactivegoal. - Given no active goal When the tile renders Then no chip appears (not an error state — just absent).
- Balance changes from
watchMembers()stream update the tile live without a full-page reload.
FR-HOUSEHOLD-3 — Watch-only members visible on roster
Priority: P2 · Status: 🔨 to build (SDK watchOnly flag exists from T5)
Acceptance
- Given
watchOnly = trueWhen the tab loads Then the tile appears with a watch-only indicator, wallet glance, and goal chip. - Watch-only members never appear on the Today act surface or in assignment pickers — Household is the only overview surface where they show.
FR-HOUSEHOLD-4 — Family Goals card: list + create
Priority: P1 · Status: 🔨 to build (SDK: getGoals(memberId: null) + createGoal(scope: family))
Statement. As an admin, I can create a shared household goal; as any member,
I can see the family's active goals and their progress.
Acceptance
- Given
getGoals(memberId: null)When the card renders Then each goal shows name, progress bar (goalProgress/targetTokens), and status chip. - Given an admin When they tap "Add family goal" Then
createGoal(scope: family)is called on save and the card updates. - Given no family goals When the card renders Then a "Set a shared goal" nudge appears (never a blank card).
FR-HOUSEHOLD-5 — Family goal lifecycle: request → approve → complete
Priority: P1 · Status: 🔨 to build (state machine mirrors member-profile goals) Statement. As a non-admin, I can request a family goal for admin review; an admin can approve it; either an admin or the system marks it complete when progress is reached. Acceptance
- Given a non-admin When they submit a goal Then
requestGoal(scope: family)fires; the chip shows "awaiting approval". - Given an admin When they approve Then
approveGoal(id)fires; status →active. - Given
goalProgress >= targetTokensWhen an admin taps "Complete" ThencompleteGoal(id)fires; the goal moves to the completed section. archiveGoal/restoreGoalfollow the same state machine as member-profile goals; only difference ismemberId == null.
FR-HOUSEHOLD-6 — Read-only budget summary: recommend / edit-link
Priority: P2 · Status: 🔨 to build (blocked on Admin → Family Budget; see open decisions) Statement. As any member, I see the household economy at a glance; a non-admin can recommend a change; an admin can jump directly to the editor. Acceptance
- Given a non-admin When the widget renders Then it shows
currencyPerToken+ allocation split (spend/save/give %) and a "Recommend a change" CTA. - Given a non-admin submits a recommendation When confirmed Then
budget_recommendation_submittedfires and a confirmation appears; no economic state changes until an admin reviews it in Admin. - Given an admin When the widget renders Then the CTA is replaced by an "Edit" link → Admin → Family Budget.
FR-HOUSEHOLD-7 — Live updates via watchMembers + (future watchGoals)
Priority: P2 · Status: ❓ partial — watchMembers() exists; watchGoals() is a SDK gap
Statement. As a member, the Household tab updates in place when balances or
goals change so I always see current data without pulling to refresh.
Acceptance
- Given
watchMembers()stream When a wallet balance changes Then the affected tile updates without a full reload. - Fallback for missing
watchGoals(): one-shotgetGoals(memberId: null)on tab focus is acceptable for MVP-1; the stream is a P2 SDK addition.
FR-HOUSEHOLD-8 — Empty states
Priority: P2 · Status: 🔨 to build Acceptance
- Given no family goals When the card renders for an admin Then a "Set a shared goal" nudge appears; for a non-admin, an "Ask an admin" hint.
- Given the roster loads with zero members (defensive) When the page renders Then a recoverable error/nudge state renders (should not occur post-onboarding).
Architecture considerations
- One data path —
HouseholdPage → MembersBloc / GoalsBloc → HouseholdRepository / GoalsRepository → client_sdkfacade →HouseholdService / EconomyService→StoragePort→ Drift / Supabase RLS. Presentation never importsdriftorsupabasedirectly. - Read-only summaries roll up Money/goals —
goalProgressaggregates members' save balances (see Money); the budget summary readscurrencyPerToken+DefaultAllocationfromEconomyService. No new data shapes are needed if the SDK already exposes these. - Household-scoped RLS — all queries household-scoped; the cloud adapter relies on the household-scoped policies (SP3). The tab never reads another household's data.
- Member-keyed wallet/goals (multi-house forward-compat) — wallet and goals keyed by
memberId, nothouseholdId; a future multi-household migration never fragments money or goals. Do not hard-code one-household assumptions in bloc or repository logic. watchGoals(...)stream gap — MVP-1 ships with one-shotgetGoals(memberId: null)on tab focus; a stream variant is a P2 SDK addition flagged in the feature-doc gap ledger.
Design work (ahead of build)
- Member tile — redesign from editable-list row to read-only profile tile: avatar + display name + wallet-spend glance + 🎯 goal chip (or dash). Watch-only indicator variant. Full-tile tap target →
MemberProfilePage. - Family Goals card — goal tiles (name + progress bar + status chip) + admin-only "Add" CTA. Request vs active vs complete visual distinction; reuse member-profile goal atoms where possible.
- Budget summary widget — compact read-only card:
currencyPerToken+ allocation split. Two CTA variants: "Recommend a change" (non-admin, opens bottom sheet with type selector + optional note) vs "Edit" link (admin). - Empty states — "Set a shared goal" nudge (admin path); "Ask an admin" hint (member path); defensive zero-member recoverable error.
Decisions (resolved for MVP-1)
Resolved — see the MVP-1 decisions log for the canonical record, rationale, and status legend (✅ decided · ⚖️ counsel confirms · 🔜 MVP-1.x).
- D-HOUSEHOLD-1 — Budget summary / recommend (FR-HOUSEHOLD-6). ✅ With full money in MVP-1, the Admin → Family Budget editor lands in MVP-1, so FR-HOUSEHOLD-6 ships in MVP-1. Build sequence: budget editor before/with the Household summary.
- D-HOUSEHOLD-2 —
watchGoalsstream (FR-HOUSEHOLD-7). ✅ Poll-first (one-shot on tab focus) for MVP-1; add the SDKwatchGoalsstream as a fast follow. - D-HOUSEHOLD-3 — Family-goal celebration. ✅ Micro-animation (burst on the goal tile), reduced-motion-aware; full-screen moment deferred. No build dependency.
Out of scope (MVP-1)
- Member management (add/edit/remove/roles/invite) → Profile → Account → Members (T7 P2 build step 3).
- Multi-household switching — deferred; model is forward-compatible (wallet/goals member-keyed).
- House config (name/emoji/address edit) → Admin → House.
- Rooms/zones management —
updatePlaceSDK gap; Admin → House (conditional on gap-fill). - Economy/giving-destination config —
giveDestinationNameSDK gap; Admin → Settings. watchGoals(...)stream — one-shot poll ships first; stream is a P2 SDK nicety.- Family goal photo evidence → MVP-2.