12 KiB
Unified "Get Started" Flow
Overview
The unified get-started flow provides a single entry point for customer account creation and eligibility checking. It replaces separate /signup and /migrate pages with a streamlined flow at /auth/get-started.
User Flows
1. Direct Account Creation (/auth/get-started)
/auth/get-started
│
├─→ Step 1: Enter email
│
├─→ Step 2: Verify email (6-digit OTP)
│
└─→ Step 3: System checks accounts & routes:
│
├─→ Portal exists → "Go to login"
├─→ WHMCS exists (unmapped) → "Link account" (enter WHMCS password)
├─→ SF exists (unmapped) → "Complete account" (pre-filled form)
└─→ Nothing exists → "Create account" (full form)
2. Eligibility Check First (/services/internet/check-availability)
For customers who want to check internet availability before creating an account:
/services/internet (public)
│
└─→ Click "Check Availability"
│
└─→ /services/internet/check-availability (dedicated page)
│
├─→ Step 1: Enter name, email, address (with Japan ZIP lookup)
│
└─→ Step 2: Choose action:
│
├─→ "Just Submit Request" (secondary action)
│ └─→ SF Account + Opportunity (find/create) + Case created
│ └─→ Case description notes if Opportunity was created or matched
│ └─→ Success page shows "View Internet Plans" → /services/internet
│ └─→ User can return later via SF email to create account
│
└─→ "Create Account & Submit" (primary action)
├─→ Step 2a: OTP sent to email (inline on same page)
├─→ Step 2b: User verifies OTP
├─→ Step 2c: Complete account form (phone, DOB, password)
├─→ Creates SF Account + Opportunity + Case + WHMCS + Portal
├─→ Case description notes if Opportunity was created or matched
└─→ Success page → Auto-redirect to /dashboard (5s countdown)
Key design: The entire eligibility check flow is self-contained on /services/internet/check-availability. There is no redirect to /auth/get-started - all steps (form, OTP, account creation, success) happen on the same page using internal step state.
Account Status Detection
The system checks accounts in order and returns the first match:
Step 1: Portal User with ID Mapping
Check if Portal user exists (by email) AND has an ID mapping.
- Found:
PORTAL_EXISTS→ Redirect to login - Not found: Continue to step 2
Step 2: WHMCS Client (Billing Account)
Check if WHMCS client exists (by email).
- Found:
WHMCS_UNMAPPED→ "Link account" flow (enter WHMCS password to migrate) - Not found: Continue to step 3
WHMCS clients are existing billing customers who haven't created a Portal account yet.
Step 3: Salesforce Account Only
Check if SF Account exists (by email).
- Found:
SF_UNMAPPED→ "Complete account" flow (pre-filled form, create WHMCS + Portal) - Not found: Continue to step 4
SF-only accounts are customers who:
- Checked internet eligibility without creating an account
- Contacted us via email/phone and we created an SF record
- Were created through other CRM workflows
Step 4: No Account Found
NEW_CUSTOMER→ Full signup form
Summary Table
| Check Order | System Found | Status | User Flow |
|---|---|---|---|
| 1 | Portal + Mapping | portal_exists |
Go to login |
| 2 | WHMCS (no portal) | whmcs_unmapped |
Enter WHMCS password to link |
| 3 | SF only | sf_unmapped |
Complete account (pre-filled) |
| 4 | Nothing | new_customer |
Full signup form |
Frontend Structure
apps/portal/src/features/get-started/
├── api/get-started.api.ts # API client functions
├── stores/get-started.store.ts # Zustand state management
├── components/
│ ├── GetStartedForm/
│ │ ├── GetStartedForm.tsx # Main form container
│ │ └── steps/
│ │ ├── EmailStep.tsx # Email input
│ │ ├── VerificationStep.tsx # OTP verification
│ │ ├── AccountStatusStep.tsx# Route based on status
│ │ ├── CompleteAccountStep.tsx # Full signup form
│ │ └── SuccessStep.tsx # Success confirmation
│ └── OtpInput/OtpInput.tsx # 6-digit code input
├── views/GetStartedView.tsx # Page view
└── index.ts # Public exports
Eligibility Check Page
Location: apps/portal/src/features/services/views/PublicEligibilityCheck.tsx
Route: /services/internet/check-availability
Store: apps/portal/src/features/services/stores/eligibility-check.store.ts
A dedicated page for guests to check internet availability. This approach provides:
- Better mobile experience with proper form spacing
- Clear user journey with bookmarkable URLs
- Natural browser navigation (back button works)
- Self-contained multi-step experience (no redirects to other pages)
Steps: form → otp → complete-account → success
Path 1: "Just Submit Request" (guest, no account):
- Collects name, email, and address (with Japan ZIP code lookup)
- Creates SF Account + Opportunity (find/create) + Eligibility Case
- Shows success with "View Internet Plans" button
Path 2: "Create Account & Submit" (full account creation):
- Collects name, email, and address (with Japan ZIP code lookup)
- Sends OTP, user verifies on same page
- Collects account details (phone, DOB, password)
- Creates SF Account + Opportunity + Case + WHMCS client + Portal user
- Shows success with auto-redirect to dashboard (5s countdown)
Backend Endpoints
| Endpoint | Rate Limit | Purpose |
|---|---|---|
POST /auth/get-started/send-code |
5/5min | Send OTP to email |
POST /auth/get-started/verify-code |
10/5min | Verify OTP, return account status |
POST /auth/get-started/guest-eligibility |
3/15min | Guest eligibility (no OTP, creates SF Account + Opportunity + Case) |
POST /auth/get-started/complete-account |
5/15min | Complete SF-only account |
POST /auth/get-started/signup-with-eligibility |
5/15min | Full signup with eligibility (OTP verified) |
Domain Schemas
Location: packages/domain/get-started/
Key schemas:
sendVerificationCodeRequestSchema- email onlyverifyCodeRequestSchema- email + 6-digit codeguestEligibilityRequestSchema- email, name, address (no OTP required)completeAccountRequestSchema- sessionToken + password + profile fieldssignupWithEligibilityRequestSchema- sessionToken + full account dataaccountStatusSchema-portal_exists | whmcs_unmapped | sf_unmapped | new_customer
OTP Security
- Storage: Redis with key format
otp:{email} - TTL: 10 minutes
- Max Attempts: 3 per code
- Rate Limits: 5 codes per 5 minutes
Eligibility Check Flow Details
Path 1: "Just Submit Request" (Guest Flow)
When a user clicks "Just Submit Request":
- Calls
guestEligibilityCheckAPI withcontinueToAccount: false - Backend creates SF Account + Opportunity (find/create) + Eligibility Case
- Frontend navigates to success step with
hasAccount: false - Success page shows only "View Internet Plans" button
- User can return later via SF email to create an account at
/auth/get-started
Path 2: "Create Account & Submit" (Full Account Creation)
When a user clicks "Create Account & Submit":
- OTP Step: Calls
sendVerificationCodeAPI → navigates to OTP step (same page) - Verify OTP: User enters code, calls
verifyCodeAPI → receives session token - Complete Account: Navigates to complete-account step (same page)
- Submit: Calls
signupWithEligibilityAPI which creates:- SF Account (find or create)
- Opportunity (find or create)
- Eligibility Case
- WHMCS client
- Portal user
- Success: Shows success with "Go to Dashboard" button + auto-redirect (5s)
Guest Return Flow via SF Email
SF can send "finish your account" emails with this link format:
https://portal.example.com/auth/get-started?email={Account.PersonEmail}
- User goes to
/auth/get-started(not the eligibility check page) - Standard flow: Email (pre-filled) → OTP → Account Status → Complete
- Backend detects
sf_unmappedstatus and returns prefill data from existing SF Account
Testing Checklist
Manual Testing - Get Started Page (/auth/get-started)
- New customer flow: Enter new email → Verify OTP → Full signup form
- SF-only flow: Enter email with SF account → Verify → Pre-filled form (name, address pre-filled, add phone, DOB, password)
- WHMCS migration: Enter email with WHMCS → Verify → Enter WHMCS password
- Return flow: Customer with existing SF account returns, enters same email → Auto-links to SF account
Manual Testing - Eligibility Check Page (/services/internet/check-availability)
- Eligibility check - Just Submit Request:
- Click "Check Availability" → Fill form → Click "Just Submit Request"
- Verify success page shows only "View Internet Plans" button
- Verify SF Account + Opportunity + Case are created
- Eligibility check - Create Account & Submit:
- Click "Check Availability" → Fill form → Click "Create Account & Submit"
- Verify OTP step appears (same page, no redirect)
- Complete OTP → Verify complete-account step appears (same page)
- Fill account details → Submit
- Verify success page with auto-redirect countdown to dashboard
- Verify SF Account + Opportunity + Case + WHMCS + Portal user created
- Mobile experience: Test eligibility check page on mobile viewport
- Browser back button: After OTP success, press back → Verify graceful handling
- Existing account handling: During OTP verification, if
portal_existsorwhmcs_unmappedstatus returned, verify appropriate error message
Security Testing
- Verify OTP expires after 10 minutes
- Verify max 3 attempts per code
- Verify rate limits on all endpoints
- Verify email enumeration is prevented (same response until OTP verified)
Routes
| Route | Action |
|---|---|
/auth/get-started |
Unified account creation page |
/auth/signup |
Redirects to /auth/get-started |
/auth/migrate |
Redirects to /auth/get-started |
/services/internet/check-availability |
Guest eligibility check (public) |
Environment Variables
# OTP Configuration
OTP_TTL_SECONDS=600 # 10 minutes
OTP_MAX_ATTEMPTS=3
GET_STARTED_SESSION_TTL=3600 # 1 hour