--- 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 workspace’s 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 1–2). - 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 - T021–T024 can be written in parallel - T028 (resource query) and T029 (table filters) can be implemented in parallel - T031–T032 can be implemented in parallel with operations filter work (different file) ### US3 parallelizable work - T035–T038 can be written in parallel - T039–T042 can be implemented in parallel (different files) --- ## Implementation Strategy ### MVP scope (recommended) - Deliver Phase 1–3 (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