147 lines
10 KiB
Markdown
147 lines
10 KiB
Markdown
# 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 spec’s “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.
|