Skip to main content

Feature: Org Onboarding

Last updated: 2026-05-07

This document is the single source of truth for org onboarding. Requirements and acceptance criteria were consolidated here on 2026-05-04.

Overview

Org onboarding is a two-phase process:

  1. Phase 1 (AM-assisted) — Internal Account Manager sets up the Org in the admin portal
  2. Phase 2 (Client confirmation) — Client Admin completes setup via a guided wizard at /onboarding (link delivered via invite email)

The result is an active Org with at least one Specialist assigned, Email channel configured, and a Client Admin who has confirmed the setup.

Actors

ActorRoleWhat They Do
Account ManagerInternalCreates Org, assigns Specialists, sends invite
Client AdminClientConfirms setup, sets password, configures channels
Super AdminInternalCan view/edit any onboarding; can impersonate AM

Phase 0: Validation Gate

Before the invite is sent, the system hard-blocks until all pass:

  • All required company fields complete
  • At least 1 Specialist assigned with complete profile (name, avatar, email, skill tags)
  • AM's own profile complete
  • Trial end date set (default: 30 days from invite send date)

Endpoint: GET /am/orgs/:orgId/phase0-status

Route note: AM-facing endpoints use the /am/orgs/ prefix internally (NestJS routing), but the frontend accesses them through /ops/clients/[id]/setup/* routes.

AM Wizard — 4 Steps

The AM wizard has 4 steps accessed from /ops/clients/new (step 1) and /ops/clients/[id]/setup/* (steps 2–4).

Phase 1: AM-Assisted Setup

Step 1.1 — Company Information

AM enters on behalf of the client:

Required: company legal name, subdomain (slug), industry, primary corporate email domain(s), admin email address (optional), company website, country/timezone

The AM wizard labels this field "Subdomain" in the UI. The code and DB call it slug. After the client confirms in onboarding Step 2.2, the slug is immutable.

Optional: company logo, billing email, company size, secondary email domains

Slug rules:

  • Format: ^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$ (3–63 chars)
  • Validated in real-time via GET /orgs/slug-check?slug=...
  • Reserved word list enforced (api, app, www, admin, etc.) — see config/reserved-slugs.ts
  • Not reserved until client confirms in Step 2.2

Email domain rules:

  • Personal domains blocked (gmail, yahoo, etc.) — see config/blocked-email-domains.ts
  • Admin email must match an approved corporate domain
  • No DNS verification required

Step 1.2 — Assign Specialists

AM selects 1+ Specialists from the platform pool. For each Specialist:

  • Confidence Threshold set (integer 0–101; default 101 = Never autoreply)
  • Optional: designate a primary Specialist

Specialist constraints:

  • Specialist ↔ Org relationship is many-to-many via OrgSpecialistAssignment
  • Specialist profile must be complete (name, avatar, email, skill tags)
  • Specialist email format: {firstname}`@`{HWORK_DOMAIN} (routing alias only; not a login)
  • Only SuperAdmin can create/modify Specialist personas. AMs assign existing ones.

Step 1.3 — Account Manager Profile

AM verifies their global profile (name, avatar, email). Shown to client during onboarding and in the portal. Not per-Org — shared profile.

Step 1.4 — Send Client Invitation

After Phase 0 validation passes:

  • System sends welcome email to admin email with AM name/avatar, org name, workspace URL, and CTA
  • Invitation token expires in 7 days; resending issues a fresh 7-day window
  • Trial clock does NOT start until Phase 2 completion
  • Org status: pending_client_confirmation
  • Stale orgs (90+ days in pending_client_confirmation) are auto-archived; restorable by Super Admin

Step 1.4 UX (as of PR #243):

  • Send button is enabled as soon as company info, specialist, and AM profile gates pass. The trialEndDateSet check is satisfied client-side (trial date is set on this very step).
  • "Copy Onboarding Link" button is available before and after sending — AM can share the link directly without waiting for the email.
  • "Complete Setup" CTA appears for orgs already in pending_client_confirmation status (re-entry after first send).

Phase 2: Client Confirmation

Client accesses the onboarding wizard via the invite email link (/onboarding route).

Step 2.1 — Account Verification

  • Email OTP sent to the admin email on record
  • Client Admin sets password
  • Profile fields: full name, job title (optional), phone (optional)

Step 2.2 — Review & Confirm Company Information

Client sees AM-entered data pre-populated and can edit most fields. The slug is permanently reserved at the end of this step.

FieldClient Can Change?
Company legal nameYes
SlugYes (once, here only) — immutable after confirmation
IndustryYes
Primary corporate email domainNo — AM-controlled
Admin emailYes — must still match approved domain
Website, country, timezoneYes

Slug reservation uses a pessimistic write lock + server-side re-validation to prevent race conditions.

Step 2.3 — Meet Your Specialist

Read-only profile card(s) for each assigned Specialist. Client sees: name, avatar, email, skill tags, bio. Client does not see the Specialist Team composition (Experts + Agents behind the persona).

To request a different Specialist: use Settings post-onboarding (AM fulfills the request).

Step 2.4 — Set Up Channels

Email (default, always on):

  • Specialist routing address pre-configured ({firstname}`@`{HWORK_DOMAIN})
  • Client can set a custom display name for outbound messages
  • No technical setup from client

Email Whitelist:

  • Pre-seeded from org's corporate domain(s) at completion
  • Client Admin can add additional approved domains or specific addresses
  • Non-whitelisted inbound email rejected at channel routing layer

WhatsApp (optional):

  • Present but marked skippable
  • Full Meta embedded signup flow: design deferred — tracked in issue #101

Coming Soon (shown as locked): Slack, Telegram, WeChat, Microsoft Teams

Step 2.5 — Optional Steps (Skippable)

StepDescription
Invite teammatesAdd Client Members by email (must match approved domain)
Billing & invoicingAdd payment method (required before trial end, not before completion)
Customize SpecialistAdd welcome message or custom bio

TrialBanner displays throughout portal: "Your trial ends in N days — add billing to continue."

Step 2.6 — Onboarding Complete

  • Org status: pending_client_confirmationactive
  • Trial clock starts (org.trialStartedAt = now())
  • Client Admin redirected to /client/chat
  • AM receives email notification
  • Welcome summary email sent to Client Admin (Specialist contact info, workspace URL, next steps)
  • Onboarding wizard link becomes invalid (token status = 'accepted')

API Endpoints

All onboarding endpoints are prefixed with /onboarding/:token/.

EndpointDescription
POST /:token/verify-emailSend OTP to admin email
POST /:token/confirm-otpVerify OTP → session JWT
POST /:token/set-credentialsSet password (+ optional 2FA)
POST /:token/profileSave name, title, phone
GET /:token/orgOrg details for wizard
GET /:token/specialistAssigned Specialist card
POST /:token/confirm-slugFinalize and reserve slug
GET /:token/whitelistList whitelist entries
POST /:token/whitelistAdd email/domain to whitelist
DELETE /:token/whitelist/:idRemove whitelist entry
POST /:token/invite-membersInvite multiple Client Members
POST /:token/completeFinalize onboarding (Step 2.6)

AM-side endpoints are under /am/orgs/ (NestJS routing) — see docs/api/reference.md.

Status After Audit (2026-04-30)

StatusCount
✅ RESOLVED89
⚠️ PARTIAL5
❌ OPEN6

Open items: WhatsApp onboarding UX (issue #101), slug churn/rebrand/cross-env enforcement (AC-SLUG-04/05/06).