# 数据分类与代码生成工具

Cherry Studio 数据重构项目的自动化工具集，用于管理数据分类和生成 TypeScript 代码。

**版本**: 2.0.0
**更新日期**: 2025-11-28

> ⚠️ **阶段性使命已完成（重要）**
>
> 本工具中仅 **代码生成（generate）** 流水线仍在使用。数据提取、一致性/生成校验、重复键检查等命令与脚本已完成阶段性使命，**不再支持，请勿再次运行**。
>
> | 仍可用 | 已弃用（不再支持） |
> | --- | --- |
> | `npm run generate`、`generate:preferences`、`generate:boot-config`、`generate:migration` | `npm run extract`、`validate`、`validate:gen`、`check:duplicates`、`all` |
>
> 对应脚本文件已加 `DO-NOT-USE-` 前缀（`DO-NOT-USE-extract-inventory.js`、`DO-NOT-USE-validate-consistency.js`、`DO-NOT-USE-validate-generation.js`、`DO-NOT-USE-check-duplicates.js`）；运行已弃用的 npm 命令只会打印一行提示。下文中保留的相关章节仅作历史记录，如有疑问请询问作者。

## 概述

本工具集提供以下功能：

- **数据提取**: 扫描源代码，构建数据清单
- **分类管理**: 维护分类映射，支持增量更新
- **代码生成**: 生成 TypeScript 接口和迁移映射
- **验证检查**: 确保清单与分类之间的一致性

## 目录结构

```
v2-refactor-temp/tools/data-classify/
├── scripts/
│   ├── lib/
│   │   └── classificationUtils.js          # 共享工具函数（仅被下方已弃用脚本使用）
│   ├── generate-all.js                     # 运行所有生成器
│   ├── generate-preferences.js             # 生成 preferenceSchemas.ts
│   ├── generate-boot-config.js             # 生成 bootConfigSchemas.ts
│   ├── generate-migration.js               # 生成 PreferencesMappings.ts + BootConfigMappings.ts
│   ├── DO-NOT-USE-extract-inventory.js     # [已弃用] 从源码提取数据清单
│   ├── DO-NOT-USE-validate-consistency.js  # [已弃用] 验证数据一致性
│   ├── DO-NOT-USE-validate-generation.js   # [已弃用] 验证生成代码质量
│   └── DO-NOT-USE-check-duplicates.js      # [已弃用] 检查重复的目标键
├── data/
│   ├── classification.json         # 分类映射（自动生成，人工维护）
│   ├── inventory.json              # 数据清单（脚本生成）
│   └── target-key-definitions.json # 复杂映射的 target key 定义（人工维护）
├── package.json
└── README.md                       # 本文档
```

## 快速开始

```bash
# 进入工具目录
cd v2-refactor-temp/tools/data-classify

# 安装依赖
npm install

# 生成所有代码（当前唯一仍受支持的流程）
npm run generate

# 或仅生成单一目标
npm run generate:preferences   # 仅生成 preferenceSchemas.ts
npm run generate:boot-config   # 仅生成 bootConfigSchemas.ts
npm run generate:migration     # 仅生成 PreferencesMappings.ts + BootConfigMappings.ts
```

> `extract` / `validate` / `validate:gen` / `check:duplicates` / `all` 已弃用，不再支持，详见顶部说明。

## 可用脚本

| 脚本                           | 说明                                             | 状态        |
| ------------------------------ | ------------------------------------------------ | ----------- |
| `npm run generate`             | 运行所有代码生成器                               | ✅ 可用     |
| `npm run generate:preferences` | 仅生成 preferenceSchemas.ts                      | ✅ 可用     |
| `npm run generate:boot-config` | 仅生成 bootConfigSchemas.ts                      | ✅ 可用     |
| `npm run generate:migration`   | 仅生成 PreferencesMappings.ts + BootConfigMappings.ts | ✅ 可用     |
| `npm run extract`              | 从源文件提取数据清单                             | ⛔ 已弃用   |
| `npm run validate`             | 验证数据一致性                                   | ⛔ 已弃用   |
| `npm run validate:gen`         | 验证生成代码质量                                 | ⛔ 已弃用   |
| `npm run check:duplicates`     | 检查重复的目标键                                 | ⛔ 已弃用   |
| `npm run all`                  | 运行完整工作流                                   | ⛔ 已弃用   |

