TenantAtlas/specs/072-managed-tenants-workspace-enforcement/plan.md
ahmido 38d9826f5e feat: workspace context enforcement + ownership safeguards (#86)
Implements workspace-first enforcement and UX:
- Workspace selected before tenant flows; /admin routes into choose-workspace/choose-tenant
- Tenant lists and default tenant selection are scoped to current workspace
- Workspaces UI is tenantless at /admin/workspaces

Security hardening:
- Workspaces can never have 0 owners (blocks last-owner removal/demotion)
- Blocked attempts are audited with action_id=workspace_membership.last_owner_blocked + required metadata
- Optional break-glass recovery page to re-assign workspace owner (audited)

Tests:
- Added/updated Pest feature tests covering redirects, scoping, tenantless workspaces, last-owner guards, and break-glass recovery.

Notes:
- Filament v5 strict Page property signatures respected in RepairWorkspaceOwners.

Co-authored-by: Ahmed Darrazi <ahmeddarrazi@MacBookPro.fritz.box>
Reviewed-on: #86
2026-02-02 23:00:56 +00:00

35 lines
1.8 KiB
Markdown

# Plan — 072 Managed Tenants workspace context enforcement
## Tech
- Laravel 12
- Filament v5 + Livewire v4
- Pest v4
## Approach
1. Treat `/admin/w/{workspace}/...` as the portfolio / workspace entry space.
2. Move Managed Tenants list/onboarding UX to workspace-scoped routes.
3. Make `/admin/managed-tenants/*` legacy-only (redirect to the correct workspace-scoped URL).
4. Enforce workspace/tenant consistency for all `/admin/t/{tenant}` routes (deny-as-not-found on mismatch).
5. Ensure the panel UX makes the active workspace visible and switchable from the topbar.
## Key decisions
- **Workspace is not Filament tenancy**; it remains session + middleware.
- Hard enforcement is implemented in middleware that runs on tenant-scoped routes.
- Prefer redirects over removing routes immediately, to avoid breaking deep links, but ensure they are no longer primary UX.
- Default tenant selection must respect the current workspace context to avoid cross-workspace tenant URLs.
## Files (expected)
- `routes/web.php`
- `app/Providers/Filament/AdminPanelProvider.php`
- `app/Http/Middleware/EnsureWorkspaceSelected.php`
- `app/Support/Middleware/DenyNonMemberTenantAccess.php` (or `EnsureFilamentTenantSelected.php`, depending on existing enforcement location)
- `app/Filament/Pages/ManagedTenants/*` (legacy redirects / removal)
- New/updated workspace landing page under `app/Filament/Pages/Workspaces/*` (or equivalent)
- Pest tests in `tests/Feature/Routing/` or `tests/Feature/Filament/`
## Test plan
- Feature test: `/admin/managed-tenants` redirects to `/admin/w/{workspace}/managed-tenants` when workspace is selected.
- Feature test: `/admin/t/{tenant}` returns 404 when workspace context missing.
- Feature test: `/admin/t/{tenant}` returns 404 when tenant.workspace_id != current workspace.
- Optional: workspace landing lists only workspace tenants.