import { and, eq } from 'drizzle-orm'; import * as z from 'zod'; import { settings } from '~~/drizzle/schema'; import { db } from '~~/server/lib/db'; const appearanceSchema = z.object({ colorScheme: z.enum(['light', 'dark', 'system']).optional(), accent: z.string().optional(), neutral: z.string().optional(), hinting: z.number().min(0).max(100).optional(), fontSize: z.string().optional(), }); const updateSettingsSchema = z.object({ systemAssistants: z.object({ rename: z.object({ enabled: z.boolean(), modelId: z.string().nullable(), }).partial().optional(), }).optional(), appearance: appearanceSchema.optional(), }); export default defineEventHandler(async (event) => { await protectRoute(event); const userId = event.context.user!.id as string; const body = await readBody(event); const parseResult = updateSettingsSchema.safeParse(body); if (!parseResult.success) { throw createError({ statusCode: 400, message: parseResult.error.issues[0]!.message, }); } const updates = parseResult.data; const existing = await db.query.settings.findFirst({ where: { userId }, }); if (!existing) { throw createError({ statusCode: 404, statusMessage: 'Settings not found', }); } const existingId: string = existing.id; const mergeAppearance = ( existingAppearance: Record | null, incoming: typeof updates.appearance, ): Record => { const base = existingAppearance || {}; if (!incoming) return base; return { ...base, ...incoming }; }; const newSystemAssistants = { rename: { enabled: updates.systemAssistants?.rename?.enabled ?? existing.systemAssistants.rename?.enabled ?? false, modelId: updates.systemAssistants?.rename?.modelId !== undefined ? updates.systemAssistants.rename.modelId : existing.systemAssistants.rename?.modelId ?? null, }, }; const newAppearance = mergeAppearance( existing.appearance as Record | null, updates.appearance, ); await db.update(settings) .set({ appearance: newAppearance, systemAssistants: newSystemAssistants, }) .where(and(eq(settings.id, existingId))); const updated = await db.select() .from(settings) .where(and(eq(settings.id, existingId))) .limit(1); return updated[0]; });