## Summary - align the system-panel Operations, Failed operations, and Stuck operations pages to the read-only registry contract by removing inline row triage and keeping row-click inspection - keep retry, cancel, and mark-investigated behavior on the canonical system operation detail page while adding the explicit `Show all operations` return path and updated `Operations / Operation` copy - add and update focused Pest and Livewire coverage for list CTA behavior, detail-owned triage, and view-only versus manage-capable platform access - add Spec 170 implementation artifacts plus the follow-on Spec 171 and Spec 172 packages ## Testing - `vendor/bin/sail artisan test --compact tests/Feature/System/Spec114/OpsTriageActionsTest.php` - `vendor/bin/sail artisan test --compact tests/Feature/Guards/ActionSurfaceContractTest.php` - `vendor/bin/sail artisan test --compact tests/Feature/System/Spec114/OpsFailuresViewTest.php` - `vendor/bin/sail artisan test --compact tests/Feature/System/Spec114/OpsStuckViewTest.php` - integrated browser smoke on `/system/ops/runs`, `/system/ops/failures`, `/system/ops/stuck`, empty states via search filter, and detail-page retry confirmation visibility ## Notes - branch pushed from `170-system-operations-surface-alignment` - latest commit: `64b4d741 feat: align system operations surfaces` Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #201
5.2 KiB
5.2 KiB
Data Model: System Operations Surface Alignment
Overview
This feature introduces no new persisted entity, no new table, and no new status family. It reuses existing OperationRun truth and existing platform capability checks, while narrowing where triage actions are exposed in the UI.
Entity: OperationRun
- Type: Existing persisted model
- Purpose in this feature: Canonical record shown on the three system list pages and on the system run detail page.
Relevant Fields
| Field | Type | Notes |
|---|---|---|
id |
integer | Displayed as Operation #<id> and used in canonical detail routing. |
workspace_id |
integer | Required for platform-wide run context. |
tenant_id |
integer nullable | Nullable for tenantless/platform runs; still shown on system lists and detail. |
initiator_name |
string nullable | Default-visible operator truth on the all-runs list. |
type |
string | Rendered through OperationCatalog::label(...). |
status |
string | Badge-rendered lifecycle dimension. |
outcome |
string | Badge-rendered execution-outcome dimension. |
context |
array/json | Stores triage metadata such as retry, cancel, and investigation context. |
created_at |
timestamp | Used for default-visible list activity time and recency on all three lists. |
started_at |
timestamp nullable | Supports stuck classification and detail timing. |
completed_at |
timestamp nullable | Preserved for completed/failed runs and detail history. |
Relationships
| Relationship | Target | Purpose |
|---|---|---|
workspace |
Workspace |
Default-visible context on all system lists and on the detail page. |
tenant |
Tenant |
Default-visible context on all system lists and on the detail page. |
Feature-Specific Invariants
- All three system lists eager-load
tenantandworkspace. Runsshows the full platform-wide run set.Failuresfilters tostatus=completedandoutcome=failed.Stuckfilters throughStuckRunClassifierand exposes a derivedstuck_classlabel.- List inspection always resolves to
SystemOperationRunLinks::view($run).
State Transitions Used By This Feature
| Transition | Preconditions | Result |
|---|---|---|
| Inspect list row | Operator has platform.operations.view |
No state change; opens canonical detail page. |
| Retry run | Run is completed, failed, and retryable | Creates a new queued OperationRun with context.triage.retry_of_run_id and audit action platform.system_console.retry. |
| Cancel run | Run is queued or running and cancelable | Updates the current run to completed/failed through OperationRunService and logs platform.system_console.cancel. |
| Mark investigated | Operator has manage capability and supplies a valid reason | Updates context.triage.investigated on the current run and logs platform.system_console.mark_investigated. |
Entity: PlatformUser Capability Gate
- Type: Existing persisted/authenticated actor model
- Purpose in this feature: Separates inspection access from triage access on system-panel surfaces.
Relevant Capability Fields
| Capability | Purpose |
|---|---|
platform.access_system_panel |
Required to enter the system panel. |
platform.operations.view |
Required to access the system runs/failures/stuck/detail surfaces. |
platform.operations.manage |
Required to see and execute triage actions on the detail page. |
Feature-Specific Invariants
- View-only users can load list and detail pages but cannot see triage actions.
- Manage-capable users retain retry/cancel/mark-investigated on the detail header.
- No new capability is introduced.
Derived UI Contract: System Operations Lists
- Type: Derived UI surface, not persisted
- Routes:
/system/ops/runs/system/ops/failures/system/ops/stuck
- Surface Type:
ReadOnlyRegistryReport - Primary Question: Which operation should I open next?
Contract Rules
- Primary inspect affordance is full-row click only.
- Row actions are empty.
- Bulk actions are empty.
- Visible collection naming uses
Operationsand visible singular naming usesOperation. /system/ops/runsusesGo to runbooksas its single header and empty-state CTA./system/ops/failuresand/system/ops/stuckuseShow all operationsas their single header and empty-state CTA.
Derived UI Contract: System Run Detail
- Type: Derived UI surface, not persisted
- Route:
/system/ops/runs/{run} - Surface Type: Detail-first operational surface
- Primary Question: What happened on this operation, and what follow-up is appropriate?
Contract Rules
- Header actions remain the only triage location for retry, cancel, and mark investigated.
- The detail surface exposes
Show all operationsas the canonical return path and keepsGo to runbooksavailable as secondary navigation. cancelremains destructive and confirmation-gated.mark investigatedretains thereasonvalidation rule: required, minimum 5 characters, maximum 500 characters.- No new page, modal surface, or alternate triage route is introduced.
Persistence Impact
- Schema changes: None
- Data migration: None
- New indexes: None
- Retention impact: None