# Quickstart: Workspace Chooser v1 **Feature**: 107-workspace-chooser | **Date**: 2026-02-22 ## Prerequisites - Branch: `107-workspace-chooser` checked out - Sail running: `vendor/bin/sail up -d` - Existing workspace + user fixtures (factory-based) ## Implementation Order ### Phase A: Foundation (no visible changes) 1. **Add `AuditActionId` enum cases** — `WorkspaceAutoSelected`, `WorkspaceSelected` 2. **Extract `WorkspaceRedirectResolver`** — shared tenant-count branching helper (DRY the 4 current copies) 3. **Tests for redirect resolver** — verify 0/1/>1 tenant branching ### Phase B: Middleware Refactor (core behavior change) 4. **Refactor `EnsureWorkspaceSelected`** — implement 7-step algorithm from spec - Step 1: workspace-optional path bypass (keep existing `isWorkspaceOptionalPath()`) - Step 2: `?choose=1` handling (new) - Step 3: stale session detection + flash warning (enhanced) - Step 4-5: single membership auto-resume + audit (new) - Step 6: `last_workspace_id` auto-resume + audit (new) - Step 7: fallback to chooser (existing) 5. **Middleware tests** — all 7 steps covered ### Phase C: Chooser Page Upgrade (UI changes) 6. **Refactor `ChooseWorkspace` page**: - Remove "Create workspace" header action - Add `withCount('tenants')` to query - Load membership roles keyed by workspace_id - Expose `getWorkspaceRole()` and `getWorkspaceMemberships()` for Blade 7. **Update `choose-workspace.blade.php`**: - Add role badge per card - Add tenant count per card - Add "Manage workspaces" link (capability-gated) - Update empty state (spec copy) - Replace form POST with `wire:click="selectWorkspace({{ $workspace->id }})"` 8. **Add audit logging in `selectWorkspace()`** — emit `workspace.selected` with metadata 9. **Chooser page tests** — metadata display, empty state, manage link visibility, audit events ### Phase D: User Menu Integration 10. **Register "Switch workspace" in `AdminPanelProvider`** — `userMenuItems()` with visibility condition 11. **User menu tests** — visible when >1 workspace, hidden when 1 ### Phase E: Cleanup & Verification 12. **Replace inline tenant-branching** in `SwitchWorkspaceController` and `routes/web.php` with `WorkspaceRedirectResolver`; add `WorkspaceAuditLogger::log()` for `context_bar` switch path in `SwitchWorkspaceController` 13. **Run full test suite** — verify no regressions 14. **Pint formatting** — `vendor/bin/sail bin pint --dirty` 15. **Commit + push** ## Key Files to Understand First | File | Why | |------|-----| | `app/Http/Middleware/EnsureWorkspaceSelected.php` | The middleware being refactored | | `app/Filament/Pages/ChooseWorkspace.php` | The page being upgraded | | `app/Support/Workspaces/WorkspaceContext.php` | The workspace session manager | | `app/Services/Audit/WorkspaceAuditLogger.php` | Where audit events are emitted | | `app/Support/Audit/AuditActionId.php` | Where enum cases are added | | `app/Http/Controllers/SwitchWorkspaceController.php` | POST switch (redirect resolver integration) | | `routes/web.php` (lines 36-82) | `/admin` route with duplicated branching | ## Verification Commands ```bash # Run workspace-related tests vendor/bin/sail artisan test --compact tests/Feature/Workspaces/ # Run specific middleware test vendor/bin/sail artisan test --compact --filter=EnsureWorkspaceSelected # Run chooser page test vendor/bin/sail artisan test --compact --filter=ChooseWorkspacePage # Format vendor/bin/sail bin pint --dirty # Full suite vendor/bin/sail artisan test --compact ```