Skip to content

Onboarding Timeline — Feature & Engagement Guide

Overview

This doc maps the ideal user journey from signup through full activation over 30 days. It serves as the canonical reference for understanding what a new user experiences, when gamification triggers fire, and how the dashboard evolves as users progress.

Audience: Product/design (UX flow, emotional arc) and engineering (technical triggers, component references). Technical details are in collapsible sections.

Related docs:

  • Dashboard — layout, quick check-in flow, onboarding detection
  • Feature Tour — reusable walkthrough engine + the flagship first-run dashboard tour
  • Achievements — badges, XP, levels, ranks
  • Goal Builder — 4-slide guided goal construction flow (universal, no variant gate)
  • User Guide — end-user getting started walkthrough
  • North Star — activation KPIs and milestone horizons
  • Brand Guide — tone, anti-social app philosophy

30-Day Arc

timeline
    title User Onboarding — 30-Day Arc
    section Day 1 · First Session
        Sign up via Clerk : Feeling — Curious
        13-slide onboarding wizard : Feeling — Excited
        Create first goal + confetti : Feeling — Accomplished
        Customize goal : Feeling — Invested
        Badges earned — first_sign_in, create_first_goal : XP 0 · Streak 1
    section Days 2–3 · Return & Explore
        First return visit : Feeling — Reinforced
        Streak begins (day 2) : +50 XP per day
        Habit check-ins : +25 XP each
        Create second goal : Possible new badges
        Badges — create_second_category, create_second_type : XP ~100–200
    section Days 4–7 · Habit Formation
        Join first community : Feeling — Belonging
        Ally activity in feed : Social connection
        First goal completion possible : +500 XP
        Badge — join_first_community, complete_first_goal : Possible Level 2
    section Days 8–14 · Deepening
        Multiple active goals : Full dashboard unlocked
        Regular check-in routine : XP accumulating
        Community participation : Encouragements given
        Expected — Level 2–3, streak 8–14 : 5+ badges
    section Days 15–30 · Activated User
        Habits solidified : Automatic routine
        5th–10th goal completions : Rare/Epic badges
        Full feature usage : DashboardHero, ActionHub
        Expected — Level 4–5, streak 15–30 : 8+ badges

First Session Flow

The legacy OnboardingWizard.vue modal (a 5-slide dashboard overlay) was deleted in Phase 47 (e9c3ee002, "delete OnboardingWizard and remove Dashboard wiring"). Onboarding is now a full-page, 13-slide flow at /welcome/:slideId. For the exact slide-by-slide breakdown, validation rules, and mutation signatures, see Onboarding Flow (technical) — that document is the source of truth; the flowchart below shows only the session-level shape.

Shipped: an optional, skippable "Our Philosophy" slide (PhilosophySlide.vue, v4.1 Phase 3) can appear early in the wizard, behind the onboarding_pledge_enabled flag — it surfaces the same anti-addictive-design values shown on the public /our-story page. See Onboarding Flow (technical) § Philosophy slide for the full contract.

flowchart TD
    A[User clicks Sign Up] --> B[Clerk OAuth screen<br/>Google · Apple · Email]
    B --> C[Redirect to app]
    C --> D{Router auth guard}
    D -->|No token| E[Redirect to /sign-in]
    D -->|Token present| F[syncClerkUser mutation]

    F --> G[Backend: SyncUser resolve]
    G --> G1[RecordSignIn interaction]
    G --> G2[Backfill profile from Clerk API]
    G --> G3{first_sign_in UserAction exists?}
    G3 -->|No| G4["Create first_sign_in UserAction 🏅"]
    G3 -->|Yes| G5[Skip — returning user]

    G4 --> H{useOnboardingGate: shouldOnboard?}
    G5 --> H
    H -->|onboardingCompletedAt is falsy| I["Redirect to /welcome/:slideId<br/>13-slide wizard, full-page, no chrome"]
    H -->|already completed| J[Dashboard]

    I --> K["Slides 2–5: life area, goal name,<br/>goal shape, goal why"]
    K --> L["Slides 6–9: Coach persona, tone,<br/>focus, rhythm"]
    L --> M["Slide 10: goal motivation snapshot"]
    M --> N["Slide 13: Done — confetti"]

    N --> O{Goal name given?}
    O -->|Yes| P["CompleteOnboardingAndCreateGoal mutation<br/>(atomic: stores onboarding state + creates goal)"]
    P --> Q["create_first_goal badge 🏅"]
    Q --> R["/dashboard?source=wizard"]
    O -->|No| S["StoreOnboardingState mutation only"]
    S --> T["/goals/create?source=wizard&coachPersona=...&category=..."]

    R --> X[GettingStartedCard appears<br/>if goal still lacks category/type]
    X --> Y{User customizes or skips}
    Y --> Z["WelcomePrompt: Ready to add more goals?"]
    Z --> AA[Dashboard — sparse state]

