feat: add reusable gallery carousel and ranking feed infrastructure

This commit is contained in:
2026-02-28 07:56:25 +01:00
parent 67ef79766c
commit 6536d4ae78
36 changed files with 3177 additions and 373 deletions

53
app/Models/RankList.php Normal file
View File

@@ -0,0 +1,53 @@
<?php
declare(strict_types=1);
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
/**
* App\Models\RankList
*
* Stores an ordered list of artwork IDs for a feed surface.
* Rebuilt hourly by RankBuildListsJob.
*
* scope_id = 0 is the sentinel for "global" scope.
*
* @property int $id
* @property string $scope_type global | category | content_type
* @property int $scope_id 0 = global; category.id or content_type.id otherwise
* @property string $list_type trending | new_hot | best
* @property string $model_version
* @property array $artwork_ids Ordered array of artwork IDs
* @property \Carbon\Carbon|null $computed_at
*/
class RankList extends Model
{
protected $table = 'rank_lists';
public $timestamps = false;
protected $fillable = [
'scope_type',
'scope_id',
'list_type',
'model_version',
'artwork_ids',
'computed_at',
];
protected $casts = [
'scope_id' => 'integer',
'artwork_ids' => 'array',
'computed_at' => 'datetime',
];
// ── Scope helpers ──────────────────────────────────────────────────────
/** Resolve scope_id: null → 0 (global sentinel). */
public static function resolveScope(?int $id): int
{
return $id ?? 0;
}
}