Skip to content

Once framework#1867 ships: replace the 5 denormalized rollup workarounds with live cross-object rollups #84

Description

@os-zhuang

背景

有 5 个模板因为 framework#1867(hook 沙箱在嵌套跨对象写入时崩溃 memory access out of bounds)把 header/rollup 字段降级成了「手工维护的存储字段」。各 CHARTER / hooks 里都明确记着这个原因,例如 packages/compliance/src/hooks/index.ts:

compliance_control.last_status / last_assessed_at are STORED fields … a nested engine write from a hook is unsupported in the standalone runtime (the QuickJS hook sandbox crashes on nested writes; ctx.services.data is undefined) …

受影响字段:

模板 字段 现状
expense expense_report.total_amount 存储字段,client/seed 维护
procurement procurement_order.received_amount 存储字段,client/seed 维护
project pm_project.progress_percent / actual_cost 存储字段
content content_publication.total_* flow/存储,非 live
compliance compliance_control.last_status / last_assessed_at 存储字段

平台侧状态(framework)

底层限制已在 framework 侧解决:

  • 崩溃已修复:沙箱早已改为 deferred-promise + pump 的宿主调用模型,嵌套写入不再二次展开 asyncify 栈 → 不再崩溃。
  • framework#3232(评审中)补齐了回归覆盖 + 修掉了钩子超时被硬钳到 250ms 的 declared ≠ enforced 缺口(现可按 spec 声明更大的 timeoutMs,给较深的 rollup 链留预算)。
  • 已用 真实 SQLite(better-sqlite3,落盘) 验证:expense_lineafterInsert/afterUpdate 钩子嵌套写 expense_report.total_amount,insert/update 都正确回填、无崩溃(见 framework#3232 的 nested-write-real-sqlite.integration.test.ts)。

建议的转换路径(待 framework 修复发布 + 本仓 bump @objectstack 后再做)

按聚合类型选对工具:

  1. 可声明的求和/计数/极值 rollup(且需 delete 安全)→ 用原生 summary 字段,而不是钩子。引擎在删除时会自己捕获子记录 FK 的 pre-image 并重算父级;afterDelete 钩子只拿到 { id, options }、拿不到被删行的 FK,天然不适合做删除回滚。适用:expense_report.total_amountprocurement_order.received_amountcontent_publication.total_*
  2. 条件式 / 非聚合的跨对象写入 → 用嵌套写钩子(现已安全)。适用:compliance_control.last_status/last_assessed_at(取最近一次 assessment 的结果)、pm_project 的派生进度。较深的链在钩子 body 里声明更大的 timeoutMs(≤30_000ms)。

验收(遵循本仓 AGENTS.md「build 通过 ≠ 能跑」)

每个模板转换后必须 boot all env 实测:Server is ready + seeded on empty DB + 0 条 ERROR,并确认子记录变更后父级字段实时更新。同时更新对应 CHARTER 的「Rollup vs. lifecycle hooks」段落与 AGENTS.md 的 Runtime gotchas(移除已过时的 #1867 崩溃说明)。

门槛

依赖 framework#1867 的修复正式发布,且本仓把 @objectstack/*^11.2.0 bump 到含修复的版本。在此之前保持现状(现状对所 pin 的已发布运行时是正确的)——不要提前转换,否则会 advertise 一个已发布运行时尚未提供的能力。

关联:framework#1867、framework#3232、framework#3233。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions