补充路径即身份的踩坑记录
记录发布 DTO 同时带路径参数与 body 身份字段导致第二个真源的问题 写明现行口径:handler 只从 Path 取值,body 不重复 gameId / versionNumber
This commit is contained in:
@@ -6653,3 +6653,11 @@ Cocos Creator 根目录由 `package.json.creator.version` 与普通 `assets/`
|
||||
- **现行口径**:`direct_game_creator_claude_code_chat_at` 改成一次用户回合最多 `CLAUDE_DIRECT_TURN_MAX_ATTEMPTS = 3` 次尝试(第一版:2 次自动重试),**只有两个条件同时成立才自动重放**:①失败是"静默超时"(`连续 N ms 没有任何事件`;45 分钟硬上限不重放,否则一次回合能被拖到两小时以上);②这一轮从头到尾**没有请求过任何工具**——模型一旦发过 `tool_use`,重跑就可能把付费生成 / 构建 / 试玩再执行一遍(哪怕结果还没回来,操作也可能已经在途),这时改为落一条"本轮已经请求过工具,不会自动重放;请手动重试"的过程行。每次重试前先落一条 `role:"system"` 过程行(`等待模型回执超时,正在自动重试(第 2/3 次)`),重试同样走 `resume`,历史与上下文不丢。最终失败时的 `已尝试 N 次` 由宿主回填:详情尾部的 `;本轮已自动重试 N 次` 只是结构化传递标记,分类器会把它摘掉,不落到用户可见详情里。
|
||||
- **验证**:`cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml --features=cocos-editor-execute,unity-editor-execute,godot-editor-execute --bin genarrative-ai-game-creator-shell claude_` 37 passed。新增三条:`claude_direct_retry_policy_retries_only_safe_timeouts`(逐格钉住重试/停下的四种决定)、`claude_direct_timeout_is_only_auto_replayed_without_tool_requests`(硬上限不重放、请求过工具不重放)、`claude_direct_retry_attempts_reach_the_structured_error_without_leaking`(attempts 结构化,标记不落到用户可见详情)。
|
||||
- **关联**:`apps/ai-game-creator-shell/src-tauri/src/agent/claude_code_cli.rs`。
|
||||
|
||||
## 2026-10-07 发布 DTO 里同时出现路径身份字段:`versionNumber` 到底听路径还是听 body
|
||||
|
||||
- **现象**:把游戏分发发布面收敛成 `POST /games` 与 `POST /games/{game_id}/versions/{version_number}` 后,`NewGameVersionRequest` 里一度仍保留 `gameId` / `versionNumber`,`GameDistributionCreateVersionRequest` 也带 `versionNumber`。于是同一个事实有两个来源:路径里的 `{version_number}` 与 body 里的 `versionNumber`。handler 必须写「哪个优先、不一致怎么办」的分支,客户端也会猜「传 body 是不是能覆盖路径」——既多一处校验,又多一类只能靠运行时发现的不一致。
|
||||
- **根因**:沿用了「请求体自带完整身份」的旧习惯(旧两步 `POST /games/{gameId}/versions` 的 body 必须带 `versionNumber`,因为没有路径槽)。REST 子里**路径已经是资源身份**,body 再写一份就变成第二个真源。
|
||||
- **现行口径**:**路径即身份,body 不得重复路径参数**。只要路径里有 `{game_id}` / `{version_number}`,handler 只从 `Path(…)` 取值,不存在「路径优先还是 body 优先」的校验分支;`NewGameVersionRequest` 因此去掉 `gameId` 与 `versionNumber`(`POST /games` 无路径槽,只带 `projectKey`,首版号固定 `1`;追加版本的身份全在路径)。同一轮复核其余带路径参数的写端点(`submit` / `cancel` / `purchase` / `reviews` / `theme members` / `admin review`),请求体都不含路径身份字段。
|
||||
- **验证**:`cargo test -p shared-contracts publish`(`publish_version_request_body_has_no_path_identity`)、`cargo test -p api-server game_distribution`、`npm run check:game-distribution-dto-parity`、`git diff --check`。
|
||||
- **关联**:`docs/adr/【ADR】游戏分发版本以versionNumber为对外身份-2026-10-07.md`(「路径即身份(body 不重复路径参数)」)、`server-rs/crates/shared-contracts/src/game_distribution_publish.rs`、`server-rs/crates/api-server/src/modules/game_distribution.rs`、`apps/ai-game-creator-shell/src-tauri/src/game_package_upload.rs`。
|
||||
|
||||
Reference in New Issue
Block a user