Web: Boost-Platzierung auf Start- und Branchenseite ausspielen

Geboostete PMs besetzen Lead- und Top-Slots vor der Chronologie
(HomePageData/CategoryPageData ueber boosted()-Scope) und tragen das
Badge "Top-Platzierung". Abgelaufene Boosts wirken nicht.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Kevin Adametz 2026-07-10 17:05:10 +00:00
parent 0665553c88
commit df6b24518c
10 changed files with 183 additions and 19 deletions

View file

@ -95,18 +95,36 @@ class CategoryPageData
'images' => fn ($query) => $query->orderByDesc('is_preview')->orderBy('sort_order')->limit(1),
];
$leadRelease = $base()->with($with)->orderByDesc('published_at')->first();
// Gebuchte Boosts (Decision-Update §2.2): geboostete PMs der Branche
// besetzen Lead- und Top-Plätze vor der Chronologie; die Views
// markieren sie über `boostedIds`.
$boostedReleases = $base()
->boosted()
->with($with)
->orderByDesc('published_at')
->limit(3)
->get();
$boostedIds = $boostedReleases->modelKeys();
$leadRelease = $boostedReleases->first()
?? $base()->with($with)->orderByDesc('published_at')->first();
// Ohne mediumText-Spalte `text`: Top-/Feed-Listen rendern nur
// Titel/Meta, der Volltext wäre unnötiger I/O.
$listColumns = ['id', 'portal', 'language', 'slug', 'title', 'category_id', 'company_id', 'published_at', 'content_score'];
$topReleases = $base()
->with($with)
->when($leadRelease, fn (Builder $query) => $query->whereKeyNot($leadRelease->getKey()))
->orderByDesc('published_at')
->limit(2)
->get($listColumns);
$topBoosted = $boostedReleases->slice(1)->take(2)->values();
$topChronoSlots = 2 - $topBoosted->count();
$topReleases = $topChronoSlots > 0
? $base()
->with($with)
->when($leadRelease, fn (Builder $query) => $query->whereKeyNot($leadRelease->getKey()))
->when($boostedIds !== [], fn (Builder $query) => $query->whereNotIn('id', $boostedIds))
->orderByDesc('published_at')
->limit($topChronoSlots)
->get($listColumns)
: collect();
$topReleases = $topBoosted->concat($topReleases)->values();
$excludeIds = collect([$leadRelease?->getKey()])->merge($topReleases->modelKeys())->filter()->all();
@ -249,6 +267,7 @@ class CategoryPageData
'leadRelease' => $leadRelease,
'topReleases' => $topReleases,
'feedReleases' => $feedReleases,
'boostedIds' => $boostedIds,
'mostReadReleases' => $mostReadReleases,
'categoryStats' => $stats,
'topNewsrooms' => $topNewsrooms,