## Summary - keep `/admin/reviews/workspace` workspace-scoped in shell and sidebar context - treat `tenant` query hints on the customer review workspace as page-level filters only - update the customer review workspace tests and Spec 311 navigation contract to match the workspace-hub IA ## Testing - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Reviews/CustomerReviewWorkspacePageTest.php` - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/WorkspaceContextTopbarAndTenantSelectionTest.php tests/Feature/Filament/PanelNavigationSegregationTest.php` - `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent` - `git diff --check` Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #366
190 lines
13 KiB
Markdown
190 lines
13 KiB
Markdown
# Implementation Plan: Workspace / Environment Surface Scope Contract
|
|
|
|
**Branch**: `311-workspace-environment-surface-scope-contract` | **Date**: 2026-05-15 | **Spec**: `specs/311-workspace-environment-surface-scope-contract/spec.md`
|
|
**Input**: Feature specification from `/specs/311-workspace-environment-surface-scope-contract/spec.md`
|
|
|
|
## Summary
|
|
|
|
Implement the global admin surface scope contract: route scope controls shell/navigation, page filters control data. Explicit workspace-wide surfaces remain tenantless in the shell even with query filters or remembered/Filament tenant context. Canonical environment routes remain environment-bound. Legacy tenant-owned admin lists keep their existing data scoping until a separate route cutover handles them.
|
|
|
|
## Technical Context
|
|
|
|
**Language/Version**: PHP 8.4, Laravel 12, Filament v5, Livewire v4
|
|
**Primary Dependencies**: Existing Filament panel, `TenantPageCategory`, `NavigationScope`, `OperateHubShell`, `CanonicalAdminTenantFilterState`
|
|
**Storage**: No database changes
|
|
**Testing**: Pest v4 / Livewire component tests / HTTP feature tests
|
|
**Validation Lanes**: focused feature/unit tests, Pint dirty, `git diff --check`
|
|
**Target Platform**: TenantPilot admin panel
|
|
**Project Type**: Laravel monorepo
|
|
**Performance Goals**: No extra database work beyond existing widget/list queries
|
|
**Constraints**: No migrations, no RBAC changes, no Customer Review Workspace product completion, no broad navigation rebuild, no sidebar query magic
|
|
**Scale/Scope**: Representative workspace-wide surfaces, canonical environment routes, and legacy tenant-owned regression coverage
|
|
|
|
## UI / Surface Guardrail Plan
|
|
|
|
- **Guardrail scope**: shell scope, topbar labels, sidebar classification, and table/widget filter defaults.
|
|
- **Native vs custom classification summary**: Filament-native pages/resources/widgets only; no custom styling.
|
|
- **Shared-family relevance**: global admin navigation shell and workspace-wide monitoring/governance/reporting surfaces.
|
|
- **State layers in scope**: route path, query filter values, table filter session state, remembered tenant session, Filament tenant context.
|
|
- **Audience modes in scope**: workspace operator/admin only.
|
|
- **Decision/diagnostic/raw hierarchy plan**: N/A.
|
|
- **Raw/support gating plan**: N/A.
|
|
- **One-primary-action / duplicate-truth control**: prevent duplicate truth by making shell route-owned and filters page-owned.
|
|
- **Handling modes by drift class or surface**: explicit workspace-wide surfaces become tenantless shell; canonical environment routes remain tenant-bound; legacy tenant-owned lists remain current behavior.
|
|
- **Repository-signal treatment**: test-first red/green on representative surfaces and parity tests.
|
|
- **Special surface test profiles**: Livewire tests must set a realistic `referer` when asserting route-derived shell behavior.
|
|
- **Required tests or manual smoke**: focused Pest/Livewire tests; browser smoke not required because no styling/layout change.
|
|
- **Exception path and spread control**: future workspace-wide surfaces must be added to `TenantPageCategory` and covered by the surface matrix.
|
|
- **Active feature PR close-out entry**: Workspace / Environment Surface Scope Contract.
|
|
|
|
## Shared Pattern & System Fit
|
|
|
|
- **Cross-cutting feature marker**: admin shell/navigation contract.
|
|
- **Systems touched**: route taxonomy, shell context, workspace-wide filters, monitoring/alerts widgets.
|
|
- **Shared abstractions reused**: `TenantPageCategory`, `TenantInteractionLane`, `OperateHubShell`, `NavigationScope`, `CanonicalAdminTenantFilterState`.
|
|
- **New abstraction introduced? why?**: No new service or registry. Existing enum gains `WorkspaceWideSurface`.
|
|
- **Why the existing abstraction was sufficient or insufficient**: The existing taxonomy already owns page category; it needed one extra category to separate explicit workspace-wide hubs from legacy workspace-scoped tenant-owned lists.
|
|
- **Bounded deviation / spread control**: explicit path matching stays centralized in `TenantPageCategory`.
|
|
|
|
## OperationRun UX Impact
|
|
|
|
- **Touches OperationRun start/completion/link UX?**: Yes, Operations list/KPI scope only.
|
|
- **Central contract reused**: `OperationRunLinks` and existing Operations page remain.
|
|
- **Delegated UX behaviors**: no start/completion changes.
|
|
- **Surface-owned behavior kept local**: Operations tabs/table query remain local.
|
|
- **Queued DB-notification policy**: unchanged.
|
|
- **Terminal notification path**: unchanged.
|
|
- **Exception path**: none.
|
|
|
|
## Provider Boundary & Portability Fit
|
|
|
|
- **Shared provider/platform boundary touched?**: provider connections and alerts as workspace-wide/provider-level surfaces.
|
|
- **Provider-owned seams**: Microsoft-specific inventory/policy/backup legacy tenant-owned lists remain out of this minimal cutover.
|
|
- **Platform-core seams**: workspace, environment, provider connection, alert delivery, audit log, governance/workspace hubs.
|
|
- **Neutral platform terms / contracts preserved**: workspace-wide, environment-bound, provider connection, environment filter.
|
|
- **Retained provider-specific semantics and why**: legacy tenant-owned direct lists retain current tenant data context pending their own route migration.
|
|
- **Bounded extraction or follow-up path**: 312 Customer Review Workspace v1 Completion follows after this contract; tenant-owned route cutover remains separate.
|
|
|
|
## Constitution Check
|
|
|
|
- Inventory-first: PASS. No inventory truth changes.
|
|
- Read/write separation: PASS. Read-only shell/list/widget behavior only.
|
|
- Graph contract path: PASS. No Graph calls changed.
|
|
- Deterministic capabilities: PASS. No capability mapping changes.
|
|
- Workspace isolation: PASS. Workspace query scopes remain enforced.
|
|
- Tenant isolation: PASS. Environment-bound routes and legacy tenant-owned lists remain protected.
|
|
- Run observability: PASS. OperationRun data visibility remains entitlement-scoped.
|
|
- Test governance: PASS. Focused tests plus parity regression; no new heavy family.
|
|
- Proportionality: PASS. One enum category in an existing taxonomy is narrower than a registry or navigation rebuild.
|
|
- No premature abstraction: PASS. No new service/interface/framework.
|
|
- Persisted truth: PASS. No persisted runtime truth.
|
|
- Behavioral state: PASS. Route category affects shell behavior only.
|
|
- Shared pattern first: PASS. Existing shell/taxonomy path reused.
|
|
- Provider boundary: PASS. Platform-core route contract stays provider-neutral.
|
|
- Filament-native UI: PASS. No assets, no view publishing.
|
|
|
|
## Test Governance Check
|
|
|
|
- **Test purpose / classification by changed surface**: Feature tests for admin shell and Livewire pages/widgets; Unit test for route category classification.
|
|
- **Affected validation lanes**: focused Feature/Unit lane.
|
|
- **Why this lane mix is narrowest sufficient proof**: The bug is route/shell/filter behavior, provable by HTTP and Livewire component tests without browser layout verification.
|
|
- **Narrowest proving command(s)**:
|
|
- Focused contract and neighboring surface tests under `tests/Feature/...`
|
|
- `tests/Unit/Tenants/TenantPageCategoryTest.php`
|
|
- `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent`
|
|
- `git diff --check`
|
|
- **Fixture / helper / factory / seed / context cost risks**: Reuses existing factories/helpers; no new heavy fixture family.
|
|
- **Expensive defaults or shared helper growth introduced?**: no.
|
|
- **Heavy-family additions, promotions, or visibility changes**: none.
|
|
- **Surface-class relief / special coverage rule**: Browser smoke not required; no visual layout/styling change.
|
|
- **Closing validation and reviewer handoff**: Verify representative workspace-wide surfaces, environment-bound routes, and legacy tenant-owned parity tests.
|
|
- **Budget / baseline / trend follow-up**: none expected.
|
|
- **Review-stop questions**: any per-page shell exception, query-driven sidebar, RBAC change, migration, or Customer Review product logic.
|
|
- **Escalation path**: remaining legacy route taxonomy questions belong to a follow-up route cutover/audit spec.
|
|
- **Active feature PR close-out entry**: Workspace / Environment Surface Scope Contract.
|
|
|
|
## Project Structure
|
|
|
|
```text
|
|
apps/platform/app/Support/Tenants/TenantPageCategory.php
|
|
apps/platform/app/Support/Tenants/TenantInteractionLane.php
|
|
apps/platform/app/Support/OperateHub/OperateHubShell.php
|
|
apps/platform/app/Filament/Pages/Reviews/*
|
|
apps/platform/app/Filament/Resources/AlertDeliveryResource.php
|
|
apps/platform/app/Filament/Resources/ProviderConnectionResource.php
|
|
apps/platform/app/Filament/Widgets/Alerts/AlertsKpiHeader.php
|
|
apps/platform/app/Filament/Widgets/Operations/OperationsKpiHeader.php
|
|
apps/platform/tests/Feature/**
|
|
apps/platform/tests/Unit/Tenants/TenantPageCategoryTest.php
|
|
specs/311-workspace-environment-surface-scope-contract/
|
|
```
|
|
|
|
**Structure Decision**: Extend existing taxonomy and tests in place. Do not introduce a new surface registry.
|
|
|
|
## Complexity Tracking
|
|
|
|
| Violation | Why Needed | Simpler Alternative Rejected Because |
|
|
|---|---|---|
|
|
| Add enum category | Existing `WorkspaceScoped` combined explicit workspace hubs with legacy tenant-owned lists | Forcing all `WorkspaceScoped` tenantless regressed legacy tenant-owned resource data scoping; local page exceptions would spread |
|
|
|
|
## Proportionality Review
|
|
|
|
- **Current operator problem**: Workspace hubs can display environment context in the shell while also showing page-level environment filters.
|
|
- **Existing structure is insufficient because**: `WorkspaceScoped` was too broad for both workspace hubs and legacy tenant-owned direct lists.
|
|
- **Narrowest correct implementation**: Add `WorkspaceWideSurface` to the existing category enum and force tenantless shell only there.
|
|
- **Ownership cost created**: Future workspace-wide routes must be added centrally with tests.
|
|
- **Alternative intentionally rejected**: CRW-only patch, `?tenant` sidebar switching, broad nav rewrite, or converting all legacy tenant-owned routes in this branch.
|
|
- **Release truth**: Current platform shell contract.
|
|
|
|
## Phase 0: Read-Only Findings
|
|
|
|
- Operations already behaved correctly because it had explicit all-environments/page-filter semantics.
|
|
- Customer Review Workspace, Review Register, Audit Log, Alerts, and Alert Delivery could inherit remembered/Filament tenant through shell or filter defaults.
|
|
- Provider Connections defaulted its list filter from the resolved scoped tenant instead of explicit query state.
|
|
- Legacy tenant-owned resource pages still rely on remembered tenant data context; this branch preserves them and protects them with parity tests.
|
|
|
|
## Implementation Notes
|
|
|
|
- `TenantPageCategory::fromRequest()` now uses Livewire referer paths for Livewire update requests so shell resolution matches browser route scope.
|
|
- `WorkspaceWideSurface` covers explicit workspace-wide admin surfaces, including Operations, Reviews workspace/register, Governance Inbox/Decision Register, Evidence Overview, Audit Log, Provider Connections, Alerts, and Workspace Overview.
|
|
- `OperateHubShell` returns tenantless workspace context before query/Filament/remembered tenant resolution for `WorkspaceWideSurface`.
|
|
- Customer Review Workspace and Review Register no longer default their environment filters from remembered tenant and no longer clear global last-tenant state when clearing page filters.
|
|
- Alert Delivery list and Alerts KPI are workspace-wide and no longer use shell tenant as data default.
|
|
- Operations KPI now counts the workspace entitlement scope when the shell is tenantless.
|
|
- Provider Connection list filter defaults only from explicit request state, not remembered/global context.
|
|
|
|
## Validation Plan
|
|
|
|
Run the focused contract and neighboring tests, then Pint and whitespace checks:
|
|
|
|
```bash
|
|
cd apps/platform
|
|
./vendor/bin/sail artisan test --compact <focused files>
|
|
./vendor/bin/sail bin pint --dirty --format agent
|
|
cd ../..
|
|
git diff --check
|
|
```
|
|
|
|
## Implementation Close-Out
|
|
|
|
- **Changed runtime areas**: route taxonomy, shell resolution, workspace-wide page filter defaults, Operations KPI, Alerts KPI/list, Provider Connections filter default.
|
|
- **Changed tests**: focused shell/navigation, Operations, Customer Review Workspace, Review Register, Audit Log, Alerts, Provider Connections, tenant-owned parity, and route category coverage.
|
|
- **Validation completed**:
|
|
- `cd apps/platform && ./vendor/bin/sail artisan test --compact ...` for the focused 311 selection: 172 passed, 703 assertions.
|
|
- `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent`: pass.
|
|
- `git diff --check`: pass.
|
|
- **No migrations**: confirmed.
|
|
- **No RBAC changes**: confirmed.
|
|
- **No Customer Review Workspace product logic**: confirmed; only shell/filter-scope behavior changed.
|
|
- **No asset changes**: confirmed.
|
|
- **Follow-up**: 312 can continue Customer Review Workspace v1 Completion against this shell contract.
|
|
|
|
## Filament v5 Output Contract
|
|
|
|
1. **Livewire v4.0+ compliance**: This app uses Livewire v4 with Filament v5; tests mount Filament Livewire pages/widgets.
|
|
2. **Provider registration**: No panel provider registration changes. Laravel 11+/12 provider registration remains in `apps/platform/bootstrap/providers.php`.
|
|
3. **Global search**: No globally searchable resource behavior changed. Provider Connection remains globally searchable disabled; Alert Delivery changes do not enable search.
|
|
4. **Destructive actions**: No destructive actions added or changed.
|
|
5. **Assets**: No assets added or changed; `filament:assets` deployment process unchanged.
|
|
6. **Testing**: HTTP feature tests, Livewire component tests, and route category unit tests cover the contract.
|