# 旧数据导入手册

当前工程提供两阶段、可重复执行的迁移入口，避免直接把旧 SQLite 密文或不完整外键写进新业务表。

## 1. 只读导出

在旧系统停止配置写入后，对数据库快照执行：

```bash
python3 scripts/export_legacy_data.py /secure-snapshot/gateway.db > /secure-transfer/gateway.jsonl
```

默认不导出密码、API Key、TOTP、请求头等敏感列。需要迁移 Provider/工具等凭据时，只能在隔离迁移环境使用 `--include-encrypted`；旧密文不能作为新密文直接写入，必须由专用转换步骤用旧密钥解密，再用新的用途标签和活动 KEK 加密。

## 2. 校验和暂存

先执行不连接数据库的校验：

```bash
gateway-legacy-import --input /secure-transfer/gateway.jsonl --dry-run
```

再写入 PostgreSQL 不可变暂存区：

```bash
export DATABASE_URL='postgres://...'
gateway-legacy-import --input /secure-transfer/gateway.jsonl
```

每条记录会验证 SHA-256，使用固定 namespace 生成 UUIDv5，并同时写入 `legacy_import_records` 与 `legacy_id_mappings`。相同快照重复执行会复用 batch；同一旧 ID 的内容发生变化时失败关闭，不会静默覆盖先前暂存数据。

## 3. 领域转换与验收

暂存成功不等于已写入生产业务表。必须按外键拓扑执行领域转换：部门 → 身份 → Provider/API Key → Prompt/知识/工具 → 应用版本 → 审计历史。每批转换后核对：

- 源记录数、目标记录数、明确跳过数和失败数之和相等；
- 所有旧外键都能从 `legacy_id_mappings` 找到映射；
- Provider、工具、通知、TOTP 等密文可使用新 keyring 解密，且数据库中不存在旧明文；
- 审计只迁移有界预览与结构化元数据，不迁移无限长原始正文；
- 应用发布版本引用的 Prompt、知识库和工具均存在且启用。

当前仓库没有用户的实际 SQLite 数据文件，因此已完成的是可验证暂存管道；生产领域转换必须在拿到脱敏快照及旧密钥托管授权后执行，不能凭空假设旧密文格式。
