TenantAtlas/specs/077-workspace-nav-monitoring-hub/tasks.md

216 lines
13 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 list for Spec 077 implementation"
---
# Tasks: Workspace-first Navigation & Monitoring Hub (077)
**Input**: Design documents from `/specs/077-workspace-nav-monitoring-hub/`
**Prerequisites**:
- Required: [spec.md](spec.md), [plan.md](plan.md)
- Optional (used): [research.md](research.md), [data-model.md](data-model.md), [contracts/routes.md](contracts/routes.md), [quickstart.md](quickstart.md)
**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.
- [X] T001 Create new Pest test file for workspace navigation in tests/Feature/Workspaces/WorkspaceNavigationHubTest.php
- [X] T002 Create new Pest test file for operations canonical routing in tests/Feature/Monitoring/OperationsCanonicalUrlsTest.php
- [X] 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.
- [X] T004 Add intended-URL session key constant in app/Support/Workspaces/WorkspaceContext.php
- [X] T005 Implement “store intended URL” helper in app/Support/Workspaces/WorkspaceIntendedUrl.php
- [X] T006 [P] Add tests for intended-URL helper in tests/Feature/Workspaces/WorkspaceIntendedUrlTest.php
- [X] T007 Update middleware to use intended-URL helper in app/Http/Middleware/EnsureWorkspaceSelected.php
- [X] 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)
- [X] T009 [P] [US1] Assert nav label “Switch workspace” appears when tenant is not selected in tests/Feature/Workspaces/WorkspaceNavigationHubTest.php
- [X] T010 [P] [US1] Assert no ambiguous “Workspaces” nav item exists in tests/Feature/Workspaces/WorkspaceNavigationHubTest.php
- [X] T011 [P] [US1] Assert `/admin/workspaces` is tenantless and reachable for a workspace owner in tests/Feature/Workspaces/WorkspacesResourceIsTenantlessTest.php
- [X] 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
- [X] T013 [US1] Rename fallback nav item to “Switch workspace” in app/Support/Middleware/EnsureFilamentTenantSelected.php
- [X] T014 [US1] Update user-menu copy/CTA to “Switch workspace” in resources/views/filament/partials/workspace-switcher.blade.php
- [X] T015 [US1] Rename admin sidebar item to “Manage workspaces” in app/Providers/Filament/AdminPanelProvider.php
- [X] T016 [US1] Gate “Manage workspaces” navigation visibility via capability in app/Providers/Filament/AdminPanelProvider.php
- [X] T017 [US1] Enforce workspace-scoped RBAC semantics for workspace management (404 non-member, 403 missing capability) in app/Policies/WorkspacePolicy.php
- [X] T018 [US1] Ensure workspace management breadcrumbs point to `/admin/workspaces` in app/Filament/Resources/Workspaces/WorkspaceResource.php
- [X] T019 [US1] Ensure `/admin/workspaces` routes do not require tenant context in app/Support/Middleware/EnsureFilamentTenantSelected.php
- [X] 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)
- [X] T021 [P] [US2] Assert `/admin/operations` is reachable without tenant context in tests/Feature/Monitoring/OperationsCanonicalUrlsTest.php
- [X] T022 [P] [US2] Assert `/admin/operations/{run}` works with and without tenant context in tests/Feature/Monitoring/OperationsCanonicalUrlsTest.php
- [X] T023 [P] [US2] Assert operations list defaults to current tenant (filter state) when tenant context active in tests/Feature/Monitoring/OperationsCanonicalUrlsTest.php
- [X] T024 [P] [US2] Assert clearing tenant filter shows workspace-wide runs in tests/Feature/Monitoring/OperationsCanonicalUrlsTest.php
### Implementation for User Story 2
- [X] T025 [US2] Allow `/admin/operations` (index) through tenancy-enforcing middleware without auto-setting tenant in app/Support/Middleware/EnsureFilamentTenantSelected.php
- [X] T026 [US2] Ensure workspace selection is required for `/admin/operations` and stores intended URL for return flow in app/Http/Middleware/EnsureWorkspaceSelected.php
- [X] T027 [US2] Redirect back to intended URL after workspace selection in both app/Filament/Pages/ChooseWorkspace.php and app/Http/Controllers/SwitchWorkspaceController.php
- [X] T028 [US2] Remove hard tenant scoping from query in app/Filament/Resources/OperationRunResource.php
- [X] T029 [US2] Add tenant SelectFilter with removable chip and server-side default state in app/Filament/Resources/OperationRunResource/Pages/ListOperationRuns.php
- [X] T030 [US2] Scope selectable tenants in the filter to current workspace in app/Filament/Resources/OperationRunResource/Pages/ListOperationRuns.php
- [X] 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
- [X] T032 [US2] Ensure “View all operations” CTA routes to canonical `/admin/operations` in app/Filament/Resources/TenantResource/Pages/ViewTenant.php
- [X] T033 [US2] Ensure operations pages remain DB-only (no Graph calls) by extending existing checks in tests/Feature/MonitoringOperationsTest.php
- [X] 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)
- [X] T035 [P] [US3] Assert non-member access to another workspaces operations is 404 in tests/Feature/OpsUx/NonLeakageWorkspaceOperationsTest.php
- [X] T036 [P] [US3] Assert member missing `workspace.manage` gets 403 on `/admin/workspaces/{record}/edit` in tests/Feature/OpsUx/NonLeakageWorkspaceOperationsTest.php
- [X] T037 [P] [US3] Assert invalid tenant context is auto-cleared when switching workspace in tests/Feature/Workspaces/ManagedTenantsWorkspaceRoutingTest.php
- [X] 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
- [X] T039 [US3] Implement “auto-clear invalid tenant context” check in app/Support/Middleware/EnsureFilamentTenantSelected.php
- [X] T040 [US3] Confirm and implement correct Filament v5 mechanism for clearing persisted tenant state in app/Support/Middleware/EnsureFilamentTenantSelected.php
- [X] T041 [US3] Implement reserved Monitoring placeholder pages (Alerts, Audit Log) as Filament pages under app/Filament/Pages/Monitoring/**
- [X] T042 [US3] Ensure navigation does not expose admin-only surfaces to unauthorized users in app/Providers/Filament/AdminPanelProvider.php
- [X] 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/**
- [X] 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.
- [X] T045 Run formatter on touched files via `./vendor/bin/sail bin pint --dirty`
- [X] T046 Run targeted full suite for touched areas via `./vendor/bin/sail artisan test --compact tests/Feature/Workspaces tests/Feature/Monitoring tests/Feature/OpsUx`
- [X] T047 [P] Confirm manual quickstart steps still match UI labels and routes in specs/077-workspace-nav-monitoring-hub/quickstart.md
- [X] T048 [P] Confirm route semantics still match contracts in specs/077-workspace-nav-monitoring-hub/contracts/routes.md
- [X] T049 Ensure Filament v5 + Livewire v4 APIs are used (no v3/v4 Filament APIs) in app/Filament/**
- [X] T050 Run full suite (optional) via `./vendor/bin/sail artisan test --compact`
### Post-implementation bugfixes
- [X] 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
---
## 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)
- [X] T051 [P] [FR-077-016] Assert tenant picker renders on `/admin/operations` in tests/Feature/Monitoring/HeaderContextBarTest.php
- [X] T052 [P] [FR-077-016] Assert tenant picker lists only entitled tenants in tests/Feature/Monitoring/HeaderContextBarTest.php
- [X] T053 [P] [FR-077-016] Assert deep link `/admin/operations/{run}` does not auto-switch tenant in tests/Feature/Monitoring/HeaderContextBarTest.php
### Implementation
- [X] T054 [FR-077-016] Render context bar in topbar via render hook in app/Providers/Filament/AdminPanelProvider.php
- [X] T055 [FR-077-016] Add context bar partial view in resources/views/filament/partials/context-bar.blade.php
- [X] T056 [FR-077-016] Remove implicit tenant auto-selection behavior while preserving deny-as-not-found semantics in app/Support/Middleware/EnsureFilamentTenantSelected.php
- [X] 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
### MVP scope (recommended)
- 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