Onboarding — requirements
Epic. MVP-1 requirements breakdown for Onboarding (see the feature architecture). Each FR is sized to become one or a few user stories. The wizard is the critical activation path — every step maps to an SDK call through the one data path.
| Type | Functional |
| Layer (build approach) | Cross — wizard UI + SDK setup (OnboardingBloc + HouseholdService + EconomyService) |
| RICE | R 10 × I 3 × C 80% / E 3 = 8.0 · Tier MVP-1 |
| KPI (summary) | Activation: % new households completing setup + 1st chore |
| Traces to | feature onboarding · C4 containers |
| Depends on | Account · Admin (economy seed) · Personas/authz · Children's privacy (COPPA) (VPC gate) |
Success criteria (definitive KPI)
Success = ≥ 65% of new households complete all required wizard steps AND
record a first chore_completed within 72 hours of first app open.
- Metric: households reaching both milestones (wizard complete + first approved completion) within 72 h of install, divided by all households that opened the wizard.
- Target: ≥ 65% activation rate.
- Window: 72 hours post-install — wide enough to cover a full day's chore cycle without penalising late-evening installs.
- Why this bar: a household that hasn't run the first chore loop in 72 h has not yet formed the habit; below 65% signals wizard friction or empty-state confusion, not a chore-loop problem.
- Guardrail (skip rate): if > 20% of households skip economy config the default
currencyPerTokenmay need tuning — investigate before launch. - Baseline: no install base yet — treat 65% / 72 h as the launch hypothesis; confirm with the first cohort and re-baseline from wk-1 data.
Analytics — events to record
Privacy model: OPERATIONAL (child PII only after VPC; parent-created) · INTERNAL BI (event-type + coarse, no child identity, content-free, never marketing) · MARKETING (parent/account only: count, plan type, parent-feature-active; never child-derived). All emitted through the consent-gated analytics substrate.
| Event | When | Key properties | Feeds | Priority |
|---|---|---|---|---|
onboarding_started | wizard first opened | platform | funnel denominator | P1-with-surface |
onboarding_step_completed | each step passed | step (household|admin|members|economy|chore), stepIndex | drop-off per step | P1-with-surface |
household_created | createHousehold() succeeds | householdRef (hashed) | primary activation signal | P1-with-surface |
member_invited | member added or invite sent | memberRef (hashed), kind (parent|shadow|coParent) | roster depth | P1-with-surface |
child_consent_captured | VPC consent record written for under-13 child | consentRef (opaque), path (ownAccount|supervised) | COPPA gate compliance | P1-with-surface |
economy_configured | economy step saved | currencyPerToken (coarse tier) | config adoption | P1-with-surface |
first_chore_completed | household's first approved chore_completed | choreRef (hashed), hoursFromInstall (coarse bucket) | KPI numerator — 72 h activation | P1-with-surface |
onboarding_completed | all required steps done | timeToCompleteMs, memberCount | wizard funnel exit | P1-with-surface |
onboarding_skipped | step skipped via "later" | step | skip-rate guardrail | P1-with-surface |
onboarding_started(denominator) andfirst_chore_completed(numerator) are the minimum pair to measure the KPI — both ship with the surface, not after.first_chore_completedis emitted by the chore approval path but tracked here as the activation endpoint.
Scope
Onboarding is the activation wizard: household creation → admin profile → add/invite members (VPC-gated for under-13 children) → economy config → first chore. Required steps are household name and admin profile; all others are skippable and revisitable in Admin. Steps 1–5 must be completable offline; co-parent invite email dispatch is Tier-1 only. Wizard state persists across restarts so partial setup is resumable.
Functional requirements
FR-ONBOARD-1 — Household creation
Priority: P1 · Status: 🔨 needs build (HouseholdService ready)
Statement. As a parent setting up the app, I name my household so the family
has a uniquely identified home and household-scoped RLS is established from row 0.
Acceptance
- Given a fresh install with no household When I enter a name and confirm Then
createHousehold(name: ...)persists the household; RLS is household-scoped from this point forward. - Given a name exceeding 80 characters When I submit Then the UI shows an inline validation error and does not call the SDK.
- Household emoji is optional at this step; editable later in Admin.
FR-ONBOARD-2 — Admin profile and terms acceptance
Priority: P1 · Status: 🔨 needs build Statement. As the household creator, I set my display name and accept the terms so my member record is active and the household has at least one adult admin. Acceptance
- Given household created When I set my name and confirm Then
addMember(kind: MemberKind.parent)creates me asMemberStatus.activewithMemberRole.admin. - Given an adult member record When I confirm Then
acceptTerms()records acceptance ofkCurrentTermsVersion; the wizard does not advance until accepted. - Given
termsAcceptanceRequired()returns true at any future session start Then the re-prompt is shown before any other surface is accessible.
FR-ONBOARD-3 — Add child members (consent-gated; VPC for under-13)
Priority: P1 · Status: 🔨 needs build · COPPA-critical
Statement. As a parent, I add child profiles so each child has a named member
record for chore assignment and token earning. Under-13 children are fully
supported; no child record or PII is written until verifiable parental consent
(VPC) is captured. Two under-13 paths exist: the own-account path (child will
have their own login — handled here with the full VPC gate) and the
supervised-action path (parent-managed shadow, no child login — VPC
acknowledgment still required before addMember is called).
Acceptance
- Given I add a child and indicate they are under 13 When the add flow runs Then a VPC consent step is shown before any SDK call;
consentRefis written to the consent store first. - Given VPC is not completed When I attempt to finalise the child record Then
addMemberis not called; no child record, display name, or age is stored. - Given VPC is completed When I confirm Then
addMember(kind: MemberKind.child, consentRef: ...)is called;child_consent_capturedfires withpath = ownAccountorsupervised(no child identity in the event payload). - Given a child who is 13 or older When I add them Then the VPC gate is skipped;
addMemberis called directly; age is recorded for futurelinkAccountToMember()eligibility. - Given no age is provided When I add a child Then the UI treats the member as potentially under-13 and presents the VPC flow as a precaution.
- The app never markets to children;
child_consent_capturedcarries no child identity — only the opaqueconsentRefandpath(INTERNAL BI only). - This step is skippable; child members can be added post-wizard via Admin (see FR-ADMIN-5).
FR-ONBOARD-4 — Invite co-parent
Priority: P2 · Status: 🔨 needs build Statement. As a parent, I invite a co-parent so they can join the household with full admin access once they accept. Acceptance
- Given I enter a co-parent email and confirm Then
inviteCoParent(email: ...)creates aMemberStatus.invitedrecord valid for 14 days;member_invitedfires withkind = coParent. - Given the invite is created Then the UI shows the invite token as a copyable link; email dispatch is Tier-1 and not MVP-1.
- Given
inviteCoParent()throws because that email is already active Then the UI shows a friendly "already a member" message, no crash. - This step is skippable; invites can be sent later via Admin.
FR-ONBOARD-5 — Economy configuration
Priority: P1 · Status: 🔨 needs build Statement. As a parent, I set the token exchange rate so the household economy has a concrete currency value from day one. Acceptance
- Given household created with default
currencyPerToken = 0.10When I reach this step Then the current value is pre-filled (e.g. "10 tokens = $1.00"). - Given I change the rate and confirm Then
updateEconomyConfig(currencyPerToken: ...)persists the new value;economy_configuredfires. - Given I skip Then the default of 0.10 remains;
onboarding_skippedfires withstep = economy. EarningsSplitis advanced config — shown collapsed with a "customise later in Admin" hint;EarningsSplit.fallbackis the MVP-1 default.
FR-ONBOARD-6 — First chore creation
Priority: P2 · Status: 🔨 needs build Statement. As a parent, I create one chore in the wizard so the first session has something actionable on the Today surface. Acceptance
- Given I name and save a chore Then
ChoreService.createChore()persists it;onboarding_step_completed(step: chore)fires. - Given I skip Then the wizard completes without a chore;
onboarding_skippedfires withstep = chore. - A single "quick-start" template (e.g. "Tidy your room — 5 tokens") is offered to reduce blank-slate paralysis.
FR-ONBOARD-7 — Wizard completion and checklist persistence
Priority: P1 · Status: 🔨 needs build Statement. As a parent, I see a persistent setup checklist until all required steps are done so setup is resumable across sessions. Acceptance
- Given I exit mid-flow When I reopen Then the wizard resumes at the first incomplete required step.
- Given FR-ONBOARD-1 and FR-ONBOARD-2 are done Then
onboarding_completedfires and the checklist is dismissed from the home surface. - Given optional steps remain Then each is listed in the checklist with a direct-jump link into Admin.
Architecture considerations
- One data path —
OnboardingBloc → OnboardingRepository → client_sdkfacade; no directdrift/supabaseimports in wizard presentation. - SDK seed sequence —
createHousehold()→addMember(kind: parent)+acceptTerms()→addMember(kind: child, consentRef: ...)/inviteCoParent()→updateEconomyConfig()→ChoreService.createChore(). All calls go through the facade; no step may bypass the service layer. - VPC gate (under-13 child add) —
consentRefmust be written to the consent store beforeaddMemberis called for any under-13 child. No child record, display name, or age is stored prior to that write. TheconsentRefis passed as a named parameter toaddMember; the adapter enforces the pre-condition. - Offline-capable steps — household creation, member adds, terms acceptance, and economy config write through the Drift write-through cache and sync when online. VPC consent records are durably cached offline and sync with priority.
- Household-scoped RLS —
createHousehold()writes the household row with the creator'sauthUserId; all subsequent member, chore, and consent inserts inherit the household-scoped policy (SP3). Cross-household leakage is impossible at the adapter layer. - Terms gate —
termsAcceptanceRequired()is checked at step 2 and at every authenticated session start; re-prompt blocks all surfaces until accepted.
Design work (ahead of build)
- Wizard flow map — 5-step progress indicator (Household → You → Members → Economy → First Chore); required vs optional steps visually distinct.
- Consent-gated add-child step — when the parent indicates under-13, flow transitions to a dedicated VPC screen before any field data is persisted; copy and interaction design require legal review before build begins.
- Two-path child add — own-account path (child will log in) vs supervised-only (shadow, parent-managed); clear choice at entry with plain-language labels and guidance on which path fits the child's age/phone situation.
- Invite co-parent screen — email field + optional note; clear MVP-1 notice that the link must be copied and shared manually.
- Economy step —
currencyPerTokenpicker with a live example readout;EarningsSplitcollapsed under "Advanced" disclosure. - Empty state and completion screen — "no members yet" prompt within the members step; celebratory completion screen after required steps are done.
- Persistent checklist widget — card on home surface listing incomplete optional steps; dismisses once required steps are satisfied.
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-ONBOARD-1 — VPC flow. ⚖️ In-app screen with stored attestation (email-plus on free / card on paid, per the VPC anchor); not an external service for MVP-1. Counsel signs off.
- D-ONBOARD-2 — Quick-start templates (FR-ONBOARD-6). ✅ A short picker of 3–5 curated templates (e.g. Young kids / Tweens / Mixed ages / Solo-or-teen) — modest choice beats a single forced template.
- D-ONBOARD-3 — Checklist auto-dismiss. ✅ Dismiss on first
chore_completed— ties the checklist directly to the activation KPI event. - D-ONBOARD-4 — Co-parent invite share UX. ✅ OS share sheet (covers clipboard, messaging, email in one) for MVP-1; QR deferred.
Out of scope (MVP-1)
- Co-parent email dispatch via Edge Function → Tier-1.
- Shadow-to-account claim (
linkAccountToMember) UI flow → post-MVP. - Bulk member import (CSV / contact picker) → post-MVP.
- Household templates ("family of 4 starter pack") → post-MVP.
- AI suggested chore sets in the wizard → recommender sub-project (stub only).
- TV / supervised child-bounty exception → out of onboarding scope (COPPA).