Summary Consolidates the “Tenant Operate Hub” work (Spec 085) and the follow-up adjustments from the 086 session merge into a single branch ready to merge into dev. Primary focus: stabilize Ops/Operate Hub UX flows, tighten/align authorization semantics, and make the full Sail test suite green. Key Changes Ops UX / Verification Readonly members can view verification operation runs (reports) while starting verification remains restricted. Normalized failure reason-code handling and aligned UX expectations with the provider reason-code taxonomy. Onboarding wizard UX “Start verification” CTA is hidden while a verification run is active; “Refresh” is shown during in-progress runs. Treats provider_permission_denied as a blocking reason (while keeping legacy compatibility). Test + fixture hardening Standardized use of default provider connection fixtures in tests where sync/restore flows require it. Fixed multiple Filament URL/tenant-context test cases to avoid 404s and reduce tenancy routing brittleness. Policy sync / restore safety Enrollment configuration type collision classification tests now exercise the real sync path (with required provider connection present). Restore edge-case safety tests updated to reflect current provider-connection requirements. Testing vendor/bin/sail artisan test --compact (green) vendor/bin/sail bin pint --dirty (green) Notes Includes merged 086 session work already (no separate PR needed). Co-authored-by: Ahmed Darrazi <ahmeddarrazi@ebc83aaa-d947-4a08-b88e-bd72ac9645f7.fritz.box> Co-authored-by: Ahmed Darrazi <ahmeddarrazi@MacBookPro.fritz.box> Co-authored-by: Ahmed Darrazi <ahmeddarrazi@adsmac.fritz.box> Reviewed-on: #103
193 lines
11 KiB
Markdown
193 lines
11 KiB
Markdown
|
||
---
|
||
description: "Task list for Spec 085 — Tenant Operate Hub / Tenant Overview IA"
|
||
---
|
||
|
||
# Tasks: Spec 085 — Tenant Operate Hub / Tenant Overview IA
|
||
|
||
**Input**: Design documents from `/specs/085-tenant-operate-hub/`
|
||
|
||
**Required**:
|
||
- `specs/085-tenant-operate-hub/plan.md`
|
||
- `specs/085-tenant-operate-hub/spec.md`
|
||
|
||
**Additional docs present**:
|
||
- `specs/085-tenant-operate-hub/research.md`
|
||
- `specs/085-tenant-operate-hub/data-model.md`
|
||
- `specs/085-tenant-operate-hub/contracts/openapi.yaml`
|
||
- `specs/085-tenant-operate-hub/quickstart.md`
|
||
|
||
**Tests**: REQUIRED (runtime UX + security semantics; Pest)
|
||
|
||
---
|
||
|
||
## Phase 1: Setup (Shared Infrastructure)
|
||
|
||
**Purpose**: Confirm the existing code touchpoints and test harness for Spec 085.
|
||
|
||
- [X] T001 Confirm canonical Monitoring routes + existing clear-context endpoint in routes/web.php and app/Http/Controllers/ClearTenantContextController.php
|
||
- [X] T002 Confirm the Monitoring pages exist and are canonical: app/Filament/Pages/Monitoring/Operations.php, app/Filament/Pages/Operations/TenantlessOperationRunViewer.php, app/Filament/Pages/Monitoring/Alerts.php, app/Filament/Pages/Monitoring/AuditLog.php
|
||
- [X] T003 Confirm Tenant panel provider is the entry point for tenant sidebar Monitoring shortcuts in app/Providers/Filament/TenantPanelProvider.php
|
||
- [X] T004 Confirm Laravel 11+/12 panel provider registration is in bootstrap/providers.php (not bootstrap/app.php)
|
||
- [X] T005 [P] Identify existing monitoring/tenant scoping tests to extend (tests/Feature/Monitoring/OperationsTenantScopeTest.php, tests/Feature/Operations/TenantlessOperationRunViewerTest.php)
|
||
|
||
---
|
||
|
||
## Phase 2: Foundational (Blocking Prerequisites)
|
||
|
||
**Purpose**: Shared helper behavior must match Spec 085 semantics before story work.
|
||
|
||
- [X] T006 Update scope-label copy and semantics in app/Support/OperateHub/OperateHubShell.php (MUST match FR-085-002 exactly: "Scope: Workspace — all tenants" / "Scope: Tenant — <tenant name>")
|
||
- [X] T007 Ensure OperateHubShell resolves active entitled tenant context safely (Filament tenant when present, otherwise remembered last-tenant id for the current workspace)
|
||
- [X] T008 Update OperateHubShell return affordance label to include tenant name ("Back to <tenant name>") in app/Support/OperateHub/OperateHubShell.php
|
||
- [X] T009 Add a helper method to resolve “active tenant AND still entitled” in app/Support/OperateHub/OperateHubShell.php (used by Operations index + run detail to implement stale-tenant-context behavior)
|
||
- [X] T010 Ensure Monitoring renders remain DB-only (no outbound calls / no side effects) by standardizing test guards with Http::preventStrayRequests() in tests/Feature/Spec085/*.php and existing coverage tests/Feature/Monitoring/OperationsTenantScopeTest.php and tests/Feature/Operations/TenantlessOperationRunViewerTest.php
|
||
|
||
**Checkpoint**: Shared semantics locked; user story work can begin.
|
||
|
||
---
|
||
|
||
## Phase 3: User Story 1 — Monitoring feels context-aware (Priority: P1) 🎯 MVP
|
||
|
||
**Goal**: When tenant context is active, Monitoring clearly shows tenant scope + deterministic “Back to tenant” and offers explicit “Show all tenants” to exit.
|
||
|
||
**Independent Test**: With tenant context active + entitled, GET `/admin/operations` shows `Scope: Tenant — <tenant>` and buttons `Back to <tenant>` and `Show all tenants`; clicking “Show all tenants” clears tenant context and returns to workspace-wide operations.
|
||
|
||
### Tests for User Story 1 (write first)
|
||
|
||
- [X] T011 [P] [US1] Add Spec 085 operations header tests in tests/Feature/Spec085/OperationsIndexHeaderTest.php (tenant scope label + both CTAs)
|
||
- [X] T012 [P] [US1] Add stale-tenant-context test in tests/Feature/Spec085/OperationsIndexHeaderTest.php (tenant context set but user not entitled → workspace scope + no tenant name + no back-to-tenant)
|
||
- [X] T013 [P] [US1] Add explicit-exit behavior test in tests/Feature/Spec085/OperationsIndexHeaderTest.php (POST /admin/clear-tenant-context clears Filament tenant + last tenant id)
|
||
- [X] T014 [P] [US1] Add tenant navigation shortcuts test in tests/Feature/Spec085/TenantNavigationMonitoringShortcutsTest.php (tenant sidebar shows “Monitoring” group with Runs/Alerts/Audit Log)
|
||
- [X] T015 [P] [US1] Add “deny-as-not-found” regression tests for canonical Monitoring access in tests/Feature/Spec085/DenyAsNotFoundSemanticsTest.php (non-workspace-member → 404 for /admin/operations and /admin/operations/{run})
|
||
- [X] T016 [P] [US1] Add “deny-as-not-found” regression test for tenant dashboard direct access in tests/Feature/Spec085/DenyAsNotFoundSemanticsTest.php (non-entitled to tenant → 404 for /admin/t/{tenant})
|
||
|
||
### Implementation for User Story 1
|
||
|
||
- [X] T017 [US1] Replace Tenant sidebar "Operations" item with "Monitoring" group shortcuts in app/Providers/Filament/TenantPanelProvider.php (Runs→/admin/operations, Alerts→/admin/alerts, Audit Log→/admin/audit-log)
|
||
- [X] T018 [US1] Implement Operations index scope indicator per Spec 085 in app/Filament/Pages/Monitoring/Operations.php (workspace vs tenant; stale context treated as workspace)
|
||
- [X] T019 [US1] Implement Operations index CTAs per Spec 085 in app/Filament/Pages/Monitoring/Operations.php (Back to <tenant> using App\Filament\Pages\TenantDashboard::getUrl(panel: 'tenant', tenant: $tenant); Show all tenants exits tenant context)
|
||
- [X] T020 [US1] Ensure “Show all tenants” uses an explicit server-side action (no implicit GET mutation) in app/Filament/Pages/Monitoring/Operations.php (perform the same mutations as app/Http/Controllers/ClearTenantContextController.php: Filament::setTenant(null, true) + WorkspaceContext::clearLastTenantId(); then redirect to /admin/operations)
|
||
|
||
**Checkpoint**: US1 fully testable and meets FR-085-001/002/005/007/010.
|
||
|
||
---
|
||
|
||
## Phase 4: User Story 2 — Canonical URLs with explicit scope (Priority: P2)
|
||
|
||
**Goal**: Canonical Monitoring URLs never implicitly change tenant context; tenant context may only affect default filtering and must be obvious.
|
||
|
||
**Independent Test**: With tenant context active, GET `/admin/operations` does not change tenant context and defaults the list to the active tenant (or otherwise clearly shows it’s tenant-scoped by default).
|
||
|
||
### Tests for User Story 2
|
||
|
||
- [X] T021 [P] [US2] Add non-mutation test in tests/Feature/Spec085/CanonicalMonitoringDoesNotMutateTenantContextTest.php (GET /admin/operations does not set/clear tenant context)
|
||
- [X] T022 [P] [US2] Add scope label test in tests/Feature/Spec085/CanonicalMonitoringDoesNotMutateTenantContextTest.php (no tenant context → "Scope: Workspace — all tenants")
|
||
- [X] T023 [P] [US2] Add default-tenant-filter test in tests/Feature/Monitoring/OperationsTenantScopeTest.php (tenant context active → list defaults to active tenant)
|
||
|
||
### Implementation for User Story 2
|
||
|
||
- [X] T024 [US2] Ensure Operations index query applies workspace scoping and (when tenant context is active + entitled) tenant scoping without mutating tenant context in app/Filament/Pages/Monitoring/Operations.php
|
||
- [X] T025 [US2] Ensure any default tenant filter is applied as a query/filter default only (no calls to Filament::setTenant() during GET) in app/Filament/Pages/Monitoring/Operations.php
|
||
|
||
**Checkpoint**: US2 meets FR-085-003/004/009.
|
||
|
||
---
|
||
|
||
## Phase 5: User Story 3 — Deep links are safe and recoverable (Priority: P3)
|
||
|
||
**Goal**: On `/admin/operations/{run}`, tenant-context users get a deterministic “Back to <tenant>” plus a secondary “Show all operations”; otherwise only “Back to Operations”.
|
||
|
||
**Independent Test**: With tenant context active + entitled, GET `/admin/operations/{run}` shows `← Back to <tenant>` and `Show all operations`; without tenant context it shows `Back to Operations` only.
|
||
|
||
### Tests for User Story 3
|
||
|
||
- [X] T026 [P] [US3] Add run detail header-action tests in tests/Feature/Spec085/RunDetailBackAffordanceTest.php (tenant context vs no context)
|
||
- [X] T027 [P] [US3] Add stale-tenant-context run detail test in tests/Feature/Spec085/RunDetailBackAffordanceTest.php (tenant context set but not entitled → no tenant name, no back-to-tenant)
|
||
|
||
### Implementation for User Story 3
|
||
|
||
- [X] T028 [US3] Implement deterministic back affordances for run detail in app/Filament/Pages/Operations/TenantlessOperationRunViewer.php (tenant-context+entitled → “← Back to <tenant>” + “Show all operations”; else “Back to Operations”)
|
||
- [X] T029 [US3] Ensure run detail never reveals tenant identity when the viewer is not entitled (stale tenant context treated as workspace-wide) in app/Filament/Pages/Operations/TenantlessOperationRunViewer.php
|
||
|
||
**Checkpoint**: US3 meets FR-085-006/008/010.
|
||
|
||
---
|
||
|
||
## Phase 6: Polish & Cross-Cutting Concerns
|
||
|
||
- [X] T030 [P] Confirm Spec 085 UI Action Matrix matches implemented header actions in specs/085-tenant-operate-hub/spec.md
|
||
- [X] T031 [P] Validate manual verification steps in specs/085-tenant-operate-hub/quickstart.md against actual behavior (update doc only if it drifted)
|
||
- [X] T037 Ensure “Show all tenants” clears Operations table tenant filter state (prevents stale Livewire table filter state from keeping the list scoped)
|
||
- [X] T032 Run formatting on changed files under app/ and tests/ using vendor/bin/sail bin pint --dirty
|
||
- [X] T033 Run focused test suite: vendor/bin/sail artisan test --compact tests/Feature/Spec085 tests/Feature/Monitoring/OperationsTenantScopeTest.php tests/Feature/Operations/TenantlessOperationRunViewerTest.php
|
||
- [X] T034 Fix Filament auth-pattern guard compliance by removing Gate:: usage in app/Filament/Pages/Operations/TenantlessOperationRunViewer.php (use $this->authorize(...))
|
||
- [X] T035 Ensure canonical Operate Hub routes sanitize stale/non-entitled tenant context by applying ensure-filament-tenant-selected middleware to /admin/operations, /admin/alerts, /admin/audit-log, and /admin/operations/{run}
|
||
- [X] T036 Harden Spec 085-related tests to match final copy/semantics and avoid brittle Livewire DOM assertions (tests/Feature/OpsUx/OperateHubShellTest.php, tests/Feature/Monitoring/OperationsCanonicalUrlsTest.php)
|
||
|
||
---
|
||
|
||
## Dependencies & Execution Order
|
||
|
||
### Dependency Graph
|
||
|
||
```mermaid
|
||
graph TD
|
||
P1[Phase 1: Setup] --> P2[Phase 2: Foundational]
|
||
P2 --> US1[US1 (P1): Context-aware Monitoring entry]
|
||
US1 --> US2[US2 (P2): Canonical URLs + explicit scope]
|
||
US1 --> US3[US3 (P3): Deep-link back affordances]
|
||
US2 --> P6[Phase 6: Polish]
|
||
US3 --> P6
|
||
```
|
||
|
||
### User Story Dependencies
|
||
|
||
- US1 is the MVP.
|
||
- US2 and US3 depend on the shared foundational semantics (scope labels + entitled active tenant resolution).
|
||
|
||
---
|
||
|
||
## Parallel Execution Examples
|
||
|
||
### US1
|
||
|
||
```text
|
||
In parallel:
|
||
- T011 (tests) in tests/Feature/Spec085/OperationsIndexHeaderTest.php
|
||
- T017 (tenant nav shortcuts) in app/Providers/Filament/TenantPanelProvider.php
|
||
Then:
|
||
- T018–T020 in app/Filament/Pages/Monitoring/Operations.php
|
||
```
|
||
|
||
### US2
|
||
|
||
```text
|
||
In parallel:
|
||
- T021–T022 (non-mutation + scope label tests)
|
||
- T023 (default tenant filter test) in tests/Feature/Monitoring/OperationsTenantScopeTest.php
|
||
Then:
|
||
- T024–T025 in app/Filament/Pages/Monitoring/Operations.php
|
||
```
|
||
|
||
### US3
|
||
|
||
```text
|
||
In parallel:
|
||
- T026–T027 (run detail tests) in tests/Feature/Spec085/RunDetailBackAffordanceTest.php
|
||
Then:
|
||
- T028–T029 in app/Filament/Pages/Operations/TenantlessOperationRunViewer.php
|
||
```
|
||
|
||
---
|
||
|
||
## Implementation Strategy
|
||
|
||
### MVP Scope
|
||
|
||
- Implement US1 only (T011–T020), run T033, then manually validate via specs/085-tenant-operate-hub/quickstart.md.
|
||
|
||
### Incremental Delivery
|
||
|
||
- US1 → US2 → US3, keeping each story independently testable.
|