决议语义、在途干预与审计红线
前面几页搭好了骨架,这一页进入真实业务的复杂场景。贯穿其中的是流程的两个层面:配置时的静态定义(链路、会签、路由、超时),与跑起来之后对在途实例的动态干预(退回、撤回、加签、转交)。下面先辨清决议动作,再看在途怎么改,最后是最容易出事的一条红线。
1 · 终止与回退
「不同意」有两种完全不同的语义,混淆它们是审批系统最常见的设计错误。reject 是终止:单据落 rejected 终态,流程结束,要重来得开新一轮。return 是回退:把单据退回某一步,流程并未结束,改完继续走。
图 1-1 的动作里除 approve 之外全属在途干预:它们都是在流程已经跑起来之后改这张实例的走向,与配置时定义好的链路是两个层面的事。同类动作还有加签(运行时往链里插一个审批人,分前加签与后加签)与减签。
建议 · 撤回(withdraw)应当有条件,不是发起人想撤就能撤。常见规则是只在无人开始审、或仅进行到第一级时允许;一旦已经有人审过,撤回就需要更高权限,或转为作废并保留已有记录。撤回后改了重提,走的是同一张单的新版本(revision),旧版本痕迹保留,而不是凭空一张新单。
警示 · 抄送(CC)与审批是两种角色。图 1-1 右侧的「财务存档」节点属抄送:它需要知道这件事,但不参与决议,既不卡流程,也没有通过或驳回两种结果。把抄送人放进归并策略的分母里,会让流程在无人可推进时挂死。
2 · 行级审批与部分批准
前面的单据都是整单一个结果。但报销单常有多条明细,审批人需要逐条批或拒,审批粒度从单下沉到行。整单结果因而不再二元,需要把 条子项的决议聚合(roll-up)回单据状态,即部分批准。
警示 · 批量是界面上的便利,不是审计上的便利。「批量驳回 3 条」在记录层面必须拆成 3 条独立留痕,各自带子项、决议与意见,否则事后审计追不到单条明细的依据。roll-up 规则也需显式定义:有一条被拒时整单算 partial 还是
rejected,被拒的子项是只重走那几条还是整单重审。这两个问题没有普适答案,但留空的代价是每个调用方各自猜一套。
3 · 审完之后的修正
一张单已经审完归档,此时更高级别的领导要求改掉某一步的意见文案。该怎么办取决于要改的是什么,但两种情形的正解是同一句:不原地改,而是版本化加追加留痕。
另一类「改节点文案」改的是流程模板的配置(节点名、说明),而非这张单的记录,属于流程定义与实例的版本化问题。已跑完或在途的实例应当绑定发起时的模板版本快照,改模板只影响未来发起的新单。否则历史会穿越:当年审批的人看到的根本不是现在这段文字。在途实例不随模板迁移,是流程版本化里最容易被忽略、后果也最重的一条。
4 · 动作与审计对照
| 动作 | 层面 | 对单据状态的影响 | 审计记什么 |
|---|---|---|---|
| approve / reject | 决议 | 推进 / 落 rejected 终态 | 审批人与决议 |
| return 退回 | 在途干预 | 回退到某步,不终止 | 退回目标与理由 |
| delegate 转交 | 在途干预 | 换处理人,active 不变 | 由谁转交给谁 |
| withdraw 撤回 | 在途干预,有条件 | 落 withdrawn,改完开新 revision | 撤回人与时机 |
| 加签 / 减签 | 在途干预 | 运行时增删节点 | 谁增删了谁 |
| timeout | 静态定义触发 | 系统代为推进 | 记 system 并注明超时 |
| reopen / amend / override | 审完后修正 | 开新轮或追加,不覆写 | 追加记录,旧记录保留 |