Files
avbeat-com/src/app/api/ticker/beat-news/route.ts

61 lines
1.8 KiB
TypeScript

import { NextResponse } from 'next/server';
import { createClient } from '@supabase/supabase-js';
export const runtime = 'nodejs';
export const revalidate = 300; // 5 minutes
const SUPABASE_URL = process.env.NEXT_PUBLIC_SUPABASE_URL!;
const SUPABASE_ANON = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!;
export async function GET() {
const sb = createClient(SUPABASE_URL, SUPABASE_ANON, {
db: { schema: 'bb' },
auth: { persistSession: false },
});
const cutoff = new Date(Date.now() - 7 * 86400000).toISOString();
// Primary source: bb.wp_imported_posts (BB's main article table).
let { data, error } = await sb
.from('wp_imported_posts')
.select('wp_id, wp_slug, title, category, wp_published_at')
.eq('status', 'published')
.gte('wp_published_at', cutoff)
.order('wp_published_at', { ascending: false })
.limit(30);
// Fallback: if the 7-day window is empty, show the 30 most recent
// published articles regardless of age so the ticker isn't blank.
if (!error && (data?.length ?? 0) === 0) {
const recent = await sb
.from('wp_imported_posts')
.select('wp_id, wp_slug, title, category, wp_published_at')
.eq('status', 'published')
.order('wp_published_at', { ascending: false })
.limit(30);
data = recent.data;
error = recent.error;
}
if (error) {
return NextResponse.json({ error: error.message, items: [] }, { status: 500 });
}
const items = (data || []).map((a) => ({
id: String(a.wp_id),
href: `/news/${a.wp_slug}`,
title: a.title,
category: a.category || null,
published_at: a.wp_published_at,
}));
return NextResponse.json(
{ items },
{
headers: {
'Cache-Control': 'public, s-maxage=300, stale-while-revalidate=600',
},
}
);
}