fix(FN-4907): invalidate stale settings caches on sync and provider writes

Fusion-Task-Id: FN-4907
Fusion-Task-Lineage: e84d5357-0719-4cc7-ab3f-f665ac83b218
This commit is contained in:
Fusion (runfusion.ai)
2026-05-17 10:07:08 -07:00
committed by gsxdsm
parent f6d6f0f4c0
commit 4416de159c
4 changed files with 37 additions and 0 deletions

View File

@@ -4,6 +4,7 @@ import net from "node:net";
import type { CustomProvider } from "@fusion/core";
import { ApiError, badRequest, notFound } from "../api-error.js";
import type { ApiRouteRegistrar } from "./types.js";
import { invalidateAllGlobalSettingsCaches } from "../project-store-resolver.js";
/**
* Masks an API key for safe display, showing only the first 3 and last 4 characters.
@@ -459,6 +460,7 @@ export const registerCustomProviderRoutes: ApiRouteRegistrar = (ctx) => {
const settings = await store.getGlobalSettingsStore().getSettings();
const providers = settings.customProviders ?? [];
await store.updateGlobalSettings({ customProviders: [...providers, provider] });
invalidateAllGlobalSettingsCaches();
res.status(201).json(sanitizeProvider(provider));
} catch (err: unknown) {
@@ -497,6 +499,7 @@ export const registerCustomProviderRoutes: ApiRouteRegistrar = (ctx) => {
const nextProviders = [...providers];
nextProviders[targetIndex] = updatedProvider;
await store.updateGlobalSettings({ customProviders: nextProviders });
invalidateAllGlobalSettingsCaches();
res.json(sanitizeProvider(updatedProvider));
} catch (err: unknown) {
@@ -528,6 +531,7 @@ export const registerCustomProviderRoutes: ApiRouteRegistrar = (ctx) => {
const nextProviders = providers.filter((provider) => provider.id !== providerId);
await store.updateGlobalSettings({ customProviders: nextProviders });
invalidateAllGlobalSettingsCaches();
res.json({ success: true });
} catch (err: unknown) {
if (err instanceof ApiError) {

View File

@@ -1,4 +1,5 @@
import { ApiError, badRequest } from "../api-error.js";
import { invalidateAllGlobalSettingsCaches } from "../project-store-resolver.js";
import { getFusionAuthPath } from "../auth-paths.js";
import { readStoredAuthProvidersFromDisk, toProviderAuthEntries } from "./register-settings-sync-helpers.js";
import type { ApiRouteRegistrar } from "./types.js";
@@ -64,6 +65,20 @@ export const registerSettingsSyncInboundRoutes: ApiRouteRegistrar = (ctx) => {
// Apply remote settings
const result = await central.applyRemoteSettings(payload);
// Apply inbound global settings through TaskStore so process-local caches
// and settings listeners receive consistent updates.
if (result.success && payload.global && typeof payload.global === "object") {
const localGlobal = await store.getGlobalSettingsStore().getSettings() as Record<string, unknown>;
const globalPatch = Object.fromEntries(
Object.entries(payload.global as Record<string, unknown>)
.filter(([key, value]) => value !== undefined && localGlobal[key] === undefined),
);
if (Object.keys(globalPatch).length > 0) {
await store.updateGlobalSettings(globalPatch);
invalidateAllGlobalSettingsCaches();
}
}
// Build applied/skipped field lists
const appliedFields = [
...Object.keys(payload.global || {}),