TenantAtlas/specs/055-ops-ux-rollout/data-model.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

3.4 KiB

Phase 1 Data Model: Ops-UX Constitution Rollout (v1.3.0 Alignment) (055)

Date: 2026-01-18

This feature is a migration: it standardizes how existing operation_runs records are presented via three UX surfaces.

Entities

1) OperationRun (existing)

Source: operation_runs table

Fields (relevant to this feature)

  • id (int)
  • tenant_id (int)
  • user_id (int|null) — initiator user
  • initiator_name (string)
  • type (string) — operation type identifier
  • status (string) — active: queued|running, terminal: completed
  • outcome (string) — pending|succeeded|partially_succeeded|failed|cancelled (existing vocabulary)
  • started_at (timestamp|null)
  • completed_at (timestamp|null)
  • summary_counts (jsonb) — canonical “metrics” source for this rollout
  • failure_summary (jsonb) — array of failures with sanitized messages
  • context (jsonb) — structured context used for related links

Status / Outcome (UX-canonical)

The Ops-UX surfaces (toast/widget/db notifications) use the canonical statuses:

  • active: queued | running
  • terminal: succeeded | partial | failed

Legacy / compatibility mapping (if older records exist)

Some existing records may use legacy fields/values (for example status=completed with an outcome). These MUST be normalized for UX rendering as follows:

Normalization rules:

  • status=completed AND outcome=succeeded -> terminal=succeeded
  • status=completed AND outcome=partially_succeeded -> terminal=partial
  • status=failed OR outcome=failed -> terminal=failed

Notes:

  • The Monitoring UI MUST remain usable if legacy values exist.
  • Normalization is a presentation concern for Ops-UX; storage may remain unchanged during rollout.

2) OperationCatalog (new/standardized)

Purpose: single source of truth for operation labels.

Fields

  • operation_type (string) → label (string)

Rules

  • Any code-produced operation type must be registered (CI guard).
  • Unknown types from historical data render as Unknown operation.

3) OperationRunUrl (new helper)

Purpose: canonical URL generator for “View run”.

Rule: all “View run” links must route to Monitoring → Operations → Run Detail.

4) OperationUxPresenter (new presenter/builder)

Purpose: centralized presentation for all three surfaces.

Responsibilities

  • Toast copy for queued intent
  • Progress widget row presentation (label, status text, optional progress)
  • Terminal DB notification title/body/status and optional summary rendering

Validation rules

Summary counts (operation_runs.summary_counts)

  • Must be a flat object/dictionary.
  • Allowed keys only:
    • total, processed, succeeded, failed, skipped, created, updated, deleted, items, tenants
  • Values must be numeric and normalized to integers.
  • Invalid keys/values are ignored; if nothing valid remains, no summary is rendered.

Failure messages

  • Short, sanitized, no secrets/tokens, no payload dumps.
  • Used only for terminal failure notification body as optional suffix.

Relationships

  • OperationRun belongs to Tenant
  • OperationRun belongs to User (initiator) (nullable)

Derived fields for presentation

  • OperationLabel = OperationCatalog::label(type) (or Unknown operation)
  • UxStatus = Queued|Running|Completed|Partial|Failed (derived)
  • ProgressPercent (optional) = processed / total only when both exist and are valid