# Data Model: Dashboard Recovery Posture Honesty ## Existing Evidence Models ### TenantBackupHealthAssessment Existing derived tenant-level backup-input assessment from `TenantBackupHealthResolver`. | Field | Type | Meaning | |------|------|---------| | `tenantId` | integer | Tenant scope for the assessment | | `posture` | string | `absent`, `stale`, `degraded`, or `healthy` backup-input posture | | `primaryReason` | string nullable | Why the current backup-input posture is not calmly healthy | | `headline` | string | Operator-facing headline for the backup-input truth | | `supportingMessage` | string nullable | Supporting backup-health explanation | | `healthyClaimAllowed` | boolean | Whether the surface may speak positively about backup-input health | | `primaryActionTarget` | action target nullable | Canonical backup drillthrough | | `positiveClaimBoundary` | string | Canonical statement that backup health reflects backup inputs only and does not prove restore success | ### RestoreRun Existing tenant-owned operational record of restore activity. | Field | Type | Meaning | |------|------|---------| | `id` | integer | Restore-run identity | | `tenant_id` | integer | Tenant scope | | `backup_set_id` | integer nullable | Backup set used for the run | | `status` | string | Restore lifecycle status | | `is_dry_run` | boolean | Whether the record is preview-only | | `results` | array/json | Item-, foundation-, and assignment-level execution outcomes | | `metadata` | array/json | Additional execution and preview metadata, including `non_applied` and scope basis | | `completed_at` | datetime nullable | Terminal completion timestamp | | `operationRun` | relation nullable | Linked `OperationRun` for umbrella execution outcome | ### RestoreResultAttention Existing per-run derived truth from `RestoreSafetyResolver::resultAttentionForRun(...)`. | State | Follow-up required | Meaning | |------|--------------------|---------| | `not_executed` | no | Preview-only or not-yet-executed record; proves preview truth only | | `failed` | yes | Execution failed; no recovery claim can be made | | `partial` | yes | Execution reached terminal state but some items or assignments failed or only partially applied | | `completed_with_follow_up` | yes | Execution completed, but skipped or non-applied work still weakens confidence | | `completed` | no | No visible follow-up remains, but tenant-wide recovery is still not proven | Relevant fields carried by the value object: | Field | Type | Meaning | |------|------|---------| | `state` | string | One of the five result-attention states above | | `summary` | string | Operator-facing explanation of the outcome | | `followUpRequired` | boolean | Whether the result weakens confidence or needs action | | `primaryNextAction` | string | Recommended next action for the run | | `recoveryClaimBoundary` | string | Canonical claim-boundary identifier for the run outcome | | `tone` | string | Summary tone for UI presentation | ## Derived Surface Projection ### Recovery Evidence Summary This spec does **not** add a new persisted entity. It adds a derived tenant-level dashboard projection that combines existing backup health and restore evidence at render time. | Field | Type | Persisted | Meaning | |------|------|-----------|---------| | `tenantId` | integer | no | Tenant scope | | `backupPosture` | string | no | Current `TenantBackupHealthAssessment.posture` | | `relevantRestoreHistoryPresent` | boolean | no | Whether the tenant has any executed, non-preview restore history | | `latestRelevantRestoreRunId` | integer nullable | no | The most recent executed restore run relevant to overview continuity | | `latestRelevantAttentionState` | string nullable | no | Result-attention state for the latest relevant run | | `overviewState` | string | no | Canonical state key: `unvalidated`, `weakened`, or `no_recent_issues_visible` | | `headline` | string | no | Operator-facing dashboard headline for the recovery-evidence condition | | `summary` | string | no | Supporting summary text for the state | | `claimBoundary` | string | no | Text that prevents the summary from becoming a proof claim | | `action` | object nullable | no | Nested action payload with `label`, `url`, `disabled`, and `helperText`, matching the contract `ActionLink` shape | ### Overview State Rules | Overview state | Entry rule | Required surface effect | |------|------------|-------------------------| | `unvalidated` | No executed, non-preview restore history exists for the tenant | Dashboard must show that recovery confidence is unvalidated and provide a next action into restore history | | `weakened` | Latest relevant restore history resolves to `failed`, `partial`, or `completed_with_follow_up` | Needs Attention must surface the weakened condition and link to the exact run or canonical restore-run list fallback | | `no_recent_issues_visible` | Relevant restore history exists and the latest relevant attention is `completed` | The dashboard may say no recent restore issues are visible, but must preserve the non-proof boundary | Operator-facing copy may say that recovery evidence is not yet known, but the canonical derived state remains `unvalidated`. ### Non-qualifying restore records The following records do **not** count as relevant restore history for overview confidence: - `is_dry_run = true` - `status in [draft, scoped, checked, previewed]` - Any record whose `RestoreResultAttention.state` is `not_executed` ## Relationships | Source | Relationship | Target | Use in this spec | |------|--------------|--------|------------------| | Tenant | has many | BackupSet | Existing backup-input truth via `TenantBackupHealthResolver` | | Tenant | has many | RestoreRun | Existing restore-history truth used for overview evidence | | RestoreRun | belongs to | BackupSet | Supports drillthrough context | | RestoreRun | optionally belongs to | OperationRun | Contributes operation outcome to `RestoreResultAttention` | ## Derived Continuity Context The canonical restore-run list receives a **non-persisted page context** from the dashboard for fallback continuity. | Field | Type | Meaning | |------|------|---------| | `recovery_posture_reason` | query string | Why the user arrived on the restore-run list from the dashboard | Suggested reason values: - `no_history` - `failed` - `partial` - `completed_with_follow_up` - `no_recent_issues_visible` These are list-continuity reasons only. They are not new persisted domain states.