补齐外部图片编辑场景白名单
在 External v1 权威契约中加入 scene 有效类型 用 OpenAPI 扩展精确声明完整快速编辑白名单 强化契约测试并同步外部接入文档
This commit is contained in:
@@ -1088,7 +1088,17 @@
|
||||
],
|
||||
"operationId": "editExternalEditorImage",
|
||||
"summary": "重绘/调整编辑器图片素材",
|
||||
"description": "主来源只接受当前账号已登记的项目资源 ID 或素材 ID(sourceReferenceId);objectKey、URL、Data URL 与 Blob URL 即使归属当前账号也返回 400。服务端从命中的业务记录派生 canonical objectKey、assetObjectId 与权威类型,只允许普通静态图片(类型为 null)、spec、character、icon-spritesheet、icon-spec、publication-material 或 ui-design,其他及未知类型返回 400。提供 targetLayerId 时必须同时提供 projectId,目标图层必须关联有效项目资源;双方都有 assetObjectId 时必须相同,否则回退比较 canonical bucket/objectKey。同一对象的来源默认类型与目标资源默认类型冲突、目标有效类型或媒体类型不允许、来源或目标不存在/越权/缺少对象时均返回 400,任务不会入队。referenceImageSrcs 仍只作为辅助参考图。",
|
||||
"description": "主来源只接受当前账号已登记的项目资源 ID 或素材 ID(sourceReferenceId);objectKey、URL、Data URL 与 Blob URL 即使归属当前账号也返回 400。服务端从命中的业务记录派生 canonical objectKey、assetObjectId 与权威类型;快速编辑的完整有效类型白名单为普通静态图片(类型为 null)、spec、character、icon-spritesheet、icon-spec、publication-material、ui-design 和 scene,其他及未知类型返回 400。提供 targetLayerId 时必须同时提供 projectId,目标图层必须关联有效项目资源;双方都有 assetObjectId 时必须相同,否则回退比较 canonical bucket/objectKey。同一对象的来源默认类型与目标资源默认类型冲突、目标有效类型或媒体类型不允许、来源或目标不存在/越权/缺少对象时均返回 400,任务不会入队。referenceImageSrcs 仍只作为辅助参考图。",
|
||||
"x-genarrative-allowed-effective-asset-kinds": [
|
||||
null,
|
||||
"spec",
|
||||
"character",
|
||||
"icon-spritesheet",
|
||||
"icon-spec",
|
||||
"publication-material",
|
||||
"ui-design",
|
||||
"scene"
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"ExternalApiKey": []
|
||||
|
||||
@@ -214,7 +214,7 @@ SpacetimeDB procedure:
|
||||
|
||||
外部生成接口复用站内编辑器已有 DTO、入队器和 worker executor,不维护第二套生成语义:
|
||||
|
||||
- 图片生成 / 重绘 / 规范图 / 宣发图 / UI 设计图复用 `/api/editor/images/generations` 与 `/api/editor/images/edits` 的校验、模型归一、计费和持久化规则,但 External handler 固定只入队。External v1 图片修改必须提交当前账号已登记的项目资源 ID 或素材 ID 作为 `sourceReferenceId`;上传对象必须先登记为项目资源或素材。objectKey、URL、Data URL、Blob URL 以及旧 `sourceImageSrc/sourceResourceId/assetKind` 字段均返回 `400`。服务端分别按资源 ID 与素材 ID 主键窄查,双表冲突、未命中、越权或对象记录无效均失败关闭,类型只接受业务记录派生的 `null / spec / character / icon-spritesheet / icon-spec / publication-material / ui-design`。请求带 `targetLayerId` 时必须同时带 `projectId`;目标图层必须关联有效项目资源,来源与目标优先比较 `assetObjectId`,缺失时比较 canonical `(bucket, objectKey)`,来源默认类型还必须与目标资源默认类型一致。入队载荷保存版本化权威快照,worker 执行前再次定点解析并拒绝身份或类型漂移;仅以素材 ID 编辑时不伪造项目资源关系。主站和 External 的通用图片入口共用场景专用合同边界校验,禁止用 `kind = scene` 或 `assetKind = scene` 绕过后端场景 Prompt 组装;场景专用 handler 自己构造规范请求,不受该通用入口校验影响。
|
||||
- 图片生成 / 重绘 / 规范图 / 宣发图 / UI 设计图复用 `/api/editor/images/generations` 与 `/api/editor/images/edits` 的校验、模型归一、计费和持久化规则,但 External handler 固定只入队。External v1 图片修改必须提交当前账号已登记的项目资源 ID 或素材 ID 作为 `sourceReferenceId`;上传对象必须先登记为项目资源或素材。objectKey、URL、Data URL、Blob URL 以及旧 `sourceImageSrc/sourceResourceId/assetKind` 字段均返回 `400`。服务端分别按资源 ID 与素材 ID 主键窄查,双表冲突、未命中、越权或对象记录无效均失败关闭,快速编辑的完整有效类型白名单为 `null / spec / character / icon-spritesheet / icon-spec / publication-material / ui-design / scene`,OpenAPI 的 `x-genarrative-allowed-effective-asset-kinds` 必须与后端白名单精确一致。请求带 `targetLayerId` 时必须同时带 `projectId`;目标图层必须关联有效项目资源,来源与目标优先比较 `assetObjectId`,缺失时比较 canonical `(bucket, objectKey)`,来源默认类型还必须与目标资源默认类型一致。入队载荷保存版本化权威快照,worker 执行前再次定点解析并拒绝身份或类型漂移;仅以素材 ID 编辑时不伪造项目资源关系。主站和 External 的通用图片入口共用场景专用合同边界校验,禁止用 `kind = scene` 或 `assetKind = scene` 绕过后端场景 Prompt 组装;场景专用 handler 自己构造规范请求,不受该通用入口校验影响。
|
||||
- 图标 spritesheet 和 UI 设计图素材提取复用站内拆分逻辑,生成图集后按连通域切片,并把图集与切片都按请求写入项目资源和素材库。
|
||||
- 角色动画、视频、音效和背景音乐复用站内编辑器生成链路;请求携带 `assetFolderId` 时按站内规则写入素材库,音频类外部调用使用 API Key 所属账号作为 asset owner。
|
||||
- API Key 管理接口仍只属于登录态个人中心,不进入外部 OpenAPI JSON。
|
||||
|
||||
@@ -2012,6 +2012,19 @@ mod tests {
|
||||
json!(false)
|
||||
);
|
||||
let image_edit_operation = &parsed["paths"]["/api/external/v1/editor/images/edits"]["post"];
|
||||
assert_eq!(
|
||||
image_edit_operation["x-genarrative-allowed-effective-asset-kinds"],
|
||||
json!([
|
||||
null,
|
||||
"spec",
|
||||
"character",
|
||||
"icon-spritesheet",
|
||||
"icon-spec",
|
||||
"publication-material",
|
||||
"ui-design",
|
||||
"scene"
|
||||
])
|
||||
);
|
||||
assert!(
|
||||
image_edit_operation["description"]
|
||||
.as_str()
|
||||
@@ -2019,6 +2032,7 @@ mod tests {
|
||||
&& description.contains("sourceReferenceId")
|
||||
&& description.contains("assetObjectId")
|
||||
&& description.contains("bucket/objectKey")
|
||||
&& description.contains("scene")
|
||||
&& description.contains("未知类型")
|
||||
&& description.contains("返回 400"))
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user