## Summary - align tenant dashboard KPI, attention, compare, and operations truth so the page does not read calmer than the tenant's actual state - preserve tenant-safe drill-through continuity into findings, baseline compare, and canonical operations, including disabled helper states for permission-limited members - add the Spec 173 artifact set and focused regression coverage for dashboard truth alignment and drill-through behavior ## Validation - `vendor/bin/sail bin pint --dirty --format agent` - `vendor/bin/sail artisan test --compact tests/Feature/Filament/DashboardKpisWidgetTest.php tests/Feature/Filament/TenantDashboardTruthAlignmentTest.php tests/Feature/Monitoring/OperationsDashboardDrillthroughTest.php tests/Feature/Filament/NeedsAttentionWidgetTest.php tests/Feature/Filament/BaselineCompareNowWidgetTest.php tests/Feature/Filament/BaselineCompareSummaryConsistencyTest.php tests/Feature/Findings/FindingsListDefaultsTest.php tests/Feature/Findings/FindingsListFiltersTest.php tests/Feature/Findings/FindingAdminTenantParityTest.php tests/Feature/OpsUx/CanonicalViewRunLinksTest.php tests/Feature/Filament/TenantDashboardTenantScopeTest.php tests/Feature/Filament/TenantDashboardDbOnlyTest.php tests/Feature/Filament/TableStandardsBaselineTest.php tests/Feature/Filament/TableDetailVisibilityTest.php` - integrated browser smoke on the tenant dashboard, including a permission-limited member scenario Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #204
13 KiB
Phase 1 Data Model: Tenant Dashboard KPI & Attention Truth Alignment
Overview
This feature does not add a table, persisted summary entity, or new runtime domain subsystem. It aligns existing persistent tenant truth and existing derived summary contracts so the tenant dashboard's KPI, attention, compare, and recency surfaces describe the same tenant reality.
Persistent Source Truths
Tenant
Purpose: Scope boundary for every dashboard query and every destination opened from the tenant dashboard.
Key fields:
idworkspace_idexternal_id
Validation rules:
- Every dashboard summary and destination must resolve for one explicit tenant scope at a time.
- Canonical admin destinations opened from the dashboard must preserve this tenant scope through filters or navigation context.
Finding
Purpose: Source of drift, workflow, severity, and due-state truth used by tenant dashboard KPI and attention surfaces.
Key fields:
tenant_idworkspace_idfinding_typestatusseveritydue_atassignee_user_idscope_keybaseline_operation_run_idcurrent_operation_run_id
Validation rules:
- Canonical active/open semantics come from
Finding::openStatusesForQuery(). - Canonical high-severity tenant-summary semantics use
SEVERITY_HIGHplusSEVERITY_CRITICAL. - If a dashboard metric intentionally uses a narrower subset, the label and destination must say so explicitly.
Relevant state families:
newacknowledgedtriagedin_progressreopenedrisk_acceptedresolvedclosed
FindingException / Governance Validity
Purpose: Supplies expiring and lapsed accepted-risk governance truth used by tenant-level attention and calmness guards.
Key fields:
tenant_idworkspace_idfinding_idstatuscurrent_validity_statereview_due_atexpires_at
Validation rules:
- Expiring and lapsed governance must remain derived from existing validity state and timing rules.
- No dashboard-local governance state family may replace or reinterpret existing validity truth.
OperationRun
Purpose: Source of tenant activity, compare execution state, and canonical operation detail navigation.
Key fields:
idtenant_idworkspace_idtypestatusoutcomecreated_atstarted_atcompleted_atcontext
Validation rules:
- Canonical active operations semantics come from
OperationRun::scopeActive()and the Operations pageactivetab. - Dashboard activity signals must remain distinct from governance posture signals.
- Attention-worthy operations follow-up is narrower than generic activity and is limited to failed, warning, or unusually long-running or stalled tenant runs that require operator review.
Existing Runtime Source Objects
BaselineCompareStats
Purpose: Existing compare- and governance-aware source object that already owns overdue, expiring, lapsed, and high-severity active findings counts alongside compare posture inputs.
Key consumed fields:
profileNamestateoperationRunIdlastComparedHumanfindingsCountoverdueOpenFindingsCountexpiringGovernanceCountlapsedGovernanceCountactiveNonNewFindingsCounthighSeverityActiveFindingsCount
Validation rules:
- Existing compare and governance counts remain the source of truth for compare-backed dashboard calmness guards.
- The feature must not create a second competing count path for the same compare-backed summary family.
BaselineCompareSummaryAssessment
Purpose: Existing summary contract that maps compare stats into posture family, tone, headline, supporting message, and next-action intent.
Key consumed fields:
stateFamilytoneheadlinesupportingMessagereasonCodepositiveClaimAllowednextActionLabel()nextActionTarget()
Validation rules:
- Dashboard compare calmness must remain sourced from this assessment path.
- If the dashboard suppresses additional calm claims beyond compare posture, it must do so by consuming existing tenant attention truth, not by inventing a new tone system.
TenantGovernanceAggregate
Purpose: Existing derived tenant-scoped summary contract that already combines compare posture and governance-related counts for tenant dashboard consumers.
Key consumed fields:
headlineprofileNamelastComparedLabelcompareStatesummaryAssessmentoverdueOpenFindingsCountexpiringGovernanceCountlapsedGovernanceCounthighSeverityActiveFindingsCountnextActionLabelnextActionTargetstats
Validation rules:
- The feature should extend or reuse this existing contract rather than creating a new dashboard-only aggregate.
- Widgets using this aggregate must not re-query the same owned summary fields locally.
Derived Dashboard View Contracts
Dashboard KPI Metric
Purpose: Compact tenant dashboard stat that names one count universe and one matching destination.
Fields
| Field | Type | Required | Description |
|---|---|---|---|
key |
string | yes | Stable metric identity such as new_drift, high_severity_active, or active_operations |
label |
string | yes | Operator-facing label that must match the actual count universe |
count |
integer | yes | Metric value |
problemFamily |
enum | yes | Shared dashboard problem family limited to findings or operations for the KPI strip in this slice |
findingUniverse |
enum nullable | no | new_drift_only, open_drift, or active_findings when applicable |
severityUniverse |
enum nullable | no | high_only or high_and_critical when applicable |
destination |
object | yes | Shared destination contract carrying kind, tenant-scoping, semantics label, any filter state needed to reproduce the same subset, and disabled/helper-text state when a visible affordance is intentionally non-clickable |
Validation rules
- The metric label must accurately reflect
findingUniverseandseverityUniversewhen either is present. - The destination must reproduce the same subset or explicitly broaden it with visible framing.
- The metric
problemFamilymust use the same shared family naming used byAttentionItemand the internal OpenAPI contract. - If a KPI remains visible for an in-scope member who lacks destination capability, the shared
destinationcontract must carry the disabled state and helper text instead of implying a clickable drill-through. - In this slice, KPI destinations are limited to
tenant_findingsorcanonical_operations, withnonereserved only for intentionally passive reassurance states. - A canonical operations destination must carry tenant filter state from the dashboard context.
Needs Attention Item
Purpose: One dashboard attention row that describes a tenant-level problem and tells the operator where to go next.
Fields
| Field | Type | Required | Description |
|---|---|---|---|
key |
string | yes | Stable attention identity such as overdue_findings, lapsed_governance, or baseline_compare_posture |
title |
string | yes | Operator-facing problem name |
body |
string | yes | Short explanation of the risk or follow-up need |
supportingMessage |
string nullable | no | Secondary explanatory text when the item needs more context without changing its primary destination |
badge |
string | yes | Existing summary family label such as Findings, Governance, Baseline, or Operations |
tone |
string | yes | Existing tone family used by the shared contract |
problemFamily |
enum | yes | findings, governance, compare, or operations |
actionLabel |
string nullable | no | Primary follow-up verb for this item |
actionDisabled |
boolean nullable | no | Whether the visible follow-up state is intentionally non-clickable for an in-scope member lacking destination capability |
helperText |
string nullable | no | Helper text explaining why the visible follow-up state is disabled or non-clickable |
nextStepLabel |
string nullable | no | Secondary text when the compare assessment already defines the next step |
destination |
object | yes | Shared destination contract carrying the target surface semantics, including disabled/helper-text state when the visible follow-up is intentionally non-clickable |
Validation rules
- Central attention items must be actionable:
destinationmust be present, and the item must expose eitheractionLabel,nextStepLabel, or a disabled explanatory state for an in-scope member who lacks the downstream capability. - If the visible follow-up is disabled,
actionDisabledmust betrueandhelperTextmust be populated. - Central attention item destinations are limited to
tenant_findings,baseline_compare_landing, orcanonical_operationsin this slice. - Each item may expose one primary destination only.
- Items derived from
TenantGovernanceAggregatemust reuse its count and posture fields rather than recompute them.
Findings Destination Filter State
Purpose: Structured state needed to make a dashboard findings drill-through semantically recoverable on the tenant findings list.
Fields
| Field | Type | Required | Description |
|---|---|---|---|
tenant |
tenant route key | yes | Tenant route scope |
tab |
enum nullable | no | needs_action, overdue, risk_accepted, resolved, or all |
status |
string nullable | no | Explicit status filter when a narrower subset is intended |
high_severity |
boolean nullable | no | Whether the destination must enable the high-severity quick filter |
finding_type |
string nullable | no | drift when the dashboard metric is drift-only |
Validation rules
- A dashboard findings link must use at least one of
tab,status,high_severity, orfinding_typewhen the originating KPI or attention item names a subset narrower than the default list. high_severity=truemust align with the findings list's existingHIGH + CRITICALfilter semantics.
Operations Destination Filter State
Purpose: Structured state needed to keep /admin/operations tenant-safe and semantically continuous when opened from the tenant dashboard.
Fields
| Field | Type | Required | Description |
|---|---|---|---|
workspace_id |
integer | yes | Existing workspace context |
tenant_id |
integer or tenant route key | yes | Active tenant filter for canonical admin operations |
activeTab |
enum nullable | no | active, failed, blocked, succeeded, partial, or all; blocked reproduces warning, stalled, or unusually long-running follow-up and failed reproduces terminal failure follow-up |
navigationContext |
string nullable | no | Optional serialized canonical back-link context carried through the canonical operations destination |
Validation rules
- Dashboard operations links must preserve tenant filter state.
- Operations activity KPIs should use the
activeTab=activesemantics when the metric names active work. - Operations follow-up links must use
failedfor terminal failure follow-up andblockedfor warning, stalled, or unusually long-running follow-up so dashboard semantics stay recoverable on/admin/operations.
Relationships
- One
Tenantowns manyFindingrows and manyOperationRunrows. - One
Findingmay have zero or one current effectiveFindingExceptiongovernance state relevant to this slice. - One
TenantGovernanceAggregatesummarizes one tenant using oneBaselineCompareStatsinstance and oneBaselineCompareSummaryAssessmentinstance. DashboardKpis,NeedsAttention, andBaselineCompareNowconsume overlapping derived truth and must remain semantically aligned.RecentDriftFindingsandRecentOperationsconsume the same tenant scope but are diagnostic-only consumers, not posture owners.
Lifecycle Notes
- Tenant dashboard loads for one current tenant.
- Aggregate-backed summary surfaces resolve the current tenant's compare and governance truth.
- KPI and attention surfaces expose destinations whose filter state must preserve the originating problem family.
- Recency surfaces expose recent records for context only.
- Canonical operations and tenant findings destinations resolve within the same tenant scope and remain subject to existing server-side authorization.
Migration Notes
- No schema migration is required.
- No new persisted artifact is required.
- If implementation needs a new helper, it should stay local to existing
OperationRunLinks, findings list filter handling, or the existing aggregate path rather than introducing a new dashboard framework.