From 897bc42a96f1b17123d9c8047ba8135252384db5 Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 18 Sep 2026 17:42:22 +0000 Subject: [PATCH] fix: persist settings migration with allowed update --- src/lib/stores/settings-store.ts | 20 +++++++++++++------- src/test/settings-store.test.ts | 14 ++++++++------ 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/lib/stores/settings-store.ts b/src/lib/stores/settings-store.ts index f77ad983d..d1c958a2c 100644 --- a/src/lib/stores/settings-store.ts +++ b/src/lib/stores/settings-store.ts @@ -148,6 +148,18 @@ async function upsertSettings(payload: { } } +async function persistMigratedFeatureConfigs(featureConfigs: Record) { + const userId = await getUserId(); + if (!userId) return; + const { error } = await supabase + .from('user_settings') + .update({ feature_configs: featureConfigs, updated_at: new Date().toISOString() }) + .eq('user_id', userId); + if (error) { + console.warn('[SettingsStore] Failed to persist migrated settings:', error.message); + } +} + export const useSettingsStore = create()( persist( (set, get) => ({ @@ -253,13 +265,7 @@ export const useSettingsStore = create()( wikiResearchEnabled: get().wikiResearchEnabled, }); if (configsNeedMigration) { - await upsertSettings({ - language, - output_language: outputLanguage, - theme, - feature_configs: mergedConfigs, - custom_system_prompt: customSystemPrompt ?? null, - }); + await persistMigratedFeatureConfigs(mergedConfigs); } }, resetLocalData: () => { diff --git a/src/test/settings-store.test.ts b/src/test/settings-store.test.ts index c3e5bb835..c7cf23927 100644 --- a/src/test/settings-store.test.ts +++ b/src/test/settings-store.test.ts @@ -164,18 +164,18 @@ describe("settings-store", () => { expect(attack).toMatchObject({ provider: "openrouter", model: "z-ai/glm-5.3-flash", reasoningEffort: "low" }); expect(attack).not.toHaveProperty("apiKey"); - const settingsWrite = supabaseMock.from.mock.results.find(({ value }) => value.upsert.mock.calls.length)?.value; - expect(settingsWrite.upsert).toHaveBeenCalledWith( + const settingsWrite = supabaseMock.from.mock.results.find(({ value }) => value.update.mock.calls.length)?.value; + expect(settingsWrite.update).toHaveBeenCalledWith( expect.objectContaining({ feature_configs: expect.objectContaining({ generate: expect.objectContaining({ provider: "openrouter", model: "z-ai/glm-5.3-flash" }), attack: expect.objectContaining({ provider: "openrouter", model: "z-ai/glm-5.3-flash" }), }), }), - { onConflict: "user_id" }, ); - expect(settingsWrite.upsert.mock.calls[0][0].feature_configs.generate).not.toHaveProperty("apiKey"); - expect(settingsWrite.upsert.mock.calls[0][0].feature_configs.generate).not.toHaveProperty("baseUrl"); + expect(settingsWrite.update.mock.calls[0][0].feature_configs.generate).not.toHaveProperty("apiKey"); + expect(settingsWrite.update.mock.calls[0][0].feature_configs.generate).not.toHaveProperty("baseUrl"); + expect(settingsWrite.update.mock.results[0].value.eq).toHaveBeenCalledWith("user_id", "user_1"); }); it("does not rewrite server feature configs that are already canonical", async () => { @@ -192,7 +192,9 @@ describe("settings-store", () => { await useSettingsStore.getState().hydrateFromServer(); - const settingsWrites = supabaseMock.from.mock.results.filter(({ value }) => value.upsert.mock.calls.length); + const settingsWrites = supabaseMock.from.mock.results.filter(({ value }) => + value.upsert.mock.calls.length || value.update.mock.calls.length + ); expect(settingsWrites).toHaveLength(0); });