TenantAtlas/specs/107-workspace-chooser/quickstart.md

88 lines
3.5 KiB
Markdown

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