TenantAtlas/app/Support/Operations/LifecycleReconciliationReason.php
2026-03-23 22:52:37 +01:00

84 lines
3.0 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Support\Operations;
use App\Support\ReasonTranslation\NextStepOption;
use App\Support\ReasonTranslation\ReasonResolutionEnvelope;
enum LifecycleReconciliationReason: string
{
case StaleQueued = 'run.stale_queued';
case StaleRunning = 'run.stale_running';
case InfrastructureTimeoutOrAbandonment = 'run.infrastructure_timeout_or_abandonment';
case QueueFailureBridge = 'run.queue_failure_bridge';
case AdapterOutOfSync = 'run.adapter_out_of_sync';
public function operatorLabel(): string
{
return match ($this) {
self::StaleQueued => 'Run never started',
self::StaleRunning => 'Run stopped reporting progress',
self::InfrastructureTimeoutOrAbandonment => 'Infrastructure ended the run',
self::QueueFailureBridge => 'Queue failure was reconciled',
self::AdapterOutOfSync => 'Lifecycle was reconciled from related records',
};
}
public function shortExplanation(): string
{
return match ($this) {
self::StaleQueued => 'The run stayed queued past its lifecycle window and was marked failed.',
self::StaleRunning => 'The run stayed active past its lifecycle window and was marked failed.',
self::InfrastructureTimeoutOrAbandonment => 'Queue infrastructure ended the job before normal completion could update the run.',
self::QueueFailureBridge => 'The platform bridged a queue failure back to the owning run and marked it failed.',
self::AdapterOutOfSync => 'A related restore record reached terminal truth before the operation run was updated.',
};
}
public function actionability(): string
{
return match ($this) {
self::AdapterOutOfSync => 'non_actionable',
default => 'retryable_transient',
};
}
/**
* @return array<int, NextStepOption>
*/
public function nextSteps(): array
{
return match ($this) {
self::AdapterOutOfSync => [
NextStepOption::instruction('Review the related restore record before deciding whether to run the workflow again.'),
],
default => [
NextStepOption::instruction('Review worker health and logs before retrying this operation.'),
],
};
}
public function defaultMessage(): string
{
return $this->shortExplanation();
}
/**
* @param array<string, mixed> $context
*/
public function toReasonResolutionEnvelope(string $surface = 'detail', array $context = []): ReasonResolutionEnvelope
{
return new ReasonResolutionEnvelope(
internalCode: $this->value,
operatorLabel: $this->operatorLabel(),
shortExplanation: $this->shortExplanation(),
actionability: $this->actionability(),
nextSteps: $this->nextSteps(),
showNoActionNeeded: false,
diagnosticCodeLabel: $this->value,
);
}
}