## Summary - Removes the legacy Tenant CRUD create page (`/admin/tenants/create`) so tenant creation is handled exclusively via the onboarding wizard. - Updates tenant selection flows and pages to prevent Livewire polling/notification-related 404s on workspace-scoped routes. - Aligns empty-state UX with enterprise patterns (avoid duplicate CTAs). ## Key changes - Tenant creation - Removed `CreateTenant` page + route from `TenantResource`. - `TenantResource::canCreate()` now returns `false` (CRUD creation disabled). - Tenants list now surfaces an **Add tenant** action that links to onboarding (`admin.onboarding`). - Onboarding wizard - Removed redundant legacy step-cards from the blade view (Wizard schema is the source of truth). - Disabled topbar on the onboarding page to avoid lazy-loaded notifications. - Choose tenant - Enterprise UI redesign + workspace context. - Uses Livewire `selectTenant()` instead of a form POST. - Disabled topbar and gated BODY_END hook to avoid background polling. - Baseline profiles - Hide header create action when table is empty to avoid duplicate CTAs. ## Tests - `vendor/bin/sail artisan test --compact --filter='Onboarding|ManagedTenantOnboarding'` - `vendor/bin/sail artisan test --compact --filter='ManagedTenantsLivewireUpdate'` - `vendor/bin/sail artisan test --compact --filter='TenantSetup|TenantResourceAuth|TenantAdminAuth|ListTenants'` - `vendor/bin/sail artisan test --compact --filter='BaselineProfile'` - `vendor/bin/sail artisan test --compact --filter='ChooseTenant|TenantMake|TenantScoping|AdminTenantScoped|AdminHomeRedirect|WorkspaceContext'` ## Notes - Filament v5 / Livewire v4 compatible. - No new assets introduced; no deploy pipeline changes required. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #131
3.5 KiB
3.5 KiB
Quickstart: Workspace Chooser v1
Feature: 107-workspace-chooser | Date: 2026-02-22
Prerequisites
- Branch:
107-workspace-chooserchecked out - Sail running:
vendor/bin/sail up -d - Existing workspace + user fixtures (factory-based)
Implementation Order
Phase A: Foundation (no visible changes)
- Add
AuditActionIdenum cases —WorkspaceAutoSelected,WorkspaceSelected - Extract
WorkspaceRedirectResolver— shared tenant-count branching helper (DRY the 4 current copies) - Tests for redirect resolver — verify 0/1/>1 tenant branching
Phase B: Middleware Refactor (core behavior change)
- Refactor
EnsureWorkspaceSelected— implement 7-step algorithm from spec- Step 1: workspace-optional path bypass (keep existing
isWorkspaceOptionalPath()) - Step 2:
?choose=1handling (new) - Step 3: stale session detection + flash warning (enhanced)
- Step 4-5: single membership auto-resume + audit (new)
- Step 6:
last_workspace_idauto-resume + audit (new) - Step 7: fallback to chooser (existing)
- Step 1: workspace-optional path bypass (keep existing
- Middleware tests — all 7 steps covered
Phase C: Chooser Page Upgrade (UI changes)
- Refactor
ChooseWorkspacepage:- Remove "Create workspace" header action
- Add
withCount('tenants')to query - Load membership roles keyed by workspace_id
- Expose
getWorkspaceRole()andgetWorkspaceMemberships()for Blade
- 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 }})"
- Add audit logging in
selectWorkspace()— emitworkspace.selectedwith metadata - Chooser page tests — metadata display, empty state, manage link visibility, audit events
Phase D: User Menu Integration
- Register "Switch workspace" in
AdminPanelProvider—userMenuItems()with visibility condition - User menu tests — visible when >1 workspace, hidden when 1
Phase E: Cleanup & Verification
- Replace inline tenant-branching in
SwitchWorkspaceControllerandroutes/web.phpwithWorkspaceRedirectResolver; addWorkspaceAuditLogger::log()forcontext_barswitch path inSwitchWorkspaceController - Run full test suite — verify no regressions
- Pint formatting —
vendor/bin/sail bin pint --dirty - 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