## Summary - collapse secondary and diagnostic operation-run sections by default to reduce page density - visually emphasize the primary next step while keeping counts readable but secondary - keep failures and other actionable detail available without dominating the default reading path ## Testing - vendor/bin/sail artisan test --compact tests/Feature/Filament/OperationRunBaselineTruthSurfaceTest.php tests/Feature/Filament/OperationRunEnterpriseDetailPageTest.php tests/Feature/Filament/EnterpriseDetailTemplateRegressionTest.php tests/Feature/Operations/TenantlessOperationRunViewerTest.php - vendor/bin/sail bin pint --dirty --format agent Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #194
183 lines
8.5 KiB
Markdown
183 lines
8.5 KiB
Markdown
# Data Model: Operation Run Detail Hierarchy, Deduplication, and Decision Guidance Hardening
|
|
|
|
## Overview
|
|
|
|
This feature does not add or change persisted domain entities. It introduces a stricter derived page model for the canonical operation-run detail surface using existing `OperationRun`, artifact-truth, operator-explanation, summary-count, and lifecycle data.
|
|
|
|
The core design task is to transform an existing run record into a decision-first presentation contract without changing:
|
|
|
|
- `OperationRun` persistence
|
|
- route identity
|
|
- RBAC semantics
|
|
- status and outcome lifecycle ownership
|
|
- type-specific payload availability
|
|
|
|
## Existing Persistent Entity
|
|
|
|
### OperationRun
|
|
|
|
- Purpose: Canonical workspace-owned execution record for operational work tracked in Monitoring.
|
|
- Persistent fields used by this feature:
|
|
- `id`
|
|
- `workspace_id`
|
|
- `tenant_id`
|
|
- `type`
|
|
- `status`
|
|
- `outcome`
|
|
- `initiator_name`
|
|
- `summary_counts`
|
|
- `failure_summary`
|
|
- `context`
|
|
- `created_at`
|
|
- `started_at`
|
|
- `completed_at`
|
|
- Existing relationships used by this feature:
|
|
- `workspace`
|
|
- `tenant`
|
|
- `user`
|
|
|
|
## Derived View Models
|
|
|
|
### 1. RunDetailPageModel
|
|
|
|
Top-level page payload consumed by the enterprise-detail layout and viewer wrapper.
|
|
|
|
| Field | Type | Source | Notes |
|
|
|---|---|---|---|
|
|
| `header` | object | Existing `SummaryHeaderData` | Run identity, badges, key facts, existing page-level actions |
|
|
| `decisionZone` | object | New derived payload | First-class operator summary immediately after header |
|
|
| `supportingGroups` | list<object> | Existing supporting-card inputs regrouped | Replaces or restructures the current dense `Current state` card |
|
|
| `mainSections` | list<object> | Existing section builder output | Used for supporting detail and type-specific detail after the decision zone |
|
|
| `technicalSections` | list<object> | Existing technical-detail output | Diagnostics-last content such as context JSON |
|
|
| `attentionBanners` | list<object> | Existing viewer wrapper helpers | Context mismatch, blocked prerequisite, stale or reconciled lifecycle attention |
|
|
|
|
## 2. DecisionZoneModel
|
|
|
|
The primary operator reading block. It must answer: what happened, is the result trustworthy enough to use, and what should happen next.
|
|
|
|
| Field | Type | Source | Required | Notes |
|
|
|---|---|---|---|---|
|
|
| `executionState` | badge or labeled fact | `status` plus centralized badge rendering | Yes | Lifecycle state, not result quality |
|
|
| `outcome` | badge or labeled fact | `outcome` plus centralized badge rendering | Yes | Execution result, not artifact usability |
|
|
| `artifactTruth` | object | `ArtifactTruthPresenter::forOperationRun()` when available | Conditional | Required when the run has artifact-relevant operator meaning |
|
|
| `resultMeaning` | string | operator explanation headline or evaluation label | Conditional | Human-readable interpretation of what the result means |
|
|
| `resultTrust` | string or badge | operator explanation trust level | Conditional | Confidence or reliability meaning stays distinct from outcome |
|
|
| `primaryNextStep` | object | Derived precedence chain | Yes | Exactly one primary next step |
|
|
| `compactCounts` | object or null | `SummaryCountsNormalizer` output | Optional | Only when counts add decision value and do not duplicate diagnostics |
|
|
| `attentionNote` | string or null | lifecycle or caveat helper | Optional | Short exceptional-state caveat if needed in-zone |
|
|
|
|
### PrimaryNextStepModel
|
|
|
|
| Field | Type | Source | Notes |
|
|
|---|---|---|---|
|
|
| `text` | string | Derived from prioritized guidance sources | Canonical operator action statement |
|
|
| `source` | enum-like string | `operator_explanation`, `artifact_truth`, `ops_ux`, `blocked_reason`, `lifecycle_attention` | Debugging and testability only |
|
|
| `secondaryGuidance` | list<string> | Non-primary guidance sources | Must not render as equal-priority duplicates |
|
|
|
|
### Proposed precedence for `primaryNextStep`
|
|
|
|
1. Operator explanation next action when present
|
|
2. Artifact-truth next step when it is more specific than generic run guidance
|
|
3. Blocked-execution guidance when outcome is `blocked`
|
|
4. Lifecycle guidance when stale or reconciled state requires explicit attention
|
|
5. Generic `OperationUxPresenter::surfaceGuidance()`
|
|
6. Fallback `No action needed` only when the result is explicitly trustworthy and no follow-up is indicated
|
|
|
|
## 3. SupportingGroupModel
|
|
|
|
Semantically grouped supporting context that sits below or beside the decision zone but above diagnostics.
|
|
|
|
| Group | Purpose | Typical fields |
|
|
|---|---|---|
|
|
| `guidance` | Secondary operator context that supports the primary next step | coverage statement, contextual caveat, related follow-up links |
|
|
| `lifecycle` | Freshness, reconciliation, tenant lifecycle, and contextual caveats | freshness, lifecycle truth, reconciled at, reconciled by |
|
|
| `timing` | Operational timestamps and elapsed timing | created, started, completed, elapsed |
|
|
| `metadata` | Secondary facts that do not drive the first decision | target scope, initiator, viewer-context notes |
|
|
|
|
Rules:
|
|
|
|
- The same semantic fact must not appear in multiple supporting groups unless the representation serves a genuinely different purpose.
|
|
- Supporting groups must not restate the same primary next step as the decision zone.
|
|
- Supporting groups may explain why the primary next step exists, but not compete with it.
|
|
|
|
## 4. CountPresentationModel
|
|
|
|
| Field | Type | Purpose |
|
|
|---|---|---|
|
|
| `summaryLine` | string or null | Compact operator-facing count hint |
|
|
| `primaryFacts` | list<object> | Single main count presentation if counts materially help first-pass understanding |
|
|
| `diagnosticFacts` | list<object> | Optional deeper breakdown when the detailed count grid serves investigation |
|
|
|
|
Rules:
|
|
|
|
- `primaryFacts` and `diagnosticFacts` must not be identical renderings of the same normalized counts.
|
|
- If the detailed count grid remains in main content, the compact summary line must be materially different and lighter-weight.
|
|
- If counts are low-signal for the run, both may be omitted.
|
|
|
|
## 5. TypeSpecificDetailModel
|
|
|
|
Represents operation-type-specific content that follows the canonical decision summary.
|
|
|
|
| Operation Type | Existing section examples | Ordering rule |
|
|
|---|---|---|
|
|
| `baseline_compare` | compare facts, evidence gap details, compare evidence | After decision zone and supporting groups |
|
|
| `baseline_capture` | capture evidence | After decision zone and supporting groups |
|
|
| verification-capable runs | verification report | After decision zone and supporting groups |
|
|
| any run with failures | failures section | After decision zone and supporting groups |
|
|
| reconciled runs | lifecycle reconciliation payload | After decision zone and supporting groups |
|
|
|
|
Rules:
|
|
|
|
- Type-specific sections may deepen or explain the decision, but they must not replace the canonical summary.
|
|
- Raw JSON remains valid only as diagnostics or deep detail.
|
|
|
|
## 6. DiagnosticSectionModel
|
|
|
|
Lower-priority technical or investigative information.
|
|
|
|
| Section | Source | Default posture |
|
|
|---|---|---|
|
|
| `failures` | `failure_summary` | Visible after decision and supporting context |
|
|
| `reconciliation` | `context.reconciliation` | Visible only when relevant; diagnostic |
|
|
| `context` | redacted `context` payload | Collapsed by default |
|
|
| raw evidence payloads | baseline compare or capture payload arrays | Secondary or collapsible |
|
|
|
|
Rules:
|
|
|
|
- Diagnostic sections must remain available for support and investigation.
|
|
- Diagnostic sections must never be required to answer the primary operator questions.
|
|
|
|
## Render Ordering Contract
|
|
|
|
The surface must obey this order:
|
|
|
|
1. Attention banners that indicate exceptional context without duplicating neutral page facts
|
|
2. Header identity and route-level actions
|
|
3. Primary decision zone
|
|
4. Supporting semantic groups
|
|
5. Type-specific supporting detail
|
|
6. Diagnostic and raw context sections
|
|
|
|
## Validation Rules
|
|
|
|
- Exactly one primary next-step statement is rendered at top-level priority.
|
|
- No identical normalized count block appears more than once in the main content hierarchy.
|
|
- `Outcome`, `Artifact truth`, and `Result trust` remain independently visible when the run supplies those semantics.
|
|
- Diagnostic JSON or raw technical context cannot appear before the decision zone.
|
|
- Type-specific detail cannot render above the canonical decision zone.
|
|
|
|
## State Notes
|
|
|
|
There are no new persisted state transitions in this feature.
|
|
|
|
The relevant page-state modes that must remain representable are:
|
|
|
|
- completed and trustworthy
|
|
- completed with follow-up required
|
|
- failed
|
|
- blocked
|
|
- stale
|
|
- reconciled
|
|
- artifact unavailable or limited confidence
|
|
- type-specific diagnostic-heavy runs
|