--- description: "Task list for Workspace Foundation & Managed Tenant Onboarding Unification (v1)" --- # Tasks: Workspace Foundation & Managed Tenant Onboarding Unification (v1) **Input**: Design documents from `/specs/068-workspace-foundation-v1/` **Prerequisites**: plan.md (required), spec.md (required) **Tests**: REQUIRED (Pest) — this feature changes runtime routing + authorization UX. **Operations**: No new long-running/remote/queued/scheduled work expected. **RBAC**: MUST preserve semantics: - non-member / not entitled to tenant scope → 404 (deny-as-not-found) - member but missing capability → 403 ## Format: `[ID] [P?] [Story] Description with file path` - **[P]**: Can run in parallel (different files, no dependencies) - **[US#]**: Which user story this task belongs to --- ## Phase 1: Setup (Shared Infrastructure) **Purpose**: Confirm local tooling and repo structure for safe iteration. - [x] T001 Verify Sail app boots and admin routes resolve using docker-compose.yml and routes/web.php - [x] T002 [P] Identify existing managed-tenant CRUD entry points to de-duplicate using app/Filament/Resources/TenantResource.php and app/Filament/Resources/TenantResource/Pages/ListTenants.php --- ## Phase 2: Foundational (Blocking Prerequisites) **Purpose**: RBAC capability primitives and shared context helpers needed by all user stories. - [x] T003 Add managed-tenant capability constants to app/Support/Auth/Capabilities.php - [x] T004 Update default role-to-capability mapping for managed-tenant capabilities in app/Services/Auth/RoleCapabilityMap.php - [x] T005 [P] Ensure Gate registration picks up new capabilities (and add regression assertions if needed) in app/Providers/AuthServiceProvider.php - [x] T006 [P] Add/extend capability registry tests for managed-tenant capabilities in tests/Unit/Auth/CapabilitiesRegistryTest.php - [x] T007 [P] Add/extend “unknown capability” guard coverage for managed-tenant capabilities usage in tests/Unit/Auth/UnknownCapabilityGuardTest.php - [x] T008 [P] Add/extend UI enforcement unit coverage for managed-tenant actions (disabled vs hidden vs executable) in tests/Unit/Support/Rbac/UiEnforcementTest.php **Checkpoint**: Capability strings exist, role mapping covers them, and unit tests enforce the registry. --- ## Phase 3: User Story 1 — Add managed tenant via single front door (Priority: P1) 🎯 MVP **Goal**: Exactly one visible “Add managed tenant” entry exists, and legacy `/admin/new` redirects to the canonical onboarding page. **Independent Test**: - Visiting `/admin/new` redirects to `/admin/managed-tenants/onboarding`. - The managed-tenant list shows a single “Add managed tenant” entry point. ### Tests for User Story 1 - [x] T009 [P] [US1] Add feature test for legacy redirect `/admin/new` → `/admin/managed-tenants/onboarding` in tests/Feature/ManagedTenants/OnboardingRedirectTest.php - [x] T010 [P] [US1] Add feature test that onboarding page is reachable for authorized users in tests/Feature/ManagedTenants/OnboardingPageTest.php - [x] T011 [P] [US1] Add feature test ensuring the tenants list exposes only one onboarding CTA in tests/Feature/ManagedTenants/SingleEntryPointTest.php ### Implementation for User Story 1 - [x] T012 [US1] Create tenantless onboarding Filament page class in app/Filament/Pages/ManagedTenants/Onboarding.php - [x] T013 [P] [US1] Create onboarding page Blade view in resources/views/filament/pages/managed-tenants/onboarding.blade.php - [x] T014 [US1] Register canonical onboarding route `/admin/managed-tenants/onboarding` via panel authenticated routes in app/Providers/Filament/AdminPanelProvider.php - [x] T015 [US1] Register legacy redirect `/admin/new` → canonical onboarding in app/Providers/Filament/AdminPanelProvider.php - [x] T016 [US1] Update tenants list header action to a single labeled CTA (“Add managed tenant”) and ensure it links to canonical onboarding in app/Filament/Resources/TenantResource/Pages/ListTenants.php - [x] T017 [US1] Redirect the resource create route (if still reachable) to canonical onboarding to avoid a second onboarding entry point in app/Filament/Resources/TenantResource/Pages/CreateTenant.php **Checkpoint**: US1 complete — one front door, legacy redirect works, tests pass. --- ## Phase 4: User Story 2 — Manage tenants without tenant-in-tenant navigation (Priority: P2) **Goal**: Managed-tenant list/view/edit screens are tenantless (no `/admin/t/{tenant}/...` required). **Independent Test**: - Managed-tenant list loads without a tenant route prefix. - Managed-tenant view/edit URLs are tenantless. ### Tests for User Story 2 - [X] T018 [P] [US2] Add feature test that managed-tenant list route is tenantless (no `/t/` prefix) in tests/Feature/ManagedTenants/TenantlessRoutesTest.php - [X] T019 [P] [US2] Add feature test that managed-tenant view route is tenantless (no `/t/` prefix) in tests/Feature/ManagedTenants/TenantlessRoutesTest.php - [X] T020 [P] [US2] Add feature test that managed-tenant edit route is tenantless (no `/t/` prefix) in tests/Feature/ManagedTenants/TenantlessRoutesTest.php ### Implementation for User Story 2 - [X] T021 [US2] Confirm resource is tenantless-scoped and keep it that way (`$isScopedToTenant = false`) in app/Filament/Resources/TenantResource.php - [X] T022 [US2] Ensure navigation label/grouping uses “Managed tenants” terminology in app/Filament/Resources/TenantResource.php - [X] T023 [US2] Ensure direct URL access to view/edit enforces RBAC-UX (non-member → 404, member missing capability → 403) via tenantless managed-tenant pages in app/Filament/Pages/ManagedTenants/ - [X] T023a [P] [US2] Add feature test: member without `tenant_managed_tenants.manage` receives 403 when attempting to access the managed-tenant edit page in tests/Feature/ManagedTenants/AuthorizationSemanticsTest.php **Checkpoint**: US2 complete — tenantless management routes and consistent auth semantics. --- ## Phase 5: User Story 3 — Open an active tenant context and handle archived tenants safely (Priority: P3) **Goal**: “Open” works for active tenants via session-only selection, and archived tenants show a status screen. **Independent Test**: - Active tenant “Open” stores selection in session and lands on a deterministic page that shows the selected tenant. - Archived tenant “Open” shows a status page (not 404) for viewers. - Restore/force delete actions require confirmation and are authorization-guarded. ### Tests for User Story 3 - [X] T024 [P] [US3] Add feature test: “Open” on active tenant sets session selection and redirects deterministically in tests/Feature/ManagedTenants/OpenActiveTenantTest.php - [X] T025 [P] [US3] Add feature test: “Open” on archived tenant shows status page (not 404) in tests/Feature/ManagedTenants/OpenArchivedTenantTest.php - [X] T026 [P] [US3] Add feature test: archived status page hides or disables restore/force-delete when unauthorized in tests/Feature/ManagedTenants/ArchivedActionsAuthorizationTest.php - [X] T027 [P] [US3] Add feature test: restore/force-delete require confirmation and are server-side blocked when unauthorized in tests/Feature/ManagedTenants/ArchivedActionsAuthorizationTest.php ### Implementation for User Story 3 - [X] T028 [P] [US3] Implement session-backed managed-tenant context helper (get/set/clear) in app/Support/ManagedTenants/ManagedTenantContext.php - [X] T029 [US3] Create deterministic tenantless “current managed tenant” landing page in app/Filament/Pages/ManagedTenants/Current.php - [X] T030 [P] [US3] Create landing page Blade view showing selected tenant identity in resources/views/filament/pages/managed-tenants/current.blade.php - [X] T031 [US3] Create archived status Filament page in app/Filament/Pages/ManagedTenants/ArchivedStatus.php - [X] T032 [P] [US3] Create archived status Blade view in resources/views/filament/pages/managed-tenants/archived-status.blade.php - [X] T032a [US3] Register tenantless page routes for “current” and “archived status” in app/Providers/Filament/AdminPanelProvider.php (ensure paths match spec: `/admin/managed-tenants/current` and `/admin/managed-tenants/archived`) - [X] T033 [US3] Add “Open” table action on managed-tenant list, authorized by `tenant_managed_tenants.view`, with archived handling in app/Filament/Resources/TenantResource.php - [X] T034 [US3] Add “Open” action on the managed-tenant view page (if present) with same behavior in app/Filament/Resources/TenantResource/Pages/ViewTenant.php - [X] T035 [US3] Add restore + force-delete actions on archived status page with `->action(...)` + `->requiresConfirmation()` + server-side auth checks in app/Filament/Pages/ManagedTenants/ArchivedStatus.php **Checkpoint**: US3 complete — “Open” is deterministic for active tenants and safe/clear for archived tenants. --- ## Phase 6: Polish & Cross-Cutting Concerns **Purpose**: Hardening, consistency, and developer ergonomics. - [x] T036 [P] Ensure all destructive-like actions use `->action(...)` + `->requiresConfirmation()` consistently in app/Filament/Resources/TenantResource.php - [x] T037 [P] Run Pint on changed files to match repo style in composer.json (via `vendor/bin/sail bin pint --dirty`) - [X] T038 Run targeted Pest suite for this feature in tests/Feature/ManagedTenants/ --- ## Dependencies & Execution Order - Phase 1 (Setup) → Phase 2 (Foundational) → US1 (MVP) → US2 → US3 → Polish ### User Story Dependencies - US1 depends on Phase 2 (capabilities available for authorization checks). - US2 depends on Phase 2; can be started after US1, but is logically independent. - US3 depends on Phase 2 and benefits from US2 being in place (tenantless navigation). --- ## Parallel Execution Examples ### After Foundational Phase - [P] tasks in Phase 2 can be split across registry/mapping/tests. - US1 tests (T009–T011) can be written in parallel. - US3 page/view creation tasks (T029–T032) can be done in parallel with the context helper (T028). --- ## Implementation Strategy ### MVP Scope (recommended) - Complete Phase 1 + Phase 2 + US1. - Validate only US1 acceptance scenarios and ship. ### Incremental Delivery - Add US2 next (tenantless route guarantees). - Add US3 last (session context + archived safe UX).