diff --git a/docs/adr/【ADR】游戏分发版本以versionNumber为对外身份-2026-10-07.md b/docs/adr/【ADR】游戏分发版本以versionNumber为对外身份-2026-10-07.md index 28c36be08..4c15ffd19 100644 --- a/docs/adr/【ADR】游戏分发版本以versionNumber为对外身份-2026-10-07.md +++ b/docs/adr/【ADR】游戏分发版本以versionNumber为对外身份-2026-10-07.md @@ -40,7 +40,7 @@ URL 里那串随机 UUID 既不可读,客户端也无法在提交前独立构 继续用 `{version_id}`。完整端点表: | 方法 | 路径 | 请求 | 响应 | 鉴权 / 头 | -| ----------------------------- | ------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- | ------------------------------------- | +|-------------------------------|---------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------|---------------------------------------| | POST | `/api/game-distribution/games` | multipart:`metadata` = `NewGameVersionRequest`(JSON),`cover` / `screenshot` 二进制 part | `GameDistributionPublishVersionResponse` | Bearer + `Idempotency-Key` + 发布灰度 | | POST | `/api/game-distribution/games/{game_id}/versions/{version_number}` | 同上;body 不含 `gameId` / `versionNumber`,身份全部取自路径 | `GameDistributionPublishVersionResponse` | Bearer + `Idempotency-Key` + 发布灰度 | | GET | `/api/game-distribution/games/{game_id}/versions/{version_number}` | – | 版本详情(`GameDistributionPrivateVersion` + 作品上下文) | Bearer | @@ -61,7 +61,7 @@ URL 里那串随机 UUID 既不可读,客户端也无法在提交前独立构 | GET | `/api/game-distribution/games/{game_id}/network/stats` | – | `GameDistributionNetworkStatsResponse`(子树归集) | Bearer(原路径改名) | - `POST /games` 首次发布只强制 `project_key`,`game_id` 由 - `derive_game_distribution_game_id(owner, project_key)` 派生;**首版号固定为 `1`**(版本身份只在 + `derive_game_distribution_game_id(owner, project_key)` 派生; **首版号固定为 `1`**(版本身份只在 路径 `…/versions/{version_number}` 里出现);带 `fork` 时是衍生首版。 - 作品资料编辑走既有通用 `PATCH /api/game-distribution/my-games/{game_id}`(自带 `expected_publication_revision` CAS);共创授权 `forkAuthorization` 并入该 PATCH,删除单字段 @@ -74,9 +74,9 @@ URL 里那串随机 UUID 既不可读,客户端也无法在提交前独立构 #### 路径即身份(body 不重复路径参数) -- 只要路径里有 `{game_id}` / `{version_number}`,请求体就**不得**再出现同名字段:handler 只从 +- 只要路径里有 `{game_id}` / `{version_number}`,请求体就 **不得**再出现同名字段:handler 只从 `Path(…)` 取值,不存在「路径优先还是 body 优先」的校验分支。 -- `NewGameVersionRequest` 因此**去掉** `gameId` 与 `versionNumber`:`POST /games` 只带 `projectKey` +- `NewGameVersionRequest` 因此 **去掉** `gameId` 与 `versionNumber`:`POST /games` 只带 `projectKey` (无路径槽,首版号固定 `1`);`POST /games/{game_id}/versions/{version_number}` 的身份全在路径。 - 复核:game-distribution 其余带路径参数的写端点(`submit` / `cancel` / `purchase` / `reviews` / `theme members` / `admin review` / `fork-authorization`)请求体都不含路径身份字段;唯二重复的是 @@ -85,7 +85,7 @@ URL 里那串随机 UUID 既不可读,客户端也无法在提交前独立构 #### GitHub 术语对齐 | 现名 | 语义 | GitHub 术语 | 新名 | -| ---------------- | --------------------------------------------------------------------- | ------------------------------------- | --------------- | +|------------------|-----------------------------------------------------------------------|---------------------------------------|-----------------| | `derived` | 直接子代列表 | forks | `forks` | | `lineage` | 以根为顶的整棵改编树 | fork network(UI「network members」) | `network` | | `contribution` | 子树各代游玩数归集(`own` / `inherited` / `total`) | Insights / stats(`/stats/…`) | `network/stats` | @@ -118,7 +118,7 @@ AGC 不是每次靠 `projectKey` 反查:它把远端身份 **存在本地**— 线上 404 → 清掉绑定、回到首次发布。 | 接口 | `projectKey` | 说明 | -| -------------------------------------------------- | ------------ | ------------------------------------------------------------- | +|----------------------------------------------------|--------------|---------------------------------------------------------------| | `POST /games` | **必填** | 没有 `gameId` 可参考,靠它派生作品身份;缺失 400 | | `POST /games/{game_id}/versions/{version_number}` | 可选 | 身份由路径 `game_id` 定;AGC 已绑定时根本不传,只在恢复时兜底 | | `PATCH /games/{game_id}/versions/{version_number}` | 不需要 | 不换身份 | @@ -143,7 +143,7 @@ AGC 不是每次靠 `projectKey` 反查:它把远端身份 **存在本地**— #### DTO / 记录类型改名(与路由术语一致) | 现名 | 新名 | -| --------------------------------------------- | ------------------------------------------------------------------------------------- | +|-----------------------------------------------|---------------------------------------------------------------------------------------| | `GameDistributionDerivedResponse` | `GameDistributionForksResponse` | | `GameDistributionDerivedGamesRecord` | `GameDistributionForksRecord` | | `GameDistributionLineageResponse` | `GameDistributionNetworkResponse` | @@ -175,9 +175,9 @@ AGC 不是每次靠 `projectKey` 反查:它把远端身份 **存在本地**— 所有 `/api/game-distribution/versions/{version_id}…` 对外路径(`:651-705`)、 `/api/game-distribution/games/{game_id}/derived`(`:796`)与 `PUT /api/game-distribution/games/{game_id}/fork-authorization`(`:721`)。 -- 一并删除只服务旧两步的 DTO:`GameDistributionCreateGameRequest` - (`shared-contracts/src/game_distribution.rs:727`)、`GameDistributionCreateVersionRequest` - (`:790`,其 body 里带 `versionNumber`)、`GameDistributionSetForkAuthorizationRequest`(`:318`)。 +- 一并删除只服务旧两步的 DTO:`GameDistributionCreateGameRequest`、 + `GameDistributionCreateVersionRequest`(body 里带 `versionNumber`)、 + `GameDistributionSetForkAuthorizationRequest`(并入 `PATCH /my-games/{game_id}`)。 - 改名的旧路径一并删:`/lineage`、`/fork-source`(含 `/package` `/project`)、`/contribution`、 `/versions/{version_id}/project-bundle`(由 `/network`、`/source`、`/network/stats`、 `/versions/{version_number}/source` 取代)。