ModerationContentType::class, 'status' => ModerationStatus::class, 'severity' => ModerationSeverity::class, 'score' => 'integer', 'reasons_json' => 'array', 'matched_links_json' => 'array', 'matched_domains_json' => 'array', 'matched_keywords_json' => 'array', 'rule_hits_json' => 'array', 'domain_ids_json' => 'array', 'user_risk_score' => 'integer', 'is_auto_hidden' => 'boolean', 'reviewed_at' => 'datetime', 'auto_hidden_at' => 'datetime', 'resolved_at' => 'datetime', 'restored_at' => 'datetime', 'content_target_id' => 'integer', 'cluster_score' => 'integer', 'priority_score' => 'integer', 'ai_confidence' => 'integer', 'is_false_positive' => 'boolean', 'false_positive_count' => 'integer', 'escalation_status' => ModerationEscalationStatus::class, 'score_breakdown_json' => 'array', ]; public function artwork(): BelongsTo { return $this->belongsTo(Artwork::class); } public function user(): BelongsTo { return $this->belongsTo(User::class); } public function reviewer(): BelongsTo { return $this->belongsTo(User::class, 'reviewed_by'); } public function resolver(): BelongsTo { return $this->belongsTo(User::class, 'resolved_by'); } public function restorer(): BelongsTo { return $this->belongsTo(User::class, 'restored_by'); } public function actionLogs(): HasMany { return $this->hasMany(ContentModerationActionLog::class, 'finding_id')->orderByDesc('created_at'); } public function aiSuggestions(): HasMany { return $this->hasMany(ContentModerationAiSuggestion::class, 'finding_id')->orderByDesc('created_at'); } public function feedback(): HasMany { return $this->hasMany(ContentModerationFeedback::class, 'finding_id')->orderByDesc('created_at'); } public function isPending(): bool { return $this->status === ModerationStatus::Pending; } public function isReviewed(): bool { return in_array($this->status, [ ModerationStatus::ReviewedSafe, ModerationStatus::ConfirmedSpam, ModerationStatus::Resolved, ], true); } public function hasMatchedDomains(): bool { return ! empty($this->matched_domains_json); } }