This commit is contained in:
2026-03-20 21:17:26 +01:00
parent 1a62fcb81d
commit 29c3ff8572
229 changed files with 13147 additions and 2577 deletions

View File

@@ -7,6 +7,7 @@ namespace App\Services;
use App\Jobs\IndexUserJob;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
use InvalidArgumentException;
/**
* UserStatsService single source of truth for user_statistics counters.
@@ -253,7 +254,7 @@ final class UserStatsService
DB::table('user_statistics')
->where('user_id', $userId)
->update([
$column => DB::raw("GREATEST(0, COALESCE({$column}, 0) + {$by})"),
$column => $this->nonNegativeCounterExpression($column, $by),
'updated_at' => now(),
]);
}
@@ -264,7 +265,7 @@ final class UserStatsService
->where('user_id', $userId)
->where($column, '>', 0)
->update([
$column => DB::raw("GREATEST(0, COALESCE({$column}, 0) - {$by})"),
$column => $this->nonNegativeCounterExpression($column, -$by),
'updated_at' => now(),
]);
}
@@ -279,6 +280,22 @@ final class UserStatsService
]);
}
private function nonNegativeCounterExpression(string $column, int $delta)
{
if (! preg_match('/^[A-Za-z_][A-Za-z0-9_]*$/', $column)) {
throw new InvalidArgumentException('Invalid statistics column name.');
}
$driver = DB::connection()->getDriverName();
$deltaSql = $delta >= 0 ? "+ {$delta}" : "- ".abs($delta);
if ($driver === 'sqlite') {
return DB::raw("max(0, COALESCE({$column}, 0) {$deltaSql})");
}
return DB::raw("GREATEST(0, COALESCE({$column}, 0) {$deltaSql})");
}
/**
* Queue a Meilisearch reindex for the user.
* Uses IndexUserJob to avoid blocking the request.