Repository navigation
object-grid 的 inputs 声明 filters(复数),渲染器只读 filter(单数):按已发布词汇写筛选条件静默无效 #7119
Description
Activity
Triage:
needs-user-decision(routingrepo:objectuikept as filed).- Why the decision box: the fix direction lands in a published contract surface —
object-grid's registeredinputsvocabulary. Option A removes the declared-but-never-read pluralfilterskey; option B would canonize the misspelling as a second de-facto contract (the card itself argues B is barred by AGENTS.md #0.1). The filer explicitly requests a direction ruling; nothing in the thread decides it yet, so this is a pending decision, not a made one. - Premise check on objectui
origin/main@53b7b88:inputsdeclares pluralfilterstwice (packages/plugin-grid/src/index.tsx:62,:79); the renderer reads singularschema.filter(ObjectGrid.tsx:440) and has zeroschema.filtersreads (counter-checked). Defect stands as described. - Recommendation for the maintainer: A —
filtershas no read point on any ref, so there is no in-the-wild working usage to preserve; A aligns declaration withlist-view, the spec vocabulary, and the renderer in one move. On approval this becomes a small queue card with the pin the card already sketches. - Dedup: no open shadow (objectui service-automation: update_record reports
successwhen written fields are silently stripped — no observability for dropped writes (split from #3356) #3407 is the cited precedent class, closed face); clean.
本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
- Why the decision box: the fix direction lands in a published contract surface —
PM 分诊(objectui 分片,session_01GTRjn8xBqp75dk7kFupVRt):挂
needs-user-decision入决策箱 ——object-grid声明 inputfilters(复数)而运行时读filter(单数),按已发布词表授权的作者拿到静默无过滤查询。方向题与 objectui#3951(grid 列键name/field双拼写)完全同族:都是「已发布作者面 vs 运行时读点」的收敛方向选择,rename 破坏按词表授权的存量、teach-alias 是 AGENTS.md #0.1 禁止的容忍写法。实施 agent 推荐 rename(声明向实现收敛)。建议维护者与 objectui#3951 同席一并裁,两单一个原则定调(声明侧收敛 or 实现侧收敛),避免两次裁出相反方向。
Generated by Claude Code
顺手记录一条本单实施时必须一并处理的相邻事实(发现于 objectstack#7118 / objectui#3895 的实施,objectui PR #3981;不另立单,因为它不是可独立完成的工作 —— 它是本单修法的一个约束)。
事实(objectui
origin/main@5bfaabde0实测)object-grid读到的schema.filter是逐字节原样送上$filter的,没有经过仓库的单一 filter 汇聚点:packages/plugin-grid/src/ObjectGrid.tsx:613 // Support new filter format packages/plugin-grid/src/ObjectGrid.tsx:614 if (schemaFilter && Array.isArray(schemaFilter)) { packages/plugin-grid/src/ObjectGrid.tsx:615 params.$filter = schemaFilter;(导出路径同源:
:1417的const filter = Array.isArray(schemaFilter) ? schemaFilter : undefined;)它是这条链上唯一不走
toFilterNode/mergeFilterNodes的消费者 ——plugin-list的buildEffectiveFilter(ListView.tsx:243)、plugin-view的ObjectView(:432)、packages/react的ElementDataSourceGate(:210)、以及 PR #3981 刚接上的RelatedList都走。为什么这是本单的约束,而不是另一个 bug
现在它不咬人,原因恰恰就是本单报告的缺陷:
inputs只声明复数filters,单数filter无人声明,所以作者根本到不了这个读点(写filter会被sdui-parser判unknown-prop)。今天到达schema.filter的只有ElementDataSourceGate合成出的 AST —— 已经是 AST,原样透传是对的。本单一旦给作者的筛选条件接上读点,作者写的就是 spec 词汇
ViewFilterRule[]([{ field, operator, value }]),而这个形状原样送上 wire 会被服务端拒绝:isFilterAST对「对象数组」为 false,wire face 答400 INVALID_FILTER—— objectui#3431 已在真实后端上实测过这条(showcase 的showcase_task.in_progressview:原样发 400,降为[['status','equals','in_progress']]后 200 带回它的 2 行)。所以修法二选一都要带上降级:
- 若把复数
filters接成读点 → 该读点必须过toFilterNode(它同时把defaultFilters那类 MongoDB 风格对象一并收进来); - 若改成把声明面重命名为单数
filter(与渲染器对齐)→ 同一处仍要过toFilterNode,否则本单会把「声明了没人读」换成「声明了、读了、发出去被 400」—— 从静默错答变成必然失败,不是修好。
判据:
toFilterNode的 doc 自己写明它是「离 wire 最后一跳」的唯一合法降级位置,所以不要在别处折叠(那会把 AST 三元组写进 spec 声明为 rule 数组的槽位,AGENTS.md #0.1 反向)。
Generated by Claude Code
Generated by Claude Code
- 若把复数
Migrated to objectstack-ai/objectui#4041 under #7167 (file-at-destination ruling, maintainer 2026-08-10). Native GitHub issue transfer is not available to this session's credential, so the card was recreated at the destination; this thread stays as the authoritative history and is linked from the new card. Closing as not planned here — moved, not rejected.
Generated by Claude Code
发现于 objectstack#6953 的实施过程(objectui 分支
claude/issue-6953-datasource-block-wiring),不在该单范围内,单独立单。事实(objectui origin/main @ 65bb513dc 实测)
object-grid(以及同一渲染器的view:grid别名)的注册inputs声明的是复数filters:而渲染器读的是单数
filter:schema.filters在ObjectGrid.tsx里 grep 不到任何读点(唯一命中是文件头注释里的一句 "Search, filters, pagination")。同一仓的list-view声明的是单数filter,与它自己的读点一致 —— 两个同族 block 对外发布了两种拼写,只有一个是真的。症状
作者(或 AI)按
object-grid已发布的inputs/manifest 写filters: [...],查询里没有$filter,拿到全表 —— 不报错,SDUI 保存门也不会报unknown-prop(filters是已声明键)。反过来,写真正生效的filter时,filters才是被 manifest 承认的那个名字,于是「发布的词汇」和「运行时读的键」指向相反。objectstack#4413 的形状,叠加 objectui#3407 那种「声明与读点拼写不一致」的变体。为什么现有门禁看不见
check:react-declaration-parity比的是两侧声明(spec zod props ↔ 本仓inputs),不观察渲染器。apps/console/src/__tests__/public-block-binding-reach.test.tsx只问一个问题:声明了objectName的 block 有没有把对象名送到数据层。object-grid送到了,所以它在那里是绿的 —— 该测试的文档也明确写了它不是「每个声明的 input 都被消费」的检查。建议范围(需要判一次方向,别直接猜)
两条路,选哪条会落进公开契约,建议由维护者定:
inputs改成单数filter,与list-view、与 spec 词汇、与渲染器读点三方对齐;filters作为从未生效过的错误拼写直接去掉(它没有任何读点,不存在「已在野的可用写法」需要兼容)。filters。⛔ 这会把一个错误拼写固化成第二套 de-facto 契约(AGENTS.md #0.1),不建议。无论哪条,需要一条钉子:按
inputs声明的名字写筛选条件时,$filter必须出现在查询里。