fix: invalidate cached public site settings
This commit is contained in:
parent
33f25f4b21
commit
bd98282bc5
@ -67,6 +67,7 @@ import {
|
||||
EXTERNAL_IMAGE_API_CONFIG_KEY,
|
||||
normalizeExternalImageApiConfig,
|
||||
} from "@/lib/external-image-api/config";
|
||||
import { clearScopedSiteSettingsCache } from "@/lib/site-settings/public-cache";
|
||||
|
||||
const settingSchema = z.object({
|
||||
key: z.string(),
|
||||
@ -270,6 +271,7 @@ export async function POST(request: Request) {
|
||||
value: normalizeExternalImageApiConfig(value),
|
||||
updatedBy: session.user.id,
|
||||
});
|
||||
clearScopedSiteSettingsCache();
|
||||
|
||||
return Response.json({
|
||||
setting: saved[0],
|
||||
@ -388,6 +390,7 @@ export async function POST(request: Request) {
|
||||
value: nextValue,
|
||||
updatedBy: session.user.id,
|
||||
});
|
||||
clearScopedSiteSettingsCache();
|
||||
|
||||
return Response.json({ setting: setting[0] });
|
||||
} catch (error) {
|
||||
|
||||
@ -98,6 +98,13 @@ import {
|
||||
normalizeOssImageMigrationConfig,
|
||||
OSS_MIGRATION_CONFIG_KEY,
|
||||
} from "@/lib/storage/migration-config";
|
||||
import {
|
||||
clearScopedSiteSettingsCache,
|
||||
deleteScopedSiteSettingsCache,
|
||||
getScopedSiteSettingsCache,
|
||||
PUBLIC_SITE_SETTINGS_CACHE_TTL_MS,
|
||||
setScopedSiteSettingsCache,
|
||||
} from "@/lib/site-settings/public-cache";
|
||||
import {
|
||||
getHomeChatAnimationHtmlBytes,
|
||||
HOME_CHAT_ANIMATION_CONFIG_KEY,
|
||||
@ -502,22 +509,19 @@ const PUBLIC_SITE_SETTINGS_SCOPES = new Set<string>([
|
||||
"home",
|
||||
]);
|
||||
|
||||
const SCOPED_SITE_SETTINGS_SERVER_CACHE_TTL_MS = 30_000;
|
||||
const scopedSiteSettingsServerCache = new Map<
|
||||
string,
|
||||
{ data: Record<string, unknown>; expiresAt: number }
|
||||
>();
|
||||
|
||||
function createScopedSiteSettingsResponse(
|
||||
scope: PublicSiteSettingsScope,
|
||||
data: Record<string, unknown>,
|
||||
cacheStatus: "HIT" | "MISS" = "MISS",
|
||||
cacheKey: string = scope
|
||||
) {
|
||||
scopedSiteSettingsServerCache.set(cacheKey, {
|
||||
data,
|
||||
expiresAt: Date.now() + SCOPED_SITE_SETTINGS_SERVER_CACHE_TTL_MS,
|
||||
});
|
||||
if (cacheStatus !== "HIT") {
|
||||
setScopedSiteSettingsCache(
|
||||
cacheKey,
|
||||
data,
|
||||
PUBLIC_SITE_SETTINGS_CACHE_TTL_MS
|
||||
);
|
||||
}
|
||||
|
||||
const response = NextResponse.json(data);
|
||||
// Lightweight public settings change rarely; keep them browser-local briefly
|
||||
@ -883,7 +887,7 @@ export async function GET(request: NextRequest) {
|
||||
const cacheKey = brandName.trim()
|
||||
? `${scopedScope}:${brandName.trim().toLowerCase()}`
|
||||
: scopedScope;
|
||||
const cached = scopedSiteSettingsServerCache.get(cacheKey);
|
||||
const cached = getScopedSiteSettingsCache(cacheKey);
|
||||
if (cached && cached.expiresAt > Date.now()) {
|
||||
return createScopedSiteSettingsResponse(
|
||||
scopedScope,
|
||||
@ -892,6 +896,9 @@ export async function GET(request: NextRequest) {
|
||||
cacheKey
|
||||
);
|
||||
}
|
||||
if (cached) {
|
||||
deleteScopedSiteSettingsCache(cacheKey);
|
||||
}
|
||||
|
||||
return getScopedPublicSiteSettings(scopedScope, {
|
||||
brandName,
|
||||
@ -2625,7 +2632,7 @@ export async function PUT(request: NextRequest) {
|
||||
}
|
||||
|
||||
await persistHomeAnimationConfig();
|
||||
scopedSiteSettingsServerCache.clear();
|
||||
clearScopedSiteSettingsCache();
|
||||
|
||||
return NextResponse.json({
|
||||
...updated,
|
||||
@ -3274,7 +3281,7 @@ export async function PUT(request: NextRequest) {
|
||||
},
|
||||
});
|
||||
}
|
||||
scopedSiteSettingsServerCache.clear();
|
||||
clearScopedSiteSettingsCache();
|
||||
|
||||
return NextResponse.json({
|
||||
...created,
|
||||
|
||||
52
lib/site-settings/public-cache.ts
Normal file
52
lib/site-settings/public-cache.ts
Normal file
@ -0,0 +1,52 @@
|
||||
const PUBLIC_SITE_SETTINGS_CACHE_TTL_MS = 30_000;
|
||||
const PUBLIC_SITE_SETTINGS_CACHE_KEY = Symbol.for(
|
||||
"ai-chatbot.public-site-settings-cache",
|
||||
);
|
||||
|
||||
type PublicSiteSettingsCacheEntry = {
|
||||
data: Record<string, unknown>;
|
||||
expiresAt: number;
|
||||
};
|
||||
|
||||
function getPublicSiteSettingsCacheStore() {
|
||||
const globalCache = globalThis as typeof globalThis & {
|
||||
[PUBLIC_SITE_SETTINGS_CACHE_KEY]?: Map<
|
||||
string,
|
||||
PublicSiteSettingsCacheEntry
|
||||
>;
|
||||
};
|
||||
|
||||
if (!globalCache[PUBLIC_SITE_SETTINGS_CACHE_KEY]) {
|
||||
globalCache[PUBLIC_SITE_SETTINGS_CACHE_KEY] = new Map<
|
||||
string,
|
||||
PublicSiteSettingsCacheEntry
|
||||
>();
|
||||
}
|
||||
|
||||
return globalCache[PUBLIC_SITE_SETTINGS_CACHE_KEY]!;
|
||||
}
|
||||
|
||||
export function getScopedSiteSettingsCache(cacheKey: string) {
|
||||
return getPublicSiteSettingsCacheStore().get(cacheKey) ?? null;
|
||||
}
|
||||
|
||||
export function setScopedSiteSettingsCache(
|
||||
cacheKey: string,
|
||||
data: Record<string, unknown>,
|
||||
ttlMs: number = PUBLIC_SITE_SETTINGS_CACHE_TTL_MS,
|
||||
) {
|
||||
getPublicSiteSettingsCacheStore().set(cacheKey, {
|
||||
data,
|
||||
expiresAt: Date.now() + ttlMs,
|
||||
});
|
||||
}
|
||||
|
||||
export function deleteScopedSiteSettingsCache(cacheKey: string) {
|
||||
getPublicSiteSettingsCacheStore().delete(cacheKey);
|
||||
}
|
||||
|
||||
export function clearScopedSiteSettingsCache() {
|
||||
getPublicSiteSettingsCacheStore().clear();
|
||||
}
|
||||
|
||||
export { PUBLIC_SITE_SETTINGS_CACHE_TTL_MS };
|
||||
Loading…
x
Reference in New Issue
Block a user