> ⛔ 标记的命令已完成阶段性使命，**不再支持**，运行只会打印提示。详见顶部说明。

## 脚本架构

> 注：下图与下表为原始完整工作流的历史记录；其中 `extract-inventory` / `validate-consistency` / `validate-generation` / `check-duplicates` 相关脚本已弃用（文件名已加 `DO-NOT-USE-` 前缀），仅 `generate-*` 仍在使用。

### 依赖关系图

```
┌─────────────────────────────────────────────────────────────┐
│                      共享模块                                │
│  scripts/lib/classificationUtils.js                         │
│  - loadClassification()    - traverseClassifications()      │
│  - saveClassification()    - calculateStats()               │
│  - loadInventory()         - normalizeType()                │
│  - extractPreferencesData() - inferTypeFromValue()          │
└─────────────────────────────────────────────────────────────┘
                    ▲                    ▲
                    │                    │
        ┌───────────┘                    └───────────┐
        │                                            │
┌───────┴───────┐                          ┌────────┴────────┐
│ extract-      │                          │ validate-       │
│ inventory.js  │                          │ consistency.js  │
│               │                          │                 │
│ 扫描源码      │                          │ 检查数据        │
│ 构建清单      │                          │ 一致性          │
└───────────────┘                          └─────────────────┘

┌─────────────────────┐
│   generate-all.js   │─────────────────────┬──────────────────────┐
│                     │                     │                      │
│   编排所有生成器    │                     │                      │
└─────────────────────┘                     │                      │
         │                                  │                      │
         │ require()                        │ require()            │ require()
         ▼                                  ▼                      ▼
┌─────────────────────┐    ┌─────────────────────┐   ┌─────────────────────┐
│ generate-           │    │ generate-           │   │ generate-           │
│ preferences.js      │    │ boot-config.js      │   │ migration.js        │
│                     │    │                     │   │                     │
│ 生成                │    │ 生成                │   │ 生成                │
│ preferenceSchemas.ts│    │ bootConfigSchemas.ts│   │ PreferencesMappings │
└─────────────────────┘    └─────────────────────┘   │ BootConfigMappings  │
                                                     └─────────────────────┘

┌─────────────────────┐                    ┌─────────────────────┐
│ validate-           │                    │ check-              │
│ generation.js       │                    │ duplicates.js       │
│                     │                    │                     │
│ 验证生成代码质量    │                    │ 检查重复目标键      │
│ (独立运行)          │                    │ (独立运行)          │
└─────────────────────┘                    └─────────────────────┘
```

### 脚本详情

| 脚本                      | 输入                                    | 输出                                          | 依赖                                                                           |
| ------------------------- | --------------------------------------- | --------------------------------------------- | ------------------------------------------------------------------------------ |
| `generate-preferences.js` | `classification.json`                   | `preferenceSchemas.ts`                        | 无                                                                             |
| `generate-boot-config.js` | `classification.json`                   | `bootConfigSchemas.ts`                        | 无                                                                             |
| `generate-migration.js`   | `classification.json`                   | `PreferencesMappings.ts`, `BootConfigMappings.ts` | 无                                                                             |
| `generate-all.js`         | -                                       | 运行三个生成器                                | `generate-preferences.js`, `generate-boot-config.js`, `generate-migration.js`  |
| `DO-NOT-USE-extract-inventory.js` _(已弃用)_    | 源代码文件                              | `data/inventory.json`                         | `classificationUtils.js`                                                       |
| `DO-NOT-USE-validate-consistency.js` _(已弃用)_ | `inventory.json`, `classification.json` | `validation-report.md`                        | `classificationUtils.js`                                                       |
| `DO-NOT-USE-validate-generation.js` _(已弃用)_  | 生成的 `.ts` 文件                       | 控制台输出                                    | 无                                                                             |
| `DO-NOT-USE-check-duplicates.js` _(已弃用)_     | `classification.json`                   | 控制台输出                                    | 无                                                                             |

## 数据分类工作流

> ⚠️ 本节为历史记录：步骤 1（提取）与步骤 4（验证）所用命令已弃用、不再支持，当前仅步骤 3（生成）仍受支持。

### 1. 提取数据清单

```bash
npm run extract
```

扫描源文件并提取以下数据源的信息：

