|null */ public function profile(?int $userId): ?array { if (! $userId) { return null; } $user = User::query()->with('statistics:user_id,uploads_count')->find($userId); if (! $user) { return null; } $findings = ContentModerationFinding::query()->where('user_id', $userId)->get([ 'id', 'status', 'is_auto_hidden', 'is_false_positive', 'matched_domains_json', 'campaign_key', 'priority_score', 'created_at', ]); $confirmedSpam = $findings->where('status', ModerationStatus::ConfirmedSpam)->count(); $safeCount = $findings->where('status', ModerationStatus::ReviewedSafe)->count(); $autoHidden = $findings->where('is_auto_hidden', true)->count(); $falsePositives = $findings->where('is_false_positive', true)->count(); $clusters = $findings->pluck('campaign_key')->filter()->unique()->count(); $domains = $findings->flatMap(static fn (ContentModerationFinding $finding): array => (array) $finding->matched_domains_json)->filter()->unique()->values(); $risk = app(UserRiskScoreService::class)->assess($userId, $domains->all()); $tier = match (true) { $risk['risk_score'] >= 75 => 'high_risk', $risk['risk_score'] >= 45 => 'monitored', $risk['risk_score'] <= 8 && $safeCount >= 2 => 'trusted', default => 'normal', }; $recommendedPolicy = match ($tier) { 'high_risk' => 'new_user_strict_mode', 'monitored' => 'comments_high_volume_antispam', 'trusted' => 'trusted_user_relaxed_mode', default => 'default', }; return [ 'user' => $user, 'risk_score' => $risk['risk_score'], 'trust_score' => max(0, 100 - $risk['risk_score'] + ($safeCount * 3) - ($falsePositives * 2)), 'tier' => $tier, 'recommended_policy' => $recommendedPolicy, 'confirmed_spam_count' => $confirmedSpam, 'safe_count' => $safeCount, 'auto_hidden_count' => $autoHidden, 'false_positive_count' => $falsePositives, 'cluster_memberships' => $clusters, 'promoted_domains' => $domains->take(12)->all(), 'signals' => $risk['signals'], ]; } }