Skip to content

文档教作者写的 ActionSchema.condition = { expression, then, else } 全仓零消费者:谓词被忽略、then/else 永不派发、零诊断 #3917

Description

@yinlianghui

Filed unassigned,来自 #3872(PR #3916)实施时为核对 condition 门文档面而做的只读排查。只记录发现,不在那个 PR 里修。

现象

@object-ui/types 声明了一个与 ActionRunner 完全不同的 condition 形状,并且有 zod schema:

// packages/types/src/crud.ts:65
export interface ActionCondition {
  /** Condition expression @example "${data.status === 'active'}" */
  expression: string;
  /** Action to execute if condition is true */
  then?: ActionSchema | ActionSchema[];
  /** …else */
  else?: ActionSchema | ActionSchema[];
}

// packages/types/src/crud.ts:212
condition?: ActionCondition;                       // ActionSchema
// packages/types/src/zod/crud.zod.ts:45 / :86 —— ActionConditionSchema,进 ActionSchema

两处文档把它当成可用能力,带完整示例教作者写:

  • content/docs/core/enhanced-actions.mdx:220 「## Conditional Execution — Execute different actions based on conditions」,示例是 condition: { expression: '${data.amount > 1000}', then: {…confirm…}, else: {…} }
  • content/docs/api/schema-reference.md:663 属性表:| `condition` | `ActionCondition` | Conditional execution with `expression`, `then`, `else`. |,示例 body 里也有 "condition": { "expression": "${data.items.length > 0}" }

全仓没有任何代码读过 expression / then / else2937bcf7d 上:

$ grep -rn "condition\.\(expression\|then\|else\)" --include=*.ts --include=*.tsx packages apps examples
(零命中)

唯一消费 action 上 condition 这个键的地方是 ActionRunner.execute 的门,它把该键当谓词读(布尔 / 裸 CEL / ${…} / { dialect, source } 信封)。{ expression, then, else } 是个没有 source 字符串的对象,toPredicateInput 归一为 undefined = 「没声明门」,于是:

  • expression 里写的谓词从不被求值;
  • then / else 里的动作从不被派发;
  • 动作照常执行,os validate / os build 全绿,运行时零诊断。

按文档写下「金额超过 1000 就走经理审批,否则直接提交」的作者,得到的是「无条件直接执行」。#3872 前后行为一致(这一形状在真值门下也是「跳过判定 → 执行」),所以不是 #3872 引入的,也不在它的修法面。

为什么按缺陷立卡(而非 observation-class)

ActionEngine.addMapping / dispatch(#3368)是零生产调用方的 dormant API;这一条不同 —— 文档在教作者用它,ActionSchema@object-ui/types 的公开面,zod schema 也照收。作者今天照文档写就能命中,且失败方式是静默的:类型全绿、校验全绿、动作照跑。

不过修法方向要先裁,所以不带自己的判断落地:

  • A:兑现它 —— ActionRunner.executecondition.expression 求值,按结果派发 then / else(嵌套 ActionSchema,涉及链式执行面)。代价:给执行入口新增一条分派路径,且这个键同时要继续支持谓词形状(布尔/裸 CEL/信封),等于一个键两种语义 —— 与 #0.1 契约优先相冲。
  • B:按 enforce-or-remove 退役 —— 删 ActionCondition / ActionSchema.condition 的这一形状与 zod schema,两处文档改写成现役写法(condition 是谓词;条件分支用 chain + 各自的 condition)。代价:公开类型的破坏性变更(按仓内约定标 minor,正文写清)。
  • C:重命名分离 —— 谓词留在 condition,分支能力若要保留则换一个键名。

倾向 B:仓内现役的条件表达面是「谓词 + 归一器 + evaluateCondition」这一套(#3492 家族刚在 visible / disabled / condition 三道门上把它收敛完),再兑现一个同名不同义的分支 DSL 会让同一个键有两种读法,正是 AI 产出的元数据最容易踩空的形状。但这动的是公开类型与文档面,留给 triage 裁。

Related: #3872(condition 门真值判定 → 已声明,PR #3916)、#3492(不变量出处)、#3850(「空谓词」范围裁决)、#3368(同类的 dormant 面,observation-class)。未认领。

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions