TenantAtlas/specs/055-ops-ux-rollout/tasks.md
ahmido bd6df1f343 055-ops-ux-rollout (#64)
Kurzbeschreibung

Implementiert Feature 055 — Ops‑UX Constitution Rollout v1.3.0.
Behebt: globales BulkOperationProgress-Widget benötigt keinen manuellen Refresh mehr; ETA/Elapsed aktualisieren korrekt; Widget verschwindet automatisch.
Verbesserungen: zuverlässiges polling (Alpine factory + Livewire fallback), sofortiger Enqueue‑Signal-Dispatch, Failure‑Message‑Sanitization, neue Guard‑ und Regressionstests, Specs/Tasks aktualisiert.
Was geändert wurde (Auszug)

InventoryLanding.php
bulk-operation-progress.blade.php
OperationUxPresenter.php
SyncRestoreRunToOperationRun.php
PolicyResource.php
PolicyVersionResource.php
RestoreRunResource.php
tests/Feature/OpsUx/* (PollerRegistration, TerminalNotificationFailureMessageTest, CanonicalViewRunLinksTest, OperationCatalogCoverageTest, UnknownOperationTypeLabelTest)
InventorySyncButtonTest.php
tasks.md
Tests

Neue Tests hinzugefügt; php artisan test --group=ops-ux lokal grün (alle relevanten Tests laufen).
How to verify manually

Auf Branch wechseln: 055-ops-ux-rollout
In Filament: Inventory → Sync (oder relevante Bulk‑Aktion) auslösen.
Beobachten: Progress‑Widget erscheint sofort, ETA/Elapsed aktualisiert, Widget verschwindet nach Fertigstellung ohne Browser‑Refresh.
Optional: ./vendor/bin/sail exec app php artisan test --filter=OpsUx oder php artisan test --group=ops-ux
Besonderheiten / Hinweise

Einzelne, synchrone Policy‑Actions (ignore/restore/PolicyVersion single archive/restore/forceDelete) sind absichtlich inline und erzeugen kein OperationRun. Bulk‑Aktionen und restore.execute werden als Runs modelliert. Wenn gewünscht, kann ich die inline‑Actions auf OperationRunService umstellen, damit sie in Monitoring → Operations sichtbar werden.
Remote: Branch ist bereits gepusht (origin/055-ops-ux-rollout). PR kann in Gitea erstellt werden.
Links

Specs & tasks: tasks.md
Monitoring page: Operations.php

Co-authored-by: Ahmed Darrazi <ahmeddarrazi@adsmac.local>
Reviewed-on: #64
2026-01-18 14:50:15 +00:00

13 KiB
Raw Blame History

description
Task list for Ops-UX Constitution Rollout (v1.3.0 Alignment) (055)

Tasks: Ops-UX Constitution Rollout (v1.3.0 Alignment) (055)

Input: Design documents from specs/055-ops-ux-rollout/

Tests: REQUIRED (Pest) — runtime behavior + UX contract enforcement.

Phase 1: Setup (Shared Infrastructure)

Purpose: Create a clean workspace for implementing and testing this migration.

  • T001 Create Ops UX test folder structure in tests/Feature/OpsUx/
  • T002 [P] Add a dedicated test file stub in tests/Feature/OpsUx/OpsUxSmokeTest.php
  • T003 [P] Add a shared test helper (factory/state helpers) in tests/Support/OpsUxTestSupport.php

Phase 2: Foundational (Blocking Prerequisites)

Purpose: Shared primitives (catalog/links/presenter/normalization) that every user story depends on.

  • T004 Update runtime unknown-type label behavior in app/Support/OperationCatalog.php (render Unknown operation, never raw type)
  • T005 [P] Add shared presenter for toast/widget/notification copy in app/Support/OpsUx/OperationUxPresenter.php
  • T059 Implement a single status normalization function for Ops-UX rendering
    • Map legacy completed/outcome values to canonical terminal statuses (succeeded|partial|failed)
    • Ensure widget and notifications consume normalized status
  • T006 [P] Add summary_counts normalizer + whitelist enforcement in app/Support/OpsUx/SummaryCountsNormalizer.php
  • T060 Consolidate allowed summary keys into one code constant/source (no duplicated lists)
    • Example shape: OperationSummaryKeys::all() (or similar)
    • Normalizer MUST reference that source
    • Catalog (if it references keys) MUST reference the same source
    • Add one guard test asserting the list matches spec.md canonical list
  • T007 [P] Add canonical “View run” URL helper wrapper in app/Support/OpsUx/OperationRunUrl.php (delegates to app/Support/OperationRunLinks.php)
  • T008 Update summary key whitelist consumption in app/Support/OperationCatalog.php to reference the consolidated source (see T060)
  • T009 Update summary sanitization to use shared normalizer in app/Services/OperationRunService.php
  • T010 Update OperationRun completed notification to use shared presenter + normalizer in app/Notifications/OperationRunCompleted.php
  • T011 Disable queued DB notification emission by default in app/Services/OperationRunService.php (align with FR-010c)
  • T012 Deprecate/stop using queued DB notification class in app/Notifications/OperationRunQueued.php (keep class but ensure no producers call it)
  • T013 Ensure all “View run” actions inside operation notifications use canonical URL helper in app/Notifications/OperationRunCompleted.php

Checkpoint: Shared contracts available; user story work can proceed.


Phase 3: User Story 1 — Consistent “I started it” feedback (Priority: P1) 🎯 MVP

Goal: Starting any operation shows queued-only intent feedback with canonical “View run”.

Independent Test: Trigger an operation start from a Filament action; observe a queued-only toast ({OperationLabel} queued / Running in the background.) and verify no queued DB notification is created.

Tests for User Story 1

  • T014 [P] [US1] Add test ensuring no queued DB notifications are emitted in tests/Feature/OpsUx/NoQueuedDbNotificationsTest.php
  • T015 [P] [US1] Add test for canonical queued toast copy builder in tests/Feature/OpsUx/QueuedToastCopyTest.php
  • T057 [US1] Enforce toast auto-dismiss duration (35 seconds) for queued intent feedback (set duration explicitly, e.g. 4000ms)
  • T058 [P] [US1] (Optional guard) Centralize toast duration in OperationUxPresenter and add a small unit test to keep it within 30005000ms

Implementation for User Story 1

  • T016 [P] [US1] Migrate queued toast copy for policy operations in app/Filament/Resources/PolicyResource.php (use OperationUxPresenter)
  • T017 [P] [US1] Migrate queued toast copy for policy version operations in app/Filament/Resources/PolicyVersionResource.php (use OperationUxPresenter)
  • T018 [P] [US1] Migrate queued toast copy for restore run operations in app/Filament/Resources/RestoreRunResource.php (use OperationUxPresenter)
  • T019 [P] [US1] Migrate queued toast copy for backup schedule operations in app/Filament/Resources/BackupScheduleResource.php (use OperationUxPresenter)
  • T020 [P] [US1] Migrate queued toast copy for backup set operations in app/Filament/Resources/BackupSetResource.php (use OperationUxPresenter)
  • T021 [P] [US1] Migrate queued toast copy for tenant sync operations in app/Filament/Resources/TenantResource.php (use OperationUxPresenter)
  • T022 [P] [US1] Migrate queued toast copy for policy view page operations in app/Filament/Resources/PolicyResource/Pages/ViewPolicy.php (use OperationUxPresenter)
  • T023 [P] [US1] Migrate queued toast copy for inventory landing operations in app/Filament/Pages/InventoryLanding.php (use OperationUxPresenter)
  • T024 [P] [US1] Migrate queued toast copy for drift landing operations in app/Filament/Pages/DriftLanding.php (use OperationUxPresenter)
  • T025 [P] [US1] Migrate queued toast copy for backup-set policy picker operations in app/Livewire/BackupSetPolicyPickerTable.php (use OperationUxPresenter)

Checkpoint: A user can start operations and get consistent queued intent feedback.


Phase 4: User Story 2 — Live awareness of active operations (Priority: P2)

Goal: A single global widget shows only tenant-scoped queued/running runs with strict copy and canonical links.

Independent Test: Create active runs in the DB; the widget shows max 5 rows, each row has Queued/Running only, and terminal runs never render.

Tests for User Story 2

  • T026 [P] [US2] Add widget filtering test (never show terminal) in tests/Feature/OpsUx/ProgressWidgetFiltersTest.php
  • T027 [P] [US2] Add widget max-5 + overflow link test in tests/Feature/OpsUx/ProgressWidgetOverflowTest.php
  • T062 [US2] Add restore execution → OperationRun sync regression test in tests/Feature/OpsUx/RestoreExecutionOperationRunSyncTest.php

Implementation for User Story 2

  • T028 [US2] Migrate widget query from BulkOperationRun to OperationRun in app/Livewire/BulkOperationProgress.php
  • T029 [US2] Enforce tenant-wide scope + Monitoring access guard in app/Livewire/BulkOperationProgress.php
  • T030 [US2] Update widget UI strings + strict status text in resources/views/livewire/bulk-operation-progress.blade.php
  • T031 [US2] Implement max-5 + overflow link behavior in resources/views/livewire/bulk-operation-progress.blade.php
  • T032 [US2] Use canonical “View run” URLs in widget rows in resources/views/livewire/bulk-operation-progress.blade.php (via OperationRunUrl / OperationRunLinks)
  • T033 [US2] No % in widget; widget may show elapsed time only
  • T034 [US2] Implement calm polling schedule + pause rules in resources/views/livewire/bulk-operation-progress.blade.php
  • T063 [US2] Dispatch ops-ux:run-enqueued browser event after successful enqueue so the widget refreshes immediately
    • Producers: app/Filament/Pages/InventoryLanding.php, app/Filament/Pages/DriftLanding.php, app/Filament/Resources/BackupScheduleResource.php, app/Filament/Resources/PolicyResource.php, app/Filament/Resources/PolicyResource/Pages/ListPolicies.php, app/Filament/Resources/RestoreRunResource.php, app/Filament/Resources/TenantResource.php, app/Livewire/BackupSetPolicyPickerTable.php, app/Filament/Resources/BackupSetResource/RelationManagers/BackupItemsRelationManager.php
  • T035 [US2] Confirm widget injection remains global and consistent in app/Providers/Filament/AdminPanelProvider.php

Run detail polling (missing coverage for FR-013)

  • T053 [US2] Add run-detail polling controller/hook that applies calm polling while status is active (queued|running) (only poll when run detail is visible; stop immediately on terminal; backoff 1s (first 10s) → 5s → 10s (after 60s))
  • T054 [US2] Pause run-detail polling when a modal is open (global modal flag) and resume when closed (no network update spam while confirm dialogs/modals are open)
  • T055 [US2] Pause run-detail polling when browser tab is hidden (Page Visibility API) and resume when visible (no polling when document.hidden = true)
  • T056 [P] [US2] Add a small guard test/component test that run-detail polling is disabled once the run becomes terminal
  • T061 [US2] Surface elapsed time + expected duration + stuck guidance in run detail

Checkpoint: Widget is constitution-compliant and becomes the single active-ops surface.


Phase 5: User Story 3 — Audit + outcome without spam (Priority: P3)

Goal: Exactly one terminal DB notification per run (initiator-only) with canonical copy, canonical link, safe summary.

Independent Test: Transition a run to terminal multiple times (or call completion twice); verify only one DB notification exists and it contains only whitelisted numeric summary keys.

Tests for User Story 3

  • T036 [P] [US3] Add terminal notification idempotency test in tests/Feature/OpsUx/TerminalNotificationIdempotencyTest.php
  • T037 [P] [US3] Add summary whitelist + numeric-only test in tests/Feature/OpsUx/SummaryCountsWhitelistTest.php
  • T038 [P] [US3] Add canonical “View run” action test for notifications in tests/Feature/OpsUx/NotificationViewRunLinkTest.php

Implementation for User Story 3

  • T039 [US3] Refactor terminal notification copy/title/body to use presenter in app/Notifications/OperationRunCompleted.php
  • T040 [US3] Ensure initiator-only delivery is enforced in app/Services/OperationRunService.php
  • T041 [US3] Ensure terminal notification is emitted exactly once per run in app/Services/OperationRunService.php
  • T042 [US3] Ensure notification summary renders only normalized summary_counts in app/Notifications/OperationRunCompleted.php
  • T043 [US3] Ensure failure message suffix is sanitized + short in app/Notifications/OperationRunCompleted.php

Checkpoint: Terminal outcomes are auditable without spam.


Phase 6: User Story 4 — Regression-safe by default (Priority: P4)

Goal: Guards prevent drift (catalog coverage, canonical links, surface rules, summary rules).

Independent Test: Introduce a fake operation type in code and confirm tests fail; confirm “View run” always resolves to the canonical Monitoring run-detail destination.

Tests for User Story 4

  • T044 [P] [US4] Add catalog coverage guard test in tests/Feature/OpsUx/OperationCatalogCoverageTest.php
  • T045 [P] [US4] Add canonical “View run” helper usage guard test in tests/Feature/OpsUx/CanonicalViewRunLinksTest.php
  • T046 [P] [US4] Add unknown-type runtime label test in tests/Feature/OpsUx/UnknownOperationTypeLabelTest.php

Implementation for User Story 4

  • T047 [US4] Ensure OperationRunResource type label rendering never shows raw type in app/Filament/Resources/OperationRunResource.php
  • T048 [US4] Ensure Monitoring Operations page type labels never show raw type in app/Filament/Pages/Monitoring/Operations.php
  • T049 [US4] Ensure any remaining “View run” links use canonical helper in app/Support/OperationRunLinks.php

Checkpoint: Drift prevention is enforced in CI.


Phase 7: Polish & Cross-Cutting Concerns

  • T050 [P] Run Pint autofix for touched files via app/ and tests/ (validate against composer.json scripts)
  • T051 Run targeted test suite for Ops UX via tests/Feature/OpsUx/ (document exact filter in specs/055-ops-ux-rollout/quickstart.md)
  • T052 [P] Remove or update any stale queued-notification references in app/Services/OperationRunService.php

Dependencies & Execution Order

User Story Dependencies

  • US1 (P1) depends on Phase 2 (Foundational) tasks T004T013.
  • US2 (P2) depends on Phase 2 (Foundational) tasks T004T013.
  • US3 (P3) depends on Phase 2 (Foundational) tasks T004T013.
  • US4 (P4) depends on completion of US1US3 (guards should reflect final behavior).
  1. Phase 2 (Foundational)
  2. US1 (queued toast + no queued DB notifications)
  3. US3 (terminal notification contract)
  4. US2 (widget)
  5. US4 (guards)

Parallel Opportunities

  • Within Phase 2: T005T007 can be done in parallel.
  • US1 migration tasks T016T025 are parallelizable (different files).
  • US4 tests T044T046 can be written in parallel.

Parallel Example: User Story 1

  • Task: T016 (PolicyResource) + T017 (PolicyVersionResource) + T018 (RestoreRunResource) can run in parallel.
  • Task: T019 (BackupScheduleResource) + T020 (BackupSetResource) can run in parallel.

Implementation Strategy

MVP scope

Ship US1 + the minimum foundational primitives (Phase 2) to guarantee:

  • queued-only toast copy is consistent
  • queued DB notifications are banned
  • canonical “View run” destination is available

Then layer US3 (terminal notification) before US2 (widget) to ensure audit outcomes are reliable early.