软件交接清单:外包团队撤走时,你应该拥有什么
不少公司在付完最后一笔款之后才发现,自己没法部署自己的产品。这里列出所有应该在你名下的东西,以及如何在合作结束前逐项验证。
当公司来找我们接手一个既有产品时,有一种模式反复出现:从法律上说他们拥有代码,却依然发不了版。仓库是在的。部署账号属于一个已经离职的人。域名注册在外包公司名下。没人知道生产环境需要哪些环境变量。
这很少是恶意。通常只是没人把"存在某个人脑子里的东西"写下来。但结果是一样的,而预防的时机是项目开始之前,不是结束的时候。
所有权究竟意味着什么
拥有一个软件包含五件事,而代码只是第一件:
- 你有代码,连同它的历史。
- 你能从一台干净的机器上构建并运行它。
- 你能部署,不必问任何人。
- 你控制它依赖的账号和域名。
- 你理解那些决策,足以去改动它。
缺任何一件,你拥有的就不是一个产品,而是一份依赖。
清单
代码
- 仓库在你的组织下,不是个人账号,也不是外包公司的。
- 完整的历史,不是一个压扁的提交。历史就是文档。
- 所有分支和标签,包括当前生产环境正在跑的那个标签。
- 设计源文件(Figma 或同类)在你的工作区里,并注明字体与授权情况。
构建与运行
- 一份在干净机器上能跑通的 README。这个测试是字面意义上的:一个从没见过这个项目的人照着做,把应用跑起来。如果它在第四步断掉,那就是没做完。
- 依赖版本已锁定,锁文件提交进仓库。
.env.example列出每一个变量、它的用途,以及从哪里获取。- 怎么跑测试,以及一次通过的运行长什么样。
部署
- 你能自己部署到生产环境,并且在交接前真的做过一次。不是"需要的话我们能做"。是已经做过了。
- 流水线配置在仓库里,不是点进某个没人看得到的控制台里。
- 你知道怎么回滚,并且试过。
- 数据库迁移有文档,包括如何对生产环境执行。
账号与域名
这一类造成的痛苦最多,因为每一项都很小、都容易忘:
- 域名注册商在你名下,续费用的卡不会随某个人的离职而失效。
- DNS,并记录每条记录是做什么用的。
- 主机、云、CDN。
- App Store 和 Play Console 在你的组织下,连同签名密钥和证书。丢了 Android 签名密钥,意味着你再也无法更新那个应用条目。
- 邮箱、事务性邮件服务商,以及为其做身份验证的那些 DNS 记录。
- 错误追踪、统计分析、支付服务商。
- 每一个第三方 API key,以及它记在哪个账户上扣费。
逐项确认:所有者是不是一个由你公司控制的地址? 不是某个人的工作邮箱。是一个能在有人离职后依然存在的共享地址或角色地址。
理解
- 一份简短的架构说明:有哪些部件,请求怎么流动。
- 对那些不写下来就会让下一位工程师困惑的选择,写决策记录。为什么用这个数据库。为什么不用那个框架。为什么存在这段奇怪的绕行代码。
- 一份运维手册:什么会坏、告警是什么意思、凌晨两点该做什么。
- 已知问题和有意为之的取巧,诚实地写下来。
决策记录是价值最高、却没人写的文档。代码显示做了什么。只有写下来的决策才显示什么被否决了、以及为什么,而那才是阻止下一个团队重犯你已经付过学费的错误的东西。
在合作结束前验证它
一份交接文档只是一项声明。趁写它的人还联系得上时去验证。
两个练习,都值得花一个下午:
- 干净机器测试。 一个没做过这个项目的人拿一台全新笔记本,照着 README 做,在本地把它跑起来。他们每卡住一处,就是一处文档缺陷。当场修掉。
- 部署测试。 你的团队做一处微小改动,发到生产环境,确认,然后回滚。如果其中任何一步需要外包公司,交接就没完成。
请在最后一笔付款之前做这些,而不是之后。这不是不信任;这是唯一一个所有人都还在场、也还有动力的时刻。
在一开始就设置好
上面几乎所有事情,在第一天都微不足道,到第九个月都很昂贵。项目启动时:
- 在你的组织下创建账号,然后邀请外包团队进来,而不是反过来。
- 自己注册域名。
- 从一开始就用角色地址持有账号所有权。
- 约定文档属于"完成"的一部分,而不是收尾时的任务。
这样设置之后,交接就不再是一个事件。它变成撤销几项访问权限,因为一切本来就是你的。
签约之前该问什么
三个值得问任何外包公司的问题,包括我们:
- 账号会在谁的名下? 从一开始就在你名下,是唯一好的答案。
- 没有你们,我们能部署吗? 以及能不能在项目进行中就证明,而不是结束之后?
- 如果我们在第三个月停止合作会怎样? 诚实的回答会描述一个流程。含糊的回答是一个警告。
一家对自己工作有信心的外包公司,没有理由扣住任何东西。如果这些答案让你觉得不舒服,那就是你在整场销售对话里学到的最有用的东西。