Implement creator studio and upload updates
This commit is contained in:
83
app/Services/Moderation/UserRiskScoreService.php
Normal file
83
app/Services/Moderation/UserRiskScoreService.php
Normal 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,
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user