Skip to content

feat(actions): api 型动作需要「成功后跳转到服务端返回的记录」能力(ActionSchema 跳转键 + 响应进入插值作用域) #9474

Description

@baozhoutao

一句话

api 型动作要能把「服务端返回的记录 id」作为成功后的跳转目标。 目前平台没有任何合法写法能做到「点按钮 → 服务端新建/克隆一条记录 → 前端跳到那条新记录的页面」。

业务场景(应用项目实测,@objectstack/spec@17.0.0 / @objectstack/console@17.0.0)

制造业项目里「任务版本 → 复制为新版本」按钮:api 动作触发 afterUpdate Hook 克隆出 v+1 草稿,用户点完仍停在旧版本记录页,必须手动回列表重新筛选才能找到新版本继续编辑。同款「复制类动作停在原记录页」在同一项目还有 4 处(任务复制/检查项复制/排班计划复制/设备复制),是通用诉求不是孤例。

现状排查(为什么现有能力都够不着)

  1. ActionSchema 为 strict,对 redirect / chain / onSuccess / navigate+to 四种写法 safeParse 全部报 Unrecognized key(s),schema 层没有「成功后跳转」的任何键;
  2. console 前端 executeAPI 只返回 {success, data},从不产生跳转;refreshAfter 只刷新当前页;
  3. interpolateTarget 插值作用域只有 ${param.*} 与 ${ctx.origin|apiBase|user|org|recordId|selection}——接口响应不在作用域内,即便服务端把新记录 id 吐出来,前端也没有合法通道消费它;
  4. executeChain 不把上一步返回值喂给下一步,链式动作同样表达不了。

诉求(两件必须配套,任一单独放开都不够)

  1. ActionSchema 放开一个成功后跳转的键(如 redirect / onSuccess.navigate);
  2. 让接口响应进入地址插值作用域(如 ${result.id}),或平台约定「响应里带某约定字段(如 navigateTo)即跳转」。

项目侧现状

按「平台能覆盖的问题等平台、不绕行」纪律,项目侧未做 type:'url' 302 / modal 自跳等偏方,原单挂起等待本能力(内部单:steedos-labs/os-project-titanwind-ehr#1172)。

Activity

  1. os-support-ai commented on Aug 18, 2026

    @os-support-ai
    Collaborator

    Triage: ⇒ needs-user-decision, domain:spec, type Feature — this widens ActionSchema's public surface (a post-success navigation key) and adds an interpolation-scope capability (server response entering ${...} scope), so it sits on the manual floor (feature + contract shape) regardless of how strong the pull is. And the pull is strong: five concrete sites in one real manufacturing app, filed with a measured capability audit (strict schema refuses all four spellings; executeAPI returns {success, data} and never navigates; interpolateTarget's scope excludes the response; executeChain passes nothing forward), and the project is correctly holding the no-workaround line waiting on the platform.

    Four-facet card face:

    • Platform long-term coherence: "act on the server's answer" is a primitive, not an app-specific hook — the clone/copy-then-open shape recurs in any versioned-record domain. One declared key beats N app workarounds; but the key's design (a single onSuccess.navigate vs. response-driven navigateTo convention) decides whether this stays one primitive or grows a callback tree.
    • Measured business pull: measured, external, five sites in one project plus a parked internal card — the strongest pull shape a feature request can carry at this stage.
    • AI-agent error-resistance: a closed declared key (onSuccess.navigate: '${result.id}'-style, schema-validated) is the error-resistant form; the alternative convention (server response magically triggering navigation via an undeclared field) is the silent-behaviour shape to avoid. If accepted, prefer the declared key + explicit scope addition, loudly rejected when the referenced response field is absent.
    • Startup scope discipline: this is scope expansion — two coupled additions (schema key + interpolation scope), each a permanent obligation, and the console must implement both. Mitigant: the requester is right that the two halves are useless separately, so if accepted it is one decision, not two.

    Recommendation: accept the need as real and rule the shape — smallest coherent form is one ActionSchema key (e.g. onSuccess: { navigate: string }) plus ${result.*} entering the target-interpolation scope for that key only, response-convention route rejected. Cross-repo note for whoever implements: contract-first split applies (spec key first, console consumption Blocked-by: it, objectui half filed at dispatch time). (Triage seat, session session_019gCKd9EZfQ6MbGTnMHHJvW.)


    Generated by Claude Code

  2. os-steve commented on Aug 18, 2026

    @os-steve
    Collaborator

    Maintainer ruling recorded — ruled TOGETHER with #9566 (maintainer, 2026-08-18, in-session to the domain:spec PM, verbatim 「同意」 on the presented unified shape; full ruling text on #9566, comment 5328006218-adjacent). Summary of what answers this card's two asks:

    1. ActionSchema.onSuccess (closed key: navigate template + openIn: 'self' | 'newTab') — the post-success navigation key this card measured as missing (its probes redirect/chain/onSuccess/navigate+to all correctly bounced off the strict schema; the fix declares ONE shape rather than loosening).
    2. ${result.*} joins the navigate template's interpolation scope — the server response becomes consumable, closing this card's item 2.
    3. Defaults: schema-declared navigation defaults 'self'; the shipped { redirectUrl } handler convention keeps new-tab unless the handler opts into 'self' (no behavior flip for existing metadata).

    One spec PR delivers both cards' contract halves (Fixes #9474 + Fixes #9566, branch claude/issue-9566-onsuccess-navigation, fable/clause-②); the console wiring is the downstream objectui card(s) filed at landing with Blocked-by: — the end-to-end capability your project waits on (steedos-labs/os-project-titanwind-ehr#1172) arrives with that half.


    Generated by Claude Code

  3. self-assigned this
    on Aug 18, 2026
  4. os-steve commented on Aug 18, 2026

    @os-steve
    Collaborator

    Delivered together with #9566 by draft PR #9601 (Fixes both cards) — the OS-DEV-REPORT lives on #9566: #9566 (comment)


    Generated by Claude Code


    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

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions