Some checks failed
Main Confidence / confidence (push) Failing after 45s
## Summary - introduce surface-aware compressed governance outcomes and reuse the shared truth/explanation seams for operator-first summaries - apply the compressed outcome hierarchy across baseline, evidence, review, review-pack, canonical review/evidence, and artifact-oriented operation-run surfaces - expand spec 214 fixtures and Pest coverage, and fix tenant-panel route assertions by generating explicit tenant-panel URLs in the affected Filament tests ## Validation - `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent` - focused governance compression suite from `specs/214-governance-outcome-compression/quickstart.md` passed (`68` tests, `445` assertions) - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/InventoryItemResourceTest.php tests/Feature/Filament/BackupSetUiEnforcementTest.php tests/Feature/Filament/RestoreRunUiEnforcementTest.php` passed (`18` tests, `81` assertions) Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #253
101 lines
3.4 KiB
PHP
101 lines
3.4 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Support\Ui\GovernanceArtifactTruth;
|
|
|
|
use App\Support\Badges\BadgeCatalog;
|
|
use App\Support\Badges\BadgeSpec;
|
|
use InvalidArgumentException;
|
|
|
|
final readonly class CompressedGovernanceOutcome
|
|
{
|
|
/**
|
|
* @param list<array{
|
|
* label: string,
|
|
* value: string,
|
|
* badge: ?BadgeSpec
|
|
* }> $secondaryFacts
|
|
*/
|
|
public function __construct(
|
|
public string $surfaceFamily,
|
|
public string $decisionDirection,
|
|
public string $primaryLabel,
|
|
public string $primaryReason,
|
|
public string $nextActionText,
|
|
public BadgeSpec $primaryBadge,
|
|
public array $secondaryFacts = [],
|
|
public bool $diagnosticsAvailable = false,
|
|
public ?string $diagnosticsSummary = null,
|
|
) {
|
|
if (trim($this->surfaceFamily) === '') {
|
|
throw new InvalidArgumentException('Compressed governance outcomes require a surface family.');
|
|
}
|
|
|
|
if (! in_array($this->decisionDirection, [
|
|
'usable',
|
|
'publishable',
|
|
'internal_only',
|
|
'stale',
|
|
'blocked',
|
|
'follow_up_needed',
|
|
'historical_only',
|
|
], true)) {
|
|
throw new InvalidArgumentException(sprintf('Unsupported compressed governance decision direction [%s].', $this->decisionDirection));
|
|
}
|
|
|
|
if (trim($this->primaryLabel) === '') {
|
|
throw new InvalidArgumentException('Compressed governance outcomes require a primary label.');
|
|
}
|
|
|
|
if (trim($this->primaryReason) === '') {
|
|
throw new InvalidArgumentException('Compressed governance outcomes require a primary reason.');
|
|
}
|
|
|
|
if (trim($this->nextActionText) === '') {
|
|
throw new InvalidArgumentException('Compressed governance outcomes require a next action.');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @return array{
|
|
* surfaceFamily: string,
|
|
* decisionDirection: string,
|
|
* primaryLabel: string,
|
|
* primaryReason: string,
|
|
* nextActionText: string,
|
|
* primaryBadge: array{label: string, color: ?string, icon: ?string, iconColor: ?string},
|
|
* secondaryFacts: list<array{
|
|
* label: string,
|
|
* value: string,
|
|
* badge: ?array{label: string, color: ?string, icon: ?string, iconColor: ?string}
|
|
* }>,
|
|
* diagnosticsAvailable: bool,
|
|
* diagnosticsSummary: ?string
|
|
* }
|
|
*/
|
|
public function toArray(): array
|
|
{
|
|
return [
|
|
'surfaceFamily' => $this->surfaceFamily,
|
|
'decisionDirection' => $this->decisionDirection,
|
|
'primaryLabel' => $this->primaryLabel,
|
|
'primaryReason' => $this->primaryReason,
|
|
'nextActionText' => $this->nextActionText,
|
|
'primaryBadge' => BadgeCatalog::summaryData($this->primaryBadge),
|
|
'secondaryFacts' => array_values(array_map(
|
|
static fn (array $fact): array => [
|
|
'label' => $fact['label'],
|
|
'value' => $fact['value'],
|
|
'badge' => $fact['badge'] instanceof BadgeSpec
|
|
? BadgeCatalog::summaryData($fact['badge'])
|
|
: null,
|
|
],
|
|
$this->secondaryFacts,
|
|
)),
|
|
'diagnosticsAvailable' => $this->diagnosticsAvailable,
|
|
'diagnosticsSummary' => $this->diagnosticsSummary,
|
|
];
|
|
}
|
|
}
|