## Summary - harden the workspace overview into a governance-aware attention surface that separates governance risk from activity and keeps calm states honest - add tenant-bound attention, workspace-wide operations continuity, and low-permission fallback behavior for workspace-originated operations drill-through - add the full Spec 175 artifact set and focused workspace overview regression coverage, plus align remaining operation-viewer wording and guard expectations so the suite stays green ## Testing - `vendor/bin/sail artisan test --compact tests/Feature/Filament/WorkspaceOverviewAccessTest.php tests/Feature/Filament/WorkspaceOverviewAuthorizationTest.php tests/Feature/Filament/WorkspaceOverviewLandingTest.php tests/Feature/Filament/WorkspaceOverviewNavigationTest.php tests/Feature/Filament/WorkspaceOverviewContentTest.php tests/Feature/Filament/WorkspaceOverviewEmptyStatesTest.php tests/Feature/Filament/WorkspaceOverviewPermissionVisibilityTest.php tests/Feature/Filament/WorkspaceOverviewOperationsTest.php tests/Feature/Filament/WorkspaceOverviewDbOnlyTest.php tests/Feature/Filament/WorkspaceOverviewGovernanceAttentionTest.php tests/Feature/Filament/WorkspaceOverviewSummaryMetricsTest.php tests/Feature/Filament/WorkspaceOverviewDrilldownContinuityTest.php` - `vendor/bin/sail artisan test --compact tests/Unit/Support/RelatedActionLabelCatalogTest.php tests/Feature/078/VerificationReportTenantlessTest.php tests/Feature/144/CanonicalOperationViewerContextMismatchTest.php tests/Feature/Baselines/BaselineCompareSummaryAssessmentTest.php tests/Feature/Baselines/TenantGovernanceAggregateResolverTest.php tests/Feature/Filament/ReferencedTenantLifecyclePresentationTest.php tests/Feature/Guards/NoAdHocFilamentAuthPatternsTest.php tests/Feature/Monitoring/AuditLogInspectFlowTest.php tests/Feature/Monitoring/HeaderContextBarTest.php tests/Feature/Monitoring/OperationLifecycleFreshnessPresentationTest.php tests/Feature/Monitoring/OperationRunResolvedReferencePresentationTest.php tests/Feature/Notifications/OperationRunNotificationTest.php tests/Feature/OpsUx/QueuedToastCopyTest.php tests/Feature/OpsUx/TerminalNotificationFailureMessageTest.php tests/Feature/System/OpsRunbooks/OpsUxStartSurfaceContractTest.php tests/Feature/Verification/VerificationReportRedactionTest.php` - `vendor/bin/sail bin pint --dirty --format agent` - `vendor/bin/sail artisan test --compact` ## Notes - branch pushed as `175-workspace-governance-attention` - full suite result: `3235 passed, 8 skipped` Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #206
314 lines
14 KiB
Markdown
314 lines
14 KiB
Markdown
# Phase 1 Data Model: Workspace Governance Attention Foundation
|
|
|
|
## Overview
|
|
|
|
This feature does not add a table, persisted workspace summary, or new cross-domain runtime subsystem. It aligns the existing workspace overview surface with already-available tenant truth so the workspace home can answer which visible tenants need governance attention, why they need it, and where the operator should jump next.
|
|
|
|
## Persistent Source Truths
|
|
|
|
### Workspace
|
|
|
|
**Purpose**: Scope boundary for the workspace home and all workspace-safe aggregates.
|
|
|
|
**Key fields**:
|
|
- `id`
|
|
- `name`
|
|
- `slug`
|
|
|
|
**Validation rules**:
|
|
- Workspace overview aggregation must always resolve for one explicit workspace.
|
|
- Non-members must receive deny-as-not-found behavior before any workspace truth is rendered.
|
|
|
|
### Tenant
|
|
|
|
**Purpose**: Scope boundary and identity anchor for every governance-aware workspace attention item.
|
|
|
|
**Key fields**:
|
|
- `id`
|
|
- `workspace_id`
|
|
- `external_id`
|
|
- `name`
|
|
- `status`
|
|
|
|
**Validation rules**:
|
|
- Only active tenants inside the current workspace and inside the current user's entitled tenant slice may contribute to workspace attention or governance-risk metrics.
|
|
- Every workspace attention item must identify one visible tenant explicitly.
|
|
|
|
### Finding
|
|
|
|
**Purpose**: Source of overdue findings, high-severity active findings, and other governance workflow pressure promoted into workspace attention.
|
|
|
|
**Key fields**:
|
|
- `tenant_id`
|
|
- `workspace_id`
|
|
- `finding_type`
|
|
- `status`
|
|
- `severity`
|
|
- `due_at`
|
|
- `scope_key`
|
|
|
|
**Validation rules**:
|
|
- Canonical open and active semantics remain sourced from existing finding query helpers.
|
|
- Workspace promotion must not invent a second finding status universe.
|
|
|
|
### FindingException / Governance Validity
|
|
|
|
**Purpose**: Source of lapsed governance and expiring governance truth for risk-accepted findings.
|
|
|
|
**Key fields**:
|
|
- `tenant_id`
|
|
- `workspace_id`
|
|
- `finding_id`
|
|
- `status`
|
|
- `current_validity_state`
|
|
- `review_due_at`
|
|
- `expires_at`
|
|
|
|
**Validation rules**:
|
|
- Lapsed and expiring governance remain derived from existing validity-state rules.
|
|
- Workspace promotion must not replace existing governance-validity semantics with a new workspace-specific status family.
|
|
|
|
### OperationRun
|
|
|
|
**Purpose**: Source of workspace activity, operation failures, and canonical operation drill-through.
|
|
|
|
**Key fields**:
|
|
- `id`
|
|
- `workspace_id`
|
|
- `tenant_id`
|
|
- `type`
|
|
- `status`
|
|
- `outcome`
|
|
- `created_at`
|
|
- `completed_at`
|
|
|
|
**Validation rules**:
|
|
- Active operations and failed or warning operations remain activity truths, not governance truths.
|
|
- Workspace attention may still include operations follow-up, but those items must remain semantically distinct from governance items.
|
|
|
|
### AlertDelivery
|
|
|
|
**Purpose**: Source of workspace alert-delivery failures that remain supporting attention but no longer define workspace calmness by themselves.
|
|
|
|
**Key fields**:
|
|
- `workspace_id`
|
|
- `tenant_id`
|
|
- `status`
|
|
- `created_at`
|
|
|
|
**Validation rules**:
|
|
- Alert-delivery failures remain lower-priority supporting signals once governance-critical tenant states exist.
|
|
|
|
### EvidenceSnapshot and TenantReview
|
|
|
|
**Purpose**: Existing tenant-level evidence and review truth that may serve as a precise workspace drill-through target when already-available truth makes them the best next jump.
|
|
|
|
**Key fields**:
|
|
- `tenant_id`
|
|
- `workspace_id`
|
|
- `status` or completeness fields on the owning model
|
|
- associated detail identifiers needed by tenant evidence or review resources
|
|
|
|
**Validation rules**:
|
|
- This slice does not add a new workspace evidence or review aggregate.
|
|
- Evidence or review destinations may only be used when existing tenant truth already makes them the most precise action target.
|
|
|
|
## Existing Runtime Source Objects
|
|
|
|
### TenantGovernanceAggregate
|
|
|
|
**Purpose**: Existing derived tenant summary that already combines compare posture with overdue, expiring, lapsed, and high-severity counts.
|
|
|
|
**Key consumed fields**:
|
|
- `tenantId`
|
|
- `workspaceId`
|
|
- `compareState`
|
|
- `stateFamily`
|
|
- `tone`
|
|
- `headline`
|
|
- `supportingMessage`
|
|
- `overdueOpenFindingsCount`
|
|
- `expiringGovernanceCount`
|
|
- `lapsedGovernanceCount`
|
|
- `highSeverityActiveFindingsCount`
|
|
- `nextActionLabel`
|
|
- `nextActionTarget`
|
|
- `positiveClaimAllowed`
|
|
- `summaryAssessment`
|
|
|
|
**Validation rules**:
|
|
- Workspace promotion should consume this existing summary contract before considering lower-level recomputation.
|
|
- Any workspace calmness or ranking rule based on compare or governance must remain consistent with this aggregate.
|
|
|
|
### BaselineCompareStats
|
|
|
|
**Purpose**: Existing compare-backed statistics object underlying the tenant governance aggregate.
|
|
|
|
**Key consumed fields**:
|
|
- `overdueOpenFindingsCount`
|
|
- `expiringGovernanceCount`
|
|
- `lapsedGovernanceCount`
|
|
- `highSeverityActiveFindingsCount`
|
|
- compare posture state and evidence-gap fields needed by `summaryAssessment`
|
|
|
|
**Validation rules**:
|
|
- Workspace code should not fork a second compare-summary model while this object already provides the necessary facts.
|
|
|
|
### BaselineCompareSummaryAssessment
|
|
|
|
**Purpose**: Existing compare posture contract that maps compare stats into a state family, tone, headline, and next-action intent.
|
|
|
|
**Key consumed fields**:
|
|
- `stateFamily`
|
|
- `tone`
|
|
- `headline`
|
|
- `supportingMessage`
|
|
- `reasonCode`
|
|
- `nextActionTarget()` semantics as reflected into the aggregate
|
|
|
|
**Validation rules**:
|
|
- Workspace compare attention and calmness suppression should reuse this assessment path rather than inventing a workspace-only tone system.
|
|
|
|
### WorkspaceOverviewBuilder Payload
|
|
|
|
**Purpose**: Existing page-level payload that already carries summary metrics, attention items, recent operations, quick actions, and empty states for `/admin`.
|
|
|
|
**Validation rules**:
|
|
- Governance hardening extends this payload shape rather than replacing the page with a new surface framework.
|
|
- Existing visible-tenant filtering remains the workspace aggregation guardrail.
|
|
|
|
## Derived Workspace View Contracts
|
|
|
|
### Workspace Summary Metric
|
|
|
|
**Purpose**: Compact workspace stat that answers one scope, governance-risk, or activity question and optionally opens one matching destination.
|
|
|
|
#### Fields
|
|
|
|
| Field | Type | Required | Description |
|
|
|------|------|----------|-------------|
|
|
| `key` | string | yes | Stable metric identity such as `accessible_tenants`, `governance_attention_tenants`, `overdue_findings_tenants`, or `active_operations` |
|
|
| `label` | string | yes | Operator-facing label that must accurately describe the counted universe |
|
|
| `value` | integer | yes | Metric value |
|
|
| `category` | enum | yes | `scope`, `governance_risk`, `activity`, or `alerts` |
|
|
| `description` | string | yes | Short explanation of what the metric means |
|
|
| `color` | string | yes | Existing tone family used by the widget |
|
|
| `destination` | object nullable | no | Shared drill-through contract when the metric is actionable |
|
|
|
|
#### Validation rules
|
|
|
|
- Governance-risk metrics count affected visible tenants, not raw issue totals.
|
|
- Activity metrics remain activity-only and must not imply governance health.
|
|
- The stat strip must make the difference between `governance_risk` and `activity` categories obvious.
|
|
|
|
### Workspace Attention Item
|
|
|
|
**Purpose**: One prioritized workspace triage item that names a visible tenant problem and one next jump.
|
|
|
|
#### Fields
|
|
|
|
| Field | Type | Required | Description |
|
|
|------|------|----------|-------------|
|
|
| `key` | string | yes | Stable attention identity such as `tenant_overdue_findings`, `tenant_lapsed_governance`, `tenant_compare_attention`, or `tenant_failed_operation` |
|
|
| `tenantId` | integer | yes | Visible tenant identifier |
|
|
| `tenantLabel` | string | yes | Tenant name shown to the operator |
|
|
| `family` | enum | yes | `governance`, `findings`, `compare`, `evidence`, `review`, `operations`, or `alerts` |
|
|
| `urgency` | enum | yes | `critical`, `high`, `medium`, or `supporting` |
|
|
| `title` | string | yes | Primary operator-facing summary |
|
|
| `body` | string | yes | Short explanation of why this needs attention |
|
|
| `badge` | string | yes | Existing family label shown in the UI |
|
|
| `badgeColor` | string | yes | Existing tone family used for the item |
|
|
| `supportingMessage` | string nullable | no | Secondary explanatory text when needed |
|
|
| `destination` | object nullable | no | Shared drill-through contract |
|
|
| `actionDisabled` | boolean nullable | no | Whether the visible next step is intentionally disabled |
|
|
| `helperText` | string nullable | no | Explanation when the visible next step is disabled |
|
|
|
|
#### Validation rules
|
|
|
|
- Every workspace attention item is tenant-bound and must include both `tenantId` and `tenantLabel`.
|
|
- Governance, findings, compare, evidence or review, and operations items must remain semantically distinct.
|
|
- Compare attention promotes `BaselineCompareSummaryAssessment::STATE_STALE` directly and only treats `BaselineCompareSummaryAssessment::STATE_ACTION_REQUIRED` as materially degraded compare posture when the aggregate's next action remains compare-specific rather than findings-driven.
|
|
- `BaselineCompareSummaryAssessment::STATE_CAUTION` stays below the workspace-attention threshold unless another governance signal independently warrants promotion.
|
|
- Workspace-wide operations or alert totals remain in summary metrics or recent operations until they can be attributed to one visible tenant.
|
|
- Each item may expose one primary destination only.
|
|
- Every item must either expose a non-null destination or set `actionDisabled=true` with explanatory `helperText`; null destination without an explicit disabled state is invalid.
|
|
- If the most precise destination is not available to the current in-scope user, the item must either use an allowed fallback or expose a disabled explanatory state instead of a clickable dead end.
|
|
|
|
### Workspace Recent Operation
|
|
|
|
**Purpose**: One bounded recent-operations entry shown on the workspace overview as diagnostic recency, not governance posture.
|
|
|
|
#### Fields
|
|
|
|
| Field | Type | Required | Description |
|
|
|------|------|----------|-------------|
|
|
| `id` | integer | yes | Operation run identifier |
|
|
| `title` | string | yes | Operator-facing operation label |
|
|
| `tenantLabel` | string nullable | no | Tenant name when the run is tenant-bound |
|
|
| `statusLabel` | string | yes | Human-readable run status |
|
|
| `statusColor` | string | yes | Existing tone family for the run status |
|
|
| `outcomeLabel` | string | yes | Human-readable run outcome |
|
|
| `outcomeColor` | string | yes | Existing tone family for the run outcome |
|
|
| `guidance` | string nullable | no | Short follow-up guidance when helpful |
|
|
| `startedAt` | string | yes | Render-ready recency label |
|
|
| `destination` | object | yes | Canonical operation-detail drill-through target |
|
|
|
|
#### Validation rules
|
|
|
|
- The recent-operations collection is bounded to the five most recent visible runs.
|
|
- Recent operations remain diagnostic context and do not define calmness on their own.
|
|
- `tenantLabel` may be null only when the run is genuinely workspace-wide rather than tenant-bound.
|
|
|
|
### Workspace Drill-Through Target
|
|
|
|
**Purpose**: Shared navigation contract used by summary metrics and attention items.
|
|
|
|
#### Fields
|
|
|
|
| Field | Type | Required | Description |
|
|
|------|------|----------|-------------|
|
|
| `kind` | enum | yes | `choose_tenant`, `tenant_dashboard`, `tenant_findings`, `baseline_compare_landing`, `tenant_evidence`, `tenant_reviews`, `operations_index`, `operation_detail`, `alerts_overview`, `switch_workspace`, or `none` |
|
|
| `url` | string nullable | no | Destination URL when the target is actionable |
|
|
| `tenantRouteKey` | string nullable | no | Tenant route scope when the destination is tenant-bound |
|
|
| `filters` | object nullable | no | Query or state needed to reproduce the same subset on the destination |
|
|
| `label` | string nullable | no | Primary action label |
|
|
| `disabled` | boolean | yes | Whether the target is intentionally non-clickable |
|
|
| `helperText` | string nullable | no | Explanation shown when the target is disabled |
|
|
|
|
#### Validation rules
|
|
|
|
- `kind=none` may only be used for intentionally passive reassurance states.
|
|
- `tenant_findings` must carry the filter state needed to reproduce overdue, high-severity, expiring-governance, or other directly filterable findings subsets when applicable.
|
|
- Aggregate lapsed-governance attention uses `tenant_dashboard` when the current tenant findings filters would otherwise narrow the full invalid-governance family to a smaller subset such as `missing_support`.
|
|
- `operations_index` may carry tenant and tab filters but must remain the canonical admin operations route and the workspace-member-safe fallback for low-permission workspace states.
|
|
- `alerts_overview` targets the existing alerts overview at `/admin/alerts`, which remains the canonical alert-delivery follow-up surface for this slice.
|
|
- `switch_workspace` targets `/admin/choose-workspace` and is the default zero-tenant recovery action.
|
|
|
|
### Workspace Calmness State
|
|
|
|
**Purpose**: The derived claim that the workspace is currently calm enough for an empty or reassurance state.
|
|
|
|
#### Fields
|
|
|
|
| Field | Type | Required | Description |
|
|
|------|------|----------|-------------|
|
|
| `isCalm` | boolean | yes | Whether the workspace may currently make a calmness claim |
|
|
| `checkedDomains` | array<enum> | yes | Domains actually checked before the claim was made: `governance`, `findings`, `compare`, `evidence`, `review`, `operations`, `alerts`, `tenant_access` |
|
|
| `title` | string | yes | Empty-state or reassurance title |
|
|
| `body` | string | yes | Supporting explanation constrained to the checked domains |
|
|
| `nextAction` | object | yes | One bounded next action |
|
|
|
|
#### Validation rules
|
|
|
|
- `isCalm=true` is invalid whenever any visible tenant has governance-critical conditions inside the checked domains.
|
|
- Zero-tenant states and low-permission states must not masquerade as healthy calmness states.
|
|
- Zero-tenant states default `nextAction.kind` to `switch_workspace`, while low-permission states default `nextAction.kind` to `operations_index` unless a more specific allowed in-scope recovery action exists.
|
|
- Calm wording must not imply portfolio health beyond the `checkedDomains` list.
|
|
|
|
## Ranking Rules
|
|
|
|
1. Governance-critical tenant conditions outrank activity-only and alert-only items.
|
|
2. A single tenant may contribute multiple raw issues, but workspace attention should surface a bounded prioritized subset.
|
|
3. The stat strip answers portfolio counts by tenant, while the attention list answers which tenant to open next.
|
|
4. Recent operations remain supporting recency context and do not participate in calmness unless explicitly modeled as an operations-follow-up issue.
|