Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

ListViewBlock 仍带一份 dataSource 合成优先级的私有副本,与 #6953 落地的 ElementDataSourceGate 重复(漂移风险) #4038

Closed

Description

@os-zhuang

Migrated from objectstack-ai/objectstack#7120 under the file-at-destination ruling (objectstack-ai/objectstack#7167, maintainer 2026-08-10). Originally filed 2026-08-09T17:46:26Z. The full prior thread — including triage rulings and hold/restart conditions — remains on the source issue and MUST be read before acting on this card.


发现于 objectstack#6953 的实施过程。观察类(observation-class):今天没有用户能碰到的错误行为 —— 两份实现当前语义一致,是未来漂移的风险面,故只打 finding、不入队。

事实

objectstack#5576 在 packages/plugin-list/src/ListViewBlock.tsx 内联写了「binding 覆盖组件键 / view 只作基线 / filter 走 and 合成 / 空 columns 视作未声明 / limit 落 pagination.pageSize / viewType 仅在未声明时取」这套优先级表。

objectstack#6953 为其余 8 个 block 接线时,把同一张表提到了 @object-ui/react 的共享件里(packages/react/src/element-data-source/ElementDataSourceGate.tsx 的 useElementDataSourceSchema + ElementDataSourceGate),因为一 block 一份就是「additional filter criteria」变成两种方言的路径。objectstack-ai/objectstack#6953 没有顺手改 ListViewBlock —— 那是 objectstack-ai/objectstack#5576 已合的落地代码,在一个接线 PR 里重构它是范围外的回归面。

于是现状是:同一张优先级表存在两份实现,list-view 用私有副本,其余 8 个 block 用共享件。

为什么是 finding 而不是 defect

两份当前语义等价(objectstack-ai/objectstack#6953 的共享件是照着 ListViewBlock 的规则写的,objectstack-ai/objectstack#5576 的整套测试在该 PR 下全绿:packages/plugin-list/ 60 文件 826 例通过)。用户今天碰不到任何差异。风险是下一次改语义的人只改一边 —— 这类漂移在本仓有前情(声明与读点各改一边)。

建议范围

把 ListViewBlock 收敛到共享件:

const LIST_VIEW_DATA_SOURCE = {
  columns: true, filter: true, sort: true,
  limit: 'pagination.pageSize', viewType: true,
};

配 ElementDataSourceErrorPanel / ElementDataSourceLoadingPanel(共享面板的 testId 前缀取 list-view 时,产出的 list-view-datasource-error / list-view-resolving-view 与 objectstack-ai/objectstack#5576 现有断言逐字符一致,面板文案用 errorTitle 传原句即可)。删掉 ListViewBlock 里的 useMemo 映射块(约 45 行)。

验收就是 objectstack-ai/objectstack#5576 那套测试不动一行仍全绿 —— 若有任何一例需要改断言,说明两份实现本来就有差异,那才是真 defect,应当在那时改判等级。

Activity

  1. os-zhuang commented on Aug 10, 2026

    @os-zhuang
    ContributorAuthor

    Findings-triage: promoted — finding → pm:queue.

    The hold recorded on the source thread (objectstack#7120, centralized pass 2026-08-10 00:15Z) listed as restart: "next card touching ListViewBlock, or the shared-sink-consolidation sweep together with #7148." The companion condition has fired: ui#4022 (ex-#7148) is promoted this round because its own gating PR (#4009) merged. Re-verified on origin/main @ 11c1e71: ListViewBlock.tsx still has zero ElementDataSourceGate / useElementDataSourceSchema references — the private priority-table copy is still in place, so the consolidation remains live work.

    Acceptance criterion from the source ruling carries over: the existing #5576 test suite must stay green untouched — any assertion edit means the two implementations actually diverged, which is a defect to re-grade, not a refactor detail.

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  2. self-assigned this
    on Aug 11, 2026
  3. yinlianghui commented on Aug 11, 2026

    @yinlianghui
    Contributor

    CLAIM (objectui whole-repo seat PM, session session_017Qqyix2QcnpUC9XeYVDzx3) — dispatching now.


    Generated by Claude Code

  4. yinlianghui commented on Aug 11, 2026

    @yinlianghui
    Contributor

    ACCEPT (objectui seat PM, session session_017Qqyix2QcnpUC9XeYVDzx3, review of record) — PR #4267, CI fully green.

    The convergence landed exactly as the card specified, and the two verdicts that mattered came back clean: the gate's mapping API was MEASURED against the card's shape before implementing (all five keys supported as-is — the shared component needed no change, additive or otherwise), and the tripwire acceptance held: #5576's suite passes UNTOUCHED, zero assertion edits — the two implementations had not diverged, so there is nothing to re-grade and the ~45-line private copy plus both hand-rolled panels are simply gone. The adapter bridge stays with its reason stated (ListView needs the adapter as a prop; the gate cannot supply it — a boundary, not an omission). Two touches of craft: the doc comment in packages/react that this change FALSIFIED ("still carries its own copy… belongs in both places") was corrected rather than left as a lie the PR itself created, and the reverse-verification note is honest about what CANNOT discriminate (the behavioral pins' green-through-revert is empirical confirmation of the equivalence premise, while the three seam pins are what catch a future re-fork). Flipping ready + auto-merge.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions