diff --git a/app/Http/Controllers/UsersController.php b/app/Http/Controllers/UsersController.php index b226a6e1965..bd15199ce68 100644 --- a/app/Http/Controllers/UsersController.php +++ b/app/Http/Controllers/UsersController.php @@ -844,7 +844,7 @@ private function getExtra($page, array $options, int $perPage = 10, int $offset $includes = ScoreTransformer::USER_PROFILE_INCLUDES; $query = $this->user->soloScores() ->recent($this->mode, $options['includeFails'] ?? false) - ->reorderBy('unix_updated_at', 'desc') + ->reorderBy('ended_at', 'desc') ->with(ScoreTransformer::USER_PROFILE_INCLUDES_PRELOAD); $userRelationColumn = 'user'; break; diff --git a/app/Models/Solo/Score.php b/app/Models/Solo/Score.php index 54ccba83100..0f3d8ab4c2e 100644 --- a/app/Models/Solo/Score.php +++ b/app/Models/Solo/Score.php @@ -19,6 +19,7 @@ use App\Models\ScoreToken; use App\Models\Traits; use App\Models\User; +use Carbon\CarbonImmutable; use Illuminate\Contracts\Filesystem\Filesystem; use Illuminate\Database\Eloquent\Builder; use LaravelRedis; @@ -181,14 +182,21 @@ public function scopeIndexable(Builder $query): Builder */ public function scopeRecent(Builder $query, string $ruleset, bool $includeFails): Builder { + $minTime = CarbonImmutable::now()->subDays(1); + return $query // ensure correct index is used ->from(\DB::raw("{$this->getTable()} FORCE INDEX (user_ruleset_index)")) ->default() ->forRuleset($ruleset) ->includeFails($includeFails) - // 1 day (24 * 3600) - ->where('unix_updated_at', '>', time() - 86_400); + // unix_updated_at may be updated arbitrarily, so also filter by `ended_at` to ensure + // only recent scores are returned. + ->where('ended_at', '>', $minTime) + // we still want to filter by `unix_updated_at` to make the query efficient (is in the PK). + ->where('unix_updated_at', '>', $minTime->getTimestamp()) + // ensure correct partition in production + ->where('preserve', '>=', 0); } public function scopeVisibleUsers(Builder $query): Builder