Implements Spec 098: workspace-level settings slices for Backup retention, Drift severity mapping, and Operations retention/threshold. Spec - specs/098-settings-slices-v1-backup-drift-ops/spec.md What changed - Workspace Settings page: grouped Backup/Drift/Operations sections, unset-input UX w/ helper text, per-setting reset actions (confirmed) - Settings registry: adds/updates validation + normalization (incl. drift severity mapping normalization to lowercase) - Backup retention: adds workspace default + floor clamp; job clamps effective keep-last up to floor - Drift findings: optional workspace severity mapping; adds `critical` severity support + badge mapping - Operations pruning: retention computed per workspace via settings; scheduler unchanged; stuck threshold is storage-only Safety / Compliance notes - Filament v5 / Livewire v4: no Livewire v3 usage; relies on existing Filament v5 + Livewire v4 stack - Provider registration unchanged (Laravel 11+/12 uses bootstrap/providers.php) - Destructive actions: per-setting reset uses Filament actions with confirmation - Global search: not affected (no resource changes) - Assets: no new assets registered; no `filament:assets` changes Tests - vendor/bin/sail artisan test --compact tests/Feature/SettingsFoundation/WorkspaceSettingsManageTest.php \ tests/Feature/SettingsFoundation/WorkspaceSettingsViewOnlyTest.php \ tests/Feature/BackupScheduling/BackupScheduleLifecycleTest.php \ tests/Feature/Drift/DriftPolicySnapshotDriftDetectionTest.php \ tests/Feature/Scheduling/PruneOldOperationRunsScheduleTest.php \ tests/Unit/Badges/FindingBadgesTest.php Formatting - vendor/bin/sail bin pint --dirty Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #120
8.4 KiB
| description |
|---|
| Task list for 098-settings-slices-v1-backup-drift-ops |
Tasks: 098 — Settings Slices v1 (Backup + Drift + Operations)
Input: Design documents from /specs/098-settings-slices-v1-backup-drift-ops/ (spec.md, plan.md)
Tests: REQUIRED (Pest) — runtime behavior changes.
Scope: workspace-level settings; DB-only rendering; no Graph calls.
Phase 1: Setup (Shared Infrastructure)
- T001 Confirm feature branch + clean working tree in specs/098-settings-slices-v1-backup-drift-ops/spec.md
- T002 Verify Settings Foundation dependency is present by locating SettingsRegistry in app/Support/Settings/SettingsRegistry.php
- T003 [P] Capture baseline behaviors + constants and record them in specs/098-settings-slices-v1-backup-drift-ops/plan.md by reviewing app/Jobs/ApplyBackupScheduleRetentionJob.php, app/Services/Drift/DriftFindingGenerator.php, app/Jobs/PruneOldOperationRunsJob.php, routes/console.php
Phase 2: Foundational (Blocking Prerequisites)
Purpose: Shared settings primitives + Workspace Settings page patterns used by all slices.
- T004 Update Settings registry validation to match spec (max 365) in app/Support/Settings/SettingsRegistry.php
- T005 [P] Add per-setting reset UX pattern scaffolding (no global reset) in app/Filament/Pages/Settings/WorkspaceSettings.php
- T006 Add “unset input + helper text shows default/effective” support in app/Filament/Pages/Settings/WorkspaceSettings.php
- T007 [P] Update existing workspace settings RBAC tests for new per-setting reset actions in tests/Feature/SettingsFoundation/WorkspaceSettingsViewOnlyTest.php
- T008 [P] Update existing manage test to assert per-setting reset (not header reset) in tests/Feature/SettingsFoundation/WorkspaceSettingsManageTest.php
Checkpoint: Workspace Settings page supports per-setting resets and unset presentation without changing behavior.
Phase 3: User Story 1 — Backup retention defaults (Priority: P1) 🎯 MVP
Goal: Workspace overrides for backup retention default + min floor; job clamps effective keep-last to floor. Independent Test: Run ApplyBackupScheduleRetentionJob behavior with/without workspace overrides and verify clamping.
Tests (US1)
- T009 [P] [US1] Add/extend retention job tests to cover default + floor clamp in tests/Feature/BackupScheduling/BackupScheduleLifecycleTest.php
- T010 [P] [US1] Add validation tests for backup settings bounds (1..365) via SettingsWriter in tests/Feature/SettingsFoundation/WorkspaceSettingsManageTest.php
Implementation (US1)
- T011 [US1] Register backup floor setting and tighten keep-last rules (1..365) in app/Support/Settings/SettingsRegistry.php
- T012 [US1] Extend Workspace Settings UI: Backup section adds
backup.retention_keep_last_default+backup.retention_min_floorfields with per-setting reset actions in app/Filament/Pages/Settings/WorkspaceSettings.php - T013 [US1] Update Workspace Settings save logic: empty field triggers reset (delete override) instead of persisting null in app/Filament/Pages/Settings/WorkspaceSettings.php
- T014 [US1] Apply floor clamping for both schedule override and resolved default in app/Jobs/ApplyBackupScheduleRetentionJob.php
Phase 4: User Story 2 — Drift severity mapping (Priority: P2)
Goal: Workspace-level finding_type → severity mapping with default medium and strict validation; normalize severities to lowercase.
Independent Test: Generate drift findings and assert severity uses mapping when present; saving invalid mapping is rejected.
Tests (US2)
- T015 [P] [US2] Add drift generator test asserting default severity remains medium when no mapping set in tests/Feature/Drift/DriftPolicySnapshotDriftDetectionTest.php
- T016 [P] [US2] Add drift generator test asserting mapped severity is applied when mapping exists in tests/Feature/Drift/DriftPolicySnapshotDriftDetectionTest.php
- T017 [P] [US2] Add settings save validation tests for drift severity mapping JSON shape + allowed values in tests/Feature/SettingsFoundation/WorkspaceSettingsManageTest.php
Implementation (US2)
- T018 [US2] Add
Finding::SEVERITY_CRITICALconstant and ensure severity domain remains stable in app/Models/Finding.php - T019 [US2] Extend finding severity badge mapping to include
critical(BADGE-001 compliant) in app/Support/Badges/Domains/FindingSeverityBadge.php - T020 [US2] Register
drift.severity_mappingsetting with JSON validation + canonical normalization (lowercase values, string keys) in app/Support/Settings/SettingsRegistry.php - T021 [US2] Update DriftFindingGenerator to resolve workspace severity mapping (via SettingsResolver in workspace context) and apply mapped severity (fallback medium) in app/Services/Drift/DriftFindingGenerator.php
- T022 [US2] Extend Workspace Settings UI: Drift section adds JSON textarea for
drift.severity_mappingwith unset behavior + per-setting reset in app/Filament/Pages/Settings/WorkspaceSettings.php
Phase 5: User Story 3 — Operations retention + stuck threshold (Priority: P3)
Goal: Workspace-level operations.operation_run_retention_days drives pruning; operations.stuck_run_threshold_minutes is stored only.
Independent Test: Create old/new OperationRuns across workspaces and verify prune respects per-workspace retention; stuck threshold persists and reloads.
Tests (US3)
- T023 [P] [US3] Update pruning schedule test to match new job behavior (per-workspace retention) in tests/Feature/Scheduling/PruneOldOperationRunsScheduleTest.php
- T024 [P] [US3] Add prune job test verifying per-workspace retention cutoff using workspace settings in tests/Feature/Scheduling/PruneOldOperationRunsScheduleTest.php
- T025 [P] [US3] Add workspace settings save/reset tests for operations keys in tests/Feature/SettingsFoundation/WorkspaceSettingsManageTest.php
Implementation (US3)
- T026 [US3] Register operations settings keys with correct bounds in app/Support/Settings/SettingsRegistry.php
- T027 [US3] Refactor PruneOldOperationRunsJob to compute retention per workspace (SettingsResolver + Workspace iteration) and prune by workspace_id in app/Jobs/PruneOldOperationRunsJob.php
- T028 [US3] Ensure scheduler continues to enqueue prune job without needing a parameter in routes/console.php
- T029 [US3] Extend Workspace Settings UI: Operations section adds
operation_run_retention_days+stuck_run_threshold_minutesfields with unset behavior + per-setting reset in app/Filament/Pages/Settings/WorkspaceSettings.php
Phase 6: Polish & Cross-Cutting Concerns
- T030 [P] Confirm multi-key save emits one audit entry per key changed by reviewing app/Services/Settings/SettingsWriter.php and Workspace Settings save flow in app/Filament/Pages/Settings/WorkspaceSettings.php
- T031 [P] Run Pint formatting on touched files via vendor/bin/sail bin pint --dirty (e.g., app/Filament/Pages/Settings/WorkspaceSettings.php, app/Support/Settings/SettingsRegistry.php, app/Jobs/ApplyBackupScheduleRetentionJob.php, app/Services/Drift/DriftFindingGenerator.php, app/Jobs/PruneOldOperationRunsJob.php)
- T032 Run focused settings UI tests via vendor/bin/sail artisan test --compact tests/Feature/SettingsFoundation/WorkspaceSettingsManageTest.php
- T033 Run focused drift tests via vendor/bin/sail artisan test --compact tests/Feature/Drift/DriftPolicySnapshotDriftDetectionTest.php
- T034 Run focused pruning tests via vendor/bin/sail artisan test --compact tests/Feature/Scheduling/PruneOldOperationRunsScheduleTest.php
- T035 [P] Add an automated regression test asserting per-setting reset actions require confirmation (destructive-like) in tests/Feature/SettingsFoundation/WorkspaceSettingsManageTest.php
- T036 [P] Add an automated regression test asserting multi-key save produces one audit entry per key changed (FR-008a) in tests/Feature/SettingsFoundation/WorkspaceSettingsManageTest.php
Dependencies & Execution Order
- Setup (Phase 1) → Foundational (Phase 2) → US1 (Phase 3) → US2 (Phase 4) → US3 (Phase 5) → Polish (Phase 6)
Parallel Execution Examples
US1 parallel example: T009 + T011 + T014
US2 parallel example: T015 + T018 + T021
US3 parallel example: T023 + T027 + T029
Implementation Strategy
- MVP = US1 only (backup defaults + floor clamp) with updated Workspace Settings UX and tests.
- Then US2 (drift mapping) and US3 (operations retention/threshold) as independent increments.