forked from ChaiHao/BPOS-MVP
三面拆分⑰:编辑即其身 —— 保存写回本版,新版本只出自「新建」
用户问:为什么编辑一个版本、保存就自动多一个副本?那不是我要的。
旧机制「保存恒新增版本号」改为:
- savePackage:pkg.version 已存在 → **就地写回该版**(号不变、状态不变);
`asNew: true`(新建按钮)或新流程首版才铸新版本号(服务端算,不生效)
- 底线三道,一道不少:
① **在途钉版不可变** —— 该版有未完结工作流(按 (包,版本) 钉定义)→ 409,
一字不落库;「就地覆盖会改掉在途正在读的编排」由这道闸守,不再靠只插不改一刀切
② **生效版必须始终可运行** —— 写回生效版跑闭合闸,不闭合 412 带整份报告;
未生效版画图不检查、随手存
③ **陈旧编辑不复活** —— 流程存在而版本号已被清理 → 409(实测:停在已删旧版上的
标签页发来保存,把老内容静默复活成了新版本;StaleVersionError 拦死)
- store:新增 updatePackageDefinition(只许命中现存版本)+ countPinnedInFlight
- 前端:保存按钮「保存 v{n}」;新建走 asNew;文案全线「新建才长版本」
- 测试:save-package.test 六例(写回/钉版/热改闭合/asNew/防复活/首版);
过程中揪出双 API 进程并存(旧进程霸端口跑旧代码)——已重启归一
实测:改名保存 → 版本列表仍唯一 v4 生效中,名字已写回;八例端到端全绿;
五闸退出码全过(api:check 提交后转绿)。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
公开出口: index.ts
|
||||
- 类型:`ProcessService` `StartWorkflowInput` `WorkflowRecord` `ClosureReport` `ClosureViolation`
|
||||
`ActivityContractFace` `Candidate` `Resolution` `NodeInstance` `WorkflowState` `Dispatch`
|
||||
- 错误:`NotClosedError` `PositionVacantError`
|
||||
- 错误:`NotClosedError` `PinnedVersionError` `PositionVacantError`
|
||||
- 端口类型:`ProcessStore` `ActivityDirectory` `OrgDirectory` `TaskGateway` `ApprovalGateway`
|
||||
`Sfeel` `FlowEventPublisher` `ReceiptNotifier`
|
||||
- 用例工厂:`createProcessService(deps): ProcessService`(含 `setPackageState` 版本启停)
|
||||
@@ -25,9 +25,15 @@
|
||||
被依赖: trigger, app(治理台 · 工作流管理)
|
||||
|
||||
不变量(OS 03 / 3.2):
|
||||
- **画图不检查,激活才查完整**(产品决策 2026-07-28):`savePackage` 不跑闭合校验,
|
||||
随手画的半成品也存得进来(存出来即 `retired`,不生效);`setPackageState` 激活时
|
||||
跑 `checkClosure`,不闭合抛 `NotClosedError`(HTTP 412 带整份报告)。
|
||||
- **编辑即其身**(产品决策 2026-07-28 第四轮):`savePackage` 对已存在的版本
|
||||
**就地写回**(号不变、状态不变);新版本只出自显式新建(`asNew: true`)或
|
||||
新流程首版(插入,`retired` 不生效)。两道底线:
|
||||
① **在途钉版不可变** —— 该版有未完结工作流(按 (包, 版本) 钉定义)即抛
|
||||
`PinnedVersionError`(HTTP 409),一字不落库;改动请新建一版。
|
||||
② **生效版必须始终可运行** —— 写回生效版跑 `checkClosure`,不闭合抛
|
||||
`NotClosedError`(HTTP 412 带整份报告);未生效版画图不检查、随手存。
|
||||
- **激活才查完整**:`setPackageState` 激活时跑 `checkClosure`,
|
||||
不闭合抛 `NotClosedError`(HTTP 412 带整份报告)。
|
||||
违规项:未完成边、必填未映射、类型冲突、孤立节点、多默认出边、
|
||||
活动未装载、审批岗位不存在、容忍分支被下游必填依赖 —— 任一即 `closed = false`,激活被拒。
|
||||
(活动点不核岗位 —— 契约不带负责人,`missing-owner-position` 只出自审批点。)
|
||||
@@ -53,8 +59,9 @@
|
||||
- **一条流恰一个生效版本**(产品决策 2026-07-28):`setPackageState` 激活即独占
|
||||
(同流其余版本一并停用);停用生效版 = 整条流下线,新起单被拒。
|
||||
起单取**生效版**;在途工作流按启动时钉住的版本号读定义 —— 启停对它们零影响。
|
||||
- **保存恒新增版本号**(服务端算,不采信入参):工作流按 (包id, 版本) 读定义,
|
||||
就地覆盖会改掉在途任务正在读的编排。store 层因此**只插不改**,撞键宁可报错也不静默覆盖。
|
||||
- **版本号服务端算**(新建时,不采信入参):工作流按 (包id, 版本) 读定义;
|
||||
store 的写回(`updatePackageDefinition`)只许命中已存在的版本,撞不存在报错;
|
||||
「就地覆盖会改掉在途正在读的编排」由在途钉版闸守着,不再靠只插不改一刀切。
|
||||
- **求值语义前后端同源**:画布的即时校验与后端裁决共用 `checkClosure`
|
||||
- **负责人解析确定性**:轮值并列时按 staffId 稳定排序;同输入必同结果,结果与依据留痕
|
||||
- **工作流状态是聚合投影**:流程层不另设状态机;计量对象是**节点实例**,
|
||||
|
||||
Reference in New Issue
Block a user