export type AccountLanguage = "zh-CN" | "en-US"; export type AccountAnswerDepth = "concise" | "balanced" | "deep"; export type AccountEvidenceDisplay = "summary" | "inline" | "full"; export type AccountNotificationKey = "pendingConfirmation" | "executionWriteback" | "releaseGate" | "failureAlert"; export type AccountSettingsSaveScope = "local" | "account"; export interface AccountProfileSettings { displayName: string; roleTitle: string; email: string; defaultLanguage: AccountLanguage; } export interface AccountAiPreferenceSettings { answerDepth: AccountAnswerDepth; evidenceDisplay: AccountEvidenceDisplay; } export interface AccountNotificationPreference { enabled: boolean; desktop: boolean; emailDigest: boolean; } export type AccountNotificationSettings = Record; export interface AccountSettings { profile: AccountProfileSettings; aiPreferences: AccountAiPreferenceSettings; notifications: AccountNotificationSettings; saveScope: AccountSettingsSaveScope; updatedAt: string; } export interface AccountSettingsSeed { displayName?: string | null; roleTitle?: string | null; email?: string | null; } const STORAGE_KEY = "pmflow:account-settings:v1"; export const accountNotificationLabels: Record = { pendingConfirmation: { title: "待确认", detail: "AI 生成草案、变更项或写入前确认需要你拍板时提醒。", }, executionWriteback: { title: "执行回写", detail: "Agent、IDE 或集成系统回传开发进度、分支、PR 与测试结果时提醒。", }, releaseGate: { title: "发布门禁", detail: "发布校验、合规检查、验收项阻塞或通过时提醒。", }, failureAlert: { title: "失败提醒", detail: "AI 调用、同步任务、执行回写或外部集成失败时提醒。", }, }; export const accountNotificationKeys: AccountNotificationKey[] = [ "pendingConfirmation", "executionWriteback", "releaseGate", "failureAlert", ]; export function createDefaultAccountSettings(seed: AccountSettingsSeed = {}): AccountSettings { return { profile: { displayName: seed.displayName?.trim() || "张子墨", roleTitle: seed.roleTitle?.trim() || "产品负责人", email: seed.email?.trim() || "", defaultLanguage: "zh-CN", }, aiPreferences: { answerDepth: "balanced", evidenceDisplay: "inline", }, notifications: { pendingConfirmation: { enabled: true, desktop: true, emailDigest: false }, executionWriteback: { enabled: true, desktop: true, emailDigest: false }, releaseGate: { enabled: true, desktop: true, emailDigest: true }, failureAlert: { enabled: true, desktop: true, emailDigest: true }, }, saveScope: "local", updatedAt: new Date().toISOString(), }; } function isBrowserStorageAvailable(): boolean { return typeof window !== "undefined" && typeof window.localStorage !== "undefined"; } function readStoredAccountSettings(): Partial | null { if (!isBrowserStorageAvailable()) return null; const raw = window.localStorage.getItem(STORAGE_KEY); if (!raw) return null; try { const parsed = JSON.parse(raw) as Partial; return parsed && typeof parsed === "object" ? parsed : null; } catch { return null; } } function persistAccountSettings(settings: AccountSettings): void { if (!isBrowserStorageAvailable()) { throw new Error("当前环境不支持本机暂存"); } window.localStorage.setItem(STORAGE_KEY, JSON.stringify(settings)); } function mergeAccountSettings(base: AccountSettings, stored: Partial | null): AccountSettings { if (!stored) return base; return { ...base, ...stored, profile: { ...base.profile, ...stored.profile, }, aiPreferences: { ...base.aiPreferences, ...stored.aiPreferences, }, notifications: { ...base.notifications, ...stored.notifications, }, }; } export async function getAccountSettings(seed?: AccountSettingsSeed): Promise { const defaults = createDefaultAccountSettings(seed); return mergeAccountSettings(defaults, readStoredAccountSettings()); } export async function updateAccountSettings(nextSettings: AccountSettings): Promise { const persisted = { ...nextSettings, saveScope: "local" as const, updatedAt: new Date().toISOString(), }; persistAccountSettings(persisted); return persisted; }