feat(settings): storage budgets, retention days and cache TTL settings (CACHE-2)

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-09-29 17:16:50 +08:00
1 parent c3aaf901ad
commit 58e358e4a9
2 files changed
+139 -8

No files matched your search

@@ -1,5 +1,11 @@
import { createCipheriv, createDecipheriv, createHmac, randomBytes, randomUUID } from "node:crypto";
import { DEFAULT_SETTINGS, GlobalSettings, type SecretPurpose, type SettingsKey } from "@umt/contracts";
import {
DEFAULT_SETTINGS,
GlobalSettings,
type SecretPurpose,
type SettingsKey,
withStorageDefaults,
} from "@umt/contracts";
import type { DB, Kysely } from "@umt/db";
import type { Logger } from "pino";
import type { EventBusPort } from "../../http/sse.ts";
@@ -335,7 +341,13 @@ export function createSettingsReader(deps: {
for (const key of Object.keys(DEFAULT_SETTINGS) as SettingsKey[]) {
const def = DEFAULT_SETTINGS[key];
const v = stored.get(key);
const merged = v && typeof v === "object" && !Array.isArray(v) ? { ...def, ...(v as object) } : def;
// storage 是两层结构:逐层补缺省,旧库里缺子字段也能整体通过校验
const merged =
key === "storage"
? withStorageDefaults(v)
: v && typeof v === "object" && !Array.isArray(v)
? { ...def, ...(v as object) }
: def;
const parsed = GlobalSettings.shape[key].safeParse(merged);
if (!parsed.success) deps.logger.warn({ key }, "settings 值不合法,回退缺省");
out[key] = parsed.success ? parsed.data : def;