homepage: auto-promote advertiser stories + premium slots in Industry News

Three-tier sort on the Industry News feed:
1. Premium — articles pinned via adv.featured_story_slots (paid slots).
   Sorted by position ascending. Highlighted with an amber left-border
   gradient + ★ Featured ribbon.
2. Advertiser — articles whose title contains the company name of a
   current active banner advertiser on this property, AND were published
   in the last 48 hours. Highlighted with a blue left-border gradient
   + ◆ Advertiser ribbon. Multiple matches ordered by publish date.
3. General — everything else, newest first.

After 48h, advertiser stories naturally drop back into the general
tier. Premium slots fall off when their ends_at passes.

Detection is title-only with case-insensitive word-boundary match; the
longest matching company name wins so "Sony Pictures" beats "Sony"
when both advertise. Backed by the new adv.active_advertisers_by_
property view.

createAdminClient() now accepts an optional schema arg so we can hit
adv from BB without juggling clients.

API revalidate dropped 300 → 60s so the feed reflects campaign flips
within a minute.
This commit is contained in:
Ryan Salazar
2026-05-27 12:25:20 +00:00
parent d82b8edd21
commit c1ab36297c
4 changed files with 227 additions and 10 deletions

View File

@@ -8,7 +8,7 @@ import { createClient } from "@supabase/supabase-js";
* Needs SUPABASE_SERVICE_ROLE_KEY in the env (set as a Coolify app env var,
* NOT prefixed with NEXT_PUBLIC_ so it never ships to the client bundle).
*/
export function createAdminClient() {
export function createAdminClient(schema?: string) {
const url = process.env.NEXT_PUBLIC_SUPABASE_URL;
const key = process.env.SUPABASE_SERVICE_ROLE_KEY;
if (!url || !key) {
@@ -18,6 +18,6 @@ export function createAdminClient() {
}
return createClient(url, key, {
auth: { persistSession: false, autoRefreshToken: false },
db: { schema: process.env.NEXT_PUBLIC_SUPABASE_SCHEMA || "bb" },
db: { schema: schema || process.env.NEXT_PUBLIC_SUPABASE_SCHEMA || "bb" },
});
}