import { NextResponse } from "next/server" import { createSupabaseAdminClient } from "@/lib/supabase/admin" import { authenticateApiRequest } from "@/lib/api-auth" export async function GET(request: Request) { const authResult = await authenticateApiRequest(request) if (!authResult.authenticated) { return NextResponse.json( { error: authResult.error }, { status: authResult.status } ) } const { searchParams } = new URL(request.url) const feedIdentifier = searchParams.get("feedIdentifier") const isRead = searchParams.get("isRead") const isSaved = searchParams.get("isSaved") const cursor = searchParams.get("cursor") const limitParameter = searchParams.get("limit") const parsedLimit = Number(limitParameter) const limit = Number.isFinite(parsedLimit) && parsedLimit > 0 ? Math.min(Math.floor(parsedLimit), 100) : 50 const adminClient = createSupabaseAdminClient() const { data: subscriptionRows } = await adminClient .from("subscriptions") .select("feed_id") .eq("user_id", authResult.user.userIdentifier) const subscribedFeedIdentifiers = (subscriptionRows ?? []).map( (row) => row.feed_id ) if (subscribedFeedIdentifiers.length === 0) { return NextResponse.json({ entries: [], nextCursor: null }) } let query = adminClient .from("entries") .select( "id, feed_id, guid, title, url, author, summary, image_url, published_at, enclosure_url, enclosure_type, user_entry_states!left(read, saved)" ) .in("feed_id", subscribedFeedIdentifiers) .is("owner_id", null) .order("published_at", { ascending: false }) .limit(limit + 1) if (feedIdentifier) { query = query.eq("feed_id", feedIdentifier) } if (cursor) { query = query.lt("published_at", cursor) } const { data, error } = await query if (error) { return NextResponse.json( { error: "failed to load entries" }, { status: 500 } ) } interface EntryRow { id: string feed_id: string guid: string | null title: string | null url: string | null author: string | null summary: string | null image_url: string | null published_at: string | null enclosure_url: string | null enclosure_type: string | null user_entry_states: Array<{ read: boolean; saved: boolean }> | null } let entries = (data as unknown as EntryRow[]).map((row) => { const state = row.user_entry_states?.[0] return { entryIdentifier: row.id, feedIdentifier: row.feed_id, guid: row.guid, title: row.title, url: row.url, author: row.author, summary: row.summary, imageUrl: row.image_url, publishedAt: row.published_at, enclosureUrl: row.enclosure_url, enclosureType: row.enclosure_type, isRead: state?.read ?? false, isSaved: state?.saved ?? false, } }) if (isRead === "true") entries = entries.filter((entry) => entry.isRead) if (isRead === "false") entries = entries.filter((entry) => !entry.isRead) if (isSaved === "true") entries = entries.filter((entry) => entry.isSaved) if (isSaved === "false") entries = entries.filter((entry) => !entry.isSaved) const hasMore = entries.length > limit if (hasMore) entries = entries.slice(0, limit) const nextCursor = hasMore && entries.length > 0 ? entries[entries.length - 1].publishedAt : null return NextResponse.json({ entries, nextCursor }) }