Skip to content

spec: dashboard date filter 的 defaultValue 没有作者时校验 —— 拼错的预设名要到浏览器控制台才被发现 #4614

Description

@os-zhuang

越界发现,来自 objectui#3151 的实现(渲染器侧那一半已修)。未认领,仅记录。

背景

GlobalFilterSchema.defaultValuestring | number | boolean,对 type: 'date' | 'dateRange' 的 filter 而言,作者能写的字符串实际上只有两类合法值:

  1. 一个已知的日期区间预设名(last_7_daysthis_month、…);
  2. 一个 ISO 日期(2026-01-15),或一个日期宏 token({today}{7_days_ago})。

第三类(既不是预设名也不是日期,通常就是拼错:last_7_dayz)在 spec 层是完全合法的 —— schema 只知道它是 string。

现在发生什么

  • objectstack#4475:预设名那一半在 objectui#3150 修好之前会降级成等值比较,KPI 全为 0(200 OK,零行,没有任何信号)。
  • objectui#3151:拼错的值会降级成一个永不命中的等值比较,同样是 200 OK + 0。已修:buildFilterCondition 现在跳过该 filter 并 console.warn 点名 filter 与该值。

为什么还值得单独立一条

objectui#3151 的修复是运行时的,只能给出一条 console.warn:

  • 只有打开 devtools 的人看得见 —— dashboard 照常渲染,只是不再过滤;
  • CI / publish 完全看不见:一份 AI 生成的 dashboard 元数据带着拼错的 defaultValue 可以一路发布上线,没有任何门拦它;
  • 它是放宽方向(跳过 = 不过滤)。这是三选一里对作者最友好的失败模式(数字会明显变化而不是变成 0),但它不是拒绝

按 Prime Directive #12(contract-first:在作者/发布时大声拒绝,而不是在消费端容忍),这类「只有两种合法拼法」的值应当在 spec 层就被钉死,而不是靠每个消费者各自宽容。这也正是 AI 写元数据最容易藏错的地方 —— 声明即强制,才不会让一个拼写错误在 13 个 widget 上安静地复制 13 遍。

需要定夺的选项(维护者决定,不要直接实现)

  • A. 在 GlobalFilterSchema 上做条件校验:当 typedate / dateRange 时,defaultValue 必须匹配 预设名枚举 | ISO 日期 | 日期宏 token(superRefine)。
    • 长期正确性:最强 —— 声明即强制,发布/解析时硬失败,错误在作者手上而不是在用户的 0 上。
    • 代价:预设名清单目前住在 objectui 的 PRESET_RANGES,spec 要成为这份词汇表的唯一来源(日期宏 token 已经有 DATE_MACRO_TOKENS / DATE_MACRO_PARAM_RE 在 spec 里,可以复用);会拒绝掉存量里已有的拼错元数据(这正是意图,但要走 ADR-0087 的转换/迁移评估)。
  • B. 只做 publish-gate lint,schema 保持宽松。
    • 代价:schema 与 lint 两处知识,容易漂移;z.infer 出来的类型仍然说「任意 string 都行」。
  • C. 什么都不做,只留 objectui 的运行时 console.warn
    • 代价:门槛完全落在「有人正好打开了 devtools」,AI 生成的元数据依旧可以带着拼写错误发布。

倾向 A:两条判据同向 —— 长期架构上它把 filter 值的词汇表收进 spec 这一个契约里(消费端不必再各自宽容),AI 写元数据这条上它在作者时就硬拒绝而不是在渲染时静默降级。但它要动 spec 的公开契约(词汇表归属 + 存量元数据的处置),所以先立此条请维护者定夺,不在 objectui#3151 的 PR 里顺手做。

关联

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions