*/ use DerivesWorkspaceIdFromTenant; use HasFactory; public const string FINDING_TYPE_DRIFT = 'drift'; public const string FINDING_TYPE_PERMISSION_POSTURE = 'permission_posture'; public const string FINDING_TYPE_ENTRA_ADMIN_ROLES = 'entra_admin_roles'; public const string SEVERITY_LOW = 'low'; public const string SEVERITY_MEDIUM = 'medium'; public const string SEVERITY_HIGH = 'high'; public const string SEVERITY_CRITICAL = 'critical'; public const string STATUS_NEW = 'new'; public const string STATUS_ACKNOWLEDGED = 'acknowledged'; public const string STATUS_RESOLVED = 'resolved'; protected $guarded = []; protected $casts = [ 'acknowledged_at' => 'datetime', 'evidence_jsonb' => 'array', 'resolved_at' => 'datetime', ]; public function tenant(): BelongsTo { return $this->belongsTo(Tenant::class); } public function baselineRun(): BelongsTo { return $this->belongsTo(OperationRun::class, 'baseline_operation_run_id'); } public function currentRun(): BelongsTo { return $this->belongsTo(OperationRun::class, 'current_operation_run_id'); } public function acknowledgedByUser(): BelongsTo { return $this->belongsTo(User::class, 'acknowledged_by_user_id'); } public function acknowledge(User $user): void { if ($this->status === self::STATUS_ACKNOWLEDGED) { return; } $this->forceFill([ 'status' => self::STATUS_ACKNOWLEDGED, 'acknowledged_at' => now(), 'acknowledged_by_user_id' => $user->getKey(), ]); $this->save(); } /** * Auto-resolve the finding. */ public function resolve(string $reason): void { $this->status = self::STATUS_RESOLVED; $this->resolved_at = now(); $this->resolved_reason = $reason; $this->save(); } /** * Re-open a resolved finding. */ public function reopen(array $evidence): void { $this->status = self::STATUS_NEW; $this->resolved_at = null; $this->resolved_reason = null; $this->evidence_jsonb = $evidence; $this->save(); } }