Skip to content

script 的 config 契约要接入 #4277 的执行期 parse,先得有判别式(actionType)形态 #4343

Description

@os-zhuang

#4278#4277 在同一天落地,两者交界处留下一个明确的后续,记在这里以免被当成「忘了接」。

现状

#4277(#4332)让 12 个「有契约」的内置节点在执行前 parse() 自己的
node.config(service-automation/builtin/parse-config.ts),并让 registerFlow()
拒绝 descriptor configSchema 未声明的键。

#4278(#4325)给另外三个 descriptor-schemaless 节点补上了执行器派生的契约
(spec/automation/schemaless-node-config.zod.ts:ScriptConfigSchema /
SubflowConfigSchema / DecisionConfigSchema),但刻意没有接入 parse,也没有发布
descriptor configSchema——两件事是同一个理由。

为什么不能直接接上去

它们的键集不等于契约。

  • script —— 合法键随 actionType 变:内置副作用分支读
    template / recipients / variables;函数分支读
    function / inputs / outputVariable;内联 script 是被识别但不执行的第三种。
    平铺 parse 只能取这些键的并集,于是
    { actionType: 'email', function: 'x' } 这种自相矛盾的配置照样通过——检了个寂寞;
    若反过来收紧成任一分支,就会拒绝另一半合法元数据。
  • decision —— 完全可以不带 conditions,只靠出边的 edge.condition 分支
    (这是遗留但合法的形态)。
  • subflow —— 这个其实最接近可接入:键集扁平,flowName 执行期必需,
    执行器已经用 refuseNode() 拒绝缺失的情况。

建议做法

  1. subflow 可以先接——低风险,把现有的 refuseNode 换成统一的 parse guard,
    与其它 12 个节点的失败形态一致(guard refusal,不走 fault 边)。
  2. script 需要先改造成判别式:按 actionType 拆成
    z.discriminatedUnion(或等价的 superRefine),分支分别声明各自的键。
    这同时会让「自相矛盾的配置」在作者时就被拒,而不是运行到一半才发现
    ——actionType: 'email' 却写了 function 是当前唯一还能悄悄通过的形态。
  3. decision 大概率维持现状:它的真实契约一半在边上,不在 config 里;
    接 parse 的收益仅限于「conditions[] 元素的类型」,可以等 2 做完再评估。

一个附带好处:script 一旦有了判别式形态,objectui 的
flow-node-config.spec-reconciliation.test.ts(objectui#3099)可以从「键集并集比对」
升级为「按 actionType 分支比对表单的 showWhen 分组」——那才是表单实际的形状,
也能挡住「某个分支少提供了一个字段」这类 #4278 没覆盖到的漂移。

Related

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions