Skip to content

record:reference_rail 的 entry 授权面比页面所需更窄,且该形状未被 spec 声明:filter 写了静默失效、标题拿不到 pluralLabel #986

Description

@yinlianghui

来源:#972 / PR #983 实施过程的测量结论。#972 的「Open Tasks 徽章计入 Completed」那一半按 measure-first 判定为平台能力缺口、本仓不硬改,故把测量结果单独记在这里,免得随 #972 关闭一起丢失。PR #983 已在本仓侧加了守卫挡住写法,但守卫只能挡,不能补能力。

测量对象是本仓实际装的 @objectstack/console@17.0.0-rc.3@objectstack/spec@17.0.0-rc.3产物字符串,未做浏览器实测。

实况:rail entry 只有三个键被读

参考栏对每个 entry 只发这一条查询(node_modules/@objectstack/console/dist/assets/plugins-views-CJKuyDvq.js):

find(objectName, { $filter: { [relationshipField]: parentId }, $top: limit ?? 3, $count: true })

标题解析是:

entry.title || (i18n.objectLabel ? i18n.objectLabel({ name: entry.objectName, label: humanize(entry.objectName) }) : humanize(entry.objectName))

即实际被消费的只有 objectName / relationshipField / limit / title(外加 icondisplayField 用于卡片内的行渲染)。组件注册的 inputs 只声明了 hideEmpty 一项。

三条各自独立的缺口

1. entry 没有 filter 通道,而写了不会报错

参考栏的卡片只能表达「关联的全部记录」,无法表达「关联的、且满足某谓词的记录」。商机详情页想要的「未完成任务」在 Related 页签的关联列表里是一行 filter: [{ field: 'status', op: 'neq', value: 'completed' }],在 rail entry 上则无处可写。

比「不支持」更值得记的是它不报错@objectstack/specComponentPropsMap没有 record:reference_rail 这一行,页面组件的 propertiesz.record(z.string(), z.unknown()).d.ts 里也不存在 ReferenceRailEntry 类型。所以在 entry 上补 filter 会解析通过、typecheck 通过、objectstack validate 通过、构建进产物、发布上线,然后什么也不做 —— 徽章照旧计入全部记录,而源码从此声称自己过滤了。这正是 AI 写元数据最容易踩、也最难在 review 里看出来的一类错。

2. 标题只能拿 label,拿不到 pluralLabel

objectLabel 查的键是 objects.*.label。一张带「关联记录总数」徽章、列最多三条记录的卡片,语义上要的是复数标签(objects.*.pluralLabel,本仓四个语言包都写齐了),拿到的却是单数。PR #983 删掉硬编码 title 之后,英文界面的三张卡片就是 Quote / Opportunity Line Item / Task —— 本地化对了,但数词不对。这条是纯观感,不影响任何功能。

3. title 是不可翻译的字面量

同一份产物里 record:alert 的 title 走 gt(n.title, language)(内联译文映射解析器,支持 { en, 'zh-CN', … }),参考栏则把 entry.title 当作原始 React child 直接渲染。所以 rail entry 的 title 只有两种状态:要么不写(回落到本地化对象标签),要么写一个压过所有语言包的字面量。没有「写一个会被翻译的标题」这个选项。PR #983 选择了不写,代价见第 2 条。

可能的上游修法(仅列出,不预判取舍)

  1. 只补声明不补能力:在 spec 的 ComponentPropsMap 里给 record:reference_rail 补一行严格 schema。这样第 1 条的「静默失效」立刻变成发布时的响亮拒绝,代价最小,且不需要判断有没有业务拉力。
  2. 补 filter:entry 加可选 filter,与 record:related_list 同款谓词形状,渲染侧并进 $filter
  3. 补标题通道:entry 的 title 接受内联译文映射(与 record:alert 对齐),或让无 title 时按「是列表卡片」取 pluralLabel

按「初创聚焦、能力扩张要有真实业务拉力」的口径,第 1 条与第 2、3 条的性质不同:第 1 条是把已经存在的形状说清楚(收紧,不扩张),第 2、3 条才是新增授权面 —— 目前的真实消费方只有本仓商机详情页这一个参考栏(全仓 grep 命中一处),拉力是否够,请维护者判断。

本仓侧已做的挡板

PR #983test/metadata-references.test.ts 加了三道守卫(entry 必须指向真实对象与关系字段、不得声明字面 title、不得声明 filter),并在 test/i18n-references.test.ts 加了一道(参考栏涉及的对象在四个语言包里必须都有 label —— 因为 rail 的兜底不是英文 label 而是 humanize(objectName),缺译文比没有 i18n 还糟)。第三道在干净树上是空过的,已用「植入 filter → 转红」单独证伪过,不是靠什么也没产出而通过。

重复检查

search_issues 在本仓 open issue 上查 reference rail filterreference_rail —— 命中的只有 #972(本条来源)与 #733(同一栏 Products 卡片显示原始记录 ID,是 entries 的另一种失真,与本条不同)。无既有单。若与他人同小时立单重复,烦请 PM race-close。

Refs #972 #733

Metadata

Metadata

Assignees

No one assigned

    Labels

    findingmetadataDeclarative metadata — schema, security posture, UI surfacesupstream:objectstackBlocked on / caused by the ObjectStack platform — tracked upstream

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions