Skip to main content

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).

TypeFunctional
Layer (build approach)Frontend — design_system atoms + app bloc/page + flow-test
RICER 8 × I 2 × C 80% / E 3 = 4.3 · Tier MVP-1
KPI (summary)Household-tab DAU; family-goal creation rate
Traces tofeature household · C4 components
Depends onPersonas / 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_completed in the trailing 7 days where household_viewed fires ≥ 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 first chore_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.

EventWhenKey propertiesFeeds
household_viewedHousehold tab openedmemberCount, hasFamilyGoals (bool)reach denominator (Metric A)
family_goal_createdfamily goal created or requestedgoalStatus (active|requested), targetTokens (bucketed: <100|100–499|500+)primary KPI → Metric B
member_tile_openedmember tile tappedmemberRef (opaque), hasPendingGoal (bool)tile engagement
budget_recommendation_submittednon-admin submits recommendationrecommendationType (increase|decrease|maintain)admin-handoff funnel

household_viewed and family_goal_created ship 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).spend and a 🎯 goal chip if they have an active goal.
  • 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 = true When 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 >= targetTokens When an admin taps "Complete" Then completeGoal(id) fires; the goal moves to the completed section.
  • archiveGoal / restoreGoal follow the same state machine as member-profile goals; only difference is memberId == null.

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_submitted fires 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-shot getGoals(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 pathHouseholdPage → MembersBloc / GoalsBloc → HouseholdRepository / GoalsRepository → client_sdk facade → HouseholdService / EconomyServiceStoragePort → Drift / Supabase RLS. Presentation never imports drift or supabase directly.
  • Read-only summaries roll up Money/goalsgoalProgress aggregates members' save balances (see Money); the budget summary reads currencyPerToken + DefaultAllocation from EconomyService. 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, not householdId; 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-shot getGoals(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 — watchGoals stream (FR-HOUSEHOLD-7).Poll-first (one-shot on tab focus) for MVP-1; add the SDK watchGoals stream 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 managementupdatePlace SDK gap; Admin → House (conditional on gap-fill).
  • Economy/giving-destination configgiveDestinationName SDK gap; Admin → Settings.
  • watchGoals(...) stream — one-shot poll ships first; stream is a P2 SDK nicety.
  • Family goal photo evidence → MVP-2.