TenantAtlas/specs/085-tenant-operate-hub/tasks.md
ahmido 2bf5de4663 085-tenant-operate-hub (#103)
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
2026-02-11 13:02:03 +00:00

11 KiB
Raw Permalink Blame History


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.

  • T001 Confirm canonical Monitoring routes + existing clear-context endpoint in routes/web.php and app/Http/Controllers/ClearTenantContextController.php
  • 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
  • T003 Confirm Tenant panel provider is the entry point for tenant sidebar Monitoring shortcuts in app/Providers/Filament/TenantPanelProvider.php
  • T004 Confirm Laravel 11+/12 panel provider registration is in bootstrap/providers.php (not bootstrap/app.php)
  • 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.

  • 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 — ")
  • T007 Ensure OperateHubShell resolves active entitled tenant context safely (Filament tenant when present, otherwise remembered last-tenant id for the current workspace)
  • T008 Update OperateHubShell return affordance label to include tenant name ("Back to ") in app/Support/OperateHub/OperateHubShell.php
  • 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)
  • 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)

  • T011 [P] [US1] Add Spec 085 operations header tests in tests/Feature/Spec085/OperationsIndexHeaderTest.php (tenant scope label + both CTAs)
  • 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)
  • 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)
  • T014 [P] [US1] Add tenant navigation shortcuts test in tests/Feature/Spec085/TenantNavigationMonitoringShortcutsTest.php (tenant sidebar shows “Monitoring” group with Runs/Alerts/Audit Log)
  • 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})
  • 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

  • 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)
  • 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)
  • T019 [US1] Implement Operations index CTAs per Spec 085 in app/Filament/Pages/Monitoring/Operations.php (Back to using App\Filament\Pages\TenantDashboard::getUrl(panel: 'tenant', tenant: $tenant); Show all tenants exits tenant context)
  • 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 its tenant-scoped by default).

Tests for User Story 2

  • T021 [P] [US2] Add non-mutation test in tests/Feature/Spec085/CanonicalMonitoringDoesNotMutateTenantContextTest.php (GET /admin/operations does not set/clear tenant context)
  • T022 [P] [US2] Add scope label test in tests/Feature/Spec085/CanonicalMonitoringDoesNotMutateTenantContextTest.php (no tenant context → "Scope: Workspace — all tenants")
  • 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

  • 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
  • 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 ” 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

  • T026 [P] [US3] Add run detail header-action tests in tests/Feature/Spec085/RunDetailBackAffordanceTest.php (tenant context vs no context)
  • 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

  • T028 [US3] Implement deterministic back affordances for run detail in app/Filament/Pages/Operations/TenantlessOperationRunViewer.php (tenant-context+entitled → “← Back to ” + “Show all operations”; else “Back to Operations”)
  • 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

  • T030 [P] Confirm Spec 085 UI Action Matrix matches implemented header actions in specs/085-tenant-operate-hub/spec.md
  • T031 [P] Validate manual verification steps in specs/085-tenant-operate-hub/quickstart.md against actual behavior (update doc only if it drifted)
  • T037 Ensure “Show all tenants” clears Operations table tenant filter state (prevents stale Livewire table filter state from keeping the list scoped)
  • T032 Run formatting on changed files under app/ and tests/ using vendor/bin/sail bin pint --dirty
  • T033 Run focused test suite: vendor/bin/sail artisan test --compact tests/Feature/Spec085 tests/Feature/Monitoring/OperationsTenantScopeTest.php tests/Feature/Operations/TenantlessOperationRunViewerTest.php
  • T034 Fix Filament auth-pattern guard compliance by removing Gate:: usage in app/Filament/Pages/Operations/TenantlessOperationRunViewer.php (use $this->authorize(...))
  • 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}
  • 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

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

In parallel:
- T011 (tests) in tests/Feature/Spec085/OperationsIndexHeaderTest.php
- T017 (tenant nav shortcuts) in app/Providers/Filament/TenantPanelProvider.php
Then:
- T018T020 in app/Filament/Pages/Monitoring/Operations.php

US2

In parallel:
- T021T022 (non-mutation + scope label tests)
- T023 (default tenant filter test) in tests/Feature/Monitoring/OperationsTenantScopeTest.php
Then:
- T024T025 in app/Filament/Pages/Monitoring/Operations.php

US3

In parallel:
- T026T027 (run detail tests) in tests/Feature/Spec085/RunDetailBackAffordanceTest.php
Then:
- T028T029 in app/Filament/Pages/Operations/TenantlessOperationRunViewer.php

Implementation Strategy

MVP Scope

  • Implement US1 only (T011T020), run T033, then manually validate via specs/085-tenant-operate-hub/quickstart.md.

Incremental Delivery

  • US1 → US2 → US3, keeping each story independently testable.