恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
老系统迁移无文档?从代码逆向提取PRD的实战指南
首页
资讯中心
/
老系统迁移无文档?从代码逆向提取PRD的实战指南
老系统迁移无文档?从代码逆向提取PRD的实战指南
发布时间:2026/10/4 7:03:46
1. 接手一个没有文档的老系统到底难在哪很多做企业级开发的朋友都遇到过这种局面领导拍着你的肩膀说这套系统跑了五六年了现在要迁移到新架构你先把需求文档整理出来。你打开代码仓库一看别说需求文档了连像样的注释都没几行README 还是三年前某位已经离职的同事随手写的两句话。数据库里几十张表字段命名风格从拼音缩写到英文全称混着来前端页面点进去功能倒是能跑但没人说得清每个按钮背后的业务规则。这就是典型的“代码即文档”状态。系统还活着业务还在跑但知识已经随着人员流动散掉了。你要做的不是重新发明需求而是把已经存在于代码里的隐性知识逆向提取成一份能指导迁移的 PRD。这件事的核心逻辑其实很朴素代码是系统行为的唯一真相来源数据库结构、接口定义、前端交互、定时任务、消息消费这些加起来就是一份比任何文档都精确的需求说明书只不过它用的是机器语言。我接手过一套基于 Spring Boot 加 Vue 的多商户商城系统前后端分离后端大概四十多个 Controller前端三十多个路由页面数据库 MySQL 里一百多张表。原计划两周出迁移 PRD实际花了将近一个月。踩过的坑、总结的方法下面一点点拆开讲。这篇文章适合三类人看一是正在做老系统迁移、需要补文档的后端或全栈工程师二是技术负责人想了解逆向梳理的可行路径和工期预估三是对 Spring Boot 和 Vue 技术栈有一定了解、想学习如何从代码反推业务的学习者。不需要你精通逆向工程但需要你能读懂基本的 Java 和 JavaScript 代码。2. 逆向迁移 PRD 的整体思路与工具选型2.1 为什么不能直接照着代码翻译成文档最容易想到的做法是打开每个 Controller把接口路径和参数抄下来整理成表格。我一开始也这么干做了三天就发现行不通。原因有三个第一接口数量太多纯手工抄写效率极低且容易遗漏第二接口只是入口真正的业务规则藏在 Service 层的条件判断里比如“订单金额大于 500 且用户等级为 VIP 时才免运费”这种规则不读透代码根本提取不出来第三前端页面上的交互逻辑比如某个字段在什么条件下才显示、某个按钮点击后触发几个接口调用这些信息分散在 Vue 组件里光看后端接口是拼不完整的。所以正确的思路不是“翻译代码”而是“重建业务模型”。具体来说分四层来拆数据层看表结构和字段约束服务层看业务规则和状态流转接口层看对外契约和调用关系交互层看用户操作路径和页面流转。这四层信息交叉验证才能拼出一份完整的需求画像。2.2 工具链的选择与理由工欲善其事必先利其器。我实际用到的工具组合如下工具用途选择理由IntelliJ IDEA 社区版阅读 Spring Boot 源码免费对 Java 生态支持好全局搜索和调用链追踪够用MySQL Workbench导出表结构、查看索引和外键可视化直观能直接导出 DDLSwagger 或 SpringDoc自动提取接口文档如果项目集成了就直接用没集成可以临时加依赖Vue DevTools查看组件树和路由结构浏览器插件能快速理清前端页面层级PlantUML画状态流转图和时序图文本化绘图方便版本管理和修改数据库逆向工具生成 ER 图比如 MySQL Workbench 自带的 Reverse Engineer这里重点说一下 IntelliJ IDEA 社区版。很多人觉得社区版功能不够但对于读代码这件事它的全局搜索CtrlShiftF、查找用法AltF7、调用层级CtrlAltH完全够用。我通常的做法是先用全局搜索找到所有 Controller 类然后逐个追踪每个接口的调用链一直追到 Mapper 层的 SQL 语句。这个过程虽然笨但最可靠。提示如果项目用了 MyBatis建议把 Mapper XML 文件全部打开因为很多业务查询逻辑直接写在 SQL 里光看 Java 代码会漏掉关键过滤条件。2.3 逆向 PRD 的文档结构设计一份能指导迁移的 PRD和写给新产品用的 PRD 不一样。新产品 PRD 侧重“要做什么”迁移 PRD 侧重“现在是什么”和“迁移后必须保持什么”。我的文档结构是这样的第一部分是系统概览包括技术栈、部署架构、模块划分。第二部分是数据模型包括核心表结构、字段含义、表间关系。第三部分是功能清单按模块列出所有功能点每个功能点标注对应的接口、页面和业务规则。第四部分是状态流转把订单、支付、退款等核心业务的状态机画出来。第五部分是迁移风险点标注哪些逻辑是隐性的、容易在迁移中丢失的。这个结构的好处是开发人员拿到后可以直接对照着写新代码测试人员可以对照着设计测试用例产品经理可以对照着确认业务完整性。3. 从数据库和代码中提取核心业务规则3.1 数据库表结构逆向从字段名读出业务含义数据库是系统的骨架。我拿到一套陌生系统第一件事就是导出所有表的 DDL然后逐张表分析。以那套多商户商城为例一百多张表里核心表大概二十张包括用户表、商户表、商品表、订单表、订单明细表、支付记录表、退款表、物流表、优惠券表、评价表等。看表结构的时候重点关注几类信息。第一类是字段命名比如is_deleted、status、type这种字段往往对应着业务上的软删除、状态机和分类逻辑。第二类是索引唯一索引通常意味着业务上的唯一性约束比如order_no唯一索引说明订单号不能重复。第三类是外键关系虽然很多互联网项目不建物理外键但通过字段名也能推断出关联关系比如order_id关联订单表。我遇到过一个坑订单表里有个source字段类型是 tinyint注释写的是“来源”。光看这个根本不知道有哪些取值、分别代表什么。后来在前端代码里找到了一个下拉框的选项列表才确认 1 代表 App、2 代表小程序、3 代表 H5。这种信息如果不从前端反查光看数据库是猜不出来的。3.2 Service 层业务规则提取条件判断里的隐藏需求Service 层是业务规则最密集的地方。我通常的做法是从 Controller 入口开始顺着调用链往下读把每个 if-else、switch-case 都记下来因为这些条件判断就是业务规则。举个例子那套商城的订单创建逻辑里有一段代码是这样的先检查用户是否被禁用再检查商品是否下架然后检查库存是否充足接着计算优惠券抵扣最后判断是否需要拆单。这一连串判断在代码里可能分散在五六个方法里但从前端用户视角看就是“点击下单按钮后发生的事”。逆向 PRD 要做的就是把这些分散的逻辑重新组织成一条完整的业务规则描述。我习惯用一张表格来记录这类规则规则编号触发条件业务动作代码位置备注R001用户状态为禁用拒绝下单UserService.checkStatus返回错误码 1001R002商品状态为下架拒绝下单ProductService.checkOnSale返回错误码 2001R003库存不足拒绝下单StockService.checkStock返回错误码 3001R004优惠券已过期忽略优惠券CouponService.calc不报错直接按原价这种表格在迁移时特别有用因为新系统开发时可以逐条对照实现测试时也可以逐条验证。3.3 接口契约梳理给第三方用的接口要单独标记那套系统有一部分接口是给外部合作伙伴调用的比如商户系统对接、物流回调等。这些接口和内部接口混在一起如果不仔细区分迁移时很容易漏掉或者改错。我的做法是在梳理接口时给每个接口打上标签内部接口、外部接口、回调接口。外部接口通常有签名验证、IP 白名单、频率限制等额外逻辑这些在迁移时必须保留。回调接口则要特别注意幂等性处理因为外部系统可能会重复调用。注意有些接口虽然路径看起来是内部的但实际上被前端跨域调用了这种也要标记出来。判断方法是看 Controller 上有没有CrossOrigin注解或者看前端代码里的请求地址。4. 前端交互与状态流转的还原方法4.1 Vue 路由与页面结构还原前端是用户直接接触的部分也是需求最直观的体现。那套系统用的是 Vue 2 加 Element UI路由配置在router/index.js里。我先把路由表导出来整理成页面清单然后逐个页面去看组件代码。看 Vue 组件的时候重点关注几个东西data里定义了哪些字段对应页面上的表单项和展示项、methods里有哪些方法对应页面上的操作、watch里监听了什么对应字段联动逻辑、computed里计算了什么对应派生数据。把这些串起来就是一个页面的完整功能描述。比如商品编辑页面data里有商品名称、价格、库存、分类、图片列表等字段methods里有保存、上架、下架、删除等操作watch里监听了分类变化去加载对应的属性模板。这些信息组合起来就能写出“商品编辑页面支持修改商品基本信息、控制上下架状态、根据分类动态展示扩展属性”这样的需求描述。4.2 状态流转图订单从创建到完成的全链路状态流转是迁移中最容易出问题的部分。因为状态机往往分散在多个 Service 方法里而且可能还有定时任务在后台修改状态。那套商城的订单状态有待支付、已支付、待发货、已发货、已完成、已取消、退款中、已退款。这些状态之间的流转条件我花了整整两天才理清楚。理清之后我用 PlantUML 画了一张状态图标注了每个流转的触发条件和对应的代码位置。这张图后来成了迁移 PRD 里最有价值的部分因为新系统开发时订单模块的负责人直接照着这张图实现省了大量沟通成本。除了订单还有退款单、优惠券、商户入驻申请等也有状态流转。我的建议是凡是带status字段的表都要画一张状态图不要嫌麻烦。4.3 定时任务与异步逻辑的排查这是最容易被遗漏的部分。老系统里往往有一些定时任务比如每天凌晨自动关闭超时未支付的订单、自动确认收货、自动结算商户货款等。这些逻辑不在用户操作路径上光看接口和页面是发现不了的。排查方法是在代码里全局搜索Scheduled注解或者搜索quartz、xxl-job等定时任务框架的关键字。找到之后逐个分析任务的执行逻辑、执行频率、依赖条件。那套系统里有七个定时任务其中三个和订单相关两个和结算相关还有两个是数据同步任务。这些在迁移 PRD 里都必须明确列出否则新系统上线后会出现订单状态不流转、货款不结算等严重问题。异步逻辑也是类似搜索Async、MQ、消息队列等关键字把异步处理的业务场景找出来。比如订单创建后发送通知、支付成功后更新库存等这些在迁移时都要考虑。5. 实操过程从零到一份完整 PRD 的完整记录5.1 第一阶段环境搭建与代码通读我拿到代码后的第一周主要做三件事。第一把项目跑起来。那套系统依赖 MySQL、Redis、RabbitMQ我用了半天时间配好本地环境确保能正常启动和访问。第二通读项目结构把 Maven 模块划分、包结构、配置文件都看一遍心里有个大概的模块地图。第三导出数据库 DDL 和前端路由表作为后续梳理的基础材料。这个阶段不要急着写文档先把整体感觉建立起来。我通常会画一张粗略的模块关系图标注哪些模块之间有调用关系哪些模块是独立的。5.2 第二阶段逐模块深挖与规则记录第二周到第三周我按模块逐个深挖。顺序是先核心后边缘用户模块、商品模块、订单模块、支付模块、商户模块、营销模块、物流模块。每个模块的梳理流程是固定的先看数据库表再看 Controller 接口然后追 Service 逻辑最后对照前端页面验证。每梳理完一个模块我就写一份模块级的逆向文档包括功能清单、业务规则表、状态流转图、接口列表。这些模块文档最后汇总成完整的迁移 PRD。这个阶段最耗时间的是订单模块因为涉及拆单、优惠分摊、退款计算等复杂逻辑。我光读订单相关的代码就花了三天画了四张状态图记录了三十多条业务规则。5.3 第三阶段交叉验证与遗漏排查第四周主要是查漏补缺。我把前端所有页面都点了一遍对照后端接口列表看有没有页面调用了但接口列表里没有的接口或者接口列表里有但前端没用的接口。前者说明遗漏了功能后者可能是废弃接口或者给外部用的接口。同时我把定时任务、消息消费、缓存更新这些隐性逻辑再排查一遍确保没有遗漏。最后我找了一位还在职的老员工花了两个小时对着文档过了一遍他补充了几个我漏掉的业务规则比如某个优惠券在特定节日会自动翻倍这个逻辑藏在配置表里光看代码不容易发现。5.4 第四阶段文档整理与评审最后一周把前面所有材料整理成正式 PRD按之前设计的五部分结构组织。整理过程中我把所有业务规则都编了号方便后续追溯。文档完成后组织了一次评审会邀请开发、测试、产品三方参加逐模块确认。评审会上又发现了几处理解偏差修正后定稿。整个流程下来实际耗时四周多一点产出了一份约八十页的迁移 PRD包含一百多张表结构说明、两百多个接口定义、四十多条业务规则、八张状态流转图。6. 常见问题与避坑经验实录6.1 代码里的“僵尸逻辑”怎么识别老系统里经常有一些代码看起来是业务逻辑但实际上已经废弃了。比如某个接口还在但前端早就不调用了某个配置项还在但实际不会生效。这些“僵尸逻辑”如果写进 PRD会误导新系统开发。识别方法有几个看代码提交记录如果某个方法最近两年都没改过而且没有测试覆盖大概率是废弃的看前端调用如果全局搜索接口路径在前端代码里找不到可能是废弃的看数据库数据如果某个状态值在数据表里从来没有出现过对应的逻辑可能是废弃的。我遇到过一个例子订单表里有个is_urgent字段代码里有加急处理的逻辑但查了数据库发现这个字段全是 0前端也没有设置入口确认是废弃功能没有写入 PRD。6.2 隐式业务规则配置表里的秘密有些业务规则不在代码里而在配置表里。比如那套系统有一张sys_config表里面存了各种参数订单超时时间、优惠券最大抵扣比例、商户结算周期等。这些参数在代码里是读取配置表的值而不是硬编码所以光看代码只能看到“读取配置”看不到具体数值。迁移时这些配置值必须一并迁移否则新系统行为会和老系统不一致。我的做法是把配置表里所有和业务相关的配置项都列出来标注含义、当前值、影响范围。6.3 迁移 PRD 的验收标准一份迁移 PRD 写得好不好有一个简单的验收标准拿给一个没接触过老系统的开发他能不能照着这份文档把新系统开发出来而且行为和老系统一致。如果能说明文档合格如果不能说明还有遗漏。我通常会在文档完成后找一个同事做“盲测”让他只看文档不看代码描述某个功能应该怎么实现然后对照代码看是否一致。这个方法很有效能发现很多自己没意识到的表述不清或逻辑缺失。6.4 常见问题速查表问题现象可能原因排查方法解决思路接口列表和前端调用对不上存在废弃接口或外部接口全局搜索接口路径标记接口类型区分处理状态流转理不清状态修改分散在多个地方搜索所有修改 status 的代码画状态图标注触发条件业务规则遗漏规则藏在配置表或定时任务里检查配置表和 Scheduled补充配置项清单和任务清单字段含义不明命名不规范或注释缺失查前端选项列表或问老员工结合前后端推断标注确认状态迁移后行为不一致隐式规则未迁移对比新旧系统测试结果补充隐式规则到 PRD提示逆向 PRD 不是一次性的工作建议在迁移开发过程中持续维护发现遗漏随时补充。我通常会在文档里留一个“待确认”章节把不确定的点记下来后续逐个确认。7. 迁移 PRD 的后续维护与扩展思路文档写完不是终点。新系统开发过程中开发人员会不断提出疑问这些疑问往往指向文档的薄弱环节。我的做法是每次答疑后都把答案补充到文档里让文档保持“活”的状态。另外迁移完成后这份逆向 PRD 还有别的用途。比如新同事入职时可以用它快速了解老系统的业务逻辑比如做系统重构时可以用它评估影响范围比如做数据迁移时可以用它核对字段映射关系。如果后续还要做国产化迁移比如从 MySQL 换到国产数据库、从 Spring Boot 2.x 升级到 3.x这份 PRD 同样是基础材料。因为国产化迁移最大的风险不是技术本身而是业务逻辑在迁移过程中丢失或变形。有了这份文档至少业务层面是有保障的。我个人在实际操作中的体会是逆向梳理这件事技术难度不高但耐心和细致程度要求很高。不要指望有什么工具能一键生成 PRD工具只能帮你提取接口和表结构真正的业务规则还是要靠人一行行读代码、一个个点页面、一条条问老员工。这个过程很枯燥但做完之后你对系统的理解会超过任何一个还在职的人。