isAdmin() && collect($adminOnlyKeys)->contains(static fn (string $key): bool => array_key_exists($key, $attributes))) { throw ValidationException::withMessages([ 'partner_key' => 'Only admins can update partner or trust metadata.', ]); } $payload = [ 'partner_key' => array_key_exists('partner_key', $attributes) ? ($attributes['partner_key'] ?: null) : $collection->partner_key, 'trust_tier' => array_key_exists('trust_tier', $attributes) ? ($attributes['trust_tier'] ?: null) : $collection->trust_tier, 'promotion_tier' => array_key_exists('promotion_tier', $attributes) ? ($attributes['promotion_tier'] ?: null) : $collection->promotion_tier, 'sponsorship_state' => array_key_exists('sponsorship_state', $attributes) ? ($attributes['sponsorship_state'] ?: null) : $collection->sponsorship_state, 'ownership_domain' => array_key_exists('ownership_domain', $attributes) ? ($attributes['ownership_domain'] ?: null) : $collection->ownership_domain, 'commercial_review_state' => array_key_exists('commercial_review_state', $attributes) ? ($attributes['commercial_review_state'] ?: null) : $collection->commercial_review_state, 'legal_review_state' => array_key_exists('legal_review_state', $attributes) ? ($attributes['legal_review_state'] ?: null) : $collection->legal_review_state, ]; $before = [ 'partner_key' => $collection->partner_key, 'trust_tier' => $collection->trust_tier, 'promotion_tier' => $collection->promotion_tier, 'sponsorship_state' => $collection->sponsorship_state, 'ownership_domain' => $collection->ownership_domain, 'commercial_review_state' => $collection->commercial_review_state, 'legal_review_state' => $collection->legal_review_state, ]; $collection->forceFill($payload)->save(); $fresh = $collection->fresh(); app(CollectionHistoryService::class)->record( $fresh, $actor, 'partner_program_metadata_updated', 'Collection partner and governance metadata updated.', $before, $payload, ); return $fresh; } public function publicLanding(string $programKey, int $limit = 18): array { $normalizedKey = trim($programKey); if ($normalizedKey === '') { return [ 'program' => null, 'collections' => new EloquentCollection(), 'editorial_collections' => new EloquentCollection(), 'community_collections' => new EloquentCollection(), 'recent_collections' => new EloquentCollection(), ]; } $baseQuery = Collection::query() ->public() ->where('program_key', $normalizedKey) ->where('placement_eligibility', true) ->with(['user:id,username,name', 'coverArtwork:id,user_id,title,slug,hash,thumb_ext,published_at,is_public,is_approved,deleted_at']); $collections = (clone $baseQuery) ->orderByDesc('ranking_score') ->orderByDesc('health_score') ->limit(max(1, min($limit, 24))) ->get(); $leadCollection = $collections->first() ?: (clone $baseQuery)->first(); $partnerLabels = (clone $baseQuery)->whereNotNull('partner_label')->pluck('partner_label')->filter()->unique()->values()->all(); $sponsorshipLabels = (clone $baseQuery)->whereNotNull('sponsorship_label')->pluck('sponsorship_label')->filter()->unique()->values()->all(); return [ 'program' => $leadCollection ? [ 'key' => $normalizedKey, 'label' => $leadCollection->banner_text ?: $leadCollection->badge_label ?: Str::headline(str_replace(['_', '-'], ' ', $normalizedKey)), 'description' => $leadCollection->summary ?: $leadCollection->description ?: sprintf('Public collections grouped under the %s program, prepared for discovery, partner, and editorial surfaces.', Str::headline(str_replace(['_', '-'], ' ', $normalizedKey))), 'promotion_tier' => $leadCollection->promotion_tier, 'partner_labels' => $partnerLabels, 'sponsorship_labels' => $sponsorshipLabels, 'trust_tier' => $leadCollection->trust_tier, 'collections_count' => (clone $baseQuery)->count(), ] : null, 'collections' => $collections, 'editorial_collections' => (clone $baseQuery)->where('type', Collection::TYPE_EDITORIAL)->orderByDesc('ranking_score')->limit(6)->get(), 'community_collections' => (clone $baseQuery)->where('type', Collection::TYPE_COMMUNITY)->orderByDesc('ranking_score')->limit(6)->get(), 'recent_collections' => (clone $baseQuery)->latest('published_at')->limit(6)->get(), ]; } }