Implements Spec 087: Legacy Runs Removal (rigorous). ### What changed - Canonicalized run history: **`operation_runs` is the only run system** for inventory sync, Entra group sync, backup schedule execution/retention/purge. - Removed legacy UI surfaces (Filament Resources / relation managers) for legacy run models. - Legacy run URLs now return **404** (no redirects), with RBAC semantics preserved (404 vs 403 as specified). - Canonicalized affected `operation_runs.type` values (dotted → underscore) via migration. - Drift + inventory references now point to canonical operation runs; includes backfills and then drops legacy FK columns. - Drops legacy run tables after cutover. - Added regression guards to prevent reintroducing legacy run tokens or “backfilling” canonical runs from legacy tables. ### Migrations - `2026_02_12_000001..000006_*` canonicalize types, add/backfill operation_run_id references, drop legacy columns, and drop legacy run tables. ### Tests Focused pack for this spec passed: - `tests/Feature/Guards/NoLegacyRunsTest.php` - `tests/Feature/Guards/NoLegacyRunBackfillTest.php` - `tests/Feature/Operations/LegacyRunRoutesNotFoundTest.php` - `tests/Feature/Monitoring/MonitoringOperationsTest.php` - `tests/Feature/Jobs/RunInventorySyncJobTest.php` ### Notes / impact - Destructive cleanup is handled via migrations (drops legacy tables) after code cutover; deploy should run migrations in the same release. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #106
3.3 KiB
Phase 1 — Data Model: Legacy Runs Removal (Spec 087)
Branch: 087-legacy-runs-removal
Date: 2026-02-12
Canonical Entity: OperationRun
Table: operation_runs
Model: App\\Models\\OperationRun
Key fields (existing):
idworkspace_id(required)tenant_id(nullable; tenant-scoped runs use this)user_id(nullable)initiator_nametype(canonical run_type)status/outcomerun_identity_hash(idempotency)summary_counts(JSON)failure_summary(JSON)context(JSON)started_at/completed_atcreated_at/updated_at
Spec impact:
typemust be standardized to the underscore identifiers listed in FR-012.
Legacy Entities (To Remove)
InventorySyncRun
Table: inventory_sync_runs
Model: App\\Models\\InventorySyncRun
Notes:
- Acts as a legacy duplicate run store.
- Has
operation_run_idbridge column (added later).
Plan: remove model + table, and rely on operation_runs.
EntraGroupSyncRun
Table: entra_group_sync_runs
Model: App\\Models\\EntraGroupSyncRun
Notes:
- Legacy duplicate run store.
- Has
operation_run_idbridge column.
Plan: remove model + table, and rely on operation_runs.
BackupScheduleRun
Table: backup_schedule_runs
Model: App\\Models\\BackupScheduleRun
Notes:
- Currently used for schedule run history + retention/purge selection.
- Has
operation_run_idbridge column.
Plan: remove model + table and replace schedule “run history” with querying operation_runs by type + context.
Drift Findings: References Must Become Canonical
Table: findings
Model: App\\Models\\Finding
Current fields (relevant):
baseline_run_id→ FK toinventory_sync_runs(nullable)current_run_id→ FK toinventory_sync_runs(nullable)
Planned fields:
baseline_operation_run_id→ FK tooperation_runs(nullable)current_operation_run_id→ FK tooperation_runs(nullable)
Backfill rule:
- If
baseline_run_idpoints to aninventory_sync_runsrow with a non-nulloperation_run_id, and thatoperation_runsrow exists, copy it. - Same for
current_run_id. - Otherwise leave null (matches spec edge-case expectations).
Inventory Items: Last Seen Run Reference Must Become Canonical
Table: inventory_items
Model: App\\Models\\InventoryItem
Current fields (relevant):
last_seen_run_id→ FK toinventory_sync_runs(nullable)last_seen_operation_run_id→ FK tooperation_runs(nullable; already exists)
Plan:
- Backfill
last_seen_operation_run_idviainventory_sync_runs.operation_run_idwhere possible. - Drop
last_seen_run_idafter code is migrated.
Backup Schedules: Run History
Table: backup_schedules
Model: App\\Models\\BackupSchedule
Planned behavior:
- Remove
runs()relationship that points tobackup_schedule_runs. - For UI/history, query
operation_runsusing:type = backup_schedule_run|backup_schedule_retention|backup_schedule_purgecontext->backup_schedule_id = {id}(and optionally scheduled time metadata)
Validation Rules (from spec)
- All new run records created by this feature must have
typein the FR-012 allow-list. - Run visibility is workspace-scoped; non-members must be deny-as-not-found (404).