docs/architecture/storage-key-architecture.md
本文档详细说明了应用中存储键的两种用途及其关系,解决了数据导出不完整的架构问题。
用途: 实际的数据存储操作(localStorage、Dexie、文件存储等)
// PreferenceService添加 'pref:' 前缀
private readonly PREFIX = 'pref:';
// 逻辑键名 -> 物理存储键名
'app:settings:ui:theme-id' -> 'pref:app:settings:ui:theme-id'
'app:settings:ui:preferred-language' -> 'pref:app:settings:ui:preferred-language'
'app:selected-optimize-model' -> 'pref:app:selected-optimize-model'
'app:selected-test-model' -> 'pref:app:selected-test-model'
'app:selected-optimize-template' -> 'pref:app:selected-optimize-template'
'app:selected-user-optimize-template' -> 'pref:app:selected-user-optimize-template'
'app:selected-iterate-template' -> 'pref:app:selected-iterate-template'
// 核心服务直接使用存储,无前缀
'models' // ModelManager
'user-templates' // TemplateManager
'prompt_history' // HistoryManager
用途: JSON数据交换格式,用于数据导入导出
{
"version": 1,
"data": {
"userSettings": {
"app:settings:ui:theme-id": "dark", // 逻辑键名
"app:settings:ui:preferred-language": "zh-CN", // 逻辑键名
"app:settings:ui:builtin-template-language": "zh-CN", // 现在也通过PreferenceService
"app:selected-optimize-model": "gemini",
"app:selected-test-model": "siliconflow",
"app:selected-optimize-template": "general-optimize",
"app:selected-user-optimize-template": "user-template-id",
"app:selected-iterate-template": "iterate"
},
"models": [...],
"userTemplates": [...],
"history": [...]
}
}
DataManager在导出时直接使用逻辑键名查找存储,但实际存储的键名可能带有前缀,导致找不到数据。
// ❌ 原有的错误实现
for (const key of UI_SETTINGS_KEYS) {
const value = await this.storage.getItem(key); // 查找 'app:settings:ui:theme-id'
// 但实际存储的是 'pref:app:settings:ui:theme-id'
}
DataManager现在区分两种存储方式,使用正确的服务来获取数据:
// 通过PreferenceService存储的设置键
const PREFERENCE_BASED_KEYS = [
'app:settings:ui:theme-id',
'app:settings:ui:preferred-language',
'app:selected-optimize-model',
'app:selected-test-model',
'app:selected-optimize-template',
'app:selected-user-optimize-template',
'app:selected-iterate-template'
] as const;
// 直接存储的设置键
const DIRECT_STORAGE_KEYS = [
'app:settings:ui:builtin-template-language',
] as const;
// ✅ 修复后的导出逻辑
// 导出通过PreferenceService存储的设置
for (const key of PREFERENCE_BASED_KEYS) {
const value = await this.preferenceService.get(key, null);
if (value !== null) {
userSettings[key] = String(value);
}
}
// 导出直接存储的设置
for (const key of DIRECT_STORAGE_KEYS) {
const value = await this.storage.getItem(key);
if (value !== null) {
userSettings[key] = value;
}
}
// ✅ 修复后的导入逻辑
if (PREFERENCE_BASED_KEYS.includes(normalizedKey as any)) {
// 通过PreferenceService存储
await this.preferenceService.set(normalizedKey, value);
} else if (DIRECT_STORAGE_KEYS.includes(normalizedKey as any)) {
// 直接存储
await this.storage.setItem(normalizedKey, value);
}
| 键名 | 存储方式 | 物理键名 | 用途 |
|---|---|---|---|
app:settings:ui:theme-id | PreferenceService | pref:app:settings:ui:theme-id | 主题设置 |
app:settings:ui:preferred-language | PreferenceService | pref:app:settings:ui:preferred-language | 界面语言 |
app:settings:ui:builtin-template-language | PreferenceService | pref:app:settings:ui:builtin-template-language | 内置模板语言 |
app:selected-optimize-model | PreferenceService | pref:app:selected-optimize-model | 优化模型选择 |
app:selected-test-model | PreferenceService | pref:app:selected-test-model | 测试模型选择 |
app:selected-optimize-template | PreferenceService | pref:app:selected-optimize-template | 系统优化模板 |
app:selected-user-optimize-template | PreferenceService | pref:app:selected-user-optimize-template | 用户优化模板 |
app:selected-iterate-template | PreferenceService | pref:app:selected-iterate-template | 迭代模板 |
models | 直接存储 | models | 模型配置 |
user-templates | 直接存储 | user-templates | 用户模板 |
prompt_history | 直接存储 | prompt_history | 提示词历史 |
应用支持旧版本数据的导入,通过LEGACY_KEY_MAPPING自动转换:
const LEGACY_KEY_MAPPING: Record<string, string> = {
'theme-id': 'app:settings:ui:theme-id',
'preferred-language': 'app:settings:ui:preferred-language',
'builtin-template-language': 'app:settings:ui:builtin-template-language',
};
导入旧版本数据时,系统会:
packages/ui/src/constants/storage-keys.tspackages/core/src/constants/storage-keys.tspackages/core/src/services/data/manager.tspackages/core/src/services/preference/service.tsdocs/testing/ai-automation/storage-key-consistency/