# 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
```
