没有一步到位的系统,
只有一次次改对。

这一页记录项目是怎么被推着往前走的:哪些地方踩了坑、当时怎么判断、最后改成什么样。 数据来源是项目内的变更记录、数据库迁移序列与阶段验收文档,不是我事后回忆的版本。

26 次数据库迁移 M0–M5 里程碑 4 个攻坚记录
TIMESPAN
2026.06 起,持续迭代中
PROJECTS
溯源平台 · Genesis · 模拟游戏 · 成绩分析
TRACKING
变更记录 + 迁移脚本 + 阶段验收
01 / TIMELINE

项目不是依次做的,是并行推的

几个项目在时间上是交叠的。下面这条线按月份排列,标出每个阶段真正发生的事—— 包括那些不太好看的节点。

  1. 2026.06 / 立项

    Genesis Engine 定下四条设计支柱

    先把规则写死:第一性原则、完全可追溯、模拟与表现分离、模块不可知。 后续所有代码评审都以这四条为准。

    设计原则先行
  2. 2026.07 上旬 / 迁移

    把 Unity 项目重写成 C++20 平台

    源系统是 Unity IL2CPP 的商业游戏(C#),目标是自己设计的 Qt6 + C++20 架构。 分 Phase 4–7 推进,按模块迁移而非整体重写。

    跨语言重写
  3. 2026.07.14 / 溯源平台起步

    从 PDA 扫码端开始,而不是从后台

    第一批数据库迁移围绕 PDA 与扫码作业展开。先让产线和仓库能干活, 再补管理端——顺序反了会做出一堆没人用的界面。

    先落地现场作业
  4. 2026.07.27–28 / 密集迭代

    两天内十余次迁移:商城、订单、箱型、配送

    服务点模型、分销关系、订单发货、价格规则、SKU 与箱型绑定、学校配送陆续落地。 这是整个项目改动最密集的两天。

    高频小步
  5. 2026.07.29 / 回头补债

    发现隔离防线被系统性绕过,停下来重构

    在功能推进最猛的时候,发现全仓库 29 处绕过租户拦截器的调用。当天暂停加功能, 先出风险评估,再动手重构。

    P0 风险处置
  6. 2026.07.30–31 / 结算对齐

    对账与推荐关系

    对账规则、对账备注、推荐人关系相继入库。 涉及钱的部分,宁可多加两张表,也不在代码里凑。

    资金链路
  7. 2026.08 / 上线

    小程序备案完成,平台投入生产

    管理后台、溯源 H5、PDA 端与小程序进入实际使用;合规资料整理成册。

    生产环境运行
  8. 2026.09 / 商业化

    设备激活支付上线,顺手修掉一个老问题

    新增按设备计费的激活流程。排查时定位到长期存在的支付回调失败根因—— 一个被注入的租户条件,让公开接口永远查不到订单。

    实测通过
02 / VERSIONS

版本演进:用什么在记录变化

版本不是靠回忆整理的。四个项目各自有记录方式,好处是能回溯, 坏处是不统一——这一点后面会说。

各项目的版本记录方式与当前状态
项目 记录方式 已记录量 当前状态
学服溯源平台 数据库迁移脚本(按日期命名)+ 变更记录 26 次迁移,覆盖 7 个阶段 生产环境运行,v 迭代中
Genesis Engine 语义化版本 + 设计原则文档 + 迁移报告 v0.1.0,Phase 4–7 已迁移 在研,核心模块可编译
《我的政治世家》 里程碑体系(M0 预研 → M5 验收) M0 七份预研文档,M5 验收与性能报告 在研
成绩分析系统 按日推进 + 每日完成确认与验证脚本 DAY6–DAY9 完整记录 已交付使用

关于版本号的坦白:溯源平台目前没有严格的语义化版本号, 靠迁移脚本的日期序列来定位变更。这在单团队开发时够用, 但如果要对外开放接口或多团队协作,需要补一套正式版本策略。 这算已知的技术债,不是没意识到。

03 / BATTLES

四个攻坚记录

选这四个,不是因为它们最难,而是因为每个都暴露了一个判断错误, 并且最后是靠改结构而不是改代码解决的。

CASE 01 / 多租户隔离

29 处绕过,隔离防线形同虚设

问题:商城订单以平台作为销售主体, 订单的 tenant_id 被写成 0,不属于任何租户。企业端要查这些订单, 只能逐个方法加注解绕过租户拦截器。最终全仓库有 29 处这样的绕过。

判断:这不是写法问题,是模型问题。 靠人工保证「新增方法别忘加注解」,等于没有防线。

做法:评估为 P0(涉及资金链路与数据隔离), 约束是现有业务数据不能改变,按此前提完成重构。

结果:重构已完成。隔离策略改由结构保证,不再依赖开发者记得给方法加注解。

CASE 02 / 支付回调

回调长期失败,只能手工对账

问题:微信支付回调有时不生效, 订单状态不更新,运营只能拿流水逐笔手工核对。这个现象持续了很久, 一直当成偶发的网络问题。

判断:加设备支付时终于定位到根因—— 回调是公开接口,没有登录态,租户拦截器注入了一个不存在的租户条件, 查询自然查不到订单。

做法:公开接口显式忽略租户条件, 回调地址补别名以对齐商户后台配置,并补了回调解析的测试接缝。

结果:下单、状态轮询、二维码、订单复用上线实测全部通过。

CASE 03 / 首屏性能

H5 主包 1.29 MB,4G 下首屏超过 3 秒

问题:首屏加载了所有路由组件, 第三方 SDK(地图等)整包打进来,主 bundle 达到 1.29 MB, 移动网络下 LCP 超过 3 秒。

判断:不是压缩能解决的, 是加载策略问题——不该在首屏加载的东西被一起加载了。

做法:按路由做代码分割, 第三方库独立分包并延迟加载,设定验收基线: 主包 < 500 KB、LCP ≤ 2.0 s、CLS ≤ 0.1。

结果:优化已完成,首屏按既定基线验收。产物体积与 LCP 以构建记录实测为准,本文不代填数字。

CASE 04 / 大规模移植

从 Unity C# 重写到 C++20

问题:原有能力沉淀在一个 Unity IL2CPP 商业游戏里(C#),而新平台要遵循自研的四条设计原则, 两者在架构上不兼容,无法直接复用代码。

判断:整体重写风险不可控, 按 Phase 4–7 拆分,以模块为单位迁移,每个阶段可独立验证。

做法:先把源系统的行为写成文档, 再在新架构里重建,而不是逐行翻译代码。编译开启严格告警 (-Wall -Wextra -Wpedantic -Wconversion),把隐患挡在构建阶段。

状态:迁移完成度见各 Phase 报告,核心模块已可编译运行。

04 / DISCIPLINE

工程纪律:让改动可回溯

上面四个案例能写出来,靠的不是记性好,而是有记录可查。 下面这些做法本身不高级,但坚持下来才有价值。

MIGRATION
迁移脚本按日期命名

26 个迁移文件构成可回溯的版本序列,谁在什么时候改了什么结构,一目了然

CHANGELOG
变更写清原因

不只记「改了什么」,还记「为什么改」「上线后实测结果」

MILESTONE
阶段可验收

M0 预研到 M5 验收,每阶段有清单与报告,不靠口头确认

BASELINE
性能有基线

性能测试写清硬件与软件环境,结论可复现而非模糊描述

RISK
风险先分级

涉及资金与数据隔离的改动标记 P0,先评估再动代码

VERIFY
交付带验证

关键模块配验证脚本与测试用例,改完能自己先跑一遍

还没做好的:四个项目用了四套不同的版本记录方式, 跨项目对比时要人工对齐。下一步应该统一成一套变更模板, 这属于内部工程改进,不影响交付,但会持续消耗时间。

想看某个项目更细的过程?

演示时可以打开变更记录与迁移脚本,逐条说明当时为什么这么改。