# Onboarding and Adoption System Report

## 1. UX Strategy

MVNexus onboarding follows a **progressive, persona-aware adoption model** inspired by Linear, Notion, and Slack:

- **Calm enterprise tone** — short copy, card-based layouts, subtle animations, no gamified or childish patterns
- **Role-specific flows** — company admins, department heads, and normal users each get relevant guidance
- **Show value early** — portal URL, invite team, and first ticket are surfaced in the first session
- **Non-blocking after setup** — wizard is fullscreen on first login but dismissible; checklist and tours are optional
- **Data-driven progress** — checklist items auto-complete when real configuration exists (categories, SLA, tickets, etc.)
- **Bilingual & accessible** — full EN/AR support with RTL-aware layouts and `start` text alignment

### Persona resolution (backend)

| Priority | Persona | Trigger |
|----------|---------|---------|
| 1 | `company_admin` | Super admin or `company.departments.manage` permission |
| 2 | `department_head` | `is_department_head` / manager on any department |
| 3 | `user` | Everyone else |

---

## 2. Flows Implemented

### Department Head — “Let's set up your department” (5 steps)

| Step | Key | Features |
|------|-----|----------|
| 1 | `portal` | Name, slug, URL preview, portal toggle, EN/AR descriptions |
| 2 | `invite` | Email invite, role selector, optional head flag, pending list |
| 3 | `workflow` | Category templates (IT, HR, Facilities, Finance, Custom) |
| 4 | `notifications` | Email, SLA warning, realtime toggles with examples |
| 5 | `go_live` | Portal link copy, test ticket, dashboard CTA |

Wizard state is **resumable** via `users.onboarding_step`.

### Company Admin — Organization setup (5 steps)

| Step | Key | Action |
|------|-----|--------|
| 1 | `departments` | Link to department admin |
| 2 | `heads` | Link to user management |
| 3 | `settings` | Link to company settings |
| 4 | `users` | Review active users |
| 5 | `review` | Review SLA & notifications |

### Normal User — Lightweight welcome (4 steps)

| Step | Key | Purpose |
|------|-----|---------|
| 1 | `welcome` | Product introduction |
| 2 | `department` | Department membership guidance |
| 3 | `ticket` | Create first ticket CTA |
| 4 | `track` | Track requests via My Tickets |

---

## 3. APIs Added

All routes under `/api/v1/onboarding` (auth required):

| Method | Endpoint | Description |
|--------|----------|-------------|
| `GET` | `/onboarding/status` | Full status: persona, wizard flag, checklist, dismissed tours |
| `GET` | `/onboarding/checklist?department_id=` | Checklist progress only |
| `PATCH` | `/onboarding/step` | Persist current wizard step `{ step }` |
| `POST` | `/onboarding/complete` | Mark onboarding complete |
| `POST` | `/onboarding/tours/dismiss` | Dismiss tour `{ tour_id }` |

`/api/v1/auth/me` now includes `onboarding_completed_at`, `onboarding_step`, and `dismissed_tours`.

---

## 4. Database Changes

**Migration:** `2026_05_20_120000_add_onboarding_fields_to_users_table.php`

| Column | Type | Purpose |
|--------|------|---------|
| `onboarding_completed_at` | `timestamp` nullable | Wizard completion timestamp |
| `onboarding_step` | `string(64)` nullable | Resumable step key |
| `dismissed_tours` | `json` nullable | Array of dismissed tour IDs |

---

## 5. Components & Hooks

### Frontend (`resources/js/src/features/onboarding/`)

**Components**

| Component | Purpose |
|-----------|---------|
| `OnboardingModal` | Fullscreen wizard shell |
| `SetupWizard` | Persona-specific multi-step wizard |
| `ChecklistCard` | Dashboard “Getting Started” widget |
| `EmptyStateCard` | Reusable contextual empty states |
| `GuidedTour` | Spotlight + tooltip tour overlay |
| `WelcomeBanner` | Optional resume/dismiss banner |
| `OnboardingGate` | App-level wizard + tour orchestration |

**Hooks**

| Hook | Purpose |
|------|---------|
| `useOnboarding` | Status, step updates, completion, tour dismiss |
| `useChecklistProgress` | Standalone checklist query |
| `useGuidedTour` | Page tour state machine |

**Services & types**

- `onboardingService.ts` — API client
- `onboarding.types.ts` — TypeScript interfaces
- `onboarding.constants.ts` — Steps, templates, tour definitions

**i18n:** `locales/en/onboarding.json`, `locales/ar/onboarding.json`

### Backend (`app/Modules/Identity/`)

| Class | Role |
|-------|------|
| `OnboardingController` | HTTP layer |
| `OnboardingService` | Step/complete/dismiss logic |
| `ChecklistProgressService` | Checklist engine |
| `OnboardingPersonaResolver` | Persona + primary department |
| `OnboardingStatusResource` | JSON transformer |

---

## 6. Checklist Engine

