# Sprint 1 · UAT checklist

Every item must pass on a fresh install before Sprint 1 is signed off.

## 1. Setup wizard
- [ ] Fresh install redirects `/` to `/setup`
- [ ] All six wizard steps render and Next/Back navigation works
- [ ] Field-level validation surfaces on every step
- [ ] GSTIN must be 15 chars; PAN 10; phone/email formats validated
- [ ] Logo upload accepts PNG/JPG/SVG up to 2 MB
- [ ] Submitting the last step creates: company + admin user + default roles + default settings + default themes
- [ ] Wizard route is blocked (redirect to dashboard) after setup is completed
- [ ] Admin is auto-logged in after wizard completes

## 2. Authentication
- [ ] Login page renders and rejects invalid credentials
- [ ] Successful login redirects to `/dashboard`
- [ ] "Remember me" checkbox extends the session cookie
- [ ] Failed logins increment rate limiter; block after N attempts
- [ ] Forgot-password page always shows a generic success message (no user enumeration)
- [ ] Reset-password link works and password strength is validated
- [ ] Login history is recorded for LOGIN, LOGOUT, FAILED, LOCKED, PASSWORD_RESET
- [ ] `last_login_at` and `last_login_ip` are updated on successful login

## 3. Roles & permissions
- [ ] All five default roles exist after seed: Admin, Manager, Store Keeper, Salesman, Accountant
- [ ] Admin bypasses all gates via `Gate::before`
- [ ] Salesman cannot access `/settings/company`
- [ ] System roles cannot be deleted or renamed
- [ ] `settings/roles` page lists all roles with correct user + permission counts
- [ ] Editing a non-system role and toggling a permission group works

## 4. Dashboard
- [ ] `/dashboard` renders 10 widgets with zero values (money/count/score)
- [ ] Sales trend chart renders (7 days, zeroed series)
- [ ] Refresh button hits `/dashboard/refresh` and updates values
- [ ] Widget cards are keyboard-accessible and mobile-responsive

## 5. Settings
- [ ] `/settings` shows all six tiles + tabbed navigation
- [ ] Company / Preferences / Theme / Printer / Security forms save successfully
- [ ] Unsaved-changes guard warns before navigating away
- [ ] Theme changes apply immediately (light/dark, comfortable/compact)
- [ ] Company theme change persists across sessions
- [ ] Security policy changes are respected on the next login attempt

## 6. Profile
- [ ] `/profile` allows name/email/phone/locale/timezone/theme changes
- [ ] `/profile/password` updates password after verifying the current one
- [ ] Password change signs out other sessions
- [ ] `/profile/login-history` lists the recent events with device/IP/browser

## 7. Layout & UI framework
- [ ] Sidebar highlights active module and disables future-sprint links with a badge
- [ ] Topbar shows company logo, global search hint (Ctrl+K), theme toggle, notifications bell, profile menu
- [ ] Command palette opens with Ctrl+K, filters, and navigates on selection
- [ ] Mobile bottom nav appears below 768 px
- [ ] Toast notifications appear from server flash messages
- [ ] Error pages 403, 404, 419 render correctly

## 8. Security controls
- [ ] All forms include CSRF; POST from a different origin is rejected
- [ ] XSS attempts in name/description fields are escaped
- [ ] SQL injection payloads have no effect
- [ ] Password reset link expires per Laravel defaults
- [ ] AJAX unauthenticated response returns JSON `{ok:false, redirect: '/login'}`

## 9. Audit & activity log
- [ ] `activity_log` records CREATE/UPDATE for User, Company, Role, Setting
- [ ] Every log row carries a `company_id`

## 10. Non-functional
- [ ] Lighthouse desktop score ≥ 90 (Performance, Accessibility, Best Practices, SEO)
- [ ] No console errors on any page
- [ ] Vite build succeeds with no warnings
- [ ] `php artisan test` — all suites green
- [ ] `composer analyse` (Larastan level 6) — no new errors
