import "server-only"; import { and, desc, eq, or, sql } from "drizzle-orm"; import { cached } from "@/lib/cache"; import { db, WebsiteArticles } from "@/lib/db"; export interface NewsListItem { slug: string; title: string; shortStory: string; image: string; createdAt: Date | null; } interface NewsListRow { slug: string; title: string; shortStory: string; image: string; createdAt: Date | null; } const TTL_MS = 300_000; const CACHE_KEY = "news_list"; const FETCH_LIMIT = 30; /** * Shared, cached news list used by both the homepage and the news archive so * a single "news_list" cache entry serves both routes. Returns at most * `limit` rows with `createdAt` normalized to a Date (the cache round-trip * serializes timestamps to ISO strings). */ export async function getNewsList(limit: number): Promise { try { const rows = await cached(CACHE_KEY, TTL_MS, () => db .select({ slug: WebsiteArticles.slug, title: WebsiteArticles.title, shortStory: WebsiteArticles.shortStory, image: WebsiteArticles.image, createdAt: WebsiteArticles.createdAt, }) .from(WebsiteArticles) .where( and( eq(WebsiteArticles.status, "published"), or( sql`${WebsiteArticles.publishAt} IS NULL`, sql`${WebsiteArticles.publishAt} <= NOW()`, ), ), ) .orderBy(desc(WebsiteArticles.createdAt)) .limit(FETCH_LIMIT), ); return rows .map((a) => ({ ...a, createdAt: a.createdAt ? new Date(a.createdAt) : null, })) .slice(0, limit); } catch { return []; } }