`ChecklistProgressService` evaluates live data and returns:

```json
{
  "persona": "department_head",
  "department_id": "...",
  "completed": 3,
  "total": 5,
  "items": [
    { "key": "portal_configured", "completed": true, "route": "/admin/departments", "action": "configure_portal" }
  ]
}
```

### Department Head rules

| Key | Complete when |
|-----|---------------|
| `portal_configured` | `portal_enabled` + slug exists |
| `team_invited` | >1 active dept user OR ≥1 pending invite |
| `categories_created` | ≥1 category in department |
| `sla_created` | ≥1 SLA policy in department |
| `first_ticket_created` | ≥1 ticket in department |

### Company Admin rules

| Key | Complete when |
|-----|---------------|
| `departments_created` | ≥1 department |
| `department_heads_assigned` | ≥1 department has a head |
| `company_settings_configured` | ≥1 company-scoped setting |
| `active_users_reviewed` | ≥2 active users |
| `sla_notifications_reviewed` | ≥1 SLA policy OR notification preference |

### Normal User rules

| Key | Complete when |
|-----|---------------|
| `department_selected` | User belongs to ≥1 department |
| `first_ticket_created` | User has ≥1 ticket as requester |
| `track_requests` | Same as first ticket (tracking entry point) |

---

## 7. Guided Tours

Lightweight client-side tours with spotlight overlay. Stored dismissals in `users.dismissed_tours`.

| Tour ID | Page | Steps |
|---------|------|-------|
| `dashboard` | `/dashboard` | Stats, recent tickets, checklist |
| `tickets` | `/tickets` | List, create button |
| `notifications` | `/notifications` | Inbox |
| `settings` | `/settings*` | Settings panel |

Tours auto-start after 600ms on first visit unless dismissed. Supports next/back and “Don't show again”.

---

## 8. Empty States

`EmptyStateCard` integrated into:

| Page | Context |
|------|---------|
| Admin Users | No users |
| Admin Categories | No categories |
| Admin SLA | No policies |
| Admin Invites | No pending invites |
| Tickets | No tickets |
| Notifications | Empty inbox |

Each state includes icon, title, description, and primary CTA.

---

## 9. Tests

### Backend (`tests/Feature/Identity/OnboardingApiTest.php`)

- Onboarding step persistence
- Completion clears step and sets timestamp
- Dismissed tours JSON persistence
- Department head checklist auto-completion (4/5 with sample data)
- Status includes `should_show_wizard`

### Frontend

- `OnboardingComponents.test.tsx` — ChecklistCard, EmptyStateCard
- `onboardingService.test.ts` — API client
- `DashboardPage.test.tsx` — updated with `useOnboarding` mock

Run:

```bash
php artisan test tests/Feature/Identity/OnboardingApiTest.php
npx vitest run resources/js/src/__tests__/unit/features/onboarding
```

---

## 10. Remaining Gaps

| Gap | Notes |
|-----|-------|
| Ticket detail tour | Spec mentioned ticket detail page — not yet implemented |
| Department portal tour | Public portal tour for end users |
| Admin section tour | Dedicated admin nav tour |
| Notification prefs persistence in wizard | Step 4 toggles are UI-only; not saved to `notification_preferences` |
| Company admin inline actions | Steps link out rather than inline CRUD |
| E2E onboarding smoke | No Playwright spec yet for full wizard flow |
| Confetti animation | Subtle ✦ animation only; no canvas confetti library |
| Per-department checklist on multi-dept heads | Uses primary/managed department only |
| Super admin persona | Treated as company admin |

---

## 11. UAT Readiness

| Area | Status |
|------|--------|
| First-login wizard (dept head) | ✅ Ready |
| Company admin wizard | ✅ Ready (guided links) |
| Normal user wizard | ✅ Ready |
| Resumable wizard | ✅ Ready |
| Getting Started checklist | ✅ Ready |
| Auto-complete checklist | ✅ Ready |
| Contextual empty states | ✅ Ready (key admin + tickets + notifications) |
| Guided tours | ✅ Ready (4 pages) |
| EN/AR + RTL | ✅ Ready |
| Dark mode | ✅ Compatible (uses theme tokens) |
| Mobile responsive | ✅ Wizard + checklist responsive |
| Backend persistence | ✅ Ready |
| Automated tests | ✅ Backend + frontend unit |

### Recommended UAT scenarios

1. **New department head** — log in → complete 5-step wizard → verify portal URL → checklist shows progress
2. **Resume wizard** — close on step 2 → re-login → resumes at saved step
3. **Company admin** — verify 5-step org setup and checklist on dashboard
4. **Normal user** — verify 4-step welcome flow
5. **Tour dismiss** — visit dashboard → dismiss tour → confirm no re-show
6. **Auto-complete** — create category → checklist item marks complete without refresh (within stale window)
7. **Arabic** — switch locale → verify wizard, checklist, empty states in AR with RTL layout

---

*Generated: 2026-05-20*
