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

3.5 KiB

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 casesWorkspaceAutoSelected, 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)

  1. 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)
  2. Middleware tests — all 7 steps covered

Phase C: Chooser Page Upgrade (UI changes)

  1. 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
  2. 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 }})"
  3. Add audit logging in selectWorkspace() — emit workspace.selected with metadata
  4. Chooser page tests — metadata display, empty state, manage link visibility, audit events

Phase D: User Menu Integration

  1. Register "Switch workspace" in AdminPanelProvideruserMenuItems() with visibility condition
  2. User menu tests — visible when >1 workspace, hidden when 1

Phase E: Cleanup & Verification

  1. Replace inline tenant-branching in SwitchWorkspaceController and routes/web.php with WorkspaceRedirectResolver; add WorkspaceAuditLogger::log() for context_bar switch path in SwitchWorkspaceController
  2. Run full test suite — verify no regressions
  3. Pint formattingvendor/bin/sail bin pint --dirty
  4. 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

# 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