Unclassified

User Onboarding Flow

Status: CURRENT CODE-DERIVED VIEW, NOT A CANONICAL CONTRACT. Use this file
to trace the implemented onboarding path. If behavior conflicts with
docs/architecture/ARCHITECTURE_LOCK.md
or
docs/architecture/CONSOLIDATED_PRODUCT_PLATFORM_CONTRACT_v1.2.md,
the frozen contracts win.

Generated: July 29, 2026
Based on: Frontend onboarding implementation, Gateway onboarding service, Workspace API


High-Level Onboarding Flow

┌─────────────────────────────────────────────────────────────────────────────┐
│                          ENTRY POINTS                                         │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  ┌──────────────┐                    ┌──────────────┐                      │
│  │   Direct     │                    │  Marketplace  │                      │
│  │   Sign-up    │                    │   Connector  │                      │
│  └──────┬───────┘                    └──────┬───────┘                      │
│         │                                   │                               │
│         └─────────────────┬─────────────────┘                               │
│                           │                                                  │
│                           ▼                                                  │
│                    ┌──────────────┐                                         │
│                    │ Clerk OAuth  │                                         │
│                    │  (Google/    │                                         │
│                    │   GitHub)    │                                         │
│                    └──────┬───────┘                                         │
│                           │                                                  │
│                           ▼                                                  │
│              ┌──────────────────────────────┐                                │
│              │  Gateway: getOrCreateUser    │                                │
│              │  - Check existing user       │                                │
│              │  - Create new user if needed  │                                │
│              │  - Set onboarding intent     │                                │
│              └──────────────┬───────────────┘                                │
│                           │                                                  │
│                           ▼                                                  │
└───────────────────────────────────┼───────────────────────────────────────────┘
                                    │
┌───────────────────────────────────┼───────────────────────────────────────────┐
│                      ONBOARDING SHELL (4 Steps)                               │
├───────────────────────────────────┼───────────────────────────────────────────┤
│                                   │                                          │
│         ┌─────────────────────────┼─────────────────────────┐                 │
│         │                         │                         │                 │
│         ▼                         ▼                         ▼                 │
│  ┌──────────────┐        ┌──────────────┐        ┌──────────────┐              │
│  │   Step 1     │        │   Step 2     │        │   Step 3     │              │
│  │   Welcome    │        │   Profile    │        │   Goals      │              │
│  │   Use Case   │        │  Industry/   │        │  Workspace   │              │
│  │  Selection   │        │ Department   │        │   Creation   │              │
│  └──────┬───────┘        └──────┬───────┘        └──────┬───────┘              │
│         │                       │                       │                      │
│         │ personal/work/business│ industry + department │ goal + workspace    │
│         │                       │ + company size        │ name + type          │
│         │                       │                       │                      │
│         └───────────────────────┴───────────────────────┘                      │
│                                   │                                          │
│                                   ▼                                          │
│                          ┌──────────────┐                                    │
│                          │   Step 4     │                                    │
│                          │  Complete    │                                    │
│                          │  Success +   │                                    │
│                          │  Redirect    │                                    │
│                          └──────┬───────┘                                    │
│                                 │                                          │
│         ┌───────────────────────┴───────────────────────┐                    │
│         │                                               │                    │
│         ▼                                               ▼                    │
│  ┌──────────────┐                                ┌──────────────┐              │
│  │  Workbench   │                                │  Marketplace  │              │
│  │  /app        │                                │  Connector   │              │
│  └──────────────┘                                │  Activation  │              │
│                                                 └──────────────┘              │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

Detailed Step-by-Step Flow

Step 1: Welcome (Use Case Selection)

Route: /onboarding
Component: WelcomeStep.tsx

User Selection:

  • Personal - Organize personal work
  • Work - Professional workflow
  • Business - Company data & workflows

Data Collected:

{
  useCase: "personal" | "work" | "business";
}

Backend Action:

  • Calls updateOnboardingState({ currentStep: "workspace", completedSteps: ["welcome"] })
  • Stores preference in backend session

Domain Resolution:

personal → PERSONAL domain
work → Maps department to domain (SALES, MARKETING, REVOPS, etc.)
business → Maps department to domain (SALES, MARKETING, REVOPS, etc.)

Step 2: Profile (Industry & Department)

