TenantAtlas/specs/077-workspace-nav-monitoring-hub/tasks.md
ahmido fb1046c97a Spec 077: Workspace Global Mode + context bar redundancy cleanup (#94)
Implements Spec 077 refinements: workspace Global Mode and navigation/context-bar redundancy cleanup.

Summary
- Global Mode: `/admin/workspaces` is workspace-optional (lists only member workspaces); explicit allowlist in `EnsureWorkspaceSelected`.
- Navigation cleanup: workspace switching is topbar-only; no sidebar “Switch workspace”; removes redundant “Manage workspaces” entry from context-bar.
- Context bar: when no workspace selected, tenant picker is disabled with guidance; on tenant-scoped routes `/admin/t/{tenant}/…` the tenant indicator is read-only (Filament tenant menu remains primary).
- Authorization: workspace creation is policy-driven (`WorkspacePolicy::create()`), enforced in `ChooseWorkspace` via Gate.

Safety / Compliance
- Livewire v4.0+ compliant (Filament v5).
- Panel provider registration remains in `bootstrap/providers.php` (no changes required).
- Global search: no new globally searchable resources added; no behavior changes introduced.
- Destructive actions: none added/changed.
- Assets: no new assets registered; deploy process unchanged (if assets are registered elsewhere, ensure `php artisan filament:assets` runs in deploy as usual).

Tests
- `vendor/bin/sail bin pint --dirty`
- `vendor/bin/sail artisan test --compact tests/Feature/Workspaces tests/Feature/Monitoring tests/Feature/OpsUx tests/Feature/Filament/WorkspaceContextTopbarAndTenantSelectionTest.php`

Spec artifacts
- `specs/077-workspace-nav-monitoring-hub/{spec,plan,tasks}.md`
- `specs/077-workspace-nav-monitoring-hub/contracts/routes.md`

Co-authored-by: Ahmed Darrazi <ahmeddarrazi@MacBookPro.fritz.box>
Reviewed-on: #94
2026-02-06 22:14:53 +00:00

14 KiB
Raw Blame History

description
Task list for Spec 077 implementation

Tasks: Workspace-first Navigation & Monitoring Hub (077)

Input: Design documents from /specs/077-workspace-nav-monitoring-hub/

Prerequisites:

Tests: REQUIRED (Pest) — this feature changes runtime behavior (navigation + authorization + filtering).

Livewire/Filament compatibility: Filament v5 + Livewire v4 only.


Phase 1: Setup (Shared Infrastructure)

Purpose: Prepare the minimal scaffolding for safe, test-first delivery.

  • T001 Create new Pest test file for workspace navigation in tests/Feature/Workspaces/WorkspaceNavigationHubTest.php
  • T002 Create new Pest test file for operations canonical routing in tests/Feature/Monitoring/OperationsCanonicalUrlsTest.php
  • T003 [P] Create new Pest test file for non-leakage semantics in tests/Feature/OpsUx/NonLeakageWorkspaceOperationsTest.php

Phase 2: Foundational (Blocking Prerequisites)

Purpose: Shared plumbing needed by multiple stories.

  • T004 Add intended-URL session key constant in app/Support/Workspaces/WorkspaceContext.php
  • T005 Implement “store intended URL” helper in app/Support/Workspaces/WorkspaceIntendedUrl.php
  • T006 [P] Add tests for intended-URL helper in tests/Feature/Workspaces/WorkspaceIntendedUrlTest.php
  • T007 Update middleware to use intended-URL helper in app/Http/Middleware/EnsureWorkspaceSelected.php
  • T008 [P] Add safe-redirect allowlist for intended URLs in app/Support/Workspaces/WorkspaceIntendedUrl.php

Checkpoint: Intended redirect plumbing exists and is covered by tests.


Phase 3: User Story 1 — Switch workspace without ambiguity (Priority: P1) 🎯 MVP

Goal: Clear separation between “Switch workspace” and “Manage workspaces”, with correct 404/403 behavior.

Independent Test: A signed-in user can switch workspaces via “Switch workspace”, and “Manage workspaces” is only visible/accessible when authorized.

Tests for User Story 1 (write first)

  • T009 [P] [US1] Assert nav label “Switch workspace” appears when tenant is not selected in tests/Feature/Workspaces/WorkspaceNavigationHubTest.php
  • T010 [P] [US1] Assert no ambiguous “Workspaces” nav item exists in tests/Feature/Workspaces/WorkspaceNavigationHubTest.php
  • T011 [P] [US1] Assert /admin/workspaces is tenantless and reachable for a workspace owner in tests/Feature/Workspaces/WorkspacesResourceIsTenantlessTest.php
  • T012 [P] [US1] Assert /admin/workspaces/{record} is deny-as-not-found for non-members (404) in tests/Feature/Workspaces/WorkspacesResourceIsTenantlessTest.php

Implementation for User Story 1

  • T013 [US1] Rename fallback nav item to “Switch workspace” in app/Support/Middleware/EnsureFilamentTenantSelected.php
  • T014 [US1] Update user-menu copy/CTA to “Switch workspace” in resources/views/filament/partials/workspace-switcher.blade.php
  • T015 [US1] Rename admin sidebar item to “Manage workspaces” in app/Providers/Filament/AdminPanelProvider.php
  • T016 [US1] Gate “Manage workspaces” navigation visibility via capability in app/Providers/Filament/AdminPanelProvider.php
  • T017 [US1] Enforce workspace-scoped RBAC semantics for workspace management (404 non-member, 403 missing capability) in app/Policies/WorkspacePolicy.php
  • T018 [US1] Ensure workspace management breadcrumbs point to /admin/workspaces in app/Filament/Resources/Workspaces/WorkspaceResource.php
  • T019 [US1] Ensure /admin/workspaces routes do not require tenant context in app/Support/Middleware/EnsureFilamentTenantSelected.php
  • T020 [US1] Run focused tests for US1 via ./vendor/bin/sail artisan test --compact --filter=WorkspaceNavigationHub (document in specs/077-workspace-nav-monitoring-hub/quickstart.md)

Checkpoint: UI uses unambiguous labels; /admin/workspaces follows workspace RBAC semantics (no leakage).


Phase 4: User Story 2 — Use Monitoring hub from canonical links (Priority: P2)

Goal: /admin/operations and /admin/operations/{run} work regardless of tenant context; tenant context only sets removable default filters.

Independent Test: Visiting /admin/operations works tenantless (workspace-selected), and in tenant context it defaults to that tenant via a removable filter chip.

Tests for User Story 2 (write first)

  • T021 [P] [US2] Assert /admin/operations is reachable without tenant context in tests/Feature/Monitoring/OperationsCanonicalUrlsTest.php
  • T022 [P] [US2] Assert /admin/operations/{run} works with and without tenant context in tests/Feature/Monitoring/OperationsCanonicalUrlsTest.php
  • T023 [P] [US2] Assert operations list defaults to current tenant (filter state) when tenant context active in tests/Feature/Monitoring/OperationsCanonicalUrlsTest.php
  • T024 [P] [US2] Assert clearing tenant filter shows workspace-wide runs in tests/Feature/Monitoring/OperationsCanonicalUrlsTest.php

Implementation for User Story 2

  • T025 [US2] Allow /admin/operations (index) through tenancy-enforcing middleware without auto-setting tenant in app/Support/Middleware/EnsureFilamentTenantSelected.php
  • T026 [US2] Ensure workspace selection is required for /admin/operations and stores intended URL for return flow in app/Http/Middleware/EnsureWorkspaceSelected.php
  • T027 [US2] Redirect back to intended URL after workspace selection in both app/Filament/Pages/ChooseWorkspace.php and app/Http/Controllers/SwitchWorkspaceController.php
  • T028 [US2] Remove hard tenant scoping from query in app/Filament/Resources/OperationRunResource.php
  • T029 [US2] Add tenant SelectFilter with removable chip and server-side default state in app/Filament/Resources/OperationRunResource/Pages/ListOperationRuns.php
  • T030 [US2] Scope selectable tenants in the filter to current workspace in app/Filament/Resources/OperationRunResource/Pages/ListOperationRuns.php
  • T031 [US2] Add “Recent operations” summary (last 5 by created_at) + “View all operations” CTA on tenant view page in app/Filament/Resources/TenantResource/Pages/ViewTenant.php
  • T032 [US2] Ensure “View all operations” CTA routes to canonical /admin/operations in app/Filament/Resources/TenantResource/Pages/ViewTenant.php
  • T033 [US2] Ensure operations pages remain DB-only (no Graph calls) by extending existing checks in tests/Feature/MonitoringOperationsTest.php
  • T034 [US2] Run focused tests for US2 via ./vendor/bin/sail artisan test --compact --filter=OperationsCanonicalUrls and update specs/077-workspace-nav-monitoring-hub/quickstart.md

Checkpoint: Canonical operations URLs work; tenant context only affects default filter state.


Phase 5: User Story 3 — Navigate and search without leaking inaccessible data (Priority: P3)

Goal: Enforce strict 404 vs 403 semantics without leaking admin surfaces or cross-workspace/tenant data.

Independent Test: Non-members get 404; members missing capability get 403, and no navigation labels hint at inaccessible features.

Tests for User Story 3 (write first)

  • T035 [P] [US3] Assert non-member access to another workspaces operations is 404 in tests/Feature/OpsUx/NonLeakageWorkspaceOperationsTest.php
  • T036 [P] [US3] Assert member missing workspace.manage gets 403 on /admin/workspaces/{record}/edit in tests/Feature/OpsUx/NonLeakageWorkspaceOperationsTest.php
  • T037 [P] [US3] Assert invalid tenant context is auto-cleared when switching workspace in tests/Feature/Workspaces/ManagedTenantsWorkspaceRoutingTest.php
  • T038 [P] [US3] Assert reserved Monitoring placeholder pages exist (/admin/alerts, /admin/audit-log) in tests/Feature/Monitoring/OperationsCanonicalUrlsTest.php

Implementation for User Story 3

  • T039 [US3] Implement “auto-clear invalid tenant context” check in app/Support/Middleware/EnsureFilamentTenantSelected.php
  • T040 [US3] Confirm and implement correct Filament v5 mechanism for clearing persisted tenant state in app/Support/Middleware/EnsureFilamentTenantSelected.php
  • T041 [US3] Implement reserved Monitoring placeholder pages (Alerts, Audit Log) as Filament pages under app/Filament/Pages/Monitoring/**
  • T042 [US3] Ensure navigation does not expose admin-only surfaces to unauthorized users in app/Providers/Filament/AdminPanelProvider.php
  • T043 [US3] Verify global search does not introduce new leakage for operations/workspaces and, if needed, disable global search for resources without view/edit pages in app/Filament/**
  • T044 [US3] Run focused tests for US3 via ./vendor/bin/sail artisan test --compact --filter=NonLeakageWorkspaceOperations

Checkpoint: 404/403 behavior matches spec; no cross-scope leaks.


Phase 6: Polish & Cross-Cutting Concerns

Purpose: Stabilize, format, and validate end-to-end.

  • T045 Run formatter on touched files via ./vendor/bin/sail bin pint --dirty
  • T046 Run targeted full suite for touched areas via ./vendor/bin/sail artisan test --compact tests/Feature/Workspaces tests/Feature/Monitoring tests/Feature/OpsUx
  • T047 [P] Confirm manual quickstart steps still match UI labels and routes in specs/077-workspace-nav-monitoring-hub/quickstart.md
  • T048 [P] Confirm route semantics still match contracts in specs/077-workspace-nav-monitoring-hub/contracts/routes.md
  • T049 Ensure Filament v5 + Livewire v4 APIs are used (no v3/v4 Filament APIs) in app/Filament/**
  • T050 Run full suite (optional) via ./vendor/bin/sail artisan test --compact

Post-implementation bugfixes

  • T058 Fix route conflict so Operations “View” consistently hits canonical /admin/operations/{run} by moving Filament resource view route to /admin/operations/r/{record} in app/Filament/Resources/OperationRunResource.php
  • T059 Remove “Switch workspace” from sidebar navigation (workspace switching is topbar-only) in app/Providers/Filament/AdminPanelProvider.php and app/Support/Middleware/EnsureFilamentTenantSelected.php
  • T060 Define Global Mode: make /admin/workspaces workspace-optional + add explicit allowlist in app/Http/Middleware/EnsureWorkspaceSelected.php
  • T061 Disable tenant picker when no workspace is active (Global Mode) in resources/views/filament/partials/context-bar.blade.php
  • T062 Remove “Manage workspaces” link from the topbar context switcher to avoid redundant entry points in resources/views/filament/partials/context-bar.blade.php
  • T063 Unify workspace creation authorization: ChooseWorkspace create action must use WorkspacePolicy (Gate) in app/Filament/Pages/ChooseWorkspace.php and app/Policies/WorkspacePolicy.php

Phase 7: Addendum — Header Context Bar (FR-077-016)

Goal: Always-visible context bar for Workspace + Tenant, usable on tenantless pages without implicit switching.

Tests (write first)

  • T051 [P] [FR-077-016] Assert tenant picker renders on /admin/operations in tests/Feature/Monitoring/HeaderContextBarTest.php
  • T052 [P] [FR-077-016] Assert tenant picker lists only entitled tenants in tests/Feature/Monitoring/HeaderContextBarTest.php
  • T053 [P] [FR-077-016] Assert deep link /admin/operations/{run} does not auto-switch tenant in tests/Feature/Monitoring/HeaderContextBarTest.php

Implementation

  • T054 [FR-077-016] Render context bar in topbar via render hook in app/Providers/Filament/AdminPanelProvider.php
  • T055 [FR-077-016] Add context bar partial view in resources/views/filament/partials/context-bar.blade.php
  • T056 [FR-077-016] Remove implicit tenant auto-selection behavior while preserving deny-as-not-found semantics in app/Support/Middleware/EnsureFilamentTenantSelected.php
  • T057 [FR-077-016] Persist last-selected tenant per workspace session in app/Support/Workspaces/WorkspaceContext.php and controllers/pages that select tenants

Checkpoint: Tenant picker usable on tenantless pages; no silent tenant switching.


Dependencies & Execution Order

Phase Dependencies

  • Phase 1 (Setup) → Phase 2 (Foundational)
  • Phase 2 (Foundational) → Phase 3+ (User stories)
  • Phase 3 (US1) is the MVP and should be delivered first.
  • Phase 4 (US2) depends on the clarified navigation + intended-URL plumbing (Phases 12).
  • Phase 5 (US3) depends on the implemented behavior from US1/US2 so it can assert non-leakage.

User Story Dependencies

  • US1 → US2: soft dependency (naming + intended redirect improves US2 flows)
  • US2 → US3: recommended dependency (US3 asserts final 404/403 and filter semantics)

Parallel Execution Examples

US1 parallelizable work

  • T009, T010, T011, T012 can be written in parallel (different assertions/files)
  • T013, T014, T015 can be implemented in parallel (different files)

US2 parallelizable work

  • T021T024 can be written in parallel
  • T028 (resource query) and T029 (table filters) can be implemented in parallel
  • T031T032 can be implemented in parallel with operations filter work (different file)

US3 parallelizable work

  • T035T038 can be written in parallel
  • T039T042 can be implemented in parallel (different files)

Implementation Strategy

  • Deliver Phase 13 (US1) only.
  • Validate with ./vendor/bin/sail artisan test --compact --filter=WorkspaceNavigationHub.
  • Demo “Switch workspace” vs “Manage workspaces” clarity + correct 404/403 behavior.

Incremental delivery

  • Add US2 (canonical operations URLs + removable tenant default filter)
  • Add US3 (non-leakage regression guards)
  • Finish with Phase 6 polish and a full suite run