TypeScript 97.4%
SQL 1%
JavaScript 0.9%
CSS 0.6%
1import { and, desc, eq } from "drizzle-orm";2import { withUser, json } from "@/lib/api";3import { getDb, auditEvents, conversations, messages, promptPresets, modelPresets, usageRecords, userPreferences, providerConnections, arenaSessions, arenaResponses, folders } from "@/db";45export const dynamic = "force-dynamic";67/** GET /api/account?export=1 — full account export (JSON) or the audit log. */8export const GET = withUser(async ({ req, user }) => {9 const db = getDb();10 const url = new URL(req.url);11 if (url.searchParams.get("export") === "1") {12 const [convs, msgs, prompts, presets, usage, prefs, conns, arenas, arenaResps, flds] = await Promise.all([13 db.select().from(conversations).where(eq(conversations.userId, user.id)),14 db.select().from(messages).where(eq(messages.userId, user.id)),15 db.select().from(promptPresets).where(eq(promptPresets.userId, user.id)),16 db.select().from(modelPresets).where(eq(modelPresets.userId, user.id)),17 db.select().from(usageRecords).where(eq(usageRecords.userId, user.id)),18 db.select().from(userPreferences).where(eq(userPreferences.userId, user.id)),19 db.select({ provider: providerConnections.provider, keyHint: providerConnections.keyHint, status: providerConnections.status, createdAt: providerConnections.createdAt }).from(providerConnections).where(eq(providerConnections.userId, user.id)),20 db.select().from(arenaSessions).where(eq(arenaSessions.userId, user.id)),21 db.select().from(arenaResponses).innerJoin(arenaSessions, eq(arenaResponses.sessionId, arenaSessions.id)).where(eq(arenaSessions.userId, user.id)),22 db.select().from(folders).where(eq(folders.userId, user.id)),23 ]);24 const body = JSON.stringify(25 {26 exportedAt: new Date().toISOString(),27 app: "PolyLLM",28 account: { id: user.id, email: user.email, name: user.name, createdAt: user.createdAt },29 preferences: prefs[0] ?? null,30 providers: conns, // hints only — never key material31 folders: flds,32 conversations: convs,33 messages: msgs,34 promptPresets: prompts,35 modelPresets: presets,36 arena: { sessions: arenas, responses: arenaResps.map((r) => r.arena_responses) },37 usage,38 },39 null,40 2,41 );42 return new Response(body, { headers: { "Content-Type": "application/json", "Content-Disposition": `attachment; filename="polyllm-export-${new Date().toISOString().slice(0, 10)}.json"` } });43 }44 const audit = await db45 .select()46 .from(auditEvents)47 .where(and(eq(auditEvents.userId, user.id)))48 .orderBy(desc(auditEvents.createdAt))49 .limit(100);50 return json({ audit: audit.map((a) => ({ ...a, createdAt: a.createdAt.toISOString() })) });51});52