Skip to main content
Version: Latest

5. User Journey & First Login Flow

For the exact question text, answer options, and recommendation rules referenced in steps 5–7 below, see Chapter 20 — Business Onboarding Survey Options.

5.1 End-to-end journey

  1. Registration — a new tenant registers (company info, admin email/mobile). No onboarding endpoint is involved at this stage. See the Tenant Signup and First Login Journey guide for the full registration contract, prerequisite reference-data APIs, and location validation rules.
  2. Activation — the tenant's admin verifies their account (OTP / email or mobile verification), per the platform's existing tenant activation flow.
  3. First login — the admin logs into the ERP normally and receives a JWT, exactly like any other login.
  4. Onboarding status check — the client calls GET /api/v1/onboarding/status. If isRequired: true and status: "NotStarted" (or "InProgress"), the client shows the onboarding survey; currentStep tells it which step to resume on if the admin left mid-survey.
  5. Survey — the client calls GET /api/v1/onboarding/survey?lang=ar (or en) and renders the returned steps/questions.
  6. Answers — the client submits answers via POST /api/v1/onboarding/answers, which can be called multiple times as the admin progresses (answers are merged into the session, not replaced).
  7. Recommendation — once required answers are complete, the client calls POST /api/v1/onboarding/recommendation, which returns a human-readable summary, a list of warnings (things that could not be set automatically), and the actual settings patch that would be applied — this is a preview, nothing is written yet.
  8. Apply — the admin reviews the recommendation and confirms; the client calls POST /api/v1/onboarding/apply, which writes the patch to the tenant's real AppSettings via the internal bridge (see Chapter 10) and records an apply log.
  9. Dashboard access — the client re-checks status (now Applied) and proceeds to the normal dashboard. Onboarding never blocks login — it is a first-run wizard, not a login gate.
  10. Repeat login — on any subsequent login, GET /api/v1/onboarding/status returns isRequired: false (status Applied or Skipped), so the survey is never shown again for that tenant. Verified live end-to-end in docs/testing/NEW_SUBSCRIBER_E2E_TEST_REPORT.md.

An admin can also call POST /api/v1/onboarding/skip at almost any point (status.canSkip tells the client whether skipping is currently allowed) to bypass onboarding entirely and go straight to the dashboard with default settings.

5.2 Why onboarding happens after first login, not during registration

The registration form only collects enough to create the tenant and its admin account — at that point there is no authenticated user, no resolved tenant JWT, and no permission context. Every onboarding endpoint requires Permissions.Onboarding.*, which is only evaluable once a real JWT with a Tenant/TenantId claim exists (see Chapter 9 — Authentication & Authorization). Placing the survey after first login also means it only has to be shown once, on the first real session, rather than being one more field-heavy step in an already-long signup form.

5.3 Session state machine

A TenantOnboardingSession moves through these statuses (one session per tenant per active survey):

NotStarted → InProgress → Recommended → Applied

Skipped
  • NotStarted — no session row exists yet, or one exists with no answers.
  • InProgress — at least one answer has been saved.
  • Recommended — a recommendation has been generated (recommendation can be called again to regenerate, which overwrites the previous recommendation — see Known Limitations).
  • Applied — the patch was successfully written to AppSettings; terminal for that session.
  • Skipped — the admin explicitly skipped; terminal for that session.

5.4 Resuming an in-progress survey

GET /api/v1/onboarding/status returns currentStep, computed as the step number of the first required question the admin hasn't answered yet. The client should use this to jump straight to the right step rather than always restarting at step 1.