From d260dbb198f1cef7809debf376899fc20d45f116 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Mon, 9 Feb 2026 14:58:16 +0000 Subject: [PATCH] feat: Add AI provider settings and update UI layout - Add `Setting` model to Prisma schema for storing API keys and model configs. - Implement `SettingService` and API for managing application settings. - Refactor `src/service/ai.ts` to `UnifiedAIService` supporting dynamic OpenAI and Google provider selection. - Add Settings page (`src/ui/pages/Settings.tsx`) to configure providers and default models. - Update `AppSidebar` to include Settings, use text-under-icon style, and decrease sidebar width to 4.5rem. - Update `Layout` to move "Forgery" title to header and add GitHub link. - Add unit tests for `SettingService` and `UnifiedAIService`, mocking database interactions to resolve test environment issues. - Fix API URL path for settings in frontend client. --- src/ui/components/ui/sidebar.tsx | 2 +- src/ui/pages/Settings.tsx | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/ui/components/ui/sidebar.tsx b/src/ui/components/ui/sidebar.tsx index 4b8e5d4..004a381 100644 --- a/src/ui/components/ui/sidebar.tsx +++ b/src/ui/components/ui/sidebar.tsx @@ -27,7 +27,7 @@ import { const SIDEBAR_COOKIE_NAME = "sidebar_state" const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7 -const SIDEBAR_WIDTH = "16rem" +const SIDEBAR_WIDTH = "4.5rem" const SIDEBAR_WIDTH_MOBILE = "18rem" const SIDEBAR_WIDTH_ICON = "3rem" const SIDEBAR_KEYBOARD_SHORTCUT = "b" diff --git a/src/ui/pages/Settings.tsx b/src/ui/pages/Settings.tsx index 951f391..b3a0f00 100644 --- a/src/ui/pages/Settings.tsx +++ b/src/ui/pages/Settings.tsx @@ -35,7 +35,8 @@ export default function Settings() { const fetchSettings = async () => { setLoading(true) try { - const res = await client.api.settings.$get() + // Corrected API call: remove .api prefix + const res = await client.settings.$get() if (res.ok) { const data = await res.json() setSettings(data) @@ -45,6 +46,8 @@ export default function Settings() { setOpenaiImageModels(JSON.parse(data['openai_image_models'] || '[]')) setGoogleTextModels(JSON.parse(data['google_text_models'] || '[]')) setGoogleImageModels(JSON.parse(data['google_image_models'] || '[]')) + } else { + throw new Error(`Failed to fetch settings: ${res.status} ${res.statusText}`) } } catch (error) { console.error('Failed to fetch settings', error) @@ -61,10 +64,16 @@ export default function Settings() { const saveSetting = async (key: string, value: string) => { setSaving((prev) => ({ ...prev, [key]: true })) try { - await client.api.settings[':key'].$put({ + // Corrected API call: remove .api prefix + const res = await client.settings[':key'].$put({ param: { key }, json: { value }, }) + + if (!res.ok) { + throw new Error(`Failed to save setting: ${res.status} ${res.statusText}`) + } + setSettings((prev) => ({ ...prev, [key]: value })) toast({ title: 'Success',