SPB Git
2.0 KB · 25 lines typescript
1import { z } from "zod";2import { eq } from "drizzle-orm";3import { handler, parseBody } from "@/lib/api";4import { db, schema } from "@/db";5import { audit } from "@/lib/audit";67/** GET → profile + preferences + a few workspace-level settings the Settings screen needs. */8export const GET = handler(async ({ user, ws }) => {9  const [u] = await db.select({ id: schema.users.id, username: schema.users.username, displayName: schema.users.displayName, email: schema.users.email, totpEnabled: schema.users.totpEnabled, preferences: schema.users.preferences, createdAt: schema.users.createdAt }).from(schema.users).where(eq(schema.users.id, user.id));10  const [budget] = await db.select().from(schema.settings).where(eq(schema.settings.key, "ai.daily_budget_usd"));11  return Response.json({ ...u, workspace: { id: ws.id, name: ws.name }, aiBudgetUsd: Number((budget?.value as any) ?? 20), sessionId: user.sessionId });12});13/** PATCH { displayName?, email?, preferences? } — preferences are shallow-merged into users.preferences. */14export const PATCH = handler(async ({ req, user }) => {15  const b = await parseBody(req, z.object({ displayName: z.string().trim().min(1).max(100).optional(), email: z.string().trim().email().max(200).nullable().or(z.literal("")).optional(), preferences: z.record(z.string(), z.unknown()).optional() }));16  const [cur] = await db.select({ preferences: schema.users.preferences }).from(schema.users).where(eq(schema.users.id, user.id));17  const set: Partial<typeof schema.users.$inferInsert> = { updatedAt: new Date() };18  if (b.displayName !== undefined) set.displayName = b.displayName;19  if (b.email !== undefined) set.email = b.email || null;20  if (b.preferences) set.preferences = { ...(cur?.preferences ?? {}), ...b.preferences };21  const [u] = await db.update(schema.users).set(set).where(eq(schema.users.id, user.id)).returning({ displayName: schema.users.displayName, email: schema.users.email, preferences: schema.users.preferences });22  await audit(user.id, "settings.update", undefined, { keys: Object.keys(b) });23  return Response.json(u);24});25
Files · main
Menu

Theme