185 lines
7.0 KiB
Markdown
185 lines
7.0 KiB
Markdown
# Spec 335 Repo Truth Map - Restore Run Detail / Post-Execution Proof
|
|
|
|
This file documents the repo-backed truth needed to productize the Restore Run detail/result/proof surface.
|
|
|
|
Legend:
|
|
|
|
- `repo-verified`: directly confirmed in code/migrations/tests in this repo
|
|
- `derived from existing model`: computed/derived from existing persisted fields
|
|
- `foundation-real`: persisted model exists, but linkage for this workflow may not be produced today
|
|
- `not available`: no repo-backed data exists today
|
|
- `deferred`: requires additional repo inspection before implementation
|
|
|
|
## RestoreRun Model (repo-verified)
|
|
|
|
Source:
|
|
|
|
- `apps/platform/app/Models/RestoreRun.php`
|
|
- `apps/platform/database/migrations/2025_12_10_000150_create_restore_runs_table.php`
|
|
- `apps/platform/database/migrations/2026_02_10_115908_add_operation_run_id_to_restore_runs_table.php`
|
|
|
|
Key fields:
|
|
|
|
- `managed_environment_id` (tenant/environment)
|
|
- `workspace_id` (tenant-owned isolation)
|
|
- `backup_set_id`
|
|
- `requested_by` (nullable)
|
|
- `is_dry_run` (boolean; "preview-only")
|
|
- `status` (string, see `RestoreRunStatus`)
|
|
- `requested_items` (json array of backup item ids; nullable)
|
|
- `preview` (json; nullable)
|
|
- `results` (json; nullable)
|
|
- `metadata` (json; nullable)
|
|
- `failure_reason` (nullable)
|
|
- `started_at` / `completed_at` (nullable)
|
|
- `operation_run_id` (nullable; FK to `operation_runs`)
|
|
|
|
Relationships (repo-verified):
|
|
|
|
- `$restoreRun->tenant()` -> `ManagedEnvironment` via `managed_environment_id`
|
|
- `$restoreRun->backupSet()` -> `BackupSet` via `backup_set_id` (withTrashed)
|
|
- `$restoreRun->operationRun()` -> `OperationRun` via `operation_run_id`
|
|
|
|
## RestoreRun Statuses (repo-verified)
|
|
|
|
Source:
|
|
|
|
- `apps/platform/app/Support/RestoreRunStatus.php`
|
|
|
|
Values:
|
|
|
|
- pre-execution/draft: `draft`, `scoped`, `checked`, `previewed`, `pending`
|
|
- execution: `queued`, `running`
|
|
- terminal: `completed`, `partial`, `failed`, `cancelled`
|
|
- legacy/compat: `aborted`, `completed_with_errors`
|
|
|
|
Implementation note:
|
|
|
|
- Spec 335 must map multiple persisted statuses into a smaller UI-facing decision model (derived), without inventing new persisted truth.
|
|
|
|
## Restore Results Shape (repo-verified)
|
|
|
|
Primary persistence source:
|
|
|
|
- `apps/platform/app/Services/Intune/RestoreService.php` (result assembly + `restore_runs.results` + `restore_runs.metadata`)
|
|
|
|
Persisted shape:
|
|
|
|
- `restore_runs.results` is stored as:
|
|
- `results.foundations`: list of foundation entries
|
|
- `results.items`: map keyed by `backup_item_id` (values are item outcome arrays)
|
|
|
|
Counts / summary (repo-verified):
|
|
|
|
- `restore_runs.metadata` includes (at least):
|
|
- `total`, `succeeded`, `failed`, `skipped`, `partial`, `non_applied`, `foundations_skipped`
|
|
- `scope_basis`, `check_basis`, `preview_basis` (see `RestoreRun` helpers)
|
|
- `execution_safety_snapshot` (used by result/preview surfaces)
|
|
|
|
Derived availability classification:
|
|
|
|
- Result summary counts: `derived from existing model` (from `metadata`)
|
|
- Item outcome table: `derived from existing model` (from `results.items` and related metadata)
|
|
|
|
## Restore Result Attention Contract (repo-verified)
|
|
|
|
Sources:
|
|
|
|
- `apps/platform/app/Support/RestoreSafety/RestoreSafetyResolver.php` (`resultAttentionForRun`)
|
|
- `apps/platform/app/Support/RestoreSafety/RestoreResultAttention.php`
|
|
- UI: `apps/platform/resources/views/filament/infolists/entries/restore-results.blade.php`
|
|
- Tests: `apps/platform/tests/Feature/Filament/RestoreResultAttentionSurfaceTest.php`
|
|
|
|
Contract fields (repo-verified):
|
|
|
|
- `state` in `{ not_executed, completed, partial, failed, completed_with_follow_up }`
|
|
- `summary`
|
|
- `primary_next_action`
|
|
- `primary_cause_family`
|
|
- `recovery_claim_boundary` (notably enforces "completed != recovery proven")
|
|
- `tone`
|
|
|
|
Gap vs Spec 335 UX:
|
|
|
|
- OperationRun proof state is not part of this contract today (`not available` in this contract).
|
|
- Post-run evidence state is not part of this contract today (`not available` in this contract).
|
|
|
|
## OperationRun Proof (repo-verified)
|
|
|
|
Sources:
|
|
|
|
- `apps/platform/app/Models/OperationRun.php`
|
|
- `apps/platform/app/Support/OperationRunStatus.php`
|
|
- `apps/platform/app/Support/OperationRunOutcome.php`
|
|
|
|
RestoreRun link (repo-verified):
|
|
|
|
- `restore_runs.operation_run_id` -> `operation_runs.id`
|
|
|
|
Notes:
|
|
|
|
- OperationRun "proof" is repo-real for restore runs that have `operation_run_id`.
|
|
- UI link helpers exist (repo-verified): `apps/platform/app/Support/OperationRunLinks.php` and Filament `OperationRunResource`.
|
|
|
|
## EvidenceSnapshot (post-run evidence) (foundation-real)
|
|
|
|
Sources:
|
|
|
|
- `apps/platform/app/Models/EvidenceSnapshot.php`
|
|
- `apps/platform/database/migrations/2026_03_19_000000_create_evidence_snapshots_table.php`
|
|
- Filament: `apps/platform/app/Filament/Resources/EvidenceSnapshotResource.php`
|
|
|
|
Linkage:
|
|
|
|
- Evidence snapshots can be linked to an `OperationRun` via `evidence_snapshots.operation_run_id`.
|
|
- Evidence snapshots are tenant-scoped: `(workspace_id, managed_environment_id)` and have `status` + `completeness_state`.
|
|
|
|
Evidence availability for restore runs:
|
|
|
|
- Model + viewer exist (`foundation-real`).
|
|
- Whether restore execution produces an evidence snapshot is workflow-dependent and must be verified at runtime/fixtures (`deferred`).
|
|
|
|
## Current Restore Run Detail UI (repo-verified)
|
|
|
|
Primary surface:
|
|
|
|
- Filament page: `apps/platform/app/Filament/Resources/RestoreRunResource/Pages/ViewRestoreRun.php`
|
|
- Infolist schema: `apps/platform/app/Filament/Resources/RestoreRunResource.php::infolist()`
|
|
|
|
Custom entries already in use:
|
|
|
|
- Preview entry view: `apps/platform/resources/views/filament/infolists/entries/restore-preview.blade.php`
|
|
- Results entry view: `apps/platform/resources/views/filament/infolists/entries/restore-results.blade.php`
|
|
|
|
Known gap:
|
|
|
|
- No dedicated proof/evidence aside on the detail page today (proof panel exists for Create wizard, not for View).
|
|
|
|
## Existing Tests (repo-verified)
|
|
|
|
Most relevant existing coverage:
|
|
|
|
- Result attention rendering: `apps/platform/tests/Feature/Filament/RestoreResultAttentionSurfaceTest.php`
|
|
- Restore Run UI enforcement / access semantics: `apps/platform/tests/Feature/Filament/RestoreRunUiEnforcementTest.php`
|
|
- Dashboard deep-link copy (subheading): `ViewRestoreRun::getSubheading()` covered indirectly by feature tests
|
|
|
|
Browser tests exist for Restore Create (Spec 332/333), not for Restore Run detail productization yet.
|
|
|
|
## Permissions / Capabilities (repo-verified)
|
|
|
|
RestoreRunResource access checks:
|
|
|
|
- `apps/platform/app/Filament/Resources/RestoreRunResource.php::canViewAny()` uses:
|
|
- membership + `Capabilities::TENANT_VIEW`
|
|
|
|
Detail record resolution:
|
|
|
|
- `RestoreRunResource::resolveScopedRecordOrFail()` routes through tenant-owned record resolution, preserving tenant/workspace scoping.
|
|
|
|
## Open Truth Questions (deferred)
|
|
|
|
- Do restore execution operations in current fixtures produce an `EvidenceSnapshot` linked to the restore `OperationRun`?
|
|
- If multiple evidence snapshots exist for one operation run, which one should be linked (latest active vs latest any)?
|
|
- What are the RBAC rules for viewing EvidenceSnapshot and OperationRun from the Restore Run detail surface (capability names, deny-as-not-found vs forbidden)?
|
|
|