---

description: "Task list for Spec 092 implementation"
---

# Tasks: Legacy Purge (Runs / Routes / UI / Test Shims)

**Input**: Design documents from `/specs/092-legacy-purge-final/`

**Available docs**: plan.md (required), spec.md (required), research.md, data-model.md, quickstart.md, contracts/

**Tests**: Required (Pest) — this feature changes runtime behavior (routes, queue payload compatibility, and UI).

## Phase 1: Setup (Shared Infrastructure)

**Purpose**: Establish a safe baseline for a repo-wide purge.

- [X] T001 Capture baseline by running focused tests (no code changes): `tests/Feature/Operations/LegacyRunRoutesNotFoundTest.php`, `tests/Feature/078/TenantListRedirectTest.php`
- [X] T002 Capture baseline formatting state by running `vendor/bin/sail bin pint --dirty`

---

## Phase 2: Foundational (Blocking Prerequisites)

**Purpose**: Shared guard rails and spec consistency that must be correct before story work.

- [X] T003 Confirm legacy identifier glossary in `specs/092-legacy-purge-final/spec.md` targets only removed legacy deep-link endpoints / redirect shims (and does not treat the canonical `/admin/t/{tenant:external_id}/...` tenant-plane prefix as legacy by itself)
- [X] T004 [P] Inventory legacy hotspots and annotate in `specs/092-legacy-purge-final/research.md` (confirm current matches: `app/Jobs/RunBackupScheduleJob.php`, `app/Notifications/BackupScheduleRunDispatchedNotification.php`, `app/Filament/Pages/InventoryLanding.php`, `resources/views/filament/partials/context-bar.blade.php`, `routes/web.php`, `tests/Pest.php`, `tests/Support/LegacyModels/InventorySyncRun.php`)
- [X] T005 Update guard scan exclusions in `tests/Feature/Guards/NoLegacyRunsTest.php` to explicitly exclude `docs/**` (even if not scanned today) and confirm exclusions include `database/migrations/**`, `references/**`

**Checkpoint**: Foundation ready — user story implementation can begin.

---

## Phase 3: User Story 1 — Operate without legacy concepts (Priority: P1) 🎯 MVP

**Goal**: Remove legacy artifacts from primary navigation/UX and staged-purge the legacy job field.

**Independent Test**: Navigate Inventory and Drift entry points; verify no redirect-only landing page, no legacy “inventory sync runs” copy, and no legacy URL heuristics are required. Run the focused tests listed under this story.

### Tests for User Story 1

- [X] T006 [P] [US1] Add/adjust UI copy assertion test for Drift landing in `tests/Feature/Monitoring/` or `tests/Feature/Drift/` (create if absent) to ensure “operation runs” is present and “inventory sync runs” is absent (view: `resources/views/filament/pages/drift-landing.blade.php`)
- [X] T007 [P] [US1] Add compatibility test for Deploy A job payload in `tests/Feature/BackupScheduling/RunBackupScheduleJobCompatibilityTest.php` (new) ensuring the job can be constructed without the legacy argument and older payloads still deserialize

### Implementation for User Story 1

- [X] T008 [P] [US1] Remove dead notification `app/Notifications/BackupScheduleRunDispatchedNotification.php` and update any references (if any) to avoid unused legacy artifacts
- [X] T009 [P] [US1] Remove redirect-only Inventory landing page `app/Filament/Pages/InventoryLanding.php` and delete `resources/views/filament/pages/inventory-landing.blade.php`
- [X] T010 [P] [US1] Update related links in `app/Support/OperationRunLinks.php` to link directly to the canonical Inventory Items index (remove `InventoryLanding::getUrl(...)` usage)
- [X] T011 [P] [US1] Remove InventoryLanding exemption entry from `app/Support/Ui/ActionSurface/ActionSurfaceExemptions.php`
- [X] T012 [US1] Update Drift landing copy in `resources/views/filament/pages/drift-landing.blade.php` to replace “inventory sync runs” with “operation runs”
- [X] T013 [US1] Remove legacy URL heuristic from `resources/views/filament/partials/context-bar.blade.php` (remove `str_starts_with($path, '/admin/t/')`) and derive tenant-scoped behavior from route params + workspace/tenant context only

### Deploy A — job payload compatibility release (part of FR-002)

- [X] T014 [US1] Make `backupScheduleRunId` optional in `app/Jobs/RunBackupScheduleJob.php` (compat) and stop passing dummy values at dispatch sites (search dispatchers) so new dispatches don’t require a placeholder argument
- [X] T015 [US1] Update tests that assume `backupScheduleRunId === 0` (`tests/Feature/BackupScheduling/DispatchIdempotencyTest.php`, `tests/Feature/BackupScheduling/RunNowRetryActionsTest.php`) to match the compatibility behavior

### Deploy B — final purge (scheduled after compatibility window)

- [X] T016 [US1] Remove `backupScheduleRunId` from `app/Jobs/RunBackupScheduleJob.php` entirely and delete/adjust any remaining references in app + tests