Day-by-Day Breakdown: Days 1–7

Day 1: First Session

What the User Sees

  1. Sign-in screen — Clerk OAuth with Google, Apple, or email options
  2. Onboarding wizard — full-page, 13-slide flow at /welcome/:slideId (no dashboard chrome, cannot be dismissed): goal life area, goal name, goal shape, goal why, Coach persona, tone, focus, rhythm, an optional goal-motivation snapshot, source attribution, and a Done/celebration slide. See Onboarding Flow (technical) for the full slide-by-slide reference.
  3. Confetti celebration — plays on the Done slide (respects prefers-reduced-motion)
  4. GettingStartedCard — appears on the dashboard if the newly created goal still lacks a category or type, letting the user customize it
  5. WelcomePrompt — "Ready to add more goals, {firstName}?" with CTA button
  6. Dashboard tour (behind feature_tour_enabled) — a 6-stop guided walkthrough (streak, check-in, Coach, today's actions, goals, nav) fires once, only on the /dashboard?source=wizard landing straight out of the wizard. See Feature Tour.

Emotional Journey

MomentFeelingBrand Tone
Wizard welcomeWarm, recognized"Coach who's also a friend" — personal greeting
Feature previewsCurious, intriguedQuick visual demos — no walls of text
Goal creationEmpoweredAction-forward — user does something immediately
ConfettiDelighted, accomplishedCelebratory — earned, not empty
CustomizationInvestedOwnership — "this is my goal"

Gamification Triggers

TriggerRewardXPBadgesStreakLevel
Sign up completefirst_sign_in badge0111
Create first goalcreate_first_goal badge0211

No XP is awarded on Day 1 from these actions. Streak XP begins on Day 2 when the user returns.

Technical Details

Authentication Flow:

  • Clerk OAuth → router guard in ionic_frontend/src/router/index.ts
  • syncClerkUser() calls SYNC_USER_MUTATION from src/constants/graphql/
  • Backend Mutations::SyncUser (rails_api/app/graphql/mutations/sync_user.rb):
    1. RecordSignIn.call(user:) — creates/updates UserSignIn record
    2. Backfills first_name, last_name, username from Clerk API if missing
    3. Checks if first_sign_in UserAction exists → if not, creates it (acknowledged: true)
    4. Returns { user, firstSignIn: true }

Onboarding wizard:

  • Route: /welcome/:slideId, meta.onboarding: true (hides SideMenu/BottomTabBar, full-bleed canvas)
  • Registry: ionic_frontend/src/views/welcome/placeholderSlides.ts — 13 slides, gate is useOnboardingGate.shouldOnboard (onboardingCompletedAt falsy), no A/B variant
  • DoneSlide.vue (slide 13): fires confetti on mount (skipped under prefers-reduced-motion), then submits
  • After completion: flow.reset() clears wizard state

See Onboarding Flow (technical) for the full slide registry, validation rules, and OnboardingAnswers shape.

Goal Creation Chain:

  • If goalName was given: COMPLETE_ONBOARDING_AND_CREATE_GOAL_MUTATIONOnboarding::CompleteOnboardingAndCreateGoal interaction wraps UserIdentity::StoreOnboardingState + GoalTracking::AddGoal in one transaction
  • AddGoal (rails_api/app/interactions/goal_tracking/add_goal.rb) creates the goal
  • Triggers Gamification::CreateFirstGoalActionJob.perform_later(user.id) if it's the user's first goal
  • Job (rails_api/app/jobs/gamification/create_first_goal_action_job.rb) calls UserAction.create_first_goal(user_id) directly — no sleep or artificial delay
  • UserAction.generate() creates the action record + UserFeedItem.add_badge_feed_item()
  • If no goalName was given: STORE_ONBOARDING_STATE_MUTATION only, then the user finishes goal creation on /goals/create

Post-Wizard Dashboard State (ionic_frontend/src/views/Dashboard.vue):

  • hasNewGoal computed: 1 active goal + default description + no category/type set
  • GettingStartedCard renders with autoExpand: true
  • After customization or skip: setupDismissed = true → transitions to sparse state
  • isSparseState: 1–2 active goals, hasNewGoal is false → shows WelcomePrompt

Key Files:

FileRole
ionic_frontend/src/views/welcome/placeholderSlides.ts13-slide onboarding registry
ionic_frontend/src/views/welcome/WelcomeView.vue/welcome/:slideId route component
ionic_frontend/src/views/welcome/slides/DoneSlide.vueFinal slide — confetti + submit mutation
ionic_frontend/src/components/dashboard/GettingStartedCard.vueGoal customization card
ionic_frontend/src/components/dashboard/WelcomePrompt.vue"Add more goals" CTA
ionic_frontend/src/views/Dashboard.vueState orchestration
ionic_frontend/src/composables/useOnboardingGate.tsshouldOnboard + resume-slide logic
ionic_frontend/src/router/index.tsAuth guard + syncClerkUser
rails_api/app/graphql/mutations/sync_user.rbSyncUser mutation
rails_api/app/interactions/onboarding/complete_onboarding_and_create_goal.rbAtomic onboarding-state + goal creation
rails_api/app/interactions/goal_tracking/add_goal.rbGoal creation + badge triggers
rails_api/app/models/user_action.rbBadge enum + generation

Day 2: First Return

What the User Sees

  • Dashboard greeting: "Good morning/afternoon/evening, {firstName}"
  • Streak counter updates to 2
  • If a habit was created: Today's Habits section with check-in buttons
  • Insight card with contextual tip

Emotional Journey

MomentFeelingBrand Tone
Streak counter ticks upReinforced — "the app noticed I came back""Day 2. The streak is building."
Habit check-inSatisfying micro-accomplishmentOne-tap action, immediate feedback

Gamification Triggers

TriggerRewardXPBadgesStreakLevel
Daily sign-inStreak increase+50221
Each habit check-inXP award+25 each221

Running total after Day 2 (with 2 check-ins): ~100 XP, 2 badges, streak 2, Level 1

Technical Details
  • RecordSignIn.call(user:) runs on every authenticated request via SyncUser
  • Streak update: User#update_streak! recalculates from UserSignInHistory consecutive days
  • Streak XP: GamificationService.award_xp(user, 50, 'Daily Streak') when new streak > current
  • Habit check-in: CheckInHabit interaction → GamificationService.award_xp(current_user, 25, 'Habit Check-in')

Key Files:

FileRole
rails_api/app/interactions/user_identity/record_sign_in.rbSign-in tracking
rails_api/app/interactions/goal_tracking/check_in_habit.rbHabit check-in + 25 XP
rails_api/app/services/gamification_service.rbXP awarding + level checks

Day 3: Building Momentum

What the User Sees

  • Streak counter at 3 — visual momentum growing
  • Possibly creates a second goal with a different category or type
  • If new category/type used: badge notification appears

Emotional Journey

MomentFeelingBrand Tone
Streak = 3Momentum — "I'm on a roll""Small steps. You're proving it."
Unexpected badgeDelighted — surprise rewardCelebratory without being over the top

Gamification Triggers

TriggerRewardXPBadgesStreakLevel
Daily sign-inStreak increase+50231
Habit check-insXP award+25 each231
2nd goal (new category)create_second_category badge331
2nd goal (new type)create_second_type badge3–431

Running total after Day 3 (with daily check-ins): ~200 XP, 3–4 badges, streak 3, Level 1

Technical Details
  • AddGoal interaction checks previous unique categories/types before creating the goal
  • If the new goal introduces a 2nd unique category: CreateSecondCategoryActionJob.perform_later(user.id)
  • If the new goal introduces a 2nd unique type: CreateSecondTypeActionJob.perform_later(user.id)
  • Jobs call UserAction.generate() → creates badge + feed item

Key Files:

FileRole
rails_api/app/interactions/goal_tracking/add_goal.rbCategory/type diversity detection
rails_api/app/jobs/gamification/create_second_category_action_job.rbBadge creation
rails_api/app/jobs/gamification/create_second_type_action_job.rbBadge creation

Days 4–5: Community Discovery

What the User Sees

  • Communities tab becomes relevant — browse public communities
  • Join first community → badge notification
  • Ally activity starts appearing in the dashboard feed
  • Communities OnboardingTour (separate from main wizard) may show on first visit

Emotional Journey

MomentFeelingBrand Tone
Browsing communitiesCurious — "there are others like me"Social accountability, not social media
Joining a communityBelonging — "I'm not alone in this""Your community sees the work you're putting in."
Seeing ally activityConnected — motivation from othersAccountability feed, not content feed

Gamification Triggers

TriggerRewardXPBadgesStreakLevel
Daily sign-ins (2 days)Streak increase+1004–51
Join first communityjoin_first_community badge4–54–51
Habit check-insXP award+25 each

Running total after Day 5 (with daily check-ins): ~350 XP, 4–5 badges, streak 5, Level 1

Technical Details
  • Community join triggers JoinFirstCommunityActionJob.perform_later(user.id) if it's the user's first community
  • Job calls UserAction.generate(user_id:, action: :join_first_community)
  • Communities OnboardingTour: ionic_frontend/src/components/communities/OnboardingTour.vue — separate localStorage-persisted tour

Key Files:

FileRole
rails_api/app/jobs/gamification/join_first_community_action_job.rbFirst community badge
ionic_frontend/src/components/communities/OnboardingTour.vueCommunities feature tour

Days 6–7: First Achievement

What the User Sees

  • Dashboard approaching Active User state (if 3+ goals created)
  • Momentum tiles (DashboardHero) show more metrics as the honest 3-tile hierarchy variant replaces the 4-tile sparse one
  • First goal completion possible (especially with the 14-day default target)
  • Level-up notification if XP threshold crossed (Level 2 at 500 XP)

Emotional Journey

MomentFeelingBrand Tone
Week-long streakPride — "I showed up every day""Level up. Every day added up to this."
First goal completeAccomplishment — "I actually did it"Major celebration moment
Level upProgression — "I'm growing"Earned recognition, not participation trophy

Gamification Triggers

TriggerRewardXPBadgesStreakLevel
Daily sign-ins (2 days)Streak increase+1006–71
Complete first goalcomplete_first_goal badge + 500 XP+5005–66–72
Habit check-insXP award+25 each

Running total after Day 7: ~550–700 XP, 5–6 badges, streak 7, Level 2 (threshold: 500 XP)

Technical Details
  • Goal completion: UpdateGoal interaction → GamificationService.award_xp(user, 500, 'Goal Completion')
  • Milestone detection in UpdateGoal#handle_completed_goals:
    • 1st completion → create_complete_first_goal_action
    • 5th completion → create_complete_fifth_goal_action
    • 10th completion → create_complete_tenth_goal_action
  • Level-up: GamificationService.check_for_level_up loops until XP < next threshold
  • Level 2 threshold: 500 XP → triggers CreateLevelUpNotificationJob

Key Files:

FileRole
rails_api/app/interactions/goal_tracking/update_goal.rbGoal completion + 500 XP
rails_api/app/services/gamification_service.rbLevel thresholds + level-up detection
rails_api/app/jobs/gamification/create_level_up_notification_job.rbLevel-up notification

Dashboard State Transitions

The dashboard progressively reveals features as the user advances through onboarding:

stateDiagram-v2
    [*] --> NoGoals: First sign-in

    NoGoals: No Goals
    NoGoals: "Create Your First Goal" empty state

    NewUser: New User (1 goal)
    NewUser: GettingStartedCard (auto-expanded)
    NewUser: Goal customization form

    Sparse: Sparse State (1–2 goals)
    Sparse: WelcomePrompt — "Add more goals"
    Sparse: Goal grid + AI Insight card

    Active: Active User (3+ goals)
    Active: Full dashboard — DashboardHero,
    Active: ActionHub, TodaysHabits,
    Active: Weekly Activity, Ally Feed

    NoGoals --> NewUser: Creates first goal\n(via wizard)
    NewUser --> Sparse: Customizes or skips\nsetup
    Sparse --> Active: Creates 3rd goal\nor dismisses prompt

Computed states in Dashboard.vue:

  • hasNoGoals → No Goals state
  • hasNewGoal → New User state (1 goal, default description, no category/type)
  • isSparseState → Sparse state (1–2 goals, setup dismissed)
  • Default → Active state (3+ goals)

Days 8–30: Activation & Retention

Week 2 (Days 8–14): Deepening Engagement

  • Multiple active goals across different categories
  • Regular habit check-in routine forming
  • Community participation — giving and receiving encouragements
  • Dashboard fully transitions to Active User state with all widgets visible
  • Expected progression: Level 2–3, 5+ badges, streak 8–14

Week 3 (Days 15–21): Habit Solidification

  • Daily check-ins becoming automatic
  • Potentially 5th goal completion → complete_fifth_goal badge
  • Deeper community engagement — following allies, community posts
  • AI Coach insights becoming more personalized with accumulated data
  • Expected progression: Level 3–4, 6+ badges, streak 15–21

Week 4 (Days 22–30): Activated User

  • Full feature usage: DashboardHero, ActionHub, Weekly Activity heatmap
  • Achievement showcase on profile
  • Possible 10th goal completion → complete_tenth_goal badge
  • User is now "activated" per north-star KPIs
  • Expected progression: Level 4–5, 8+ badges, streak 22–30

XP & Level Reference

LevelXP ThresholdTypical Timeline
10Day 1
2500Days 6–7
31,000Days 10–14
42,000Days 18–22
53,500Days 25–30+
65,500Month 2+
78,000Month 2–3
811,000Month 3+
915,000Month 4+
1020,000Month 5+

Success Metrics & KPIs

From the North Star metrics framework:

KPIDefinitionTargetMeasured From
Onboarding completion rate% of signups who complete wizard + create first goal> 80%Day 1
Time to first goalMinutes from signup to first goal created< 3 minDay 1
Time to first check-inHours from signup to first habit check-in< 24 hrsDay 1–2
Time to first streak (3+ days)Days from signup to 3-day streak< 5 daysDay 3–5
Activation rate% who create goal + complete first check-in within 48h> 60%Day 1–2
7-day retention% of signups who return on day 730–40%Day 7
30-day retention% of signups active at day 3015–25%Day 30

Goal Builder Flow

There is no variant_c experiment gate — every user gets the same 4-slide guided goal construction sequence (life area, goal name, goal shape, goal why) as slides 2–5 of the single onboarding registry.

flowchart TD
    subgraph goalBuilder ["Slides 2–5, all users"]
        LA["LifeAreaSlide<br/>Pick a life area (8 areas + Something else)"]
        GN["GoalNameSlide<br/>Name your goal<br/>(+ area-specific suggestion chips)"]
        GS["GoalShapeSlide<br/>Sprint / Arc / Habit / Life-list<br/>(+ conditional target date panel)"]
        GW["GoalWhySlide<br/>Optional motivation textarea"]
        LA --> GN --> GS --> GW
    end

    GW --> CB["Coach builder + goal-motivation-snapshot + source slides"]
    CB --> DS["DoneSlide"]
    DS -->|goal named| Q["CompleteOnboardingAndCreateGoal<br/>(atomic, confetti + create_first_goal badge 🏅)"]
    DS -->|no goal name| GC["StoreOnboardingState only →<br/>/goals/create for manual entry"]

Activation impact: Surfacing intent before a blank goal creation form reduces drop-off from blank-page syndrome. The optional goalWhy answer is retained in onboardingAnswers — useful for coaching interactions.

See Goal Builder and Onboarding Flow (technical) for the full technical reference.


Planned Enhancements

NOTE

Items below are on the roadmap but not yet implemented. They are included to show where they would fit in the onboarding timeline.

Goal Brainstorming Quizzes (Phase 5)

  • Where in timeline: Day 1, replaces or augments Slide 4 goal suggestions
  • What: 3–5 questions about life areas and pain points → AI generates 3–5 suggested goals via Ai::CoachService.suggest_goals()
  • Why: Reduces blank-page syndrome, increases goal quality and relevance
  • Success metric: 40%+ adoption rate, 25% reduction in onboarding drop-off

Goal Templates Library (Phase 5)

  • Where in timeline: Days 1–3, available during goal creation and from WelcomePrompt
  • What: New GoalTemplate model with pre-built milestones; template picker in goal creation flow
  • Why: Reduces friction for second/third goal creation, makes goals more structured from the start
  • Success metric: 40% faster goal setup, 1.5x more milestones per goal

Key Files Reference

FilePurpose
ionic_frontend/src/views/welcome/placeholderSlides.ts13-slide onboarding registry (goal + Coach setup)
ionic_frontend/src/views/welcome/WelcomeView.vue/welcome/:slideId route component
ionic_frontend/src/components/dashboard/GettingStartedCard.vuePost-wizard goal customization card
ionic_frontend/src/components/dashboard/WelcomePrompt.vue"Add more goals" CTA for sparse state
ionic_frontend/src/components/communities/OnboardingTour.vueCommunities feature tour (separate from wizard)
ionic_frontend/src/views/Dashboard.vueDashboard state machine (no goals → new → sparse → active)
ionic_frontend/src/composables/useOnboardingGate.tsshouldOnboard + resume-slide logic
ionic_frontend/src/router/index.tsRouter guard that triggers syncClerkUser
ionic_frontend/src/constants/graphql/user.jsSYNC_USER_MUTATION, COMPLETE_ONBOARDING_AND_CREATE_GOAL_MUTATION, STORE_ONBOARDING_STATE_MUTATION, USER_QUERY
rails_api/app/graphql/mutations/sync_user.rbBackend user sync, first sign-in detection
rails_api/app/interactions/onboarding/complete_onboarding_and_create_goal.rbAtomic onboarding-state + goal creation
rails_api/app/interactions/goal_tracking/add_goal.rbGoal creation + milestone badge triggers
rails_api/app/interactions/goal_tracking/check_in_habit.rbHabit check-in + 25 XP award
rails_api/app/interactions/goal_tracking/update_goal.rbGoal completion + 500 XP award
rails_api/app/interactions/user_identity/record_sign_in.rbSign-in tracking + streak update
rails_api/app/models/user_action.rbBadge/action enum and generation methods
rails_api/app/services/gamification_service.rbXP awarding, level thresholds, level-up detection
rails_api/app/jobs/gamification/create_first_goal_action_job.rbAsync first-goal badge
rails_api/app/jobs/gamification/create_level_up_notification_job.rbLevel-up notification

| ionic_frontend/src/components/dashboard/BetterTogetherInterstitial.vue | Post-wizard ally invite modal (v1.16 Phase 75) | | ionic_frontend/src/composables/useBetterTogetherInterstitial.ts | Trigger, state, analytics for the ally interstitial | | ionic_frontend/src/components/tour/FeatureTour.vue | Reusable guided-tour overlay engine (v4.16 Phase 1) | | ionic_frontend/src/composables/useFeatureTour.ts | Tour step resolution + server-authoritative persistence | | rails_api/app/interactions/user_identity/store_feature_tour_state.rb | Writes UserDetail.data['feature_tours'] (deep_merge, sibling-key safe) |

Last updated: 2026-08-30 — renamed MomentumBar references to DashboardHero, which superseded it (OBJ-3016); previously corrected stale OAuth provider list — GitHub is not enabled, see docs/architecture/authentication.md

Loading…