Implement creator studio and upload updates

This commit is contained in:
2026-04-04 10:12:02 +02:00
parent 1da7d3bf88
commit 0b216b7ecd
15107 changed files with 31206 additions and 626514 deletions

View File

@@ -0,0 +1,83 @@
<?php
namespace App\Services\Moderation;
use App\Enums\ModerationStatus;
use App\Models\ContentModerationFinding;
use App\Models\User;
class UserRiskScoreService
{
/**
* @param array<int, string> $domains
* @return array{risk_score:int,score_modifier:int,signals:array<string, int>}
*/
public function assess(?int $userId, array $domains = []): array
{
if (! $userId) {
return ['risk_score' => 0, 'score_modifier' => 0, 'signals' => []];
}
$user = User::query()->with('statistics:user_id,uploads_count')->find($userId);
if (! $user) {
return ['risk_score' => 0, 'score_modifier' => 0, 'signals' => []];
}
$summary = ContentModerationFinding::query()
->where('user_id', $userId)
->selectRaw('COUNT(*) as total_findings')
->selectRaw("SUM(CASE WHEN status = ? THEN 1 ELSE 0 END) as confirmed_spam_count", [ModerationStatus::ConfirmedSpam->value])
->selectRaw("SUM(CASE WHEN status = ? THEN 1 ELSE 0 END) as safe_count", [ModerationStatus::ReviewedSafe->value])
->selectRaw("SUM(CASE WHEN status = ? THEN 1 ELSE 0 END) as pending_count", [ModerationStatus::Pending->value])
->first();
$confirmedSpam = (int) ($summary?->confirmed_spam_count ?? 0);
$safeCount = (int) ($summary?->safe_count ?? 0);
$pendingCount = (int) ($summary?->pending_count ?? 0);
$domainRepeatCount = ContentModerationFinding::query()
->where('user_id', $userId)
->whereNotNull('matched_domains_json')
->get(['matched_domains_json'])
->reduce(function (int $carry, ContentModerationFinding $finding) use ($domains): int {
return $carry + (empty(array_intersect((array) $finding->matched_domains_json, $domains)) ? 0 : 1);
}, 0);
$accountAgeDays = max(0, \now()->diffInDays($user->created_at));
$uploadsCount = (int) ($user->statistics?->uploads_count ?? 0);
$riskScore = 0;
$riskScore += $confirmedSpam * 18;
$riskScore += $pendingCount * 5;
$riskScore += min(20, $domainRepeatCount * 6);
$riskScore -= min(18, $safeCount * 4);
$riskScore -= $accountAgeDays >= 365 ? 8 : ($accountAgeDays >= 90 ? 4 : 0);
$riskScore -= $uploadsCount >= 25 ? 6 : ($uploadsCount >= 10 ? 3 : 0);
$riskScore = max(0, min(100, $riskScore));
$modifier = 0;
if ($riskScore >= 75) {
$modifier = (int) \app('config')->get('content_moderation.user_risk.high_modifier', 18);
} elseif ($riskScore >= 50) {
$modifier = (int) \app('config')->get('content_moderation.user_risk.medium_modifier', 10);
} elseif ($riskScore >= 25) {
$modifier = (int) \app('config')->get('content_moderation.user_risk.low_modifier', 4);
} elseif ($riskScore <= 5 && $accountAgeDays >= 180 && $uploadsCount >= 10) {
$modifier = (int) \app('config')->get('content_moderation.user_risk.trusted_modifier', -6);
} elseif ($riskScore <= 12 && $safeCount >= 2) {
$modifier = -3;
}
return [
'risk_score' => $riskScore,
'score_modifier' => $modifier,
'signals' => [
'confirmed_spam_count' => $confirmedSpam,
'safe_count' => $safeCount,
'pending_count' => $pendingCount,
'domain_repeat_count' => $domainRepeatCount,
'account_age_days' => $accountAgeDays,
'uploads_count' => $uploadsCount,
],
];
}
}