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
Initial Signup
User creates an account through the signup form with email and password.
Redirect to Onboarding
After signup, users with is_onboarded: false are automatically redirected to /onboarding.
Complete Profile
Users fill out comprehensive profile information including personal details, company information, and address.
KYC Verification
Submit identity documents and tax information for verification (optional for initial onboarding).
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:
{
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 >
)
}
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:
Step 1: Personal
Step 2: Company
Step 3: Address
Step 4: KYC (Optional)
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" }
]
}
]
const CompanyInfoSchema = [
{
id: "company_name" ,
label: "Company Name" ,
type: "text" ,
placeholder: "Your company or organization name" ,
fieldValidators: [
{ type: "required" }
]
},
{
id: "website" ,
label: "Website" ,
type: "url" ,
placeholder: "https://example.com" ,
fieldValidators: [
{ type: "url" }
]
},
{
id: "bio" ,
label: "Bio" ,
type: "textarea" ,
placeholder: "Tell us about your company..." ,
fieldValidators: [
{ type: "maxLength" , constraints: { maxLength: 500 } }
]
}
]
const AddressSchema = [
{
id: "address_line1" ,
label: "Address Line 1" ,
type: "text" ,
placeholder: "Street address" ,
fieldValidators: [
{ type: "required" }
]
},
{
id: "address_line2" ,
label: "Address Line 2" ,
type: "text" ,
placeholder: "Apt, suite, unit, etc. (optional)"
},
{
id: "city" ,
label: "City" ,
type: "text" ,
fieldValidators: [
{ type: "required" }
]
},
{
id: "state" ,
label: "State/Province" ,
type: "text" ,
fieldValidators: [
{ type: "required" }
]
},
{
id: "country" ,
label: "Country" ,
type: "text" ,
fieldValidators: [
{ type: "required" }
]
},
{
id: "postal_code" ,
label: "Postal Code" ,
type: "text" ,
fieldValidators: [
{ type: "required" }
]
}
]
const KYCSchema = [
{
id: "tax_id" ,
label: "Tax ID" ,
type: "text" ,
placeholder: "EIN or SSN" ,
fieldValidators: [
{ type: "pattern" , constraints: {
pattern: / ^ \d {2} - \d {7} | \d {3} - \d {2} - \d {4} $ /
}}
]
},
{
id: "identity_doc" ,
label: "Identity Document" ,
type: "file" ,
placeholder: "Upload government-issued ID" ,
fieldValidators: [
{ type: "fileType" , constraints: {
types: [ "image/jpeg" , "image/png" , "application/pdf" ]
}}
]
}
]
Implementation Guide
To implement the full onboarding form, follow this pattern:
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)
]
Use Form Engine
Leverage the existing useFormEngine hook for form state management: import useFormEngine from "@app/hooks/useFormEngine" ;
const { formData , onChange , errors } = useFormEngine (
OnboardingFormSchema
);
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 ] }
/>
))}
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:
Step Navigation
Progress Indicator
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:
Document Upload
User uploads identity documents during onboarding (optional).
Status: Pending
KYC status is set to “pending” and documents are queued for review.
Admin Review
Platform administrators review submitted documents.
Approval/Rejection
KYC status is updated to “approved” or “rejected” with optional feedback.
KYC Status Types
Initial status after document submission. User can still create auctions.
Identity verified. User may receive increased limits or privileges.
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
Submit onboarding information Request 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
}
Upload identity documents for KYC verification Content-Type: multipart/form-dataForm Fields:
identity_doc: File (max 5MB, jpg/png/pdf)
user_id: number