Route: /onboarding/profile
Component: ProfileStep.tsx

User Selection:

Industry Options (12):

  • Technology / SaaS
  • Professional Services
  • Healthcare
  • Education
  • Manufacturing
  • Automotive / Mobility
  • Retail / E-commerce
  • Financial Services
  • Logistics / Supply Chain
  • Media / Entertainment
  • Government / Public Sector
  • Other

Department Groups (4 categories):

  • Revenue & Growth: Sales, Marketing, RevOps, Customer Success
  • Technology: Engineering, Product Management, IT/Technology
  • Operations: Operations, Supply Chain, Service Operations, Project Management
  • Corporate: Finance/Accounting, Legal, Human Resources

Company Size:

  • Just me, 2-10, 11-50, 51-200, 201-500, 500+

Data Collected:

{
  industry: string,
  department: string,
  companySize: string
}

Spine Schema Init:

  • When industry + department selected, triggers handleSpineInit
  • Calls updateOnboardingState({ currentStep: "configuration" })
  • Configures adaptive Spine schema for domain

Domain Mapping:

SALES → SALES domain
MARKETING → MARKETING domain
CUSTOMER_SUCCESS → CUSTOMER_SUCCESS domain
ENGINEERING → PRODUCT_ENGINEERING domain
FINANCE → FINANCE domain
OPERATIONS → CUSTOMER_SUCCESS domain
// ... (full mapping in OnboardingShell.tsx)

Step 3: Goals & Workspace

Route: /onboarding/workspace
Component: GoalsStep.tsx

User Selection:

Primary Goals (5):

  • Organize knowledge - Database icon
  • Get insights - Sparkles icon
  • Track context - Target icon
  • Improve team - Users icon
  • Automate work - Zap icon

Workspace Types (4):

  • Company
  • Department
  • Client
  • Project

Workspace Name: Free text input (default: "Acme Corp")

Data Collected:

{
  goal: string,
  workspaceName: string,
  workspaceType: string
}

Backend Actions:

  1. Update Onboarding State:
await updateOnboardingState({
  currentStep: "activation",
  completedSteps: ["workspace", "configuration", "connectors"],
  preferences: { useCase, industry, department, companySize, goal, workspaceName, workspaceType },
});
  1. Initialize Spine:
await initializeSpine({
  domain: resolvedDomain,
  industry: data.industry,
  department: data.department,
  connectors: [],
});
  1. Update User Profile:
await updateUser({
  onboarding_complete: true,
  domain: resolvedDomain,
  department: data.department,
  useCase: data.useCase,
  userName: workspaceName,
});
  1. Complete Onboarding:
await completeOnboarding({
  preferences: {
    /* all onboarding data */
  },
});
  1. Create Free Subscription:
await apiFetch("/api/v1/subscriptions", {
  method: "POST",
  body: { tenantId, planId: "free" },
});

Step 4: Completion

Route: /onboarding/complete
Component: CompletionScreen

Behavior:

  • Shows success message with checkmark
  • Auto-redirects to workbench after 3 seconds
  • Two manual options:
    • Browse Marketplace - Go to connector marketplace
    • Go to Workbench Now - Immediate redirect

Marketplace Intent Handling:

  • If user came from marketplace connector activation
  • Shows "Connect [Connector Name]" button
  • Redirects to /marketplace?activate=[connector-id]

Auto-redirect:

setTimeout(() => {
  navigate("/app", { replace: true });
}, 2000);

Backend Onboarding Service

Gateway Onboarding (services/gateway/src/onboarding.ts)

Key Functions:

getOrCreateUser

// Called after OAuth callback
// - Checks if user exists in tenant
// - Creates new user if needed
// - Returns OnboardingContext with isNewUser flag

getAvailableRoles

// Returns 10 predefined roles:
// - sales_rep, sales_manager
// - cs_manager, cs_specialist
// - finance_manager, support_lead
// - engineering_lead, marketing_manager
// - ops_manager, ceo
// Each with: suggestedConnectors, defaultDomain, defaultView

getAvailableConnectors

// Returns 15+ connectors filtered by subscription tier:
// - CRM: Salesforce, Freshsales, HubSpot
// - Enrichment: Apollo
// - Accounting: Stripe, Razorpay, QuickBooks
// - Communications: Zendesk, Intercom, Gmail, Slack, Zoom
// - Analytics: GitHub, Jira, Google Analytics
// Tiers: free, starter, pro, enterprise

