46 lines
2.9 KiB
Markdown
46 lines
2.9 KiB
Markdown
# Research — Spec 080 Workspace-Managed Tenant Administration Migration
|
||
|
||
Date: 2026-02-07
|
||
|
||
## Decision 1 — Two Filament panels (workspace + tenant)
|
||
|
||
- Decision: Implement a workspace (tenantless) panel at `/admin` and a tenant (tenancy) panel at `/admin/t/{tenant}`.
|
||
- Rationale: This makes “Manage vs Operate” enforceable via route registration (removed routes 404), avoids tenant-context chicken-and-egg, and matches Filament-native separation.
|
||
- Alternatives considered:
|
||
- Keep a single panel and conditionally hide resources when tenant is selected: rejected because routes still exist and semantics are harder to enforce.
|
||
|
||
## Decision 2 — Tenant panel path configuration to achieve `/admin/t/{tenant}`
|
||
|
||
- Decision: Configure the tenant panel with `path('admin/t')`, `tenant(Tenant::class, slugAttribute: 'external_id')`, and **no tenant route prefix** (`tenantRoutePrefix(null)` / default).
|
||
- Rationale: Filament’s tenancy routing adds `/{tenant}` after the panel path, and the optional `tenantRoutePrefix` is only prepended when it is “filled”. Leaving it blank yields `/admin/t/{tenant}` (not `/admin/t/t/{tenant}`).
|
||
- Alternatives considered:
|
||
- Keep the existing `path('admin') + tenantRoutePrefix('t')` for a tenant panel: rejected because it would conflict with the workspace panel at the same path.
|
||
|
||
## Decision 3 — Workspace context in URLs
|
||
|
||
- Decision: Workspace-managed tenant management uses `/admin/tenants*` (workspace selected in session/context; enforced by middleware).
|
||
- Rationale: Matches current app pattern (`ensure-workspace-selected`) and reduces URL churn.
|
||
- Alternatives considered:
|
||
- `/admin/w/{workspace}/tenants*`: rejected because it’s not canonical for this feature and increases link surface.
|
||
|
||
## Decision 4 — View vs mutation authorization in management scope
|
||
|
||
- Decision: Management pages are viewable for workspace members; **mutations** are capability-gated (403).
|
||
- Rationale: Aligns with RBAC-UX guidance: membership is isolation (404), capability is authorization (403).
|
||
- Alternatives considered:
|
||
- Require capability to view: rejected to avoid “mysterious forbidden” UX and because spec explicitly reserves 403 for mutations.
|
||
|
||
## Decision 5 — Global search isolation
|
||
|
||
- Decision: Managed tenants are searchable in the workspace panel only; the tenant panel must not expose tenant-management entities via global search.
|
||
- Rationale: Prevents cross-scope discovery leaks and aligns with “Manage is workspace-scoped”.
|
||
- Alternatives considered:
|
||
- Disable global search entirely: rejected (spec wants workspace search behavior).
|
||
|
||
## Decision 6 — How removed tenant-scoped management routes become 404
|
||
|
||
- Decision: Do not register tenant-management resources/pages in the tenant panel.
|
||
- Rationale: In Filament, unregistered resources/pages simply do not have routes; this is the cleanest dev-stage “no redirects” behavior.
|
||
- Alternatives considered:
|
||
- Redirect legacy tenant-scoped routes: rejected (explicit non-goal).
|