Skip to main content

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.

TypeFunctional
Layer (build approach)Cross — wizard UI + SDK setup (OnboardingBloc + HouseholdService + EconomyService)
RICER 10 × I 3 × C 80% / E 3 = 8.0 · Tier MVP-1
KPI (summary)Activation: % new households completing setup + 1st chore
Traces tofeature onboarding · C4 containers
Depends onAccount · 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 currencyPerToken may 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.

EventWhenKey propertiesFeedsPriority
onboarding_startedwizard first openedplatformfunnel denominatorP1-with-surface
onboarding_step_completedeach step passedstep (household|admin|members|economy|chore), stepIndexdrop-off per stepP1-with-surface
household_createdcreateHousehold() succeedshouseholdRef (hashed)primary activation signalP1-with-surface
member_invitedmember added or invite sentmemberRef (hashed), kind (parent|shadow|coParent)roster depthP1-with-surface
child_consent_capturedVPC consent record written for under-13 childconsentRef (opaque), path (ownAccount|supervised)COPPA gate complianceP1-with-surface
economy_configuredeconomy step savedcurrencyPerToken (coarse tier)config adoptionP1-with-surface
first_chore_completedhousehold's first approved chore_completedchoreRef (hashed), hoursFromInstall (coarse bucket)KPI numerator — 72 h activationP1-with-surface
onboarding_completedall required steps donetimeToCompleteMs, memberCountwizard funnel exitP1-with-surface
onboarding_skippedstep skipped via "later"stepskip-rate guardrailP1-with-surface

onboarding_started (denominator) and first_chore_completed (numerator) are the minimum pair to measure the KPI — both ship with the surface, not after. first_chore_completed is 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 as MemberStatus.active with MemberRole.admin.
  • Given an adult member record When I confirm Then acceptTerms() records acceptance of kCurrentTermsVersion; 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.

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; consentRef is written to the consent store first.
  • Given VPC is not completed When I attempt to finalise the child record Then addMember is 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_captured fires with path = ownAccount or supervised (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; addMember is called directly; age is recorded for future linkAccountToMember() 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_captured carries no child identity — only the opaque consentRef and path (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 a MemberStatus.invited record valid for 14 days; member_invited fires with kind = 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.10 When 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_configured fires.
  • Given I skip Then the default of 0.10 remains; onboarding_skipped fires with step = economy.
  • EarningsSplit is advanced config — shown collapsed with a "customise later in Admin" hint; EarningsSplit.fallback is 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_skipped fires with step = 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_completed fires 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 pathOnboardingBloc → OnboardingRepository → client_sdk facade; no direct drift/supabase imports in wizard presentation.
  • SDK seed sequencecreateHousehold()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)consentRef must be written to the consent store before addMember is called for any under-13 child. No child record, display name, or age is stored prior to that write. The consentRef is passed as a named parameter to addMember; 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 RLScreateHousehold() writes the household row with the creator's authUserId; all subsequent member, chore, and consent inserts inherit the household-scoped policy (SP3). Cross-household leakage is impossible at the adapter layer.
  • Terms gatetermsAcceptanceRequired() 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 stepcurrencyPerToken picker with a live example readout; EarningsSplit collapsed 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).