TenantAtlas/app/Support/OperationCatalog.php
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

65 lines
2.0 KiB
PHP

<?php
namespace App\Support;
use App\Support\OpsUx\OperationSummaryKeys;
final class OperationCatalog
{
/**
* @return array<string, string>
*/
public static function labels(): array
{
return [
'policy.sync' => 'Policy sync',
'policy.sync_one' => 'Policy sync',
'policy.capture_snapshot' => 'Policy snapshot',
'inventory.sync' => 'Inventory sync',
'directory_groups.sync' => 'Directory groups sync',
'drift.generate' => 'Drift generation',
'backup_set.add_policies' => 'Backup set update',
'backup_set.remove_policies' => 'Backup set update',
'backup_set.delete' => 'Archive backup sets',
'backup_set.restore' => 'Restore backup sets',
'backup_set.force_delete' => 'Delete backup sets',
'backup_schedule.run_now' => 'Backup schedule run',
'backup_schedule.retry' => 'Backup schedule retry',
'restore.execute' => 'Restore execution',
'policy_version.prune' => 'Prune policy versions',
'policy_version.restore' => 'Restore policy versions',
'policy_version.force_delete' => 'Delete policy versions',
];
}
public static function label(string $operationType): string
{
$operationType = trim($operationType);
if ($operationType === '') {
return 'Operation';
}
return self::labels()[$operationType] ?? 'Unknown operation';
}
public static function expectedDurationSeconds(string $operationType): ?int
{
return match (trim($operationType)) {
'policy.sync', 'policy.sync_one' => 90,
'inventory.sync' => 180,
'directory_groups.sync' => 120,
'drift.generate' => 240,
default => null,
};
}
/**
* @return array<int, string>
*/
public static function allowedSummaryKeys(): array
{
return OperationSummaryKeys::all();
}
}