*/ use HasFactory; public const string PRIMARY_CONTEXT_TENANT = 'tenant'; public const string PRIMARY_CONTEXT_OPERATION_RUN = 'operation_run'; public const string ATTACHMENT_MODE_DIAGNOSTIC_SNAPSHOT_ATTACHED = 'diagnostic_snapshot_attached'; public const string ATTACHMENT_MODE_CANONICAL_CONTEXT_ONLY = 'canonical_context_only'; public const string SEVERITY_LOW = 'low'; public const string SEVERITY_NORMAL = 'normal'; public const string SEVERITY_HIGH = 'high'; public const string SEVERITY_BLOCKING = 'blocking'; public const string EXTERNAL_HANDOFF_MODE_INTERNAL_ONLY = 'internal_only'; public const string EXTERNAL_HANDOFF_MODE_CREATE_EXTERNAL_TICKET = 'create_external_ticket'; public const string EXTERNAL_HANDOFF_MODE_LINK_EXISTING_TICKET = 'link_existing_ticket'; public const string HANDOFF_OUTCOME_INTERNAL_ONLY = 'internal_only'; public const string HANDOFF_OUTCOME_EXTERNAL_TICKET_CREATED = 'external_ticket_created'; public const string HANDOFF_OUTCOME_EXTERNAL_TICKET_LINKED = 'external_ticket_linked'; public const string HANDOFF_OUTCOME_EXTERNAL_HANDOFF_FAILED = 'external_handoff_failed'; protected $guarded = []; /** * @return array */ protected function casts(): array { return [ 'context_envelope' => 'array', ]; } /** * @return array */ public static function severityOptions(): array { return [ self::SEVERITY_LOW => 'Low', self::SEVERITY_NORMAL => 'Normal', self::SEVERITY_HIGH => 'High', self::SEVERITY_BLOCKING => 'Blocking', ]; } /** * @return list */ public static function severityValues(): array { return array_keys(self::severityOptions()); } /** * @return array */ public static function externalHandoffModeOptions(): array { return [ self::EXTERNAL_HANDOFF_MODE_INTERNAL_ONLY => 'TenantPilot only', self::EXTERNAL_HANDOFF_MODE_CREATE_EXTERNAL_TICKET => 'Create external ticket', self::EXTERNAL_HANDOFF_MODE_LINK_EXISTING_TICKET => 'Link existing ticket', ]; } /** * @return list */ public static function externalHandoffModeValues(): array { return array_keys(self::externalHandoffModeOptions()); } public function hasExternalTicket(): bool { return is_string($this->external_ticket_reference) && trim($this->external_ticket_reference) !== ''; } public function hasExternalHandoffFailure(): bool { return is_string($this->external_handoff_failure_summary) && trim($this->external_handoff_failure_summary) !== ''; } public function externalHandoffOutcome(): string { if ($this->hasExternalHandoffFailure()) { return self::HANDOFF_OUTCOME_EXTERNAL_HANDOFF_FAILED; } if (! $this->hasExternalTicket()) { return self::HANDOFF_OUTCOME_INTERNAL_ONLY; } return match ($this->external_handoff_mode) { self::EXTERNAL_HANDOFF_MODE_CREATE_EXTERNAL_TICKET => self::HANDOFF_OUTCOME_EXTERNAL_TICKET_CREATED, self::EXTERNAL_HANDOFF_MODE_LINK_EXISTING_TICKET => self::HANDOFF_OUTCOME_EXTERNAL_TICKET_LINKED, default => self::HANDOFF_OUTCOME_INTERNAL_ONLY, }; } /** * @return list */ public static function primaryContextTypes(): array { return [ self::PRIMARY_CONTEXT_TENANT, self::PRIMARY_CONTEXT_OPERATION_RUN, ]; } /** * @return list */ public static function attachmentModes(): array { return [ self::ATTACHMENT_MODE_DIAGNOSTIC_SNAPSHOT_ATTACHED, self::ATTACHMENT_MODE_CANONICAL_CONTEXT_ONLY, ]; } /** * @return BelongsTo */ public function workspace(): BelongsTo { return $this->belongsTo(Workspace::class); } /** * @return BelongsTo */ public function tenant(): BelongsTo { return $this->belongsTo(Tenant::class); } /** * @return BelongsTo */ public function operationRun(): BelongsTo { return $this->belongsTo(OperationRun::class); } /** * @return BelongsTo */ public function initiator(): BelongsTo { return $this->belongsTo(User::class, 'initiated_by_user_id'); } }