Skip to main content

Overview

The onboarding system guides new users through completing their profile after initial signup. This is a critical step for auction organizers to provide necessary business information, verify their identity, and configure their account settings before they can create auctions.

Onboarding Flow

1

Initial Signup

User creates an account through the signup form with email and password.
2

Redirect to Onboarding

After signup, users with is_onboarded: false are automatically redirected to /onboarding.
3

Complete Profile

Users fill out comprehensive profile information including personal details, company information, and address.
4

KYC Verification

Submit identity documents and tax information for verification (optional for initial onboarding).
5

Account Activation

Once completed, is_onboarded is set to true and user can access the dashboard.

Onboarding Data Structure

Based on the backend schema, the onboarding process collects the following information:
{
  user_id: number;        // Link to user account
  email: string;          // Contact email
  full_name: string;      // User's full legal name
  phone_number: string;   // Contact phone number
}
{
  company_name: string;   // Business or organization name
  website: string;        // Company website URL
  bio: string;            // Company description or bio
}
{
  address_line1: string;  // Primary address
  address_line2: string;  // Secondary address (optional)
  city: string;           // City
  state: string;          // State or province
  country: string;        // Country
  postal_code: string;    // ZIP or postal code
}
{
  kyc_status: string;           // 'pending', 'approved', 'rejected'
  kyc_verified_at: Date | null; // Verification timestamp
  identity_doc_url: string;     // Uploaded identity document
  tax_id: string;               // Tax identification number
}
{
  max_active_auctions: number;  // Maximum concurrent auctions
  can_create_auction: boolean;  // Permission to create auctions
  is_suspended: boolean;        // Account suspension status
}

Route Configuration

The onboarding route is configured without the main navigation bar:
src/routes/_without-navbar/onboarding.tsx:4
import OnboardingPage from '@/pages/onboarding/OnboardingPage'
import { createFileRoute } from '@tanstack/react-router'

export const Route = createFileRoute('/_without-navbar/onboarding')({
  component: OnboardingPage,
})

Onboarding Page Component

The main onboarding page structure:
src/pages/onboarding/OnboardingPage.tsx:38
export default function OnboardingPage() {
  return (
    <div className={styles.onboardingContainer}>
      <Typography as="h1" weight='light'>Onboarding Form</Typography>
      <OnboardingForm />
      <Button variant="primary">Submit</Button>
      <Link to="/dashboard" className={styles.routelink}>Dashboard</Link>
    </div>
  )
}

Onboarding Form Component

Currently, the onboarding form is a placeholder that will be expanded to include all required fields:
src/features/onboarding/components/OnboardingForm.tsx:4
export default function OnboardingForm() {
  return (
    <div>OnboardingForm</div>
  )
}
The onboarding form is currently under development. The full implementation will include schema-driven form fields similar to the authentication forms.

Expected Onboarding Schema

Based on the backend data structure documented in the page comments, the onboarding form should collect:
const PersonalInfoSchema = [
  {
    id: "full_name",
    label: "Full Name",
    type: "text",
    placeholder: "Enter your full legal name",
    fieldValidators: [
      { type: "required" },
      { type: "minLength", constraints: { minLength: 2 } }
    ]
  },
  {
    id: "email",
    label: "Email",
    type: "email",
    placeholder: "Contact email",
    fieldValidators: [
      { type: "required" },
      { type: "email" }
    ]
  },
  {
    id: "phone_number",
    label: "Phone Number",
    type: "tel",
    placeholder: "+1 (555) 123-4567",
    fieldValidators: [
      { type: "required" }
    ]
  }
]

Implementation Guide

To implement the full onboarding form, follow this pattern:
1

Create Schema

Define the onboarding form schema with all required fields and validation rules:
// src/features/onboarding/Schema/onboarding.schema.ts
export const OnboardingFormSchema = [
  // Personal info fields
  // Company info fields
  // Address fields
  // KYC fields (optional)
]
2

Use Form Engine

Leverage the existing useFormEngine hook for form state management:
import useFormEngine from "@app/hooks/useFormEngine";

const { formData, onChange, errors } = useFormEngine(
  OnboardingFormSchema
);
3

Render Form Fields

Map over the schema to render form fields with validation:
{OnboardingFormSchema.map((field) => (
  <TextField
    key={field.id}
    {...field}
    value={formData[field.id] ?? ""}
    onChange={(e) => onChange(e, field.id)}
    error={!!errors[field.id]}
    helperText={errors[field.id]}
  />
))}
4

Handle Submission

Submit the onboarding data and update user state:
const handleSubmit = async () => {
  await apiPOST("/onboarding", {
    body: JSON.stringify(formData)
  });
  
  // Update auth state
  useAuthStore.getState().updateOnboardingStatus(true);
  
  // Redirect to dashboard
  navigate({ to: "/dashboard" });
}
For better UX, consider implementing a multi-step onboarding wizard:
const [currentStep, setCurrentStep] = useState(1);
const totalSteps = 4;

const steps = [
  { title: "Personal Information", schema: PersonalInfoSchema },
  { title: "Company Details", schema: CompanyInfoSchema },
  { title: "Address", schema: AddressSchema },
  { title: "Verification", schema: KYCSchema }
];

const nextStep = () => setCurrentStep(prev => Math.min(prev + 1, totalSteps));
const prevStep = () => setCurrentStep(prev => Math.max(prev - 1, 1));

Account Permissions

After onboarding, users receive default permissions:

Default Permissions

{
  max_active_auctions: 5,
  can_create_auction: true,
  is_suspended: false,
  kyc_status: "pending"
}
Users can start creating auctions immediately after onboarding. KYC verification can happen asynchronously without blocking auction creation.

KYC Verification Process

KYC (Know Your Customer) verification is handled in the background:
1

Document Upload

User uploads identity documents during onboarding (optional).
2

Status: Pending

KYC status is set to “pending” and documents are queued for review.
3

Admin Review

Platform administrators review submitted documents.
4

Approval/Rejection

KYC status is updated to “approved” or “rejected” with optional feedback.

KYC Status Types

pending
string
Initial status after document submission. User can still create auctions.
approved
string
Identity verified. User may receive increased limits or privileges.
rejected
string
Verification failed. User may need to resubmit documents.

Best Practices

  • Break the form into logical steps (3-4 steps maximum)
  • Show progress indicators for multi-step forms
  • Allow users to skip optional fields
  • Save draft progress to prevent data loss
  • Validate fields on blur for immediate feedback
  • Use appropriate input types (email, tel, url)
  • Provide clear error messages
  • Validate business rules (e.g., phone number format by country)
  • Encrypt sensitive data (tax IDs, identity documents)
  • Use secure file upload with size and type restrictions
  • Implement rate limiting on submission
  • Log all onboarding attempts for audit purposes

API Endpoints

/onboarding
POST
Submit onboarding informationRequest Body:
{
  "full_name": "John Doe",
  "phone_number": "+1234567890",
  "company_name": "Acme Corp",
  "website": "https://acme.com",
  "bio": "Leading auction house...",
  "address_line1": "123 Main St",
  "city": "New York",
  "state": "NY",
  "country": "USA",
  "postal_code": "10001",
  "tax_id": "12-3456789"
}
Response:
{
  "id": 1,
  "user_id": 123,
  "kyc_status": "pending",
  "can_create_auction": true,
  "max_active_auctions": 5
}
/onboarding/upload
POST
Upload identity documents for KYC verificationContent-Type: multipart/form-dataForm Fields:
  • identity_doc: File (max 5MB, jpg/png/pdf)
  • user_id: number

Build docs developers (and LLMs) love