Files
model-platform/migrations/data
tao.chen 309b657d35 docs: align with new storage architecture (s3 + local + server-proxied PUT)
All operator- and developer-facing docs updated to reflect:

  - The unified AsyncStorageBackend abstraction (s3 + local backends).
  - The STORAGE_BACKEND toggle ("s3" default, "local" for dev /
    single-node / air-gapped deployments).
  - The 4-purpose-bucket layout (workspace / version / run_log / trash)
    in both modes — 4 separate S3 buckets in s3 mode, 4 subdirectories
    of LOCAL_STORAGE_BASE_DIR in local mode.
  - The S3_* env var naming (was RUSTFS_*).
  - The server-proxied upload flow (was browser-direct presign-PUT):
    POST /internal/v1/uploads → PUT /internal/v1/uploads/{id} with
    raw bytes → server calls backend.put().
  - The factory helpers workspaces_root() (runtime's view of the
    workspace bucket on disk) and rclone_remote_spec() (s3-mode mount
    source).
  - The "two settings describing the same thing" cleanup: the deleted
    settings.workspace_root, settings.workspaces_root, and
    settings.remote_bucket fields.

Files touched:
  - API.md (§5 data-resource upload flow, §9 storage control plane,
    §10 readiness example)
  - ARCHITECTURE.md (storage layer diagram)
  - CLAUDE.md (architecture description + volume-preservation note)
  - DEVELOP.md (settings list, Storage section, "Wire a new bucket"
    how-to, dev-export example, troubleshooting network hint)
  - README.md (architecture diagram, container table, quick-start
    credentials note, tear-down note, Storage layout section)
  - REFACTOR_NOTES.md (final container list with s3 explanation)
  - backend/README.md (storage backend description)
  - migrations/data/README.md (step 11/12 record mentioning object
    storage)

A handful of historical "RustFS" mentions are intentionally retained
where they name a specific S3-compatible product (e.g. as an example
in REFACTOR_NOTES.md's container list) or document the pre-2026
abstraction name (DEVELOP.md Storage section).
2026-08-05 13:13:20 +08:00
..

Data Migrations

该目录保存从旧版 JSON 状态文件迁移到 MySQL 的一次性工具。

数据迁移工具必须满足:

  • 默认只预检,必须显式传入 --apply 才能写数据库;
  • 单个事务提交,失败时完整回滚;
  • 可以安全重复执行,不产生重复数据;
  • 输出源文件摘要、源数据数量和实际变更数量;
  • 不修改或删除旧版 JSON 源文件。

system.json

$env:DATABASE_URL = "mysql+asyncmy://<user>:<password>@<host>:3306/<database>?charset=utf8mb4"
python -m migrations.data.migrate_system_json --source "<path>/system.json"
python -m migrations.data.migrate_system_json --source "<path>/system.json" --apply

新迁移用户使用不可登录的占位密码哈希。后续接入认证时,必须通过密码初始化、 管理员重置或外部身份认证启用登录,不能把旧版无密码账号视为已有凭据。

WORKSPACE_DEFINITIONS

旧版 Workspace 定义位于 文件1/server.pyWORKSPACE_DEFINITIONS 常量中。迁移工具通过 Python AST 仅读取这一静态常量, 不执行旧服务代码:

python -m migrations.data.migrate_legacy_workspaces --source "<path>/server.py"
python -m migrations.data.migrate_legacy_workspaces --source "<path>/server.py" --apply
  • 创建者取每个 Workspace 成员中的第一个管理员;
  • 成员角色沿用第 9 步迁入的平台注册角色;
  • 活跃目录统一为 file:///workspace/workspaces/{workspace_code}
  • 制品前缀统一为 workspaces/{workspace_id}
  • 旧审计记录仅在用户唯一属于一个 Workspace 时补齐归属。

第 9 小步执行记录

  • 执行日期:2026-07-24
  • 源文件:文件1/platform_data/system.json
  • SHA-256ef4ee0e92f4a3679c17f23aff6066688fa9231db4477208e36fcbd343cd446a7
  • 迁移结果:2 个角色、13 个权限、21 条角色权限、4 个用户、26 条审计记录
  • 角色权限:admin=13developer=8
  • 中文字段:UTF-8 校验通过,问号乱码记录为 0
  • 幂等验证:第二次执行插入和更新均为 0,跳过已有审计记录 26 条
  • 旧版源文件:未修改、未删除

第 10 小步执行记录

  • 执行日期:2026-07-24
  • 源文件及常量:文件1/server.py / WORKSPACE_DEFINITIONS
  • SHA-256d7ec05f1ab7b2cdeb78f6293de40fbe23fa74b6a7fe4ccb03a9cc64e4cc1f464
  • 迁移结果:2 个 Workspace、4 条成员关系
  • 成员分布:model-dev 2 人,risk-validation 2 人
  • 审计归属:补齐 26 条,其中 model-dev 24 条、risk-validation 2 条
  • 中文字段:UTF-8 校验通过,异常记录为 0
  • 幂等验证:第二次执行及镜像内 dry-run 的变更数均为 0
  • 镜像验证:仅挂载旧版 server.py 时,迁移工具可独立读取并完成校验
  • 旧版源文件:未修改、未删除

第 11、12 小步数据处理决定

根据实施确认,第 11、12 小步不迁移旧版资源、脚本或稳定版本数据。新实现直接 使用 MySQL、Workspace 文件目录和对象存储(s3 模式连 S3-兼容服务,local 模式 走 /data/storage 共享卷),从空的 data_resourcesscriptsversions 表开始运行。功能验收产生的临时对象和数据库记录均已清理。