# 旧库数据迁移 把旧系统(`api_yeomai_site`)的数据迁到新库,供新服务端使用。 ## 前置条件 1. 新库已建好,`DATABASE_URL` 指向它,且**已执行建表**(`pnpm prisma:migrate`)。 2. 旧库 dump 文件位于仓库根目录 `数据库/api_yeomai_site_mysql.sql` (默认路径;可用环境变量 `LEGACY_DUMP` 覆盖)。 3. `STATIC_BASE_URL` 已配置为新静态资源域名,用于改写内容字段里的旧域名。 ## 三条命令 ```bash # 1. 体检:确认旧数据能无损映射(不连数据库,纯读 dump) pnpm legacy:check # 2. 试运行:完成全部转换,但不写库,用来核对行数 pnpm legacy:migrate -- --dry-run # 3. 正式迁移 pnpm legacy:migrate ``` 如希望直连旧库读取而不是读 dump: ```bash pnpm legacy:migrate -- --from-db # 需配置 LEGACY_DATABASE_URL ``` ## 迁移做了什么 | 旧表 | 新表 | 说明 | |---|---|---| | 用户信息 | `users` | 284 行 | | 用户已购课程 | `entitlements` | 48 行,`source=2`(老数据),**不走支付直接标记为已拥有** | | 课程口令码读取信息 | `courses` | 10 行,`code` 原值保留 | | 视频课程数据 | `lessons` | 841 行,`章节id`/`播放id` 原值保留 | | 免费视频课程数据 | `free_lessons` | 12 行 | | 首页课程列表 | `home_courses` | 5 行,并自动关联到对应付费课程 | | 首页免费课程列表 | `home_free_courses` | 3 行 | | 首页横幅图片 | `banners` | 3 行 | | 网页列表 | `articles` | 2 行 | | 课程页面Tips | `course_tips` | 2 行 | | cloudconfig | `settings` | 13 行 → 12 行(ID 0 占位丢弃),数字 ID 改字符串 key | | 课程口令码 | — | **作废,不迁移** | | 各类 `xxx2` 备份表、`网页数据`、`验证码发送` | — | 废弃 | ## 必须知道的四件事 ### 1. 内容字段里的旧域名会被改写 旧库的 `首页课程列表.内容`(44 处)和 `网页列表.网页内容`(4 处)里存的是**绝对 URL**, 形如 `https://api.yeomai.site/Images/...`。旧域名退役后这些图片/视频会全部 404。 迁移时按 `STATIC_BASE_URL` 自动改写。**执行前务必确认这个变量填的是新静态域名。** ### 2. 时间按 +08:00 换算 旧库时间由服务器本地 `NOW()` 写入,是北京时间墙钟值。新库统一存 UTC, 迁移时按 `+08:00` 换算(可用 `LEGACY_UTC_OFFSET` 覆盖)。 注意旧库中确实存在 `2024-02-01` 这种**只有日期没有时间**的值,已单独处理。 ### 3. `courses.code` 绝对不能被改写 它同时是视频目录名(`Course/{code}/…/playlist.m3u8`)与封面名(`Course/{code}.png`)。 迁移脚本对它逐字透传,测试中有断言保护。 ### 4. 迁移会清空新库业务表 脚本采用「先清空再写入」实现幂等,失败可原样重跑。 **安全阀**:若新库已存在订单数据(说明已上线),脚本会拒绝执行,必须显式加 `--force`。 ## 迁移后核对 脚本会自动逐表比对行数。此外建议人工抽查: - 随机选几个老用户,确认其 `entitlements` 里的课程与升级前一致。 - 打开首页,确认轮播、新课长图、试听入口图片都能加载(验证域名改写生效)。 ## 测试 迁移的转换逻辑由 `transform.test.ts` 覆盖(18 项),跑的是**真实的旧库 dump**: ```bash pnpm test ``` 其中包含行数比对、唯一性约束、域名改写、时间换算、首页长图与课程的关联完整性。 改动迁移逻辑后请先跑测试。