- **Redux Store**: `src/renderer/store/*.ts`
- **Electron Store**: `src/main/services/ConfigManager.ts`
- **LocalStorage**: 所有使用 localStorage 的文件
- **Dexie 数据库**: `src/renderer/databases/index.ts`

> **注意**: `dexieSettings` 数据源中的字符串字面量 key 会被自动提取，但动态 key（如模板字符串拼接的）需要手动维护。详见下方 [dexieSettings 数据源](#dexiesettings-数据源) 章节。

### 2. 分类数据

编辑 `data/classification.json` 对每个数据项进行分类：

```json
{
  "originalKey": "theme",
  "type": "string",
  "status": "classified",
  "category": "preferences",
  "targetKey": "ui.theme_mode"
}
```

### 3. 生成代码

```bash
npm run generate
```

生成以下 TypeScript 文件：

- `src/shared/data/preference/preferenceSchemas.ts` - 偏好配置类型定义与默认值
- `src/shared/data/bootConfig/bootConfigSchemas.ts` - 启动配置类型定义与默认值
- `src/main/data/migration/v2/migrators/mappings/PreferencesMappings.ts` - 偏好迁移映射
- `src/main/data/migration/v2/migrators/mappings/BootConfigMappings.ts` - 启动配置迁移映射

### 4. 验证

```bash
npm run validate
npm run validate:gen
```

验证内容：

- 所有清单项都已分类
- 没有孤立的分类条目
- 命名规范一致
- 没有重复的目标键
- 生成代码结构正确

---

## 数据分类标准

根据 Cherry Studio 数据重构架构，所有数据需要分类到以下 6 个类别之一：

### 1. 偏好配置 (preferences)

**判断标准**:

- ✅ 影响应用全局行为的配置
- ✅ 用户可以修改的设置项
- ✅ 简单的数据类型（boolean/string/number/简单 array/object）
- ✅ 结构相对稳定，不经常变化
- ✅ 数据量小，可以重建
- ✅ 需要在窗口间同步

**典型例子**:

- `showAssistants`: 是否显示助手面板
- `theme`: 主题设置（light/dark/system）
- `fontSize`: 字体大小
- `language`: 界面语言

**命名规范**:

- 使用点分隔的层级结构：`ui.fontSize`、`system.language`
- 分组前缀：`ui.*`（界面）、`system.*`（系统）、`app.*`（应用行为）等

### 2. 启动配置 (bootConfig)

**判断标准**:

- ✅ 必须在 Node.js 进程启动的最早阶段同步加载（早于 `app.whenReady`、早于 lifecycle 的 `BeforeReady` 阶段）
- ✅ 影响进程级别的行为，一旦进程启动就无法更改
- ✅ 不能存储在 SQLite 中（数据库由 lifecycle `BeforeReady` 阶段初始化，远晚于 boot config 的加载时机）
- ✅ 使用同步文件 I/O 读取（`~/.cherrystudio/boot-config.json`，刻意放在 userData 之外，避免鸡生蛋问题）

**时序关系**:

```
Boot Config 加载 → bootstrap（初始化 appData 目录）→ app.whenReady → lifecycle BeforeReady（DB 初始化）→ lifecycle WhenReady
```

Boot config 在整个启动链的最前端，为后续所有阶段提供基础配置。

**典型例子**:

- `disableHardwareAcceleration`: 硬件加速开关（必须在任何 Electron API 调用前设置）
- 应用路径定义等需要在 bootstrap 阶段就确定的配置

**与 preferences 的区别**:

| | bootConfig | preferences |
| --- | --- | --- |
| 加载时机 | 进程启动最早阶段（同步） | lifecycle `BeforeReady` 阶段（异步） |
| 存储方式 | JSON 文件（`~/.cherrystudio/boot-config.json`） | SQLite 数据库 |
| 访问方式（Main） | `bootConfigService.get()` 同步 | `application.get('PreferenceService').get()` |
| 访问方式（Renderer） | `usePreference('BootConfig.*')` 统一访问 | `usePreference('key')` |

### 3. 用户数据 (user_data)

**判断标准**:

- ✅ 用户创建或输入的内容
- ✅ 不可丢失的重要数据
- ✅ 数据量可能很大
- ✅ 需要完整备份和迁移机制
- ✅ 可能包含敏感信息

**典型例子**:

- `topics`: 对话历史
- `messages`: 消息内容
- `files`: 用户上传的文件
- `knowledge_notes`: 知识库笔记

**特殊处理**:

- 敏感数据需要加密存储
- 大数据表需要考虑分页和流式处理

### 4. 缓存数据 (cache)

**判断标准**:

- ✅ 可以重新生成的数据
- ✅ 主要用于性能优化
- ✅ 丢失后不影响核心功能
- ✅ 有过期时间或清理机制

**典型例子**:

- `failed_favicon_*`: 失败的 favicon 缓存
- 搜索结果缓存
- 图片预览缓存
- 模型响应缓存

### 5. 运行时数据 (runtime)

**判断标准**:

- ✅ 内存型数据，不需要持久化
- ✅ 生命周期 ≤ 应用进程
- ✅ 应用重启后可以丢失
- ✅ 临时状态信息

**典型例子**:

- 当前选中的对话
- 临时的输入状态
- UI 组件的展开/折叠状态
- 网络请求状态

### 6. 应用资源 (resources)

**判断标准**:

- ✅ 静态资源文件
- ✅ 随应用分发的内容
- ✅ 不需要用户修改
- ✅ 暂不考虑重构

**典型例子**:

- 图标文件
- 本地化翻译文件
- 默认配置文件
- 帮助文档

---

## 分类决策流程图

```
数据项
  ↓
是否必须在进程启动最早阶段同步加载（早于 lifecycle）？
  ↓ 是                    ↓ 否
启动配置              是否用户创建/输入的内容？
(bootConfig)            ↓ 是                    ↓ 否
                      用户数据              是否需要持久化？
                                              ↓ 否        ↓ 是
                                          运行时数据    是否可重新生成？
                                                        ↓ 是         ↓ 否
                                                      缓存数据     是否用户可修改？
                                                                    ↓ 是        ↓ 否
                                                                  偏好配置    应用资源
```

---

## 分类示例

### 示例 1: Redux settings.showAssistants

```json
{
  "classifications": {
    "redux": {
      "settings": [
        {
          "originalKey": "showAssistants",
          "type": "boolean",
          "defaultValue": true,
          "status": "classified",
          "category": "preferences",
          "targetKey": "ui.show_assistants"
        }
      ]
    }
  }
}
```

**分析过程**:

1. 数据用途：控制是否显示助手面板
2. 用户可修改：✅
3. 影响全局：✅
4. 数据简单：✅ boolean 类型
5. 结论：偏好配置

### 示例 2: 嵌套结构 (Redux settings with children)

```json
{
  "originalKey": "codeEditor",
  "type": "object",
  "children": [
    {
      "originalKey": "enabled",
      "type": "boolean",
      "defaultValue": true,
      "status": "classified",
      "category": "preferences",
      "targetKey": "code_editor.enabled"
    },
    {
      "originalKey": "fontSize",
      "type": "number",
      "defaultValue": 14,
      "status": "classified",
      "category": "preferences",
      "targetKey": "code_editor.font_size"
    }
  ]
}
```

**注意**: 父级项不需要 `status`/`category`/`targetKey`，这些只在叶子节点设置。

### 示例 3: Dexie topics 表

```json
{
  "originalKey": "topics",
  "type": "table",
  "status": "classified",
  "category": "user_data",
  "targetTable": "topic",
  "notes": "用户对话历史，核心业务数据"
}
```

---

## 命名规范

偏好配置键必须遵循：`namespace.sub.key_name`

**规则**:

- 至少 2 个由点分隔的段
- 仅使用小写字母、数字、下划线
- 模式：`/^[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)+$/`

**示例**:

- `app.theme` (有效)
- `chat.input.send_shortcut` (有效)
- `Theme` (无效 - 没有点分隔符)
- `App.User` (无效 - 大写字母)

---

## 增量更新策略

> ⚠️ 本节描述的提取（`npm run extract`）流程已弃用、不再支持，仅作历史记录。

### 核心特性

- **保留已分类数据**: 重新运行提取不会丢失已有分类
- **标记删除项**: 删除的数据项被标记但不移除
- **自动发现新项**: 新数据项自动添加到待处理列表
- **自动备份**: 每次运行前自动备份原分类文件

### 更新流程

1. 代码变更后运行 `npm run extract`
2. 脚本自动备份 `classification.json` 到 `classification.backup.json`
3. 脚本识别新增和删除的数据项
4. 新项添加到 `pending` 数组
5. 删除项标记为 `status: 'classified-deleted'`
6. 手动处理新的待处理项

---

## 文件格式说明

### inventory.json 结构

```json
{
  "metadata": {
    "generatedAt": "ISO 日期",
    "version": "版本号"
  },
  "redux": {
    "moduleName": {
      "fieldName": {
        "type": "数据类型",
        "defaultValue": "默认值"
      }
    }
  },
  "electronStore": { ... },
  "localStorage": { ... },
  "dexie": { ... }
}
```

### classification.json 结构

```json
{
  "metadata": {
    "version": "版本号",
    "lastUpdated": "ISO 日期"
  },
  "classifications": {
    "redux": {
      "moduleName": [
        {
          "originalKey": "字段名",
          "type": "数据类型",
          "status": "classified|pending|classified-deleted",
          "category": "preferences|bootConfig|user_data|cache|runtime|resources",
          "targetKey": "target.key.name"
        }
      ]
    },
    "electronStore": { ... },
    "localStorage": { ... },
    "dexieSettings": {
      "settings": [
        {
          "originalKey": "字段名",
          "type": "数据类型",
          "status": "classified|pending",
          "category": "preferences",
          "targetKey": "target.key.name"
        }
      ]
    },
    "dexie": { ... }
  }
}
```

### dexieSettings 数据源

`dexieSettings` 是 classification.json 中与 `redux`、`electronStore`、`localStorage`、`dexie` 并列的第五个顶级数据源，专门用于分类 Dexie IndexedDB 中 `settings` 表的 KV 配置项。

**与 `dexie` 数据源的区别**:

| 数据源 | 用途 | 数据结构 | 典型分类 |
| --- | --- | --- | --- |
| `dexie` | Dexie 的业务数据表（files, topics 等） | 表级别，使用 `targetTable` | `user_data` |
| `dexieSettings` | Dexie 的 `settings` 表（KV 配置） | 字段级别，使用 `targetKey` | `preferences`（目前仅支持此分类） |

**classification.json 中的结构**:

```json
{
  "classifications": {
    "dexieSettings": {
      "settings": [
        {
          "originalKey": "settingKeyName",
          "type": "string",
          "defaultValue": "defaultValue",
          "status": "classified",
          "category": "preferences",
          "targetKey": "namespace.key_name"
        }
      ]
    }
  }
}
```

**在代码生成中的作用**:

1. **`generate-preferences.js`**: 作为四大偏好数据源之一（`electronStore`、`redux`、`localStorage`、`dexieSettings`），参与生成 `preferenceSchemas.ts`
2. **`generate-migration.js`**: 生成独立的 `DEXIE_SETTINGS_MAPPINGS` 映射数组，用于迁移器从 Dexie settings 表读取数据

**去重优先级**（当多个数据源映射到相同 targetKey 时）:

```
redux (最高) > dexieSettings > localStorage > electronStore (最低)
```

**已知字段清单**（参考 [PR #10162 comment](https://github.com/CherryHQ/cherry-studio/pull/10162#issuecomment-4010796619)）:

Dexie `settings` 表是一个通用 KV 存储（`{ id: string, value: any }`），所有 `image://` 键由 `ImageStorage` 服务管理。

*固定键*:

| Key | Value Type | 迁移目标 |
| --- | --- | --- |
| `translate:model` | `string` (model id) | preference |
| `translate:target:language` | `string` (langCode) | preference |
| `translate:source:language` | `string` (langCode) | preference |
| `translate:bidirectional:enabled` | `boolean` | preference |
| `translate:bidirectional:pair` | `[string, string]` (langCode pair) | preference |
| `translate:scroll:sync` | `boolean` | preference |
| `translate:markdown:enabled` | `boolean` | preference |
| `translate:detect:method` | `string` ('franc'/'llm'/'auto') | preference |
| `pinned:models` | `Model[]` | preference |
| `image://avatar` | `string` (base64 data URL \| emoji) | preference / file manager |

*动态键（基于 pattern）*:

| Key Pattern | Value Type | 迁移目标 |
| --- | --- | --- |
| `image://provider-${providerId}` | `string` (base64 data URL \| emoji \| `''`) | file manager |
| `mcp:provider:${provider.key}:servers` | `MCPServer[]` | new table |

*已知遗留键（代码中无引用，运行时 IndexedDB 中存在）*:

| Key | 说明 |
| --- | --- |
| `translate:model:prompt` | 已被 Redux `settings.translateModelPrompt` 取代，已迁移到 preference `feature.translate.model_prompt`，跳过 |

**注意事项**:

- `extract-inventory.js` 会自动提取 `db.settings.get/put/add()` 调用中的**字符串字面量** key；动态 key（模板字符串拼接）无法自动提取，需要**手动添加**
- 手动添加的条目在重新提取时会被保留（不会被覆盖或删除）
- `dexieSettings` 的 `category` 目前仅支持 `preferences`，代码生成脚本只处理该分类
- `validate-consistency.js` 不会检查 `dexieSettings` 与 inventory 的一致性
- 迁移时通过 `ctx.sources.dexieSettings.get(mapping.originalKey)` 读取数据
- 动态键（含 `${}` 模板的 pattern）需要特殊的迁移逻辑，不能用简单 1:1 映射处理

### 状态值说明

| Status               | 说明             | 操作建议                                 |
| -------------------- | ---------------- | ---------------------------------------- |
| `pending`            | 待分类           | 需要人工分析并设置 category 和 targetKey |
| `classified`         | 已分类           | 分类完成，可用于代码生成                 |
| `classified-deleted` | 已分类但源已删除 | 源代码中已不存在，保留历史记录           |

### targetKey 值说明

对于 `status: "classified"` 的项，`targetKey` 有两种情况：

| targetKey | 说明 | 生成行为 |
| --------- | ---- | -------- |
| 有效值（如 `"ui.theme"`） | 需要迁移到新系统 | 会生成到 preferenceSchemas.ts |
| `null` | 已分类，但不需要迁移 | 不会生成到 preferenceSchemas.ts |

**使用场景**：当一个数据项经过分析后，确定在新系统中不需要该配置（如已废弃、被其他配置替代、或不再需要持久化），应设置 `status: "classified"` 且 `targetKey: null`。这表示"已完成分类决策，决策结果是不加载该项"。

---

## 复杂映射支持

### 概述

除了简单的一对一映射（`originalKey → targetKey`），系统还支持复杂的数据转换：

1. **对象拆分 (1→N)**: 一个源对象拆分为多个 target keys
2. **多源合并 (N→1)**: 多个源数据合并为一个或多个目标
3. **值计算/转换**: 值需要经过计算、格式转换或逻辑处理
4. **条件映射**: 根据源数据的值决定写入哪些目标

### 架构

```
┌─────────────────────────────────────────────────────────────┐
│  classification.json (status: classified)                    │
│  ─────────────────────────────────────────                  │
│  基础数据源，包含所有简单映射的 target keys                    │
└─────────────────────────────────────────────────────────────┘
                            ↓
┌─────────────────────────────────────────────────────────────┐
│  target-key-definitions.json                                 │
│  ─────────────────────────────────────────                  │
│  用途1: 复杂迁移 - 定义需要特殊转换逻辑的 target keys          │
│  用途2: 纯新增 - 添加 v2 新功能的 preferences（非迁移）        │
└─────────────────────────────────────────────────────────────┘
                            ↓
┌─────────────────────────────────────────────────────────────┐
│  preferenceSchemas.ts (最终输出)                             │
└─────────────────────────────────────────────────────────────┘
```

### target-key-definitions.json

用于定义无法通过 `classification.json` 简单映射处理的 preference keys。主要用于两个场景：

1. **复杂迁移**: 定义需要特殊转换逻辑（对象拆分、多源合并、值计算等）产生的 target keys
2. **纯新增（非迁移）**: 添加 v2 新功能的 preferences，这些配置不是从旧代码迁移的

**文件结构**:

```json
{
  "metadata": {
    "version": "1.0.0",
    "description": "Target key definitions...",
    "lastUpdated": "2025-01-18"
  },
  "definitions": [
    {
      "targetKey": "app.window.position.x",
      "type": "number",
      "defaultValue": 0,
      "status": "classified",
      "description": "Window X position (from complex mapping)"
    }
  ]
}
```

**字段说明**:

| 字段           | 必填 | 说明                                                     |
| -------------- | ---- | -------------------------------------------------------- |
| `targetKey`    | ✓    | preference key（必须符合命名规范）                       |
| `type`         | ✓    | TypeScript 类型（string, number, boolean, 或自定义类型） |
| `defaultValue` | ✓    | 默认值（支持 `VALUE: ...` 特殊格式）                     |
| `status`       | ✓    | `classified` 启用，`pending` 禁用                        |
| `description`  |      | 可选描述                                                 |

#### 纯新增（非迁移）场景

当需要添加一个全新的 preference（不是从旧代码迁移的 v2 新功能）时，直接在 `definitions` 数组中添加即可。

**示例**: 添加 v2 版本新增的功能配置

```json
{
  "definitions": [
    {
      "targetKey": "feature.new_assistant.enabled",
      "type": "boolean",
      "defaultValue": false,
      "status": "classified",
      "description": "启用新助手功能（v2 新增，非迁移）"
    },
    {
      "targetKey": "feature.new_assistant.default_model",
      "type": "string",
      "defaultValue": "gpt-4",
      "status": "classified",
      "description": "新助手默认模型（v2 新增，非迁移）"
    }
  ]
}
```

运行 `npm run generate:preferences` 后，这些 keys 会出现在生成的 `preferenceSchemas.ts` 中。

**与复杂迁移的区别**:
- 复杂迁移需要在 `PreferenceTransformers.ts` 和 `ComplexPreferenceMappings.ts` 中实现转换逻辑
- 纯新增只需要在 `target-key-definitions.json` 中定义，无需额外代码

**建议**: 在 `description` 中注明是"复杂迁移"还是"v2 新增，非迁移"，便于后续维护。

**defaultValue 特殊格式**:

与 classification.json 保持一致，支持 `VALUE: ...` 特殊格式：

```json
// 引用枚举值
{ "defaultValue": "VALUE: PreferenceTypes.ThemeMode.system" }
// 生成: PreferenceTypes.ThemeMode.system（不加引号）

// 引用常量
{ "defaultValue": "VALUE: TRANSLATE_PROMPT" }
// 生成: TRANSLATE_PROMPT（不加引号）

// 特殊 null 值
{ "defaultValue": "VALUE: null" }
// 生成: null

// 普通字符串（不使用 VALUE: 前缀）
{ "defaultValue": "light" }
// 生成: 'light'（带引号）
```

### 复杂映射实现

复杂映射的转换逻辑定义在以下文件中：

```
src/main/data/migration/v2/migrators/
├── mappings/
│   ├── PreferencesMappings.ts          # 偏好简单映射（自动生成）
│   ├── BootConfigMappings.ts           # 启动配置映射（自动生成）
│   └── ComplexPreferenceMappings.ts    # 复杂映射配置
├── transformers/
│   └── PreferenceTransformers.ts       # 转换函数实现
├── PreferencesMigrator.ts              # 偏好迁移执行器
└── BootConfigMigrator.ts               # 启动配置迁移执行器
```

**添加复杂映射的步骤**:

1. 在 `target-key-definitions.json` 中定义 target keys（设 `status: "classified"`）
2. 在 `PreferenceTransformers.ts` 中实现转换函数
3. 在 `ComplexPreferenceMappings.ts` 中添加映射配置
4. 运行 `npm run generate:preferences` 重新生成 preferenceSchemas.ts

### 冲突处理

系统采用**严格模式**：如果简单映射和复杂映射的 target key 有冲突，迁移时会报错。

解决方法：从简单映射（classification.json）中移除冲突的 key，由复杂映射处理。

---

## 故障排除

### "Module not found" 错误

```bash
cd v2-refactor-temp/tools/data-classify
npm install
```

### 验证错误

1. 检查 `validation-report.md` 了解详情
2. 修复 `classification.json` 条目
3. 重新运行验证

### 生成代码问题

1. ~~运行 `npm run validate:gen` 识别问题~~（已弃用，不再支持）
2. 检查源分类数据
3. 使用 `npm run generate` 重新生成

### 数据项被错误标记为删除

检查提取脚本的模式是否正确匹配代码结构。

### 如何恢复意外删除的分类

从以下位置恢复 `classification.json`：

- 自动备份文件：`classification.backup.json`
- Git 历史记录
