P2 Foundry
版本治理:draft → review → merged 全流程
本体定义是业务的地基,不能随便改。Foundry 用"草稿 → 评审 → 合入 → 回滚"的浓缩版版本状态机保护它:每个版本都有完整快照与变更 diff,合入前做影响分析,并发改冲突直接 409,改错了还能回滚。本主题 4 个故事带你走完全流程。
数据工程师
管理员
版本状态机
影响分析
回滚
并发冲突
共 4 个故事
能 / 不能速览
✅ 这个主题能做
- draft → review → merged 状态机,非法状态转移(merged 再 merge、draft 直接 merge 等)被 409 拦截
- 每个版本保存完整快照 + 变更 diff(kind / op / api_name / before / after)
- 合入前影响分析:列出下游链接、动作、指标、管道、血缘、进行中编辑
- 回滚到历史 merged 版本:重建主表并生成新版本,全程留痕
- 审批策略:动作 requires_approval=true 时自动要求至少 1 人过审且不可自我批准
⛔ 这个主题做不了
- 浓缩版版本管理(快照 + diff),不是真正的 git 式多分支,复杂多人并行能力有限
- 草稿对线上查询不生效,必须合入后才可见
- 只有 review 状态可合入、只有 merged 版本可回滚,其余一律报 INVALID_VERSION_STATE
- 并发改动只能靠 base_version 冲突检测拦截,不自动合并字段,内容冲突需人工解决
适用角色
本主题面向三个角色:
- 数据工程师:建草稿、改对象定义、提交评审、执行回滚——是版本流程的主要操盘手。
- 评审人 / 管理员:在 review 阶段看 diff 与影响分析,把关后合入。
- 指标负责人:消费影响分析,确认改动对 total_gmv / aov 等口径的影响。
普通业务用户只读线上定义,不参与版本流程。
能力速览(能做什么)
版本状态机
draft → review → merged → rollback 四态流转;非法转移返回 INVALID_VERSION_STATE(HTTP 409)。
快照 + 变更 diff
每版保存完整定义快照,与基线计算 change_diff,合入前可逐条审查改了什么。
影响分析
扫描对象被引用的位置:链接、动作、指标、管道、血缘、进行中编辑,merge / rollback / delete 前自动返回。
回滚
从历史 merged 快照重建主表并生成新 merged 版本,版本号递增,改错秒级还原。
审批策略
快照中任一动作 requires_approval=true 时,提交评审自动要求至少 1 人过审且不可自我批准。
调整指南(怎么调整)
- 想改定义:先建草稿 → 改 → 提交评审 → 看影响分析 → 合入;不要直接在线上对象上改。
- 想避免冲突:建草稿前先看最新 merged 版本号,基于最新基线改,减少 CONFLICT 概率。
- 想回滚:到版本历史选一个 merged 版本执行回滚;回滚目标必须是 merged,否则报 INVALID_VERSION_STATE。
- 想加审批:给动作配 requires_approval=true,提交评审后自动要求 1 人过审;关键对象可配置严格审批策略。
- 想对比:版本历史里逐个看 change_diff,改了什么一目了然。
做得好的场景
版本治理让核心对象"受控演进、改错可退",特别适合以下场景:
- 核心对象受控演进:order 这类被指标引用的对象,任何改动都有快照、diff 与审批,改起来不心惊胆战。
- 改错可回滚:合入后发现枚举配错,一个回滚动作重建主表,秒级还原。
- 评审有据可依:影响分析把"改动会影响谁"列得清清楚楚,评审不用靠猜。
- 并发不覆盖:base_version 冲突检测杜绝静默互相覆盖,谁先合入谁赢,后到者收到 409。
限制与不足
以下是明确的边界,使用前先知道:
- 浓缩版版本管理:只有版本快照 + 变更 diff,没有真正的 git 式多分支,复杂多人并行场景能力有限。
- 草稿不生效:草稿里的修改对线上查询不可见,必须合入后才会生效。
- 状态机严格:merged 再 merge、draft 未 review 直接 merge、回滚非 merged 目标都会报 INVALID_VERSION_STATE。
- 默认审批宽松:demo 默认 min_approvals=0、允许自我批准;审批强度需自行配置(requires_approval)。
- 影响分析有盲区:pipeline_definitions / data_lineage 未建表时注明"表未就绪"并跳过扫描。
场景故事
故事 1
给 order 加"优先级"属性:draft → review → merge 全流程
场景:受控变更
角色:数据工程师 + 评审人
耗时:约 8 分钟
- 背景
- 运营要求订单带上"优先级"(高 / 中 / 低)。order 是被销售指标(total_gmv、aov)引用的核心对象,张工不敢线上直接改,决定走版本流程:新建草稿、改定义、提交评审、看影响分析、合入。
- 传统做法对比
- 以前改表 / 改模型往往直接线上改,没有评审、没有历史快照,改坏了只能靠记忆回滚;现在任何变更都有版本快照与 diff,可对比、可回滚、可审批。
- 角色
- 数据工程师(建草稿、改定义);评审人 / 管理员(提交 review、合入 merge)。
- 操作步骤
-
- 进入"版本历史",找到 order 对象
- 新建草稿(draft),版本号 = 最新 merged + 1,base_version = 最新 merged
- 在草稿中添加属性 priority(enum 高 / 中 / 低)并保存
- 提交评审(review),状态机 draft → review
- 查看影响分析,确认无风险后合入(merge)
- 系统响应
- 建草稿返回 {code:0, data:{version_id:2}};提交评审返回 {code:0, data:{version_id:2, status:"review"}};合入返回 {code:0, data:{version_id:2, impact:{object_type_name:"order", impacts:[...]}}},同时返回影响分析报告。
- 结果洞察
- 对象查询里 order 现在多出 priority 字段,线上版本号递增;版本历史里每个版本的 change_diff(kind / op / api_name / before / after)都可回看。非法转移(draft 未 review 直接 merge)会被 409 拦截。
- 调整建议
- 大改动先在草稿里分步提交,diff 更清晰;被其他对象 / 指标引用的属性删除会被拒绝,先清理依赖再删;关键对象可配置审批策略。
- 动手试一试
- 页面路径:版本历史 → order → 新建草稿。输入内容:添加属性 priority(enum:高,中,低),提交评审后合入。预期结果:状态机 draft → review → merged 走通,order version 递增,对象查询出现 priority 字段。
- 限制提示
- 这是"浓缩版"版本管理(快照 + diff),不是真正的 git 分支;草稿修改对线上查询不生效,必须合入后才可见。
故事 2
合入前影响分析:发现下游指标依赖,评审叫停
场景:影响分析
角色:数据工程师 + 指标负责人
耗时:约 5 分钟
- 背景
- 张工觉得 status 属性"没用了"想删掉,顺手建了个草稿把 status 删除并提交评审。王姐(指标负责人)在合入前看了一眼影响分析,发现 total_gmv / aov 指标、update_order_status 动作、对象查询全都在用这个属性。
- 传统做法对比
- 以前删字段前靠人肉问一圈"谁在用",漏掉一个报表就是线上事故,修复要 1~2 天;现在合入前影响分析自动列出全部依赖,改之前先看到后果。
- 角色
- 数据工程师(建草稿、提交评审);指标负责人 / 评审人(核对影响清单并叫停)。
- 操作步骤
-
- 建草稿,删除 status 属性,提交评审
- 点"影响分析"或直接发起合入
- 查看返回的 impact 清单
- 评审结论:恢复该属性,或先清理下游依赖再删
- 系统响应
- 影响分析返回:
{
"object_type_name": "order",
"impacts": [
{"type": "metric", "name": "total_gmv", "detail": "列 entity_id 引用对象 id=2"},
{"type": "metric", "name": "aov", "detail": "列 entity_id 引用对象 id=2"},
{"type": "action", "name": "update_order_status", "detail": "action belongs to object type"}
]
}
删除被下游引用的属性时,校验直接拒绝。
- 结果洞察
- 影响分析把"这个改动会影响谁"列得清清楚楚,评审人有据可依,避免了删字段引发的报表事故。进行中的编辑(ontology_edits)也会被列为影响项。
- 调整建议
- 把影响分析设为每次合入的必看步骤;对核心对象配置审批策略;指标 / 管道 / 血缘 / 编辑引用都会进清单,逐个确认后再动。
- 动手试一试
- 页面路径:版本历史 → order → 新建草稿并删除 status 属性。预期结果:合入时看到 metric total_gmv / aov 与 action update_order_status 依赖清单,删除被拒。
- 限制提示
- 影响分析只扫描已建表的方向,pipeline_definitions / data_lineage 未建表时注明"表未就绪"并跳过;扫描依赖文本列包含对象名匹配,改名需谨慎。
故事 3
改错了回滚:从历史 merged 版本重建主表 + 生成新版本
场景:回滚
角色:数据工程师
耗时:约 3 分钟
- 背景
- 张工上周合入的 v3 把 order 的 status enum 约束误改成了 ["ok","bad"],运营提交 pending 订单直接校验失败。他决定回滚到 v2,恢复 shipped / cancelled / pending。
- 传统做法对比
- 以前线上改错只能找 DBA 手工 DDL 倒腾或从备份恢复,停机半天起步;现在平台里一个回滚动作,秒级重建主表并生成新版本,全程留痕。
- 角色
- 数据工程师(发起回滚);评审人(确认回滚目标版本)。
- 操作步骤
-
- 进入"版本历史",选择 order
- 确认目标版本 v2(必须是 merged 状态)
- 点击"回滚",请求体带 target_version=2
- 查看返回的影响分析报告
- 系统响应
- POST /ontology/objects/:id/rollback(body: {"target_version":2})返回:
{
"code": 0,
"data": {
"target_version": 2,
"impact": {
"object_type_name": "order",
"impacts": [{"type": "metric", "name": "total_gmv", "detail": "列 entity_id 引用对象 id=2"}]
}
}
}
版本列表新增一个 merged 版本(版本号递增),主表按 v2 快照重建。
- 结果洞察
- 线上定义回到 v2,status 约束恢复 shipped / cancelled / pending,运营恢复正常提交流程;回滚本身也留痕成一个新版本,历史完全不丢。
- 调整建议
- 回滚目标必须是 merged 版本,否则报 INVALID_VERSION_STATE;回滚前先看影响分析确认没有新依赖;多版本并存时指定准确的 target_version。
- 动手试一试
- 页面路径:版本历史 → order → 回滚。输入内容:target_version 选上一个 merged 版本。预期结果:版本号 +1,order 定义恢复为目标版本,查询正常。
- 限制提示
- 只有 merged 版本可回滚;回滚会重建主表并新增版本,属于一次性操作,撤销回滚需要再回滚一次;demo 源表数据重启重建,但版本历史持久保留。
故事 4
两人并发改同一对象:base_version 冲突检测,后到者 409
场景:并发冲突
角色:两位数据工程师
耗时:约 5 分钟
- 背景
- 周四上午,张工给 order 加"优先级",小陈同时给 order 加"发货仓"。两人都基于 v2 建了草稿;小陈先提交评审并合入(main 到 v3),张工随后合入时被拦——他的草稿 base_version 还是 v2。
- 传统做法对比
- 以前两个人改同一张表,后写覆盖先写,谁改的都不知道,账目对不上要翻半天日志;现在合入前比对 base_version,落后就直接 409,绝不静默覆盖。
- 角色
- 两位数据工程师(各自改草稿);评审人(逐个合入)。
- 操作步骤
-
- 张工、小陈各基于 v2 建草稿,各改各的
- 小陈先提交评审并合入 → main 变成 v3
- 张工再合入 → 返回 CONFLICT
- 张工基于最新 v3 重建草稿,把"优先级"改动合并进去后再次提交
- 系统响应
- merge 返回错误:
{
"code": "CONFLICT",
"error": "merge conflict: main latest merged version is 3, draft base_version is 2"
}
HTTP 409;非法状态转移(merged 再 merge、draft 直接 merge)则返回 INVALID_VERSION_STATE。
- 结果洞察
- 并发修改不会静默互相覆盖,先到先得;后到者根据错误信息里的最新版本号,基于最新 merged 重建草稿、合并内容后再提交,改动不会丢。
- 调整建议
- 大改前先看最新 merged 版本号;把改动拆小、快速合入减少冲突窗口;冲突发生时人工把两份改动合并到一个草稿再走评审。
- 动手试一试
- 页面路径:版本历史 → order。输入内容:两个会话各建草稿改同一对象,先合一个再合另一个。预期结果:第二个合入返回 CONFLICT 409,附最新版本号。
- 限制提示
- 冲突检测按版本号比对,只防"覆盖"、不自动合并字段;内容冲突仍需人工处理;浓缩版版本管理不支持真正的多分支并行开发。
常见问题
什么改动必须走版本流程?
任何对象定义变更(属性、链接、动作、主键、约束)都建议走 draft → review → merge。前端本体工作台的变更同样走草稿 → 评审 → 合入的快速通道,并弹出影响分析。
草稿保存后线上会生效吗?
不会。草稿只是隔离的修改区,线上查询仍按最新 merged 版本走;必须提交评审并合入后才生效。
回滚会丢历史吗?
不会。回滚从历史 merged 快照重建主表,并生成一个新 merged 版本留痕;版本历史完整保留,随时可以再回滚。
为什么 merge 报 INVALID_VERSION_STATE?
状态机只允许 draft → review → merged → rollback 顺序流转。merged 再 merge、draft 未 review 直接 merge、回滚非 merged 目标都会报这个错误。
审批策略怎么生效?
快照里任一动作 requires_approval=true 时,提交评审自动要求 min_approvals=1 且不可自我批准;否则默认宽松(min_approvals=0、允许自我批准)。
主题小结
一句话:Foundry 用"草稿 → 评审 → 合入 → 回滚"的浓缩版版本状态机保护本体定义:每版有快照与 diff,合入前做影响分析,落后就 409,改错可回滚。记住三件事:草稿不生效、只有 merged 能回滚、核心对象务必配审批策略。