TenantAtlas/app/Support/Ui/OperatorExplanation/CountDescriptor.php
ahmido 1f0cc5de56 feat: implement operator explanation layer (#191)
## Summary
- add the shared operator explanation layer with explanation families, trustworthiness semantics, count descriptors, and centralized badge mappings
- adopt explanation-first rendering across baseline compare, governance operation run detail, baseline snapshot presentation, tenant review detail, and review register rows
- extend reason translation, artifact-truth presentation, fallback ops UX messaging, and focused regression coverage for operator explanation semantics

## Testing
- vendor/bin/sail bin pint --dirty --format agent
- vendor/bin/sail artisan test --compact tests/Feature/Monitoring/OperationsTenantScopeTest.php tests/Feature/Operations/OperationRunBlockedExecutionPresentationTest.php
- vendor/bin/sail artisan test --compact

## Notes
- Livewire v4 compatible
- panel provider registration remains in bootstrap/providers.php
- no destructive Filament actions were added or changed in this PR
- no new global-search behavior was introduced in this slice

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #191
2026-03-24 11:24:33 +00:00

68 lines
1.9 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Support\Ui\OperatorExplanation;
use InvalidArgumentException;
final readonly class CountDescriptor
{
public const string ROLE_EXECUTION = 'execution';
public const string ROLE_EVALUATION_OUTPUT = 'evaluation_output';
public const string ROLE_COVERAGE = 'coverage';
public const string ROLE_RELIABILITY_SIGNAL = 'reliability_signal';
public const string VISIBILITY_PRIMARY = 'primary';
public const string VISIBILITY_DIAGNOSTIC = 'diagnostic';
public function __construct(
public string $label,
public int $value,
public string $role,
public ?string $qualifier = null,
public string $visibilityTier = self::VISIBILITY_PRIMARY,
) {
if (trim($this->label) === '') {
throw new InvalidArgumentException('Count descriptors require a label.');
}
if (! in_array($this->role, [
self::ROLE_EXECUTION,
self::ROLE_EVALUATION_OUTPUT,
self::ROLE_COVERAGE,
self::ROLE_RELIABILITY_SIGNAL,
], true)) {
throw new InvalidArgumentException('Unsupported count descriptor role: '.$this->role);
}
if (! in_array($this->visibilityTier, [self::VISIBILITY_PRIMARY, self::VISIBILITY_DIAGNOSTIC], true)) {
throw new InvalidArgumentException('Unsupported count descriptor visibility tier: '.$this->visibilityTier);
}
}
/**
* @return array{
* label: string,
* value: int,
* role: string,
* qualifier: ?string,
* visibilityTier: string
* }
*/
public function toArray(): array
{
return [
'label' => $this->label,
'value' => $this->value,
'role' => $this->role,
'qualifier' => $this->qualifier,
'visibilityTier' => $this->visibilityTier,
];
}
}