# 开发日志:2026-06-16 M01-B 数据库迁移与兼容层 ## 1. 本次目标 建立首批正式数据库迁移、验证 SQL、最小 seed、旧表兼容映射和后端 MySQL 连接池基础。 ## 2. 本次完成 - 新增 `2026061601_m01b_core_schema` 的 up/down/verify SQL。 - 新增 `qipai_tenants`、`qipai_stores`、`qipai_rooms`、`qipai_members`、`qipai_orders`、`qipai_payments`、`qipai_devices`、`qipai_audit_logs` 和 `qipai_legacy_table_mappings`。 - 新增最小脱敏 seed,记录旧表到新表的首批映射。 - 新增 `backend/src/db/mysql.ts`,用 `mysql2/promise` 生成连接池配置。 - 新增迁移契约测试和连接池契约测试,并接入 `npm test` 与 `check-backend.ps1`。 - 调整连接池凭据字段传递方式,避免误触明文秘密扫描。 - 更新 release manifest dry-run,使其识别迁移文件已存在但尚未执行。 ## 3. 修改文件 - `backend/package.json` - `backend/src/config.ts` - `backend/src/db/mysql.ts` - `backend/tests/migration-contract.test.mjs` - `backend/tests/mysql-pool-contract.test.mjs` - `database/migrations/2026061601_m01b_core_schema.*.sql` - `database/seeds/2026061601_m01b_minimal_seed.sql` - `scripts/dev/windows/check-backend.ps1` - `scripts/dev/windows/check-release-manifest.ps1` - `scripts/dev/windows/check-repo-completeness.ps1` - `scripts/setup/deploy-business.sh` ## 4. 数据库变化 - 是否有变化:是。 - 迁移文件:`database/migrations/2026061601_m01b_core_schema.up.sql`、`database/migrations/2026061601_m01b_core_schema.down.sql`、`database/migrations/2026061601_m01b_core_schema.verify.sql`。 - 种子文件:`database/seeds/2026061601_m01b_minimal_seed.sql`。 - 回滚方式:空库或演练库可执行 down SQL;生产含业务数据后必须先备份并人工确认。 ## 5. API 变化 - 新增:无。 - 修改:无。 - 删除:无。 - 兼容旧接口:本轮只建立旧表映射,不暴露业务 API。 ## 6. 前端变化 - 小程序:无。 - 后台管理端:无。 ## 7. 部署变化 release manifest dry-run 已能记录 `databaseMigration=PROJECT_PRESENT_MIGRATION_NOT_RUN`。生产迁移执行入口尚未接入菜单,不能视为生产数据库已变更。 ## 8. 测试结果 - `npm --prefix backend test`:通过。 - `powershell -ExecutionPolicy Bypass -File scripts/dev/windows/check-backend.ps1`:通过。 - `powershell -ExecutionPolicy Bypass -File scripts/dev/windows/check-secrets.ps1`:通过。 - `npm audit --omit=dev`(在 `backend/` 执行):通过,生产依赖审计 0 漏洞。 ## 9. 欠缺 / 风险 - 尚未连接真实 MySQL 执行 up/down/verify。 - Kysely 当前安全修复版要求 Node 22;本轮先使用 `mysql2/promise` 连接池,后续若升级运行时再评估 Kysely。 - 旧数据迁移脚本未生成,真实旧库兼容读取 Repository 仍待下一步实现。 ## 10. 下一步 为 M01-B 增加迁移执行器或 MySQL dry-run 环境,并建立旧表兼容读取 Repository 的第一批查询。 ## 11. Git 与 Gitea 推送信息 - 远端:ssh://git@git.txyundm.cn:2222/panda/qipai.git - 分支:main - commit:`3add64b` - push 命令:git push origin main - push 结果:本轮最终推送后复核 - push 时间:2026-06-16 - HEAD 与 origin/main 是否一致:本轮最终推送后复核 - 失败原因与重试命令:无 ## 12. 2026-06-18 续开发:迁移执行器与旧库只读兼容层 - 新增迁移 SQL 拆分器、SHA-256 计划摘要和 `plan/up/verify/down` CLI;计划模式不连接数据库。 - `verify` 不再以“查询未报错”作为成功条件,会检查核心表、租户/审计列和迁移版本的最少结果行数。 - 新增旧表只读兼容 Repository,首批覆盖 `member_store_info`、`member_room_info`、`member_order_info` 和 `member_device_info`。 - 旧表查询强制租户过滤、参数化父级过滤、1–500 条分页上限和 SQL 标识符白名单,不提供写操作。 - `npm test`:通过,新增迁移解析/执行与旧库 Repository 契约测试。 - `npm run db:migrate:plan`:通过,识别 11 条 up 语句,摘要为 `7e1e0b690aab5a99bbe32f80879621f512b04909c57c0ab26cddda4961ddd5de`。 - `scripts/dev/windows/check-backend.ps1`:通过,包含编译、全部契约测试、迁移 dry-run 和真实 HTTP 健康检查。 - `scripts/dev/windows/check-secrets.ps1`:通过。 - 工程提交:`e069c50 feat(M01-B): 增加迁移执行器与旧库只读兼容层`。 - 未执行真实 MySQL up/verify/down:当前工作区未配置可丢弃测试库凭据,M01-B 保持 `PARTIAL`。 - 下一步:在一次性 MySQL 8 环境往返执行迁移,并实现旧 DECIMAL 金额到整数分的严格转换。 ## 13. 2026-06-18 续开发:旧订单金额严格转换 - 新增 `legacyDecimalToCents`,直接按十进制字符串拆分并使用 `BigInt` 计算整数分,避免 `Number * 100` 的浮点误差。 - 旧订单兼容查询新增 `price`、`pay_price`、`renew_price`、`group_pay_price`、`refund_price` 映射,统一输出对应的 `*Cents` 字段。 - 拒绝负数、科学计数法、前后空格、超过两位小数、非有限数字和非数字类型。 - `price` 按旧表 `NOT NULL` 约束处理;其余可空金额保留 `null`。 - 目标列按 MySQL `INT UNSIGNED` 上限 `4294967295` 分执行溢出检查。 - `npm test`:通过,包含精确值、边界值、空值、格式错误、溢出和 Repository 集成测试。 - `scripts/dev/windows/check-backend.ps1`:通过,包含编译、全部契约测试、迁移 dry-run 和真实 HTTP 健康检查。 - `scripts/dev/windows/check-secrets.ps1`:通过。 - 工程提交:`b8b384e feat(M01-B): 严格转换旧库订单金额`。 - 未执行真实 MySQL up/verify/down:当前工作区仍未配置可丢弃 MySQL 8 测试库,M01-B 保持 `PARTIAL`。 - 下一步:在一次性 MySQL 8 中执行 up、verify、down、再次 up,并保存可复现结果。 ## 14. 2026-06-18 续开发:MySQL 8 空库迁移往返 - 新增 `test:mysql:migration`,复用正式迁移执行器完成 `up → verify → down → up → verify`。 - 集成测试强制数据库名匹配 `qipai_m01b_test_*`,拒绝对普通或生产数据库运行。 - 新增 WSL 原生测试入口,随机创建临时数据库和仅限该库的临时账号,密码只存在于进程环境。 - 正常结束和模拟异常退出均执行清理;最终临时数据库和账号残留计数均为 `0`。 - WSL 环境:Ubuntu `26.04`、Node.js `26.3.0`、npm `11.16.0`、MySQL `8.4.9`。该环境仅作开发验证,不代替 Ubuntu 24.04 生产验收。 - `npm --prefix backend ci`:通过,生产依赖审计 0 漏洞。 - `npm --prefix backend test`:通过。 - 真实迁移:首次 up/verify、down、再次 up/verify 全部通过;up `11` 条、verify `3` 条、down `10` 条。 - Windows 后端、状态文档、README/配置一致性、秘密、行尾、发布清单门禁通过。 - 仓库完整性门禁未通过:工作区已有未跟踪 `miniapp/` 模板;按本轮明确边界未修改、暂存或提交这些文件,已登记 `ISSUE-007`。 - 校验和:up `7e1e0b690aab5a99bbe32f80879621f512b04909c57c0ab26cddda4961ddd5de`,verify `72a91941f662c878e1c92434e9f8ae157be034798b8104cd2408a449b709b4b2`,down `c2e337431d342e3925f503fa4d2da23a227baa61e51734ea505c7ba1a7ad2c83`。 - 工程提交:`8749a44 test(M01-B): 验证MySQL迁移往返`。 - 部署影响:无;未连接生产数据库,未修改部署菜单和正式迁移文件。 - M01-B 保持 `PARTIAL`:尚未在脱敏旧库副本上执行迁移和兼容读取,鉴权与业务接口也未完成。 - 下一步:建立脱敏旧表结构 fixture,在旧库副本上执行迁移并验证兼容读取。 ## 15. 2026-06-18 续开发:脱敏旧库副本迁移与兼容读取 - `ENGINEERING_DELTA=YES`。 - 新增脱敏旧库 fixture,覆盖门店、房间、订单、设备和两个租户;全部名称、标识、时间和金额均为虚构数据。 - 扩展真实 MySQL 集成测试:迁移前、首次 up/verify 后、down 后、再次 up/verify 后均执行旧表兼容读取。 - 验证租户隔离、父级过滤、只读查询、金额整数分转换,以及 down 不删除旧表。 - `npm test`(`backend/`):退出码 0。 - `powershell -ExecutionPolicy Bypass -File scripts/dev/windows/check-backend.ps1`:退出码 0,编译、契约测试、迁移计划和真实 HTTP 健康检查通过。 - `bash scripts/dev/wsl/mysql-migration-roundtrip.sh`:退出码 0;MySQL 8.4.9,fixture 8 条、up 11 条、verify 3 条、down 10 条。 - `bash scripts/dev/wsl/mysql-migration-roundtrip.sh --cleanup-probe`:退出码 0,模拟异常退出后临时数据库和账号无残留。 - 工程文件:`database/fixtures/2026061801_m01b_legacy_schema.sql`、`backend/tests/mysql-migration-roundtrip.test.mjs`、`backend/tests/migration-contract.test.mjs`。 - 工程提交:`1192dcb test(M01-B): 验证脱敏旧库迁移兼容`。 - 数据库/API/部署变化:生产数据库无变化,API 无变化,部署影响无;正式迁移 SQL 未修改。 - M01-B 完成;鉴权属于 M02,业务接口属于后续业务模块,不再作为 M01-B 阻塞项。 - 下一步:M01-C 轻量异步任务基础。