## Summary - productize the operations hub decision-first workbench and related monitoring page surfaces - add the operations workbench stats widget plus tenantless run viewer and admin scope updates - extend monitoring, ops UX, and browser coverage for the new workbench behavior - add Spec 328 artifacts under `specs/328-operations-hub-decision-first-workbench-productization` ## Testing - not run as part of this handoff Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #389
344 lines
22 KiB
Markdown
344 lines
22 KiB
Markdown
# Implementation Plan: Spec 328 - Operations Hub Decision-First Workbench Productization
|
|
|
|
**Branch**: `328-operations-hub-decision-first-workbench-productization` | **Date**: 2026-05-18 | **Spec**: `specs/328-operations-hub-decision-first-workbench-productization/spec.md`
|
|
**Input**: User-provided Spec 328 and repo inspection.
|
|
|
|
## Summary
|
|
|
|
Productize the existing workspace-scoped Operations Hub into a decision-first OperationRun workbench. The implementation must keep the current route and OperationRun truth, introduce no backend foundation, and make the first viewport answer:
|
|
|
|
```text
|
|
Which operation needs attention now?
|
|
```
|
|
|
|
The workbench will elevate the highest-priority operation, outcome, reason, impact, affected environment, trustworthy progress/proof state, and a single next action, while keeping the existing OperationRun table as secondary context and diagnostics collapsed.
|
|
|
|
## Technical Context
|
|
|
|
**Language/Version**: PHP 8.4.15, Laravel 12.52.0.
|
|
**Primary Dependencies**: Filament 5.2.1, Livewire 4.1.4, Pest 4.3.1, Tailwind CSS 4.2.2.
|
|
**Storage**: PostgreSQL; no schema change expected.
|
|
**Testing**: Pest 4 Feature/Livewire/Browser tests.
|
|
**Validation Lanes**: confidence and browser; targeted navigation guard tests.
|
|
**Target Platform**: Laravel Sail locally; Dokploy/container deployment posture unchanged.
|
|
**Project Type**: Laravel monolith under `apps/platform`.
|
|
**Performance Goals**: DB-only page render; no Graph calls during render; no extra heavy query family beyond existing operations table/detail queries unless bounded and eager-loaded.
|
|
**Constraints**: No new persisted truth, migration, package, queue/scheduler/storage/env change, deployment asset, compatibility route, or legacy alias support.
|
|
**Scale/Scope**: One existing Filament page, its Blade view, existing OperationRun table/resource helpers, feature tests, browser smoke, and spec artifacts.
|
|
|
|
## UI / Surface Guardrail Plan
|
|
|
|
- **Guardrail scope**: changed existing operator-facing strategic surface.
|
|
- **Affected routes/pages/actions/states/navigation/panel/provider surfaces**:
|
|
- `/admin/workspaces/{workspace}/operations`
|
|
- `/admin/workspaces/{workspace}/operations/{run}` only as linked canonical detail context
|
|
- `apps/platform/app/Filament/Pages/Monitoring/Operations.php`
|
|
- `apps/platform/resources/views/filament/pages/monitoring/operations.blade.php`
|
|
- `apps/platform/app/Filament/Resources/OperationRunResource.php`
|
|
- `apps/platform/app/Filament/Widgets/Operations/OperationsKpiHeader.php` only if summary card/KPI wording must be adjusted
|
|
- **No-impact class, if applicable**: N/A.
|
|
- **Native vs custom classification summary**: Native Filament page/table plus existing Blade composition; no new UI framework.
|
|
- **Shared-family relevance**: status messaging, OperationRun links, progress contract, proof/artifact links, workspace/environment filter chip, diagnostics disclosure.
|
|
- **State layers in scope**: page payload, URL query (`environment_id`, `activeTab`, `problemClass`), table filters/session state, highest-priority operation selection, diagnostics disclosure.
|
|
- **Audience modes in scope**: operator-MSP, manager, support reviewer, auditor.
|
|
- **Decision/diagnostic/raw hierarchy plan**: decision-first, proof/artifact second, diagnostics/support raw third.
|
|
- **Raw/support gating plan**: collapsed by default and capability-gated where existing capabilities support access.
|
|
- **One-primary-action / duplicate-truth control**: selected/highest-priority operation owns one primary next action; table rows and related links remain secondary.
|
|
- **Handling modes by drift class or surface**: review-mandatory for UI-003 strategic surface; document-in-feature for any UI coverage registry no-change decision.
|
|
- **Repository-signal treatment**: Spec 325 target image is visual direction only; runtime claims must be repo-verified or unavailable.
|
|
|
|
## Constitution Check
|
|
|
|
- **Inventory-first, snapshots-second**: N/A, no Graph, inventory, snapshot, backup, or restore data model change.
|
|
- **Read/write separation by default**: Page remains read-first. Any unexpected mutation requires spec/plan update, confirmation, authorization, audit, notification, and tests.
|
|
- **Single Contract Path to Graph**: No Graph calls may be added.
|
|
- **Deterministic Capabilities**: Reuse existing `OperationRunPolicy`, `OperationRunCapabilityResolver`, source policies, and capability resolvers.
|
|
- **Proportionality / anti-bloat**: No new source of truth, persisted entity, enum/status family, public abstraction, priority engine, or cross-domain UI framework.
|
|
- **Workspace isolation**: Clean workspace URL stays workspace-wide; `environment_id` is resolved through current workspace and actor entitlement.
|
|
- **Tenant/environment language**: Runtime copy must avoid tenant as platform context; provider-specific tenant wording only where explicitly provider-bound.
|
|
- **OperationRun UX**: Presentation/link semantics only. No operation start, queueing, lifecycle transition, notification, or summary-count writer changes.
|
|
- **Progress contract**: `OperationRunProgressContract` remains authoritative. Terminal runs show outcome guidance, not progress.
|
|
- **UI-COV-001**: Existing strategic surface UI-003 changes; active spec package carries repo-truth map, tests, and browser screenshots. Implementation close-out decides whether route inventory/coverage matrix updates are needed.
|
|
- **TEST-GOV-001**: Targeted Feature and Browser tests are explicit; no broad heavy-governance lane unless implementation reveals structural risk.
|
|
|
|
## Current Repo Truth Summary
|
|
|
|
Existing verified surfaces:
|
|
|
|
- `Operations` is a Filament `Page` rendered by `admin.operations.index`.
|
|
- `admin.operations.index` is `/admin/workspaces/{workspace}/operations`.
|
|
- The view currently renders `Monitoring landing`, scope/return/reset cards, tabs, lifecycle warning, and the OperationRun table.
|
|
- `OperationRunResource::table()` owns columns, row detail URL, filters, empty state, status/outcome badges, and no row/bulk actions.
|
|
- `OperationRun` owns `status`, `outcome`, problem classes, freshness/lifecycle helpers, workspace and managed-environment scope.
|
|
- `OperationRunProgressContract` already separates active counted/activity/phased/composite/none progress and returns `none` for terminal runs.
|
|
- `TenantlessOperationRunViewer` and `OperationRunResource::infolist()` already provide richer run detail, related links, proof/artifact sections, support diagnostics, and technical sections.
|
|
- `OperationRunLinks` provides canonical index/detail URLs and related resource links.
|
|
- `WorkspaceHubEnvironmentFilter::fromRequest()` accepts canonical `environment_id`, scopes to current workspace, and rejects inaccessible/cross-workspace IDs.
|
|
- Existing tests cover canonical operations URLs, workspace hub clean entry, environment filter behavior, detail access, DB-only rendering, and OperationRun authorization.
|
|
|
|
Known current productization gap:
|
|
|
|
- The page is still monitoring/table-first. It does not yet consistently promote an attention-needed operation with outcome, reason, impact, environment, progress/proof state, and one primary next action ahead of the table.
|
|
|
|
## Existing Repository Surfaces Likely Affected
|
|
|
|
Runtime files, only during later implementation:
|
|
|
|
- `apps/platform/app/Filament/Pages/Monitoring/Operations.php`
|
|
- `apps/platform/resources/views/filament/pages/monitoring/operations.blade.php`
|
|
- `apps/platform/app/Filament/Resources/OperationRunResource.php`
|
|
- `apps/platform/app/Filament/Widgets/Operations/OperationsKpiHeader.php` remains existing widget code, but it must not render before the Spec 328 workbench when the decision-first summary cards own the first viewport.
|
|
- `apps/platform/resources/lang/en/*` and `apps/platform/resources/lang/de/*` only if current project pattern requires localized strings for new stable copy.
|
|
|
|
Tests, only during later implementation:
|
|
|
|
- `apps/platform/tests/Feature/Monitoring/MonitoringOperationsTest.php`
|
|
- `apps/platform/tests/Feature/Monitoring/OperationsWorkspaceHubContractTest.php`
|
|
- `apps/platform/tests/Feature/Monitoring/OperationsCanonicalUrlsTest.php`
|
|
- `apps/platform/tests/Feature/Monitoring/OperationsHeaderHierarchyTest.php`
|
|
- `apps/platform/tests/Feature/Monitoring/OperationsTenantScopeTest.php`
|
|
- `apps/platform/tests/Feature/Monitoring/OperationLifecycleFreshnessPresentationTest.php`
|
|
- `apps/platform/tests/Feature/Operations/TenantlessOperationRunViewerTest.php`
|
|
- `apps/platform/tests/Feature/Operations/OperationRunBlockedExecutionPresentationTest.php`
|
|
- `apps/platform/tests/Unit/Support/OpsUx/OperationRunProgressContractTest.php`
|
|
- `apps/platform/tests/Feature/Navigation/WorkspaceHubEnvironmentFilterContractTest.php`
|
|
- `apps/platform/tests/Feature/Navigation/WorkspaceHubClearFilterContractTest.php`
|
|
- `apps/platform/tests/Browser/Spec328OperationsHubProductizationSmokeTest.php`
|
|
|
|
Spec/UI artifacts:
|
|
|
|
- `specs/328-operations-hub-decision-first-workbench-productization/repo-truth-map.md`
|
|
- screenshot artifacts under `specs/328-operations-hub-decision-first-workbench-productization/artifacts/screenshots/`
|
|
- optional UI coverage registry updates only if implementation materially changes route/archetype/coverage state.
|
|
|
|
## Domain / Model Implications
|
|
|
|
- No new model, table, migration, enum, status family, source of truth, or persisted display state.
|
|
- Workbench item state must derive from existing OperationRun truth:
|
|
- `status`: queued, running, completed.
|
|
- `outcome`: pending, succeeded, partially_succeeded, blocked, failed, reserved cancelled.
|
|
- `problemClass()`: active stale attention, terminal follow-up, none.
|
|
- `freshnessState()` and lifecycle reconciliation payload.
|
|
- `summary_counts` through `OperationRunProgressContract` and `SummaryCountsNormalizer`.
|
|
- `OperationCatalog::label()` for operation type labels.
|
|
- `managed_environment_id` / `tenant` relation for affected environment.
|
|
- `started_at`, `completed_at`, `created_at` for timing.
|
|
- `context`, `failure_summary`, and related models only behind safe proof/diagnostic paths.
|
|
- If exact reason, impact, artifact, evidence, or next action is missing, render explicit unavailable/missing state.
|
|
|
|
## UI / Filament Implications
|
|
|
|
- Filament v5 and Livewire v4.0+ compliance must be preserved.
|
|
- Panel providers remain in `apps/platform/bootstrap/providers.php`; no panel provider changes expected.
|
|
- No globally searchable resource is added or changed. `OperationRunResource` remains `protected static bool $isGloballySearchable = false`.
|
|
- The layout should use Filament sections/cards/badges/buttons and Tailwind utility classes consistent with existing pages; no heavy one-off CSS.
|
|
- Header must stay short:
|
|
- `Operations Hub`
|
|
- workspace label
|
|
- scope label: workspace-wide or filtered environment
|
|
- visible filter chip and clear action when filtered
|
|
- subtitle explaining execution truth and follow-up
|
|
- Main workbench must render before the operations table.
|
|
- Summary cards should be compact and action-relevant.
|
|
- Follow-up summary-card alignment: the four workbench summary cards should use native Filament `StatsOverviewWidget` / `Stat` rendering while remaining execution/attention signals. Use title, large value, concise subline, optional description/status icon, and semantic `Stat::color(...)`. Do not reintroduce custom Blade/Tailwind stat-card markup, explicit custom accent bars, generic `Total Operations` / `Avg Duration` cards, fake trends, fake sparklines, decorative charts, or health claims.
|
|
- Card emphasis should reflect execution risk: `Needs attention` strongest when actionable, `Active operations` neutral when zero, `Failed or blocked` danger/warning, and `Completed recently` muted success/secondary.
|
|
- Right-side detail/proof panel should be desktop aside and mobile stack.
|
|
- Diagnostics must be collapsed by default.
|
|
|
|
## Livewire / Page State Implications
|
|
|
|
- Existing internal methods/properties may keep legacy names only as implementation detail; runtime URL/filter language must be `environment_id` and `Environment`.
|
|
- Existing `activeTab` and `problemClass` query filters can remain if they do not conflict with `environment_id` contract.
|
|
- Highest-priority operation selection should be deterministic on page load. If interactive selection is implemented, it must not introduce persisted state or break reload/back/forward behavior.
|
|
- Clear filter must remove `environment_id` and any environment-like table/session filter state through existing helpers.
|
|
|
|
## OperationRun / Monitoring Implications
|
|
|
|
- No new `OperationRun` creation or lifecycle transition.
|
|
- No queued/running/terminal DB notification changes.
|
|
- No new summary-count writer, progress key, operation type, status, or outcome.
|
|
- Any operation proof link must use existing `OperationRunLinks`, `OperationRunResource`, related routes, and authorization.
|
|
- Raw `OperationRun.context`, `failure_summary`, stack traces, and payload-like data must not be default-visible.
|
|
|
|
## RBAC / Policy Implications
|
|
|
|
Reuse existing authorization:
|
|
|
|
- Workspace page access through current workspace membership checks and `WorkspaceCapabilityResolver::isMember()`.
|
|
- Environment access through `ManagedEnvironmentAccessScopeResolver` and current accessible environments.
|
|
- Run visibility through `OperationRunPolicy`.
|
|
- Run capability mapping through `OperationRunCapabilityResolver`.
|
|
- Evidence and artifacts through existing source policies/capabilities where links are shown.
|
|
- Support diagnostics through `Capabilities::SUPPORT_DIAGNOSTICS_VIEW` where diagnostics are exposed.
|
|
- Existing detail actions such as support diagnostics, support request, resume capture, retry/resume, or related links remain owned by the detail/source surfaces.
|
|
|
|
No new permission semantics should be added unless implementation proves existing capabilities cannot express the action and spec/plan are updated first.
|
|
|
|
## Audit / Evidence / Disclosure Implications
|
|
|
|
- No new audit event is required for read-only page rendering unless current page-open audit conventions are extended repo-wide.
|
|
- Evidence/proof should appear as state:
|
|
- operation record available
|
|
- artifact link available
|
|
- evidence linked
|
|
- proof unavailable
|
|
- diagnostics hidden
|
|
- Do not show raw provider payloads, debug metadata, internal exception traces, provider secrets, raw OperationRun payloads, or stack traces by default.
|
|
- If diagnostics disclosure is present, it must be collapsed and capability-aware.
|
|
|
|
## Data / Migration Implications
|
|
|
|
Expected outcome:
|
|
|
|
- No migrations.
|
|
- No seeders.
|
|
- No data backfills.
|
|
- No packages.
|
|
- No env vars.
|
|
- No queues/scheduler/storage changes.
|
|
- No deployment asset changes.
|
|
- No backwards compatibility layer.
|
|
- No legacy tenant query alias support.
|
|
|
|
If implementation discovers an actual schema need, stop and update spec/plan/tasks/repo-truth-map first. Default decision remains no migration.
|
|
|
|
## Localization / Copy Implications
|
|
|
|
- Runtime copy must be concise and operator-safe.
|
|
- Avoid platform-context `tenant` wording. Use `Workspace` and `Environment` for shell/filter/product context.
|
|
- Provider-bound tenant wording may remain only when describing an external Microsoft/Entra tenant identifier or provider payload outside the default decision view.
|
|
- Add EN/DE localization only if the surrounding files already route stable page copy through language files; otherwise keep localized scope as implementation-local and document the decision.
|
|
|
|
## Implementation Phases
|
|
|
|
### Phase 1 - Repo Truth And Current UI Audit
|
|
|
|
- Re-read this spec, plan, tasks, and `repo-truth-map.md`.
|
|
- Inspect current `Operations`, Blade view, `OperationRunResource`, `TenantlessOperationRunViewer`, progress contract, links, policies, and tests.
|
|
- Update `repo-truth-map.md` before runtime changes if implementation discovers new source truth or gaps.
|
|
- Confirm no migration/package/env/queue/storage/deployment asset need.
|
|
|
|
### Phase 2 - Tests First
|
|
|
|
- Add tests for repo truth map existence.
|
|
- Add Feature/Livewire/HTTP tests for decision-first workbench, non-empty attention state, empty/no-attention state, right proof panel, table secondary context, diagnostics hidden, progress/terminal semantics, RBAC action visibility, environment filter, legacy aliases, cross-workspace guard, and tenant-copy guard.
|
|
|
|
### Phase 3 - Layout Productization
|
|
|
|
- Refactor the existing page into:
|
|
- header/scope
|
|
- main operations workbench
|
|
- compact execution summary cards
|
|
- right operation/proof panel
|
|
- operations queue/history table
|
|
- collapsed diagnostics disclosure
|
|
- Keep existing tabs/table filters and canonical row links.
|
|
|
|
### Phase 4 - Data Binding
|
|
|
|
- Bind workbench and panel to repo-verified sources.
|
|
- Render unavailable states for missing reason, impact, proof, artifact, evidence, or environment data.
|
|
- Do not create synthetic success, health, artifact, or governance claims.
|
|
|
|
### Phase 5 - Progress / Outcome Semantics
|
|
|
|
- Use existing progress contract semantics.
|
|
- Show determinate progress only when active counted progress is trustworthy.
|
|
- Show activity/status only for active uncounted runs.
|
|
- Show outcome guidance for terminal failed/blocked/partial/succeeded runs.
|
|
- Do not show terminal progress bars.
|
|
|
|
### Phase 6 - Action Hierarchy And RBAC
|
|
|
|
- Show one primary next action for the selected/highest-priority operation.
|
|
- Link only to existing, authorized operation/detail/artifact/evidence/source routes/actions.
|
|
- Keep rare/debug/source actions secondary.
|
|
- Do not introduce destructive actions.
|
|
|
|
### Phase 7 - Scope / Filter Integration
|
|
|
|
- Preserve clean workspace-wide entry.
|
|
- Preserve `?environment_id=` filter, visible chip, clear filter, reload/back/forward behavior.
|
|
- Preserve legacy alias rejection and cross-workspace guard.
|
|
|
|
### Phase 8 - Browser Smoke And Screenshots
|
|
|
|
- Add targeted Browser smoke for clean, filtered, clear/reload, non-empty workbench, empty/no-attention state, right detail/proof panel, diagnostics hidden, table secondary, light mode if feasible, and no platform-context tenant wording.
|
|
- Save screenshots under the spec artifacts path when generated.
|
|
|
|
### Phase 9 - Validation And Close-Out
|
|
|
|
- Run targeted Feature/navigation tests, Browser smoke, filtered guard tests, `pint --dirty`, and `git diff --check`.
|
|
- Report full suite status honestly if not run.
|
|
- Record no migrations/seeders/packages/env/queues/scheduler/storage/deployment asset/backcompat/legacy alias support.
|
|
|
|
## Testing Strategy
|
|
|
|
Required tests:
|
|
|
|
- `it('documents_operations_hub_repo_truth_map')`
|
|
- `it('renders_operations_hub_decision_first_workbench')`
|
|
- `it('renders_highest_priority_operation_needing_attention')`
|
|
- `it('renders_operations_hub_empty_attention_state')`
|
|
- `it('renders_operations_hub_operation_detail_proof_panel')`
|
|
- `it('keeps_operations_table_available_as_secondary_context')`
|
|
- `it('operations_hub_hides_raw_diagnostics_by_default')`
|
|
- `it('operations_hub_does_not_show_progress_for_terminal_outcomes')`
|
|
- `it('operations_hub_uses_determinate_progress_only_with_trustworthy_counts')`
|
|
- `it('operations_hub_supports_canonical_environment_filter')`
|
|
- `it('operations_hub_rejects_legacy_environment_aliases')`
|
|
- `it('operations_hub_rejects_cross_workspace_environment_filter')`
|
|
- `it('operations_hub_does_not_use_tenant_as_platform_context_copy')`
|
|
- `it('operations_hub_respects_capabilities_for_primary_actions')`
|
|
|
|
Required Browser smoke:
|
|
|
|
- `tests/Browser/Spec328OperationsHubProductizationSmokeTest.php`
|
|
|
|
Browser flows:
|
|
|
|
1. Clean workspace Operations Hub.
|
|
2. Environment-filtered Operations Hub.
|
|
3. Clear filter and reload.
|
|
4. Non-empty highest-priority operation needing attention.
|
|
5. Empty/no-attention state.
|
|
6. Right operation/proof panel visible.
|
|
7. Diagnostics hidden by default.
|
|
8. Operations table/history remains secondary.
|
|
9. No platform-context tenant wording.
|
|
10. Light mode readability if supported.
|
|
|
|
## Rollout Considerations
|
|
|
|
- No feature flag expected.
|
|
- No schema rollout.
|
|
- No queue or scheduler rollout.
|
|
- No env vars.
|
|
- No new Filament asset registration expected. If implementation registers assets unexpectedly, deployment must include `cd apps/platform && php artisan filament:assets`, but the expected path is no asset change.
|
|
- Staging validation should run the targeted feature/navigation/browser lanes before production promotion.
|
|
|
|
## Risk Controls
|
|
|
|
- Use `repo-truth-map.md` as the runtime claim gate.
|
|
- Keep priority derived and feature-local.
|
|
- Keep OperationRun detail/source surfaces as owners of deep diagnostics and mutations.
|
|
- Keep progress semantics delegated to the existing progress contract.
|
|
- Keep environment filtering delegated to existing workspace hub helpers.
|
|
- Keep all raw/support information collapsed and capability-aware.
|
|
- Keep final report explicit about unavailable states and full-suite status.
|
|
|
|
## Implementation Close-Out
|
|
|
|
- Implemented a page-local decision workbench in `Operations::decisionWorkbench()` and `operations.blade.php`.
|
|
- Follow-up: replaced the custom summary-card Blade loop with a narrow native `OperationsWorkbenchStats` Filament `StatsOverviewWidget` using four `Stat::make(...)` records, descriptions, description icons, semantic colors, disabled polling, and scoped OperationRun queries.
|
|
- Preserved existing route, table, tabs, row links, scope filter, and canonical detail route.
|
|
- Added focused feature coverage and a Spec 328 browser smoke with clean, filtered, clear/reload, and empty/no-attention flows.
|
|
- Adjusted canonical operation detail shell behavior so current/remembered environment context can be displayed as context while the canonical detail return action remains workspace-oriented.
|
|
- No public backend abstraction, persisted state, migration, env var, package, queue, scheduler, storage, deployment asset, or legacy alias support was added.
|
|
- Validation passed:
|
|
- `./vendor/bin/sail artisan test tests/Feature/Monitoring tests/Feature/Operations tests/Feature/Navigation/WorkspaceHubEnvironmentFilterContractTest.php tests/Feature/Navigation/WorkspaceHubClearFilterContractTest.php --compact`
|
|
- `./vendor/bin/sail artisan test tests/Browser/Spec328OperationsHubProductizationSmokeTest.php --compact`
|
|
- `./vendor/bin/sail artisan test --filter='Operations|OperationRun|WorkspaceHub|EnvironmentFilter|ClearFilter|LegacyTenant|Spec322' --compact`
|
|
- `./vendor/bin/sail pint --dirty`
|
|
- `git diff --check`
|