修复游戏场景后端契约旁路
Project CI / Backend tests (pull_request) Failing after 10s
Project CI / Repository checks (pull_request) Failing after 10s
Project CI / Frontend tests (pull_request) Successful in 3m2s
Project CI / Native shell tests (pull_request) Successful in 12m32s

阻止通用图片接口绕过场景专用合同

规范场景任务标题与用户可见摘要

修复空白场景素材名称回退行为

补充场景接口和任务投影回归测试

同步场景技术方案与排障约定
This commit is contained in:
2026-08-06 13:44:16 +08:00
parent 0c05faeac3
commit 447c23840c
5 changed files with 232 additions and 8 deletions
@@ -448,6 +448,14 @@
- 验证:`npm run test -- src/services/image-editor/editorProjectClient.test.ts src/components/image-editor/useImageCanvasGenerationSubmissionWorkflow.test.tsx``cargo test -p api-server inline_data_url --manifest-path server-rs/Cargo.toml`
- 关联:`src/components/image-editor/useImageCanvasGenerationSubmissionWorkflow.ts``src/services/image-editor/editorProjectClient.ts``server-rs/crates/api-server/src/editor_generation_queue.rs``docs/technical/【前端架构】图片画布编辑器MVP接入方案-2026-06-11.md`
## 专用生成契约不能被通用生成接口和任务摘要绕过
- 现象:专用场景接口要求结构化 `sceneContent + stylePreset`,但调用方仍可向通用图片接口传 `kind = scene``assetKind = scene`,用任意完整 Prompt 生成并持久化正式场景;合法场景入队后,任务侧栏还可能显示后端完整规则文本和通用“生成图片”标题,空白素材名则可能回退成完整 Prompt。
- 原因:专用 handler 内部复用了通用图片 payload、队列和 Worker,但公开通用 HTTP handler 没有限制专用身份;任务摘要又无条件优先提取 payload 顶层 `prompt`,素材名默认值只处理了字段省略,没有处理空白字符串。
- 处理:公开通用 handler 拒绝专用 `kind / assetKind`,专用 handler 仍可直接调用内部共享执行函数;队列投影按 `kind = scene` 从权威 `generationInputs.fields[画面内容]` 派生标题和摘要,缺字段时失败关闭而不是回退内部 Prompt,并重新计算历史缓存;专用素材名统一把省略和空白收口为产品默认值。
- 验证:路由测试先证明旁路会越过 HTTP 边界,再断言两种旁路均返回 `400` 且指向专用端点;摘要测试覆盖新任务、历史错误缓存和缺少画面内容三种情况;标签测试覆盖省略、空白、自定义和 80 字上限。
- 关联:`server-rs/crates/api-server/src/editor_project.rs``server-rs/crates/spacetime-module/src/external_generation.rs``docs/technical/【技术方案】图片画布游戏场景生成链路-2026-08-04.md`
## 图片编辑器角色动画必须提交稳定图片引用
- 现象:图片编辑器里对尚未上传的角色图点击 `生成动画` 后,前端或后端返回 `sourceImageSrc 必须先上传 OSS`
@@ -83,7 +83,7 @@ assetLabel?
canvasCompletion?
```
请求不接受前端组装后的完整 `prompt`。本期不修改 `/api/external/v1`
请求不接受前端组装后的完整 `prompt`通用 `/api/editor/images/generations` 也必须拒绝 `kind = scene``assetKind = scene`,防止调用方绕过结构化字段校验和后端 Prompt 组装。本期不修改 `/api/external/v1`
完整 Provider Prompt 仍只能由后端生成。
@@ -121,6 +121,8 @@ prompt = 后端完整 Prompt
随后复用 `enqueue_editor_image_generation_for_owner`,队列类型继续是 `editor_image_generation`Worker 继续执行 `generate_editor_image_for_owner`
队列标题固定为“图片画布生成游戏场景”。任务摘要只展示 `generationInputs.fields` 中的“画面内容”,不得把队列 payload 里的后端完整 Prompt 暴露到任务侧栏;历史错误摘要在投影刷新时按同一规则重新派生。`assetLabel` 省略、空字符串或纯空白时统一使用“游戏场景”,不能退回完整 Prompt 作为素材名称。
计费规则:
- 前端展示价继续读取 `/api/editor/generation-pricing`