---

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 US1–US5 completion for stable regression assertions (T036, T037).

### Parallel Opportunities

- After Phase 2 completes:
  - US1 tests (T008–T009, T031) can be written in parallel with US1 implementation (T010–T012, T032).
  - US2 (T013–T015) 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 (T001–T012)
- 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)
