## Summary - turn the tenant registry into a workspace-scoped recovery triage surface with backup posture and recovery evidence columns - preserve workspace overview backup and recovery drilldown intent by routing multi-tenant cases into filtered tenant registry slices - add the Spec 186 planning artifacts, focused regression coverage, and shared triage presentation helpers ## Testing - `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent` - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/TenantRegistryRecoveryTriageTest.php tests/Feature/Filament/WorkspaceOverviewSummaryMetricsTest.php tests/Feature/Filament/WorkspaceOverviewDrilldownContinuityTest.php tests/Feature/Filament/TenantResourceIndexIsWorkspaceScopedTest.php tests/Feature/Filament/WorkspaceOverviewAuthorizationTest.php tests/Feature/Guards/ActionSurfaceContractTest.php tests/Feature/Guards/FilamentTableStandardsGuardTest.php` ## Notes - no schema change - no new persisted recovery truth - branch includes the full Spec 186 spec, plan, research, data model, contract, quickstart, and tasks artifacts Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #217
6.4 KiB
6.4 KiB
Data Model: Tenant Registry Recovery Triage
Overview
Spec 186 adds no new persisted entity. The feature is a derived registry-view slice over existing tenant, backup-health, and recovery-evidence truth.
Existing Persisted Inputs
Tenant
- Purpose: Canonical tenant identity and lifecycle record for the workspace-scoped registry.
- Key fields:
idworkspace_idexternal_idnametenant_idenvironmentstatusdomaincreated_at
- Derived fields already used by the registry:
policies_countlast_policy_sync_at
- Relationships:
- belongs to one workspace
- has many memberships
- has many policies
- has many backup sets
- has many restore runs
TenantBackupHealthAssessment
- Purpose: Existing derived tenant backup-health truth used by dashboard and workspace overview.
- Persistence: Not persisted.
- Key fields:
tenantIdposture=absent | stale | degraded | healthyprimaryReason=no_backup_basis | latest_backup_stale | latest_backup_degraded | schedule_follow_up | nullheadlinesupportingMessagelatestRelevantBackupSetIdlatestRelevantCompletedAtpositiveClaimBoundaryprimaryActionTarget
- Behavioral role in Spec 186:
- provides the registry’s
Backup posturevalue - provides the backup-attention set for workspace drilldown intent
- contributes to triage rank
- provides the registry’s
Dashboard Recovery Evidence Payload
- Purpose: Existing derived tenant recovery-evidence truth built from restore history.
- Persistence: Not persisted.
- Key fields:
backup_postureoverview_state=unvalidated | weakened | no_recent_issues_visibleheadlinesummaryclaim_boundarylatest_relevant_restore_run_idlatest_relevant_attention_statereason=no_history | failed | partial | completed_with_follow_up | no_recent_issues_visible
- Behavioral role in Spec 186:
- provides the registry’s
Recovery evidencevalue - provides the recovery-attention set for workspace drilldown intent
- contributes to triage rank
- provides the registry’s
New Derived Read Models
TenantRegistryTriageRow
- Purpose: Request-scoped row projection for the tenant registry.
- Persistence: Not persisted.
- Fields:
tenant_idtenant_route_keytenant_nameenvironmentlifecycle_statuspolicies_countlast_policy_sync_atbackup_posturebackup_reasonrecovery_evidencerecovery_reasontriage_ranknext_action_url
- Validation rules:
backup_posturemust come directly fromTenantBackupHealthAssessment::posturerecovery_evidencemust come directly fromdashboardRecoveryEvidenceForTenants(...)[tenant]['overview_state']triage_rankmust be derived from the shared registry priority table, not hard-coded independently per column or filternext_action_urlmust resolve to an allowed destination in the current workspace and tenant scope
TenantRegistryTriageIntent
- Purpose: Query-string driven list intent for opening the registry in a prefiltered triage state.
- Persistence: Not persisted.
- Fields:
backup_posture[]optional array ofabsent | stale | degraded | healthyrecovery_evidence[]optional array ofweakened | unvalidated | no_recent_issues_visibletriage_sortoptional enumdefault | worst_first
- Validation rules:
- every
backup_posture[]entry must be one of the canonical backup posture values - every
recovery_evidence[]entry must be one of the canonical recovery-evidence values - if
backup_posture[]is present for workspace backup attention, its intended set isabsent,stale, anddegraded - if
recovery_evidence[]is present for workspace recovery attention, its intended set isweakenedandunvalidated - workspace drilldowns that need weak-first behavior must set
triage_sort=worst_firstexplicitly; manual registry filtering alone does not change the default calm-browsing sort
- every
WorkspaceAttentionDestination
- Purpose: Derived navigation target from workspace overview metrics or attention items.
- Persistence: Not persisted.
- Fields:
kind= existing workspace-drilldown contract value already used by the current widgets; unchanged by this featureurltenant_route_keyoptionalfiltersoptional exact registry intent payload
- Validation rules:
- one affected visible tenant resolves to the existing single-tenant dashboard kind and opens
/admin/t/{tenant} - more than one affected visible tenant preserves the existing multi-tenant admin-plane kind while
urlnow opens filtered/admin/tenants - any registry destination must carry exact posture filter semantics, not a vague
needs attentionlabel
- one affected visible tenant resolves to the existing single-tenant dashboard kind and opens
Relationships
- Tenant has one derived
TenantBackupHealthAssessmentin registry context. - Tenant has one derived dashboard recovery-evidence payload in registry context.
- TenantRegistryTriageRow combines one
Tenantwith one backup-health assessment and one recovery-evidence payload. - WorkspaceAttentionDestination references either one specific tenant or one registry triage intent, but never both at once.
Triage Ranking Model
Canonical rank tiers
backup_posture = absentrecovery_evidence = weakenedbackup_posture = stalerecovery_evidence = unvalidatedbackup_posture = degraded- calm rows:
backup_posture = healthyandrecovery_evidence = no_recent_issues_visible
Tie-breaker
- Rows inside the same tier are secondarily ordered by
tenant_nameascending.
Rule for dual-signal tenants
- If a tenant is weak in both domains, the highest active tier governs its
triage_rank, but both posture signals remain visible in the row.
State Transitions
There are no persisted state transitions in this feature.
Derived transition rules
- A registry row moves between triage tiers only when the underlying backup-health or recovery-evidence truth changes.
- Registry intent transitions are URL-driven:
- unfiltered registry
- backup-filtered registry
- recovery-filtered registry
- manually refined registry
- cleared back to the default registry view
Notes
- The registry continues to be the source of truth for tenant identity and lifecycle metadata in workspace context.
- The registry does not become the source of truth for full backup diagnostics, restore proof, or overall recoverability.