TenantAtlas/specs/087-legacy-runs-removal/spec.md
ahmido d6e7de597a feat(spec-087): remove legacy runs (#106)
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
2026-02-12 12:40:51 +00:00

10 KiB
Raw Blame History

Feature Specification: Legacy Runs Removal

Feature Branch: 087-legacy-runs-removal
Created: 2026-02-12
Status: Draft
Input: User description: "Spec 087 — Legacy Runs Removal (RIGOROS)"

Clarifications

Session 2026-02-12

  • Q: Should we backfill legacy run history into the canonical run system before dropping legacy tables? → A: No backfill (accept losing pre-existing legacy run history)
  • Q: Should backup schedule retention/purge produce canonical run records? → A: Yes — retention and purge each produce their own canonical runs
  • Q: Which canonical run_type contract should be enforced? → A: Use the explicit list: inventory_sync, drift_generate_findings, entra_group_sync, backup_schedule_run, backup_schedule_retention, backup_schedule_purge
  • Q: For canonical run URLs, should access be 404 for non-members and 403 for members missing capability? → A: Yes — non-member/not entitled → 404; member missing capability → 403
  • Q: How broad should the “NoLegacyRuns” architecture guard scan be? → A: Scan app/, database/, resources/, and routes/ (exclude specs/ and references/)

Redirect Scope

This specs “no redirects” requirement applies to legacy run pages and legacy run UI surfaces.

The existing convenience route that redirects the tenant-scoped operations index to the canonical operations index (for example: /admin/t/{tenant}/operations/admin/operations) is not considered a legacy run page.

User Scenarios & Testing (mandatory)

User Story 1 - Single canonical run history (Priority: P1)

As a workspace member, I can see and open run history for inventory sync, Entra group sync, and backup schedules in a single, consistent place, without having to navigate multiple legacy run screens.

Why this priority: Removes duplicated tracking and inconsistent UX, and reduces confusion about which “run” is authoritative.

Independent Test: Trigger each run type once and verify it appears in the canonical Operations run list and can be opened via the canonical run detail view.

Acceptance Scenarios:

  1. Given a workspace member with permission to view operations, When a new inventory sync run starts and finishes, Then a corresponding canonical run exists and is viewable via the canonical Operations UI.
  2. Given a workspace member with permission to view operations, When a new Entra group sync run starts and finishes, Then a corresponding canonical run exists and is viewable via the canonical Operations UI.
  3. Given a workspace member with permission to view operations, When a backup schedule run starts and finishes, Then a corresponding canonical run exists and is viewable via the canonical Operations UI.

User Story 2 - Legacy run UI is intentionally gone (Priority: P1)

As a workspace member, I cannot access legacy run pages anymore. Old links intentionally fail, so there is no ambiguity about where runs are viewed.

Why this priority: Prevents “run sprawl” and ensures there is exactly one canonical run UI.

Independent Test: Attempt to access any known legacy run route and verify it is not available.

Acceptance Scenarios:

  1. Given a user (any role), When they attempt to access a legacy run URL, Then the application responds as not found.
  2. Given the application navigation, When a user browses the admin UI, Then no legacy run resources appear in navigation.

User Story 3 - Drift references canonical runs (Priority: P1)

As a workspace member using drift-related features, I see baseline/current references tied to canonical runs, and drift logic does not depend on a legacy run store.

Why this priority: Drift currently has structural coupling to a legacy run concept; removing it reduces risk and complexity.

Independent Test: Create drift findings that reference baseline/current runs and confirm the references use canonical runs (or are empty if historical data cannot be mapped).

Acceptance Scenarios:

  1. Given drift findings created after this feature ships, When a user views baseline/current references, Then the references point to canonical runs.
  2. Given historical drift findings where no safe mapping exists, When a user views baseline/current references, Then the UI remains functional and references are empty rather than erroring.

Edge Cases

  • Historical runs exist with details that were only stored in legacy run records, and this history will not be backfilled into canonical runs.
  • A user is a non-member of the workspace and attempts to view a run.
  • A user is a workspace member but lacks the capability to view operations.
  • A scheduled backup run is skipped/cancelled and still needs a canonical run record with a clear final outcome.
  • Retention/purge runs remove old data; the user expects runs to remain auditable and consistent.

Requirements (mandatory)

Constitution alignment (required): This feature changes long-running work and run tracking. It MUST ensure run observability via the canonical run system, consistent identity, and workspace-scoped visibility.

Constitution alignment (RBAC-UX): This feature changes run visibility and removes legacy pages. It MUST explicitly define not-found vs forbidden behavior and enforce authorization server-side.

Constitution alignment (BADGE-001): Any run status-like badges MUST be derived from canonical run status/outcome to keep semantics centralized.

Constitution alignment (Filament Action Surfaces): This feature removes legacy run resources and updates run links to point to the canonical operations views.

Functional Requirements

  • FR-001: The system MUST treat the canonical run system as the single source of truth for all run tracking and display.
  • FR-002: The system MUST NOT create or update legacy run records for inventory sync, Entra group sync, or backup schedule runs.
  • FR-003: The system MUST remove all legacy run UI surfaces (resources/pages/relation managers/badges) so that runs are only accessible from the canonical Operations UI.
  • FR-004: Requests to legacy run pages MUST behave as not found (no redirects).
  • FR-005: Drift-related entities MUST reference canonical runs for baseline/current/last-seen run linkage.
  • FR-006: Backup schedule retention/purge workflows MUST operate without relying on legacy run stores.
  • FR-007: Entra group sync run history and links MUST reference canonical runs only.
  • FR-008: The system MUST enforce workspace-first access rules for canonical run list and detail views:
    • non-member or not entitled to the workspace scope → not found (404)
    • member but missing capability → forbidden (403)
  • FR-009: Automated architecture checks MUST prevent reintroduction of legacy run concepts by failing CI if legacy tokens are found anywhere in: app/, database/, resources/, routes/.
  • FR-010: The system MUST NOT backfill historical legacy run records into the canonical run system; only new runs are guaranteed to be represented as canonical runs.
  • FR-011: Backup schedule retention and purge executions MUST each create their own canonical run records, observable in the canonical Operations UI.
  • FR-012: The system MUST standardize and enforce the canonical run_type identifiers for runs created by this feature:
    • inventory_sync
    • drift_generate_findings
    • entra_group_sync
    • backup_schedule_run
    • backup_schedule_retention
    • backup_schedule_purge

UI Action Matrix (mandatory when Filament is changed)

Surface Location Header Actions Inspect Affordance (List/Table) Row Actions (max 2 visible) Bulk Actions (grouped) Empty-State CTA(s) View Header Actions Create/Edit Save+Cancel Audit log? Notes / Exemptions
Operations run list Admin UI None Filtered list + open run View None None N/A N/A Yes (via canonical runs) All run types converge here
Operations run detail Admin UI None N/A N/A None None None N/A Yes (via canonical runs) Single canonical view for run details
Backup schedule detail Admin UI None Links to canonical runs View None None N/A N/A Yes Legacy run tab removed

Key Entities (include if feature involves data)

  • Operation Run: A canonical record representing a long-running operation, including type, status, timestamps, context, and summary.
  • Drift Finding: A drift detection result that may reference baseline and current runs.
  • Inventory Item: An inventory record that may reference the last run in which it was observed.
  • Backup Schedule: A recurring configuration that triggers backup operations and may trigger retention/purge operations.

Success Criteria (mandatory)

Measurable Outcomes

  • SC-001: 100% of new inventory sync, Entra group sync, and backup schedule executions produce exactly one canonical run record that is visible in the canonical Operations run list.
  • SC-002: Legacy run pages are not accessible (attempts to access legacy run URLs result in not found).
  • SC-003: Drift creation and drift UI flows do not depend on legacy run stores; baseline/current references resolve to canonical runs when mappings exist.
  • SC-004: The automated architecture guard blocks reintroduction of legacy run concepts and fails the build when legacy tokens reappear.
  • SC-005: Backup schedule retention/purge workflows complete successfully without legacy run stores and are observable through canonical runs.
  • SC-006: Each retention and each purge execution produces a canonical run record (independent from the associated backup schedule run).

Assumptions

  • Historical legacy-only run details do not need to be preserved; pre-existing legacy run history may be lost after legacy tables are removed.
  • The canonical Operations UI already exists and is the single supported run viewer.

Dependencies

  • Workspace-scoped run access rules remain enforced consistently across list and detail views.