**Checkpoint**: US1 complete — UI entry points are canonical, and the staged job cleanup is delivered (Deploy A ready; Deploy B planned/executable).

---

## Phase 4: User Story 2 — Legacy deep links fail fast (Priority: P2)

**Goal**: Remove redirect shims and ensure legacy endpoints return `404 Not Found`.

**Independent Test**: Requests to legacy tenant-scoped endpoints return 404 and do not redirect.

### Tests for User Story 2

- [X] T017 [P] [US2] Extend `tests/Feature/Operations/LegacyRunRoutesNotFoundTest.php` to include `/admin/t/{tenant}/operations` and confirm it returns 404

### Implementation for User Story 2

- [X] T018 [US2] Remove legacy redirect shim route `/admin/t/{tenant:external_id}/operations` from `routes/web.php`
- [X] T019 [US2] Update `tests/Feature/078/TenantListRedirectTest.php` to assert `404 Not Found` (no redirect) for the legacy operations list URL
- [X] T020 [US2] Ensure the legacy-routes contract stays accurate by updating `specs/092-legacy-purge-final/contracts/legacy-routes.openapi.yaml` if the covered legacy endpoints list changes

**Checkpoint**: US2 complete — old bookmarks fail fast and deterministically (404).

---

## Phase 5: User Story 3 — Prevent reintroduction (Priority: P3)

**Goal**: Remove test shims and strengthen guards so legacy patterns cannot reappear.

**Independent Test**: Reintroduce a forbidden identifier in a non-excluded path and confirm guard tests fail; remove it and confirm suite passes.

### Tests for User Story 3

- [X] T021 [P] [US3] Update guard test patterns in `tests/Feature/Guards/NoLegacyRunsTest.php` to include `backupScheduleRunId`, `BackupScheduleRunDispatchedNotification`, and the legacy UI phrase “inventory sync runs”, while keeping exclusions aligned with the spec

### Implementation for User Story 3

- [X] T022 [US3] Remove legacy test shim require in `tests/Pest.php` (`require_once __DIR__.'/Support/LegacyModels/InventorySyncRun.php';`)
- [X] T023 [US3] Delete `tests/Support/LegacyModels/InventorySyncRun.php` and update all tests that import/use `App\Models\InventorySyncRun` to use canonical `App\Models\OperationRun` patterns instead (e.g., `tests/Feature/Inventory/InventorySyncButtonTest.php`, `tests/Feature/RunStartAuthorizationTest.php`)
- [X] T024 [US3] Update `tests/Feature/Guards/NoLegacyRunBackfillTest.php` to remove references to legacy shim types (InventorySyncRun/EntraGroupSyncRun/BackupScheduleRun) if they’re no longer meaningful after the purge

**Checkpoint**: US3 complete — reintroduction is blocked automatically.

---

## Phase 6: Polish & Cross-Cutting Concerns

**Purpose**: Finish the purge with verification and repo hygiene.

- [X] T025 Run `vendor/bin/sail bin pint --dirty` and ensure formatting is clean
- [X] T026 Run the minimal full targeted suite for this change:
  - `vendor/bin/sail artisan test --compact tests/Feature/Guards/NoLegacyRunsTest.php`
  - `vendor/bin/sail artisan test --compact tests/Feature/Operations/LegacyRunRoutesNotFoundTest.php`
  - `vendor/bin/sail artisan test --compact tests/Feature/078/TenantListRedirectTest.php`
  - `vendor/bin/sail artisan test --compact tests/Feature/BackupScheduling`
- [X] T027 Confirm no migration files were modified (guardrail for FR-009)

---

## Dependencies & Execution Order

- Phase 1 → Phase 2 is required.
- US1 (Phase 3) can start after Phase 2.
- US2 (Phase 4) can start after Phase 2 and is mostly independent of US1.
- US3 (Phase 5) can start after Phase 2, but some changes may be easier after US1 removes the primary app-level legacy artifacts.
- Deploy B task (T016) must be scheduled after the compatibility window for queued jobs (operational constraint), even if code is ready.

## Dependency Graph (User Stories)

```text
Foundation (Phase 2)
  ├─> US1 (P1): UI + staged job cleanup (Deploy A)
  ├─> US2 (P2): Remove redirects; legacy deep links 404
  └─> US3 (P3): Remove test shims; strengthen guards

US1 (Deploy A) ──(compat window elapsed)──> US1 (Deploy B final purge)
```

## Parallel Execution Examples

### US1 parallelizable tasks

- T008 (notification removal), T009 (InventoryLanding removal), T010 (OperationRunLinks update), and T011 (exemption removal) can be done in parallel.
- T006 (Drift copy test) can be authored in parallel with T012.

### US2 parallelizable tasks

- T017 (extend 404 tests) can be done in parallel with T018/T019.

## Implementation Strategy

- MVP scope: US1 (Phase 3) + Deploy A (T014–T015) only.
- Then: US2 (Phase 4) to enforce 404 behavior.
- Then: US3 (Phase 5) to remove shims and lock in guards.
- Finally: Deploy B (T016) after the compatibility window.
