feat: return xp
This commit is contained in:
parent
270f10a916
commit
6f4aa9f4e4
|
|
@ -9,6 +9,7 @@ use App\Notifications\HuntParticipantJoinedNotification;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
class HuntsController extends Controller
|
class HuntsController extends Controller
|
||||||
|
|
@ -20,10 +21,14 @@ class HuntsController extends Controller
|
||||||
$filters = $this->buildMeilisearchFilters($request);
|
$filters = $this->buildMeilisearchFilters($request);
|
||||||
|
|
||||||
$search = Hunts::search($searchTerm ?? '')
|
$search = Hunts::search($searchTerm ?? '')
|
||||||
->query(fn ($query) => $query->with('participants:id,avatar_uri'))
|
->query(fn ($query) => $query
|
||||||
|
->with('participants:id,avatar_uri')
|
||||||
|
->withSum('steps', 'xp')
|
||||||
|
)
|
||||||
->options(['filter' => $filters]);
|
->options(['filter' => $filters]);
|
||||||
|
|
||||||
$result = $search->paginate(10);
|
$result = $search->paginate(10);
|
||||||
|
$this->appendTotalXpToHunts($result->getCollection());
|
||||||
|
|
||||||
Log::info('HUNTS_SEARCH_SUCCESS', [
|
Log::info('HUNTS_SEARCH_SUCCESS', [
|
||||||
'total' => $result->total(),
|
'total' => $result->total(),
|
||||||
|
|
@ -448,6 +453,17 @@ class HuntsController extends Controller
|
||||||
return $searchTerm !== '' ? $searchTerm : null;
|
return $searchTerm !== '' ? $searchTerm : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection<int, Hunts> $hunts
|
||||||
|
*/
|
||||||
|
private function appendTotalXpToHunts(Collection $hunts): void
|
||||||
|
{
|
||||||
|
$hunts->each(function (Hunts $hunt): void {
|
||||||
|
$hunt->setAttribute('xp', $hunt->totalXp());
|
||||||
|
$hunt->makeHidden('steps_sum_xp');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private function parseDateFilterUtc(mixed $value): ?Carbon
|
private function parseDateFilterUtc(mixed $value): ?Carbon
|
||||||
{
|
{
|
||||||
if (! is_string($value) || trim($value) === '') {
|
if (! is_string($value) || trim($value) === '') {
|
||||||
|
|
|
||||||
|
|
@ -17,27 +17,7 @@ class HuntResource extends JsonResource
|
||||||
public function toArray(Request $request): array
|
public function toArray(Request $request): array
|
||||||
{
|
{
|
||||||
return array_merge(parent::toArray($request), [
|
return array_merge(parent::toArray($request), [
|
||||||
'xp' => $this->totalXp(),
|
'xp' => $this->resource->totalXp(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function totalXp(): int
|
|
||||||
{
|
|
||||||
if ($this->resource->relationLoaded('steps')) {
|
|
||||||
return (int) $this->resource->steps->sum('xp');
|
|
||||||
}
|
|
||||||
|
|
||||||
$stepsSumXp = $this->resource->getAttribute('steps_sum_xp');
|
|
||||||
|
|
||||||
if ($stepsSumXp !== null) {
|
|
||||||
return (int) $stepsSumXp;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (int) (
|
|
||||||
$this->resource->steps_sum_xp
|
|
||||||
?? $this->resource->steps?->sum('xp')
|
|
||||||
?? $this->resource->steps()->sum('xp')
|
|
||||||
?? 0
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,21 @@ class Hunts extends Model
|
||||||
->withTimestamps();
|
->withTimestamps();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function totalXp(): int
|
||||||
|
{
|
||||||
|
if ($this->relationLoaded('steps')) {
|
||||||
|
return (int) $this->steps->sum('xp');
|
||||||
|
}
|
||||||
|
|
||||||
|
$stepsSumXp = $this->getAttribute('steps_sum_xp');
|
||||||
|
|
||||||
|
if ($stepsSumXp !== null) {
|
||||||
|
return (int) $stepsSumXp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (int) $this->steps()->sum('xp');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configure Meilisearch index settings
|
* Configure Meilisearch index settings
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Models\Hunts;
|
||||||
|
use App\Models\HuntSteps;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
|
use Laravel\Scout\EngineManager;
|
||||||
|
|
||||||
|
uses(RefreshDatabase::class);
|
||||||
|
|
||||||
|
it('lists hunts with total step xp', function () {
|
||||||
|
config(['scout.driver' => 'collection']);
|
||||||
|
app(EngineManager::class)->forgetEngines();
|
||||||
|
|
||||||
|
$user = User::factory()->create();
|
||||||
|
$hunt = Hunts::withoutSyncingToSearch(fn () => Hunts::factory()->create([
|
||||||
|
'title' => 'Treasure hunt',
|
||||||
|
]));
|
||||||
|
|
||||||
|
HuntSteps::factory()->create([
|
||||||
|
'hunt_id' => $hunt->id,
|
||||||
|
'xp' => 125,
|
||||||
|
]);
|
||||||
|
|
||||||
|
HuntSteps::factory()->create([
|
||||||
|
'hunt_id' => $hunt->id,
|
||||||
|
'xp' => 75,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response = $this
|
||||||
|
->actingAs($user, 'sanctum')
|
||||||
|
->getJson('/api/hunts');
|
||||||
|
|
||||||
|
$response
|
||||||
|
->assertOk()
|
||||||
|
->assertJsonPath('data.0.id', $hunt->id)
|
||||||
|
->assertJsonPath('data.0.xp', 200)
|
||||||
|
->assertJsonMissingPath('data.0.steps_sum_xp');
|
||||||
|
});
|
||||||
Loading…
Reference in New Issue