completeOnboarding

// Finalizes onboarding:
// - Updates user role in users table
// - Stores connector selections in tenant_spine_config
// - Logs onboarding event in audit_log
// - Marks onboarding_completed_at timestamp

Workspace API Endpoints

/api/v1/workspace/initialize-spine

Method: POST
Purpose: Initialize Spine schema for tenant

Request:

{
  domain: "CUSTOMER_SUCCESS" | "SALES" | "REVOPS" | ...,
  industry?: string,
  department?: string,
  connectors: Array<{
    provider: string,
    flowType: "A" | "B" | "C"
  }>
}

Response:

{
  tenantConfig: {
    id: string,
    domain: string,
    connectors: Record<string, any>
  },
  syncJobs: Array<{
    jobId: string,
    connector: string,
    status: string
  }>
}

/api/v1/workspace/onboarding-state

Methods: GET, PATCH
Purpose: Manage onboarding session state

GET Response:

{
  onboarding: {
    status: "not_started" | "in_progress" | "completed",
    currentStep: string,
    completedSteps: string[],
    connectorsConfig?: Array<{...}>,
    creamyJobId?: string,
    normalizerJobId?: string,
    preferences?: Record<string, unknown>,
    entry?: { source: "direct" | "marketplace" | "mcp" }
  }
}

PATCH Request:

{
  currentStep?: "welcome" | "workspace" | "configuration" | "connectors" | "activation" | "complete",
  completedSteps?: string[],
  preferences?: Record<string, unknown>
}

/api/v1/workspace/complete-onboarding

Method: POST
Purpose: Finalize onboarding and trigger background jobs

Request:

{
  preferences?: Record<string, any>
}

Response:

{
  success: boolean,
  redirectUrl: string,
  backgroundJobs: Array<{
    jobId: string,
    type: string,
    status: string
  }>
}

/api/v1/workspace/progress

Method: GET
Purpose: Poll sync job progress during onboarding

Response:

{
  type: "sync_progress",
  jobs: Array<{
    jobId: string,
    connector: string,
    phase: "creamy" | "needed" | "delta",
    status: "pending" | "running" | "completed" | "failed",
    progress: {
      total?: number,
      processed?: number,
      percentage?: number,
      stage?: string
    }
  }>
}

Onboarding Intent System

Purpose: Carry entry point through hosted authentication without putting connector identity in OAuth URL

File: apps/web/src/lib/onboarding-intent.ts

Intent Types:

type OnboardingIntent =
  | { version: 1; source: "direct" }
  | {
      version: 1;
      source: "marketplace";
      connector: { id: string; name: string; authType: "oauth" | "api_key" };
    };

Functions:

  • getOnboardingIntent() - Read from sessionStorage
  • ensureDirectOnboardingIntent() - Set direct intent if none exists
  • setMarketplaceConnectorIntent() - Set marketplace connector intent
  • clearOnboardingIntent() - Clear after onboarding complete

Storage: SessionStorage (navigation convenience, not source of truth)


Domain Resolution Logic

File: apps/web/src/OnboardingShell.tsx

Mapping Function:

function resolveDomain(useCase: string, department: string): string;

Domain Mappings:

Use CaseDepartmentDomain
personalanyPERSONAL
workSALESSALES
workMARKETINGMARKETING
workREVOPSREVOPS
workCUSTOMER_SUCCESSCUSTOMER_SUCCESS
workENGINEERING/PRODUCT/ITPRODUCT_ENGINEERING
workOPERATIONSCUSTOMER_SUCCESS
workSUPPLY_CHAINPROCUREMENT
workSERVICE_OPSSERVICE
workPROJECT_MANAGEMENTCUSTOMER_SUCCESS
workFINANCEFINANCE
workLEGAL/HRCUSTOMER_SUCCESS
business(same as work)(same as work)

Fallback: If no match, defaults to CUSTOMER_SUCCESS (business) or PERSONAL (personal)


Draft Persistence

Storage Key: iw_onboarding_draft_{userId}
Storage: SessionStorage

Persisted Data:

{
  version: 1,
  currentPath: string,
  data: {
    useCase?: string,
    industry?: string,
    department?: string,
    companySize?: string,
    goal?: string,
    workspaceName?: string,
    workspaceType?: string
  },
  updatedAt: number
}

Behavior:

  • Auto-saves on each step completion
  • Restores on page reload
  • Cleared after successful onboarding completion

Step Indicator

Visual Progress: 4 dots with connecting lines

●──●──●──●
Step 1 of 4

Steps:

  1. Welcome (/onboarding)
  2. Profile (/onboarding/profile)
  3. Workspace (/onboarding/workspace)
  4. Done (/onboarding/complete)

Current Step Highlighting: Primary color for completed and current steps


Animation & Transitions

Library: Framer Motion

Transitions:

  • Fade in/out between steps
  • Slide up/down for step changes
  • Scale effects on button interactions
  • Pulse animation for spine initialization indicator

Loading States:

  • Spinner during async operations
  • Disabled button states during submission
  • Progress indicators for background jobs

Error Handling

Frontend:

  • Try-catch around all async operations
  • Console error logging with context
  • Graceful degradation (continue on failure)
  • User-friendly error messages

Backend:

  • Database transaction rollback on failure
  • Audit logging for all onboarding events
  • Idempotency for retry scenarios
  • Tenant isolation enforcement

Post-Onboarding Flow

Immediate Actions:

  1. Clear sessionStorage draft
  2. Clear onboarding intent
  3. Redirect to workbench or marketplace

Workbench Entry:

  • User sees role-specific modules
  • Spine projection based on domain
  • Empty state with "Get Started" prompts
  • Suggested connectors based on role

Marketplace Entry (if connector intent):

  • Pre-selected connector from intent
  • OAuth flow initiation
  • Connector activation wizard

Subscription Creation

Default Plan: Free tier

API Call:

POST /api/v1/subscriptions
{
  tenantId: string,
  planId: "free"
}

Behavior:

  • Best-effort (failure doesn't block onboarding)
  • Console error logging
  • Can be completed later in settings

Architecture Compliance

Frozen Architecture Alignment:

✅ Product = Three Concepts Only

  • Onboarding (initial setup)
  • User Workbench (role-specific projection)
  • Silent Twin (contextual assistance)

✅ Spine is SSOT

  • Onboarding configures Spine schema
  • Spine owns all operational truth
  • Memory informs truth, not vice versa

✅ Governance is Hard Gate

  • No connector activation without approval
  • OAuth flows properly gated
  • Tenant isolation enforced

✅ Workbench is One Surface

  • No L1/L2/L4/L7 in onboarding UI
  • Single progressive flow
  • Role projection configured, not layered

✅ Twin is Silent by Default

  • Twin not involved in onboarding
  • No AI assistance during setup
  • User-driven configuration only

Key Files Reference

FilePurpose
apps/web/src/OnboardingShell.tsxMain onboarding shell with 4-step flow
apps/web/src/components/activation/onboarding/steps/WelcomeStep.tsxStep 1: Use case selection
apps/web/src/components/activation/onboarding/steps/ProfileStep.tsxStep 2: Industry/department selection
apps/web/src/components/activation/onboarding/steps/GoalsStep.tsxStep 3: Goals and workspace creation
apps/web/src/api/workspace.tsWorkspace API client (initialize-spine, onboarding-state, complete-onboarding)
apps/web/src/lib/onboarding-intent.tsOnboarding intent management (direct vs marketplace)
services/gateway/src/onboarding.tsBackend onboarding service (roles, connectors, user creation)
services/gateway/src/index.tsGateway routing for onboarding endpoints

Summary

The IntegrateWise onboarding flow is a 4-step progressive wizard that:

  1. Captures user intent (personal/work/business use case)
  2. Configures the Spine (industry + department → domain resolution)
  3. Creates the workspace (goals + workspace name + type)
  4. Initializes Spine schema and redirects to workbench or marketplace

The flow is entry-point agnostic - works equally well for direct sign-up and marketplace connector activation. It uses session storage for draft persistence, backend session for state management, and Clerk OAuth for authentication.

Key architectural principles maintained:

  • Single Workbench surface (no layer complexity)
  • Spine as single source of truth
  • Role-based domain projection
  • Governance gates for connector activation
  • Silent Twin (no AI during onboarding)