Skip to content

两处仍读/仍教 input.selectedIds(无下划线)—— 平台永远不会投递这个键,docs 示例会把下一个作者带进 #508 同一个坑 #813

Description

@yinlianghui

由 PR(#508 完成半,claude/issue-508-bulk-selectedids-restore)顺带发现,超出该 PR 文件面,按 Prime Directive #10 单独登记。

事实

多选投递的唯一声明通道是 params._selectedIds(带前导下划线的内建键,@objectstack/spec ui/action-params.zod.ts:70 的 ACTION_PARAM_BUILTIN_KEYS)。无下划线的 selectedIds:

  • 放在 顶层 → 不会并进 params 袋,body 里读到 undefined;
  • 放在 params. 下 → ADR-0104 严格参数门按「未声明」拒绝,400 Unknown action param "selectedIds"。

这一点已由平台组真机端到端验证(objectstack-ai/objectstack#5568,works as declared),也在本次 #508 的 dev server 上逐条复现。

本仓仍有两处使用无下划线拼法:

1. src/actions/lead.actions.ts:111(休眠死枝,今天不影响用户)

const selected = Array.isArray(input.selectedIds) ? input.selectedIds : [];
const ids = selected.length ? selected : (ctx.recordId ? [ctx.recordId] : []);

create_campaign 在 src/views/lead.view.ts:178 是以裸字符串 bulkActions: ['create_campaign'] 接线的,也就是 per-record fan-out —— 每行一次派发、各自带 recordId。所以这个 action 今天工作正常,走的是 ctx.recordId 那条回退;input.selectedIds 这一枝永远读到 undefined,是纯死枝。行 105-110 的注释还以现在时说「当 runtime 开始传 selectedIds,bulk 路径就会亮起来」——按 #5568 的结论,那条路径不会以这个拼法亮起来。

2. docs/developers/code_examples.md:119(更值得修的一半)

const ids = Array.isArray(input.selectedIds) ? input.selectedIds : [];

这是教给下一个作者(含 AI 作者)的示例。#508 之所以耗掉两个 RC,正是因为三轮复核都在试无下划线的形状:顶层 selectedIds、params.selectedIds,两个都被正确拒绝,于是被判定为「平台不存在多选通道」。docs 里这一行会稳定地把下一个人送进同一个结论。

建议

  • docs 示例改成 input._selectedIds,并写明它是渲染器注入的内建键、不要声明进 action 的 params[]、以及它由视图的 bulkActionDefs + execution: 'aggregate' 驱动;
  • lead.actions.ts 二选一:要么删掉死枝只留 ctx.recordId(与它 fan-out 的接线相符,最小改动),要么如果确实想要「一次派发整个选择集」,就改成 aggregate def + 读 input._selectedIds(这需要同时改 lead.view.ts,是行为变更,需产品判断)。注释的时态一并订正。

两处是同一条事实的两个落点,故合并一单,未拆。

为什么不折进 #508 的 PR

该 PR 文件面锁定 src/views/opportunity.view.ts / src/actions/opportunity.actions.ts / 两个测试 / changeset;lead.* 与 docs/ 均在面外,且 lead 那一处的处置涉及产品选择(fan-out 还是 aggregate),不宜顺手替人定。

Activity

  1. added
    bugSomething isn't working
    documentationImprovements or additions to documentation
    pm:queueReady for the PM dispatch loop
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Aug 5, 2026
  2. self-assigned this
    on Aug 5, 2026
  3. yinlianghui commented on Aug 5, 2026

    @yinlianghui
    CollaboratorAuthor

    🔒 认领(修复线 PM 派单):session_01VHrPAGEgFDoHjphqYG4BMa,分支 claude/issue-813-selectedids-teaching,worktree hotcrm-issue-813。文件面:docs/developers/code_examples.md、src/actions/lead.actions.ts(仅死枝)、changeset。

    裁定(#815 验收时已记):docs 半——示例改教声明形状(input._selectedIds + bulkActionDefs/aggregate 语境,引 #815 落地的真实实现作范例;正是这个示例让 #508 耗掉两个 RC,教学面必须先修);lead 半——lead.actions.ts:111 读无下划线键的死枝(从不执行)删除或修正为与其实际接线一致(裸字符串 fan-out → per-record recordId),现状行为不变;create_campaign 要不要改 aggregate 是另一个产品选择,⛔ 不在本单顺手。若修正方向上死枝删除会让某个测试失去覆盖对象,如实处理并报告。


    Generated by Claude Code

  4. yinlianghui commented on Aug 5, 2026

    @yinlianghui
    CollaboratorAuthor

    ✅ 验收通过 — PR #822 已转 ready 并挂 auto-merge(CI 9/9 绿)。

    判定要点:

    越界发现 #821(lookup 参数示例无 reference 退化成粘贴 ID 文本框——参数控件解析,与本单不同事实)→ 入队。#813 随本 PR 关闭。


    Generated by Claude Code

  5. added and removed on Sep 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingdocumentationImprovements or additions to documentationpm:dispatchedDispatched to a dev agent by /pm-dispatchpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions