You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

6.0 KiB

用户数据备份设计(以导出/迁移为核心)

1. 背景与目标

本设计面向 person-panel 的“用户数据可携带性”场景,核心目标是让用户可以导出自己的文件与业务数据,并可用于后续迁移或恢复到兼容系统。

已确认目标与约束:

  • 目标类型:用户可导出/迁移数据(非灾备优先)
  • 交付形态:目录结构 + 清单 JSON
  • 范围:用户全量业务数据(排除敏感凭据)
  • 敏感策略:导出时可选原始/脱敏,默认脱敏

2. 设计原则

  • 可迁移优先:导出格式稳定、可版本化、可校验
  • 文件与数据一体:业务 JSON 与媒体文件同时导出
  • 安全默认:默认脱敏,且永不导出高敏字段
  • 一致性可解释:导出基于固定时间截点,避免数据漂移
  • 演进兼容:通过 schemaVersion 管理未来格式升级

3. 总体架构

采用“异步导出任务 + 标准导出包”模式。

3.1 API 入口

  • POST /api/me/export/request
    • 创建导出任务
    • 参数:maskPolicymasked | raw,默认 masked
  • GET /api/me/export/tasks
    • 查询当前用户导出任务列表与状态
  • GET /api/me/export/tasks/:id/download
    • 下载导出结果(目录打包或直接目录挂载下载,按部署实现)

3.2 任务状态机

  • queued:任务已创建,待执行
  • running:导出中
  • succeeded:导出完成,可下载
  • failed:导出失败,包含错误信息
  • expired:产物过期被清理

3.3 一致性模型

任务进入 running 时写入 exportCutoffAt。所有 SQL 查询统一加上时间边界(可按表字段映射),保证导出结果在逻辑上对应同一时间点快照。

4. 导出包规范(v1)

4.1 目录结构

export-<userId>-<taskId>/
  manifest.json
  data/
    user.json
    profile.json
    timeline.json
    posts.json
    comments.json
    media-assets.json
    media-refs.json
    ...(其他用户归属资源)
  files/
    <storageKey 或分层路径>

4.2 manifest.json(关键字段)

  • schemaVersion: 1
  • exportedAt: 导出完成时间(ISO8601 UTC)
  • exportCutoffAt: 截点时间(ISO8601 UTC)
  • userId: 用户 ID
  • maskPolicy: maskedraw
  • stats: 各资源条数、文件数、总字节数
  • checksums:
    • data: 每个 JSON 文件的 SHA256
    • files: 每个文件的 SHA256 + 相对路径

4.3 编码与类型规范

  • JSON 使用 UTF-8
  • 时间统一 ISO8601(UTC)
  • 枚举保持稳定字符串值
  • 布尔/数值不做字符串化

5. 数据边界与脱敏规则

5.1 导出范围(全量用户业务)

按“该用户可归属”原则导出:

  • 用户基础信息(非敏感)
  • 个人资料与配置
  • 时间线、文章、评论等内容
  • 媒体元数据(mediaAssets)与引用关系(mediaRefs
  • 其他用户域业务资源(按服务注册表补齐)

5.2 永不导出字段

无论 maskPolicy 取值,以下字段均不导出:

  • 密码哈希与密码重置类 token
  • 登录会话 token / 刷新 token
  • API 密钥、签名密钥、内部凭据
  • 不可归属该用户的他人敏感数据

5.3 可配置脱敏字段

导出时支持策略切换:

  • masked(默认):
    • 邮箱:保留前后缀,隐藏中间
    • 手机号:保留前 3 后 2
    • IP:保留网段,隐藏主机位
    • 设备标识:部分掩码
  • raw
    • 输出原值,但仍遵循“永不导出字段”排除规则

6. 文件导出策略(重点)

6.1 文件来源

从用户关联的 mediaAssets 读取 storageKey,在媒体目录(当前项目已有公开上传目录)中查找实体文件,复制到导出包 files/ 下。

6.2 文件-数据关联

  • data/media-assets.json 记录资产元数据与 storageKey
  • data/media-refs.json 记录 assetId 与业务对象关联
  • 导入方据此可重建资源引用关系

6.3 完整性校验

每个导出文件生成 SHA256 写入 manifest.checksums.files。导入前可进行全量核验,防止传输损坏或篡改。

7. 执行流程与失败恢复

7.1 执行步骤

  1. 创建任务(queued
  2. Worker 抢占任务并置 running
  3. 记录 exportCutoffAt
  4. 分页导出各资源 JSON 到 data/
  5. 收集并复制媒体文件到 files/
  6. 计算校验并生成 manifest.json
  7. succeeded 并返回下载能力

7.2 失败策略

  • 任一步异常置 failed,记录 errorCode/errorMessage
  • 任务目录按 taskId 隔离,失败不会污染其他任务
  • 用户可重试,创建新任务而非复用失败产物

8. 安全与性能控制

8.1 安全控制

  • 仅允许用户导出/下载自己的任务
  • 下载链接短时有效(建议 10 分钟)
  • 导出产物过期清理(建议 24~72 小时)
  • 保留审计日志(发起人、时间、策略、结果)

8.2 性能控制

  • 大表分页读取,避免内存峰值过高
  • 文件复制并发数限流,避免 IO 打满
  • 单用户同一时刻仅允许 1 个导出任务

9. 测试与验收标准

9.1 测试建议

  • 单元测试:
    • 字段白/黑名单过滤
    • masked/raw 脱敏策略
    • manifest 校验信息生成
  • 集成测试:
    • 用户全量导出流程(含媒体文件)
    • 导出期间数据变动下的一致性行为
    • 权限边界(越权访问导出任务)

9.2 验收标准

  • 导出包包含该用户全量业务数据与关联文件
  • 永不导出字段在任何策略下都不存在
  • maskedraw 行为符合预期
  • manifest 校验通过,引用关系可重建
  • 中等数据量用户导出耗时在可接受范围

10. 分阶段落地计划(建议)

  • Phase 1:后端导出任务 + 导出包生成 + 基础下载
  • Phase 2:前端“数据导出中心”页面(发起、进度、下载、失败重试)
  • Phase 3:导入校验工具(离线校验 manifest 与文件完整性)

该设计聚焦“用户文件和数据可迁移”,优先保证格式稳定、数据完整与安全边界,便于后续演进到导入能力与跨环境迁移能力。