背景
#3413 (closes #3407 )建立了引擎级的剥离回传通道:WriteObservabilityOptions.onFieldsDropped(packages/spec/src/contracts/data-engine.ts),engine.update() 在全部 4 个剥离点(单 id / bulk × 静态 readonly #2948 / readonlyWhen #3042 )回调,事件形态为 DroppedFieldsEventSchema = { object, fields, reason }。service-automation 的 update_record/create_record 已接线 (步骤 warning + droppedFields 输出)。
但 REST 写路径尚未接线 —— 外部 API 调用方对同一类合法剥离依旧完全沉默。
现象
PATCH /data/:object/:id(packages/rest/src/rest-server.ts:3488)把 p.updateData(...) 的结果直接 res.json(result):
期望
响应携带 warning,列出被丢弃的字段名与原因。状态码/成功语义不变 (剥离是合法语义,同 #3413 的原则:不升级为失败,只是不再沉默)。
设计待拍板
回传形态 (核心分歧点):
HTTP 响应头 (如 X-ObjectStack-Dropped-Fields: approval_status;reason=readonly)—— 对响应体契约零侵入,不破坏现有客户端;缺点是浏览器端易被忽略、跨网关可能被剥;
响应体信封 ({ data, warnings })—— 结构化最好,但当前直接返回记录本体,改信封是 breaking(要么版本化,要么仅在有 warning 时才加信封 —— 后者形态不稳定,不推荐);
记录对象上注入 __warnings —— 污染数据形状,不推荐。
波及面 :PUT / bulk update / DataEngineBatchRequest / GraphQL mutation 是否同批接线;@objectstack/client SDK 是否暴露 typed warnings。
透传路径 :REST handler 与引擎之间隔着 protocol 层(p.updateData),onFieldsDropped 需要经 protocol 契约透传(或 protocol 结果附带事件列表)。
insert 对称性 :同 feat(automation): update_record/create_record 步骤对被静默剥离的写入字段挂 warning(#3407) #3413 —— insert 今天不剥离 readonly(INSERT 豁免),POST 接线只是对称/未来防御。
参考
背景
#3413(closes #3407)建立了引擎级的剥离回传通道:
WriteObservabilityOptions.onFieldsDropped(packages/spec/src/contracts/data-engine.ts),engine.update()在全部 4 个剥离点(单 id / bulk × 静态readonly#2948 /readonlyWhen#3042)回调,事件形态为DroppedFieldsEventSchema = { object, fields, reason }。service-automation 的update_record/create_record已接线(步骤 warning +droppedFields输出)。但 REST 写路径尚未接线 —— 外部 API 调用方对同一类合法剥离依旧完全沉默。
现象
PATCH /data/:object/:id(packages/rest/src/rest-server.ts:3488)把p.updateData(...)的结果直接res.json(result):readonly/readonlyWhen剥离后实际生效 < N 时,响应仍是 200 + 更新后的记录;successwhen written fields are silently stripped — no observability for dropped writes (split from #3356) #3407 流程侧被掩盖是同一类问题;期望
响应携带 warning,列出被丢弃的字段名与原因。状态码/成功语义不变(剥离是合法语义,同 #3413 的原则:不升级为失败,只是不再沉默)。
设计待拍板
X-ObjectStack-Dropped-Fields: approval_status;reason=readonly)—— 对响应体契约零侵入,不破坏现有客户端;缺点是浏览器端易被忽略、跨网关可能被剥;{ data, warnings })—— 结构化最好,但当前直接返回记录本体,改信封是 breaking(要么版本化,要么仅在有 warning 时才加信封 —— 后者形态不稳定,不推荐);__warnings—— 污染数据形状,不推荐。DataEngineBatchRequest/ GraphQL mutation 是否同批接线;@objectstack/clientSDK 是否暴露 typed warnings。p.updateData),onFieldsDropped需要经 protocol 契约透传(或 protocol 结果附带事件列表)。参考
successwhen written fields are silently stripped — no observability for dropped writes (split from #3356) #3407(流程侧同一缺口,已修)/ feat(automation): update_record/create_record 步骤对被静默剥离的写入字段挂 warning(#3407) #3413(通道落地 PR)DroppedFieldsEventSchema—packages/spec/src/data/data-engine.zod.tspackages/rest/src/rest-server.ts:3488