import { NextResponse } from "next/server" import { createSupabaseServerClient } from "@/lib/supabase/server" import { rateLimit } from "@/lib/rate-limit" export async function GET() { const supabaseClient = await createSupabaseServerClient() const { data: { user }, } = await supabaseClient.auth.getUser() if (!user) { return NextResponse.json({ error: "not authenticated" }, { status: 401 }) } const rateLimitResult = await rateLimit(`gdpr-export:${user.id}`, 3, 86_400_000) if (!rateLimitResult.success) { return NextResponse.json({ error: "too many requests" }, { status: 429 }) } const [ profileResult, subscriptionsResult, foldersResult, mutedKeywordsResult, customFeedsResult, entryStatesResult, highlightsResult, sharedEntriesResult, savedEntriesResult, ] = await Promise.all([ supabaseClient .from("user_profiles") .select("id, tier, created_at") .eq("id", user.id) .single(), supabaseClient .from("subscriptions") .select("id, feed_id, folder_id, custom_title, created_at, feeds(title, url)") .eq("user_id", user.id), supabaseClient .from("folders") .select("id, name, position, created_at") .eq("user_id", user.id), supabaseClient .from("muted_keywords") .select("id, keyword, created_at") .eq("user_id", user.id), supabaseClient .from("custom_feeds") .select("id, name, query, position, created_at") .eq("user_id", user.id), supabaseClient .from("user_entry_states") .select("entry_id, read, saved, updated_at") .eq("user_id", user.id), supabaseClient .from("user_highlights") .select( "id, entry_id, highlighted_text, note, color, text_offset, text_length, created_at, entries(title, url)" ) .eq("user_id", user.id), supabaseClient .from("shared_entries") .select("id, entry_id, share_token, created_at, entries(title, url)") .eq("user_id", user.id), supabaseClient .from("user_entry_states") .select( "entries(id, title, url, author, summary, published_at, feeds(title, url))" ) .eq("user_id", user.id) .eq("saved", true), ]) const exportData = { exportedAt: new Date().toISOString(), account: { emailAddress: user.email, displayName: user.user_metadata?.display_name ?? null, ...profileResult.data, }, subscriptions: subscriptionsResult.data ?? [], folders: foldersResult.data ?? [], mutedKeywords: mutedKeywordsResult.data ?? [], customFeeds: customFeedsResult.data ?? [], entryStates: entryStatesResult.data ?? [], highlights: highlightsResult.data ?? [], sharedEntries: sharedEntriesResult.data ?? [], savedEntries: (savedEntriesResult.data ?? []).map( (row) => (row as Record).entries ) ?? [], } const jsonString = JSON.stringify(exportData, null, 2) return new Response(jsonString, { headers: { "Content-Type": "application/json", "Content-Disposition": `attachment; filename="asa-news-gdpr-export-${new Date().toISOString().slice(0, 10)}.json"`, }, }) }