TenantAtlas/specs/080-workspace-managed-tenant-admin/tasks.md

201 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
description: "Task breakdown for Spec 080 implementation"
---
# Tasks: Workspace-Managed Tenant Administration Migration (Spec 080)
**Input**: Design documents from `/specs/080-workspace-managed-tenant-admin/` (`plan.md`, `spec.md`, `contracts/routes.md`, `research.md`, `data-model.md`, `quickstart.md`)
**Non-negotiables (repo rules)**
- Filament v5 + Livewire v4.0+ only.
- Laravel 11+: Filament panel providers are registered in `bootstrap/providers.php`.
- RBAC-UX semantics: non-member/non-entitled → 404; member missing capability on mutation → 403.
- Removed tenant-scoped management routes must not be registered (404, no redirects).
- Tests are REQUIRED (Pest).
## Phase 1: Setup (Panel Scaffolding)
**Purpose**: Introduce the tenant operations panel without changing behavior yet.
- [X] T001 Create tenant operations panel provider in app/Providers/Filament/TenantPanelProvider.php
- [X] T002 Register new provider in bootstrap/providers.php (add App\Providers\Filament\TenantPanelProvider::class)
**Checkpoint**: App boots with both panels registered.
---
## Phase 2: Foundational (Blocking Prerequisites)
**Purpose**: Establish the manage vs operate separation mechanisms (routing + middleware + discovery boundaries).
- [X] T003 Refactor workspace panel to be tenantless in app/Providers/Filament/AdminPanelProvider.php (remove ->tenant(...), ->tenantRoutePrefix('t'), tenant menu/searchable menu)
- [X] T004 Update workspace panel middleware stack in app/Providers/Filament/AdminPanelProvider.php (remove ensure-filament-tenant-selected and App\Support\Middleware\DenyNonMemberTenantAccess for workspace panel)
- [X] T005 Configure tenant panel tenancy + middleware in app/Providers/Filament/TenantPanelProvider.php (enable ->tenant(App\Models\Tenant::class, slugAttribute: 'external_id'), enforce canonical path `/admin/t/{tenant}/...`, and add ensure-filament-tenant-selected + DenyNonMemberTenantAccess)
- [X] T006 Constrain resource/page discovery so management artifacts do not get registered in tenant panel in app/Providers/Filament/TenantPanelProvider.php (use dedicated discovery roots like app/Filament/Tenant/**)
- [X] T007 [P] Add a dedicated base feature test file tests/Feature/Spec080WorkspaceManagedTenantAdminMigrationTest.php (placeholder tests + factories usage notes)
- [X] T030 [P] [FOUNDATION] Add route-shape regression tests in tests/Feature/Spec080WorkspaceManagedTenantAdminMigrationTest.php asserting tenant routes resolve as `/admin/t/{tenant}` and `/admin/t/{tenant}/diagnostics` and never `/admin/t/t/{tenant}/...`
**Checkpoint**: Workspace panel does not require tenant context; tenant panel is isolated by discovery roots.
---
## Phase 3: User Story 1 — Manage tenants from workspace scope (Priority: P1) 🎯 MVP
**Goal**: Tenants management is canonical under `/admin/tenants*` without needing tenant scope.
**Independent Test**: As a workspace member, `GET /admin/tenants` returns 200; non-member returns 404.
### Tests (Pest) — US1
- [X] T008 [P] [US1] Add access tests for workspace-managed tenant list in tests/Feature/Spec080WorkspaceManagedTenantAdminMigrationTest.php (member 200, non-member 404)
- [X] T009 [P] [US1] Add access tests for workspace-managed tenant view route in tests/Feature/Spec080WorkspaceManagedTenantAdminMigrationTest.php (member 200, non-member 404)
- [X] T031 [P] [US1] Add access tests for workspace-managed memberships route in tests/Feature/Spec080WorkspaceManagedTenantAdminMigrationTest.php (`/admin/tenants/{tenant}/memberships`, member 200, non-member 404)
### Implementation — US1
- [X] T010 [US1] Move/rename management routes to match /admin/tenants* in app/Filament/Resources/TenantResource.php (ensure resource slug becomes tenants under workspace panel)
- [X] T011 [US1] Ensure TenantResource is registered only in workspace panel (update app/Providers/Filament/AdminPanelProvider.php registration/discovery strategy)
- [X] T012 [US1] Ensure tenant route parameter identity uses Tenant.external_id in app/Models/Tenant.php (route key name) OR in TenantResource route binding configuration
- [X] T032 [US1] Ensure memberships management surface exists only under workspace scope in app/Filament/Resources/TenantResource/RelationManagers/TenantMembershipsRelationManager.php and app/Filament/Resources/TenantResource.php (`/admin/tenants/{tenant}/memberships`)
**Checkpoint**: `/admin/tenants` works in the workspace panel.
---
## Phase 4: User Story 2 — Operate inside tenant scope only when entitled (Priority: P2)
**Goal**: Operational pages remain under `/admin/t/{tenant}/*` and return 404 when user is not entitled.
**Independent Test**: Entitled user can access `GET /admin/t/{tenant}` and `GET /admin/t/{tenant}/diagnostics`; non-entitled user gets 404.
### Tests (Pest) — US2
- [X] T013 [P] [US2] Add tenant entitlement tests for concrete operational routes in tests/Feature/Spec080WorkspaceManagedTenantAdminMigrationTest.php (`/admin/t/{tenant}` and `/admin/t/{tenant}/diagnostics`: entitled 200, non-entitled 404)
### Implementation — US2
- [X] T014 [US2] Register/relocate tenant operational dashboard page into tenant panel in app/Filament/Pages/TenantDashboard.php and app/Providers/Filament/TenantPanelProvider.php
- [X] T015 [US2] Ensure tenant selection redirects into tenant panel routes in app/Filament/Pages/ChooseTenant.php (redirect should target /admin/t/{tenant}/...)
**Checkpoint**: The contracted operational routes are reachable only when entitled.
---
## Phase 5: User Story 3 — Remove tenant-scoped management CRUD routes (Priority: P3)
**Goal**: Tenant-scoped management URLs do not resolve because resources/pages are not registered in tenant panel.
**Independent Test**: Requests to removed routes return 404 (route does not exist).
### Tests (Pest) — US3
- [X] T016 [P] [US3] Add 404 regression tests for removed routes in tests/Feature/Spec080WorkspaceManagedTenantAdminMigrationTest.php (e.g. /admin/t/{tenant}/provider-connections, /admin/t/{tenant}/required-permissions)
- [X] T033 [P] [US3] Add tenant navigation regression test in tests/Feature/Spec080WorkspaceManagedTenantAdminMigrationTest.php ensuring tenant panel sidebar does not expose tenant-management entries (Tenants, Provider Connections, Memberships)
### Implementation — US3
- [X] T017 [US3] Ensure management resources are not discovered/registered in tenant panel (verify TenantResource + ProviderConnectionResource not in tenant discovery roots in app/Providers/Filament/TenantPanelProvider.php)
- [X] T018 [US3] Ensure required permissions page is not registered in tenant panel in app/Providers/Filament/TenantPanelProvider.php (and/or relocate page class under workspace-managed location)
- [X] T034 [US3] Ensure tenant panel navigation is operate-only by construction in app/Providers/Filament/TenantPanelProvider.php (no TenantResource/ProviderConnectionResource/TenantMemberships registration)
**Checkpoint**: Removed tenant-scoped management paths return 404 (no redirects).
---
## Phase 6: User Story 4 — Management actions enforce capability semantics (Priority: P2)
**Goal**: Workspace members can view management pages; mutations are forbidden (403) unless capability is present.
**Independent Test**: A representative management mutation returns 403 for a workspace member missing capability.
### Tests (Pest) — US4
- [X] T019 [P] [US4] Add mutation authorization test asserting 403 (member missing capability) in tests/Feature/Spec080WorkspaceManagedTenantAdminMigrationTest.php
- [X] T035 [P] [US4] Add audit assertion test for tenant membership mutation in tests/Feature/Spec080WorkspaceManagedTenantAdminMigrationTest.php (writes redacted AuditLog with stable action ID)
### Implementation — US4
- [X] T020 [US4] Audit management mutations in app/Services/Intune/AuditLogger.php (or existing audit service) for provider connection + membership changes with stable action IDs
- [X] T021 [US4] Ensure destructive-like actions use ->requiresConfirmation() in app/Filament/Resources/TenantResource.php and app/Filament/Resources/ProviderConnectionResource.php
**Checkpoint**: 403 vs 404 semantics match spec for mutations.
---
## Phase 7: User Story 5 — Global search isolation (Priority: P2)
**Goal**: Tenant management entities are searchable only in workspace panel; tenant panel global search does not expose them.
**Independent Test**: Workspace panel global search can resolve TenantResource results; tenant panel global search does not include TenantResource/ProviderConnectionResource.
### Tests (Pest) — US5
- [X] T022 [P] [US5] Add global search scoping tests in tests/Feature/Spec080WorkspaceManagedTenantAdminMigrationTest.php (workspace panel finds tenant; tenant panel does not expose management resources)
### Implementation — US5
- [X] T023 [US5] Ensure TenantResource has a View/Edit page for global search compliance in app/Filament/Resources/TenantResource/Pages/*
- [X] T024 [US5] Ensure tenant panel does not register tenant-management resources/pages (verify discovery roots + resource registration in app/Providers/Filament/TenantPanelProvider.php)
**Checkpoint**: Global search results do not leak across scopes.
---
## Phase 8: Polish & Cross-Cutting
**Purpose**: Link rewiring, consistency, formatting, and minimal regression validation.
- [X] T025 [P] Rewire internal CTAs from tenant-scoped management URLs to workspace-managed routes in app/Filament/Pages/Workspaces/ManagedTenantsLanding.php and app/Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php
- [X] T026 [P] Update required permissions viewer to be workspace-managed + DB-only in app/Filament/Pages/TenantRequiredPermissions.php (accept tenant via route param, avoid Tenant::current())
- [X] T027 [P] Update provider connections to support workspace-managed per-tenant routes in app/Filament/Resources/ProviderConnectionResource.php (query should use route tenant param when not in tenancy)
- [X] T038 [P] Add Provider Connections CTA on tenant view page in app/Filament/Resources/TenantResource/Pages/ViewTenant.php (links to /admin/tenants/{tenant}/provider-connections)
- [X] T036 [P] Add workspace navigation regression test in tests/Feature/Spec080WorkspaceManagedTenantAdminMigrationTest.php to assert Tenants + Monitoring entries are present in workspace panel after panel split
- [X] T037 [P] Extend RBAC regression coverage for panel boundaries in tests/Feature/TenantRBAC/* (deny-as-not-found across workspace/tenant routing boundaries)
- [X] T028 Run formatting on touched files with vendor/bin/sail bin pint --dirty (formats app/** and tests/**)
- [X] T029 Run focused tests with vendor/bin/sail artisan test --compact tests/Feature/Spec080WorkspaceManagedTenantAdminMigrationTest.php
- [X] T039 Run formatting on touched files again (post-T038) with vendor/bin/sail bin pint --dirty
- [X] T040 Re-run focused spec tests (post-T038) with vendor/bin/sail artisan test --compact tests/Feature/Spec080WorkspaceManagedTenantAdminMigrationTest.php
---
## Dependencies & Execution Order
### User Story Dependency Graph
- Setup (Phase 1) → Foundational (Phase 2) → US1 (MVP)
- US2 depends on Phase 2
- US3 depends on Phase 2 (route removal works once panel discovery boundaries are in place)
- US4 depends on US1 (needs workspace management routes/actions)
- US5 depends on Phase 2 + US1 (workspace management resources must exist)
- Polish tasks depend on US1US5 completion for stable regression assertions (T036, T037).
### Parallel Opportunities
- After Phase 2 completes:
- US1 tests (T008T009, T031) can be written in parallel with US1 implementation (T010T012, T032).
- US2 (T013T015) can proceed in parallel with US1.
- US3 tests (T016, T033) can be added early as regression guards.
---
## Parallel Example: US1
- Write tests: T008 + T009 in tests/Feature/Spec080WorkspaceManagedTenantAdminMigrationTest.php
- Implement routes: T010 in app/Filament/Resources/TenantResource.php
---
## Implementation Strategy
### MVP Scope
- Complete Phase 1 + Phase 2 + US1 (T001T012)
- Validate with T029 and manual checks from quickstart.md
### Incremental Delivery
- Add US2 + US3 next (routing guarantees + entitlement semantics)
- Then US4 (mutation semantics + audit) and US5 (global search isolation)