merge latest master
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
# 【实施计划】AGC 发布版本以工程内部版本为准
|
||||
|
||||
| 字段 | 值 |
|
||||
| --- | --- |
|
||||
| Milestone | `docs/project-memory/plans/【里程碑】AGC发布版本以工程内部版本为准-2026-10-03.md` |
|
||||
| Status | proposed |
|
||||
| Owner | Genarrative Agent |
|
||||
| 关联 | PR #565(`feat/game-works-management`);取代 `【里程碑/实施计划】AGC已发布游戏版本更新-2026-10-02` 中「用户可编辑发行版本标签」的口径 |
|
||||
|
||||
## 修改边界(不动的东西)
|
||||
|
||||
- 不改 `server-rs/crates/{spacetime-module,module-game-distribution,api-server,spacetime-client}`:服务端 `versionNumber` 语义与 `publicationRevision` CAS 保持不变。
|
||||
- 不改 `apps/admin-web/**`、不改 `src-tauri/src/project/export.rs`(两者正被其它 worker 修改)。
|
||||
- 不删除本地字段 `projectVersion`(Rust DTO 带 `deny_unknown_fields`:`server-rs/crates/shared-contracts/src/game_creation_app.rs:1121`)。
|
||||
|
||||
## 修改顺序
|
||||
|
||||
1. 文档:主规范改写 → 本里程碑 → 本实现计划 → `decision-log` 条目 → 两份 2026-10-02 计划文档的取代标注。
|
||||
2. 契约:TS 解析器改为内部版本派生。
|
||||
3. Rust:拆掉两条 `project_version` 写链路 + 删除手改命令。
|
||||
4. 渲染层:面板改只读派生、删失焦写回与 `onManifestUpdated`。
|
||||
5. service:删保存函数、改默认值与注释。
|
||||
6. 测试改写 + 门禁全跑。
|
||||
|
||||
## 逐条改动(文件 → 位置 → 改什么 → 验收)
|
||||
|
||||
| # | 文件 | 位置 | 改什么 | 验收 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| 1 | `packages/shared/src/contracts/gameCreationApp.ts` | `:1001-1013` | `resolveGameCreationAppProjectVersion` 去掉 `binding` 形参,返回 `versions.length > 0 ? versions.length : GAME_CREATION_APP_FIRST_PROJECT_VERSION`;注释改为「唯一来源 = 工程内部版本」 | `npm run agc:typecheck`;面板/服务用例 |
|
||||
| 2 | 同上 | `:1034-1037` | `projectVersion?: number \| null` 保留,注释改「遗留位:旧清单兼容读,不再读写」 | 静态检查 |
|
||||
| 3 | `server-rs/crates/shared-contracts/src/game_creation_app.rs` | `:1107-1118`、`:1090-1096` | 删 `resolve_game_creation_app_project_version` 与 `GAME_CREATION_APP_FIRST_PROJECT_VERSION` / `is_game_creation_app_project_version`;对应单测改为「字段被忽略」 | `cargo test -p shared-contracts` |
|
||||
| 4 | 同上 | `:1146-1150` | `project_version` 字段保留,注释改「遗留:仅为旧清单可解析,不再读写」 | 同上 |
|
||||
| 5 | `apps/ai-game-creator-shell/src-tauri/src/game_distribution_publish.rs` | `:24-27` | 去掉解析器 import | `cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml game_distribution_publish` |
|
||||
| 6 | 同上 | `:536-541`(`write_publication_binding`) | 删除 `manifest.project_version = Some(resolve(...))`,改为置 `None`;保留 `manifest.publication = Some(binding.clone())` | 同上 + `jq` 自检 |
|
||||
| 7 | 同上 | `:1531-1535`(发布成功回写) | 删除 `manifest.project_version = Some(version.version_number)`,改为置 `None`;保留 publication 回写 | 同上 |
|
||||
| 8 | 同上 | `:944-965` | 删除 `update_game_distribution_project_version` 命令 | 编译 + `rg` 零命中 |
|
||||
| 9 | `apps/ai-game-creator-shell/src-tauri/src/desktop.rs` | `:614` | 从 invoke handler 清单删除该命令 | 编译 |
|
||||
| 10 | `apps/ai-game-creator-shell/scripts/check-config.mjs` | `:138` | 从命令注册表删除 `'update_game_distribution_project_version'` | `npm run agc:typecheck` |
|
||||
| 11 | `apps/ai-game-creator-shell/src/services/gameDistributionPublish.ts` | `:148-167` | 删除 `saveGameDistributionProjectVersion` | typecheck + 用例 |
|
||||
| 12 | 同上 | `:329-337`、`:362-363` | 注释改为「唯一来源 = 工程内部版本」;默认值 `args.versionNumber ?? resolveGameCreationAppProjectVersion(args.manifest)` | 同上 |
|
||||
| 13 | `apps/ai-game-creator-shell/src/components/game-distribution/GameDistributionPublishPanel.tsx` | `:129-136`、`:283-288`、`:331-332`、`:397-403`、`:683-708`、`:731-734`、`:804` | 删 `parseProjectVersion`、`projectVersion`/`savedProjectVersion` state、`projectVersionSaveRequestRef`、`handleProjectVersionCommit` 与三处 setState;新增派生值 `useMemo(() => resolveGameCreationAppProjectVersion(manifest), [manifest.versions])`;提交改为 `versionNumber: projectVersion` | 面板用例 |
|
||||
| 14 | 同上 | `:947-1000` | 「项目版本」输入框改 `readOnly`(保留 `aria-label="项目版本"`),删 `onChange`/`onBlur`/`disabled`;提示语改为「来自 AGC 内部版本(版本 N)…」 | 面板用例 |
|
||||
| 15 | 同上 | `:242-243`、`:700` | 删除 `onManifestUpdated` prop 与唯一调用点 | typecheck |
|
||||
| 16 | `apps/ai-game-creator-shell/src/App.tsx` | `:1816`、`:1951` | 删除两处 `onManifestUpdated={setManifest}` | typecheck |
|
||||
| 17 | `apps/ai-game-creator-shell/tests/gameDistributionPublishPanel.test.tsx` | `:735-761`、`:778-823`、`:825-868` | 前两条改为「标签 = 内部版本数」;后两条(失焦写回 / 非法回退)整块删除;fixture `MANIFEST` 补非空 `versions` | vitest |
|
||||
| 18 | `apps/ai-game-creator-shell/tests/gameDistributionPublish.test.ts` | `:319-420` | 删 `saveGameDistributionProjectVersion` 用例块;默认值断言改为「无 `versions` → 1;N 条 → N」 | vitest |
|
||||
| 19 | `docs/【玩法创作】平台入口与玩法链路-2026-05-15.md` | `:97`、`:99`、`:106` + 新增两条 | 见主规范新条款 | `npm run check:doc-index` |
|
||||
| 20 | `docs/project-memory/plans/【实施计划】AGC已发布游戏版本更新-2026-10-02.md` | `:11`、`:23` | 行内追加「被 2026-10-03 里程碑取代」标注 | 阅读 |
|
||||
| 21 | `docs/project-memory/plans/【里程碑】AGC已发布游戏版本更新-2026-10-02.md` | `:27-30` | 同上,逐条标注被取代/收窄 | 阅读 |
|
||||
| 22 | `docs/project-memory/shared-memory/decision-log.md` | 最新条目区 | 追加本决策条目 | `npm run check:doc-index` |
|
||||
|
||||
## 验证命令
|
||||
|
||||
```bash
|
||||
npx vitest run apps/ai-game-creator-shell/tests/gameDistributionPublish.test.ts \
|
||||
apps/ai-game-creator-shell/tests/gameDistributionPublishPanel.test.tsx \
|
||||
apps/ai-game-creator-shell/tests/gameDistributionPublishLive.test.ts
|
||||
npm run agc:typecheck
|
||||
cd server-rs && cargo test -p shared-contracts
|
||||
cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml game_distribution_publish
|
||||
npm run check:doc-index
|
||||
npm run check:encoding
|
||||
git diff --check
|
||||
# 静态断言:命令与字段来源都已拆干净
|
||||
rg -n "update_game_distribution_project_version" . # 期望 0 命中
|
||||
rg -n "projectVersion" apps/ai-game-creator-shell/src packages/shared/src # 期望仅剩遗留声明/注释
|
||||
```
|
||||
|
||||
## 数据迁移
|
||||
|
||||
- 无迁移脚本。读路径立即忽略 `projectVersion`;改动点 6/7 会在下一次「平台回读绑定 / 发布成功」时把它置空,`skip_serializing_if` 使该键随下次落盘消失。
|
||||
- 平台侧历史版本行不做任何改写(不可变留痕)。
|
||||
|
||||
## 风险与回滚点
|
||||
|
||||
- 回滚点:只动 AGC 客户端 + 本地契约 + 文档;回滚 = 还原提交,服务端数据无副作用。
|
||||
- 旧客户端降级:清单里 `projectVersion` 被置空后,旧版 AGC 会回落到绑定 `latestVersionNumber`(旧行为重现),仅影响本机,需写 release note。
|
||||
- 派生标签会因「截尾删除版本」而回退(删素材连带删版本),平台接受该回退,但会产生「同一标签先后指向不同包」——这属平台现行契约允许的形态(用户手动重复提交同版本同样会产生)。
|
||||
|
||||
## 不做(本里程碑之外)
|
||||
|
||||
1. 「线上最近提交 vN」加「(平台)」字样(纯文案)。
|
||||
2. 平台历史版本号对齐(**明确不做**:不可变历史行无改写入口,会破坏审核留痕)。
|
||||
3. 后台/作者侧的「同标签多实例」可辨识列(落在 `apps/admin-web/**`,正被其它 worker 修改)。
|
||||
4. 「截尾删除致标签回退」的产品兜底(引入单调计数器 = 新字段 = SpacetimeDB schema 变更,须单独评审)。
|
||||
5. `edit-<operationId>` 形状的资源编辑版本是否计入内部版本序数(当前计入,与资源卡口径一致)。
|
||||
6. 旧客户端降级提示写 release note。
|
||||
@@ -0,0 +1,40 @@
|
||||
# 【实施计划】AGC 已发布游戏版本更新
|
||||
|
||||
| 字段 | 值 |
|
||||
| --- | --- |
|
||||
| Milestone | `docs/project-memory/plans/【里程碑】AGC已发布游戏版本更新-2026-10-02.md` |
|
||||
| Status | proposed |
|
||||
| Owner | Genarrative Agent |
|
||||
|
||||
## 修改边界
|
||||
|
||||
- `packages/shared/src/contracts/gameCreationApp.ts`:本地唯一 `projectVersion` 和 `publication` 绑定,不混入内部编辑迭代 `versions[]`。**(2026-10-03 取代:发布标签改为由工程内部 `versions[]` 派生、只读;`projectVersion` 降级为不再读写的遗留兼容位,见 `【里程碑】AGC发布版本以工程内部版本为准-2026-10-03.md`。)**
|
||||
- `packages/shared/src/contracts/gameDistribution.ts` 与 Rust shared-contracts:创建版本请求支持正整数 `versionNumber`,允许重复标签提交。
|
||||
- `apps/ai-game-creator-shell`:绑定回读、首次发布/更新 UI、项目版本输入、原 gameId 新提交、结果回写。
|
||||
- `api-server`、`spacetime-client`、`spacetime-module`:创建版本事务只校验正整数;同 gameId/同 versionNumber 生成新 versionId,publicationRevision 继续 CAS。
|
||||
- 现有创建版本 procedure 输入/生成绑定需要同步,但不修改持久表字段。
|
||||
|
||||
## 实现顺序
|
||||
|
||||
1. 契约先补唯一 `projectVersion` 和本地 publication,明确 versionId/版本标签/内部 projectRevision 的边界。
|
||||
2. 创建版本事务不再要求大于 max;未传时保留旧客户端自动递增,传入时校验正整数,并按同版本最新有效提交处理 pending 替代。
|
||||
3. AGC 发布绑定保存 gameId、最新 versionId、状态和 revision;按账号和 API origin 隔离绑定。
|
||||
4. AGC 打开项目回读已有作品;旧项目通过 localProjectId 恢复关联。
|
||||
5. 发布面板编辑 projectVersion,区分首次发布/更新,允许重复提交和回退,不再存在独立 targetVersion。**(2026-10-03 取代:面板不再编辑版本标签,标签由工程内部 `versions[]` 派生且只读;仍区分首次发布/更新。)**
|
||||
6. Rust 发布 facade 在更新模式跳过 create game,使用原 gameId 创建新 version;幂等账本把目标 projectVersion、资料和提交意图纳入发布意图。
|
||||
7. 验证重复提交同版本、回退版本、响应丢失、切换账号、publicationRevision 冲突和旧公开版本继续可玩。
|
||||
|
||||
## 数据库影响
|
||||
|
||||
- 不新增表。
|
||||
- 不修改 `version_number` 字段类型或重排字段。
|
||||
- 修改创建版本 procedure 输入 DTO 与生成绑定;按当前 SpacetimeDB 门禁验证。
|
||||
- 老客户端不传版本号仍自动递增,已有版本和历史数据不需要回填。
|
||||
|
||||
## 验证
|
||||
|
||||
- 领域/数据库创建版本测试:默认递增、指定更高版本、重复/较小/零/负数/非整数/越界输入、并发相同目标号。
|
||||
- AGC 发布面板测试:首发、更新、默认目标版本、用户改号和恢复失败。
|
||||
- AGC Rust 发布测试:跳过 create game、原 gameId、新 version、结果持久化、幂等意图区分。
|
||||
- `npm run typecheck`、定向 Rust/Vitest、schema/生成绑定检查、编码与 diff。
|
||||
- 真机发布:首次发布 → 重开项目 → 修改游戏 → 指定更高版本 → 更新送审 → 审核后原公开链接运行新包。
|
||||
@@ -0,0 +1,52 @@
|
||||
# 【实施计划】后台游戏审核详情与待审版本试玩
|
||||
|
||||
| 字段 | 值 |
|
||||
| --- | --- |
|
||||
| Milestone | `docs/project-memory/plans/【里程碑】后台游戏审核详情与待审版本试玩-2026-10-02.md` |
|
||||
| Status | in-progress |
|
||||
| Owner | Genarrative Agent |
|
||||
|
||||
## 修改边界
|
||||
|
||||
### 允许修改
|
||||
|
||||
- `server-rs/crates/api-server`:管理员版本详情/预览会话/待审版本资源读取,以及现有发行资源公共逻辑的安全复用。
|
||||
- `server-rs/crates/shared-contracts`、`apps/admin-web/src/api`:审核详情、预览会话和资料字段 DTO。
|
||||
- `apps/admin-web/src/pages/AdminGameDistributionReviewPage.tsx` 及其测试:详情工作台、试玩入口、审核动作刷新。
|
||||
- 现有 admin 权限映射、发行 sandbox/CSP/storage 兼容逻辑的必要扩展。
|
||||
- 当前玩法主规范、里程碑证据和实施计划。
|
||||
|
||||
### 明确不修改
|
||||
|
||||
- `spacetime-module` 持久表结构、`migration.rs`、SpacetimeDB schema 和现有生成绑定,除非调研发现当前字段不足并重新获得迁移确认。
|
||||
- `/api/external/v1`、作者发布页面、公开游戏详情和用户评价数据模型。
|
||||
- 审核员分派、批量审核、精选推荐和后台游戏资料编辑。
|
||||
|
||||
## 实现顺序
|
||||
|
||||
1. 固化现有详情响应的字段映射与权限边界,先补 admin DTO 和契约测试。
|
||||
2. 定义版本绑定的短期预览会话与错误语义,复用发行 ZIP 路径白名单、大小限制、HTML 注入、CSP 和响应头。
|
||||
3. 实现管理员待审版本预览资源读取,确认公开发行路径不能读取未公开版本。
|
||||
4. 将审核列表升级为详情工作台:资料分组、发布者、版本摘要、封面/截图、试玩状态和审核动作。
|
||||
5. 补齐正常、拒绝、过期、越权、Cookie、缺文件、资源 404、CAS 冲突和幂等重放测试。
|
||||
6. 运行真实本地审核 smoke,确认打开的是待审 `versionId`,不是当前公开版本;完成后回写主规范并删除临时计划。
|
||||
|
||||
## 验证命令
|
||||
|
||||
1. `npm run typecheck`
|
||||
2. `npm exec -- vitest run apps/admin-web/src/pages/AdminGameDistributionReviewPage.test.tsx apps/admin-web/src/api/adminApiClient.test.ts --root .`
|
||||
3. `cargo test -p api-server game_distribution --manifest-path server-rs/Cargo.toml`
|
||||
4. `cargo fmt --all --manifest-path server-rs/Cargo.toml -- --check`
|
||||
5. `npm run check:encoding`
|
||||
6. `npm run check:doc-index`
|
||||
7. `git diff --check`
|
||||
8. 本地 `npm run dev` + 管理员登录 + 待审版本详情/试玩 smoke。
|
||||
|
||||
## 风险与回滚点
|
||||
|
||||
- **预览越权**:Token 必须绑定 `versionId` 和过期时间;错误实现会把私有待审包变成可枚举资源。回滚点是关闭预览会话路由,不影响公开发行网关。
|
||||
- **版本串播**:预览 URL 不能复用 `game.currentVersion.entryUrl`;详情和资源读取都必须携带并校验待审版本。回滚点是隐藏试玩按钮,保留资料审核。
|
||||
- **sandbox 放宽**:不得添加 `allow-same-origin`;如 storage 兼容层回归,回滚新增注入逻辑而不放宽 sandbox。
|
||||
- **资料漂移**:详情必须展示版本冻结快照;若快照缺失,只显示明确缺失状态,不静默用作者当前资料替代。
|
||||
- **审核并发**:继续使用 `publicationRevision` 和幂等键;CAS 冲突只刷新,不自动重放决定。
|
||||
- **API 兼容**:新字段可选,旧后台响应不能因缺少冻结资料而崩溃;预览接口失败不能影响公开游戏游玩。
|
||||
@@ -0,0 +1,81 @@
|
||||
# 【实施计划】游戏作品管理与客户端发布收口-2026-09-30
|
||||
|
||||
关联 Issue:`#470`「做一下创作者作品管理,从工具到平台的一键导出和发布」。
|
||||
分支:`feat/game-works-management`。
|
||||
|
||||
## 目标
|
||||
|
||||
在 10.7「陶泥儿游戏平台」上线前,把「创作者作品管理(用户侧 / 后台)+ 客户端打包上传(只保证 Phaser 4)」这条链路补齐到可用:作品能进来、能看得见状态、能管住。
|
||||
|
||||
- 发布管道(AGC 构建打包 → 8 MiB 分片上传 → 送审 → 后台审核 → 公开可玩 → 发行网关)已实现,并有真实栈证据(见[实施计划【游戏分发阶段A领域合同】](【实施计划】游戏分发阶段A领域合同-2026-09-19.md))。
|
||||
- 本轮已补齐:客户端 Phaser 4 + Vite 工程栈门禁、发布阶段/上传百分比、发布根幂等账本;Web 作者私有详情、状态/版本筛选、版本历史、资料编辑、软删除和作者操作;后台作品搜索、作者/状态筛选、游标分页与删除状态展示。
|
||||
- 生产发布开关仍默认关闭;真实客户端 GUI 发布、生产首个作品和发布包清理策略仍需运行时取证。
|
||||
|
||||
## 已落地(本分支)
|
||||
|
||||
| 项 | 落点 | 证据 |
|
||||
| --- | --- | --- |
|
||||
| 作者读自己名下单个游戏详情 `GET /api/game-distribution/my-games/{gameId}` | `api-server/src/modules/game_distribution.rs`(`get_owner_game`、`load_owner_game_versions`、`owner_game_entry_payload`) | `cargo test -p api-server game_distribution::tests` → 26 passed;`owner_game_entry_payload_carries_private_versions_that_public_payload_omits` 断言作者条目带版本私有状态、公开投影不带 |
|
||||
| 版本私有状态补 `entryUrl` / `packageFileCount` | 同上 `private_version_payload` | 同上测试断言 |
|
||||
| 主规范路由表登记新路由并修正 `/my/games` 错名 | `docs/【玩法创作】平台入口与玩法链路-2026-05-15.md` 路由表 | — |
|
||||
|
||||
设计要点:不新增 SpacetimeDB 表与 procedure。详情路由的 game 走 `get_game_distribution_game`(owner 作用域,精确命中),版本沿用作者自有列表 procedure 的聚合结果。
|
||||
|
||||
## 计划与落地状态
|
||||
|
||||
### 波 1:闭环可用
|
||||
|
||||
- [ ] AGC 真机把「构建 → 打包 → 分片上传 → 送审」跑通一次。
|
||||
- [x] 发布进度接线:前端监听既有 `game-package-upload-progress`,渲染真实阶段与百分比。
|
||||
- [x] 幂等键落盘:按账号、origin、本地项目和包摘要持久化根键,重试复用同一 key。
|
||||
- [ ] 运营开闸 + 生产发布第一个作品,走完审核 → 公开 → 游客可玩。
|
||||
|
||||
### 波 2:管理完整
|
||||
|
||||
- [x] 作品资料编辑:展示资料在 `game` 级可编辑、立即生效并留审计;包仍随版本冻结。
|
||||
- [x] 作品软删除:`game_distribution_game` 末尾追加 `deleted_at`,公开投影与列表过滤软删行。
|
||||
- [x] 网页侧对齐:`/games/mine` 补删除、资料编辑、版本历史、作者查看未公开作品。
|
||||
- [x] 后台作品列表:游标分页 + 搜索 + 按作者/状态筛选。
|
||||
|
||||
### 波 3:运营治理
|
||||
|
||||
11. 审核历史展示(复用版本已有的 `reviewed_by_user_id` / `submitted_at` / `reviewed_at` / `published_at`,不新增表)。
|
||||
12. 批量审核操作。
|
||||
13. 精选 / 推荐位(与游玩线的推荐排序定边界)。
|
||||
14. 举报处理(先确认能否复用现役反馈管道)。
|
||||
|
||||
## 尚未完成
|
||||
|
||||
- AGC 真机 GUI 端到端发布取证。
|
||||
- 生产环境发布第一个作品并开闸。
|
||||
- 非 Phaser(Godot / Cocos / Unity)发布的主动拦截:这些工程没有 npm 构建工作区,仍只给泛化错误文案(单 HTML 项目同理)。
|
||||
- 发布包清理策略的上线验收。
|
||||
|
||||
## 不变式
|
||||
|
||||
- 新增字段一律追加到 Rust 表结构体末尾并带明确默认值;不改名、不重排、不改类型。改 schema 后同步 `migration.rs`、表目录与生成绑定,并跑 `npm run check:spacetime-schema`。
|
||||
- 公开投影不得携带作者私有字段(包摘要、驳回理由、文档本地路径)。作者视角走 owner 作用域路由。
|
||||
- 复用现役管道与组件,不新造上传、审核、发行通道。
|
||||
|
||||
## 波 1 · AGC 客户端发布切片(2026-10-01 落地;自动门禁已通过,真实 GUI/生产待验收)
|
||||
|
||||
| 项 | 落点 | 行为 |
|
||||
| --- | --- | --- |
|
||||
| 发布进度接线 | `src-tauri/src/game_package_upload.rs`、`game_distribution_publish.rs`、`commands.rs`、`src/services/gamePackageUploadProgress.ts`、`src/components/game-distribution/GamePublishProgressDialog.tsx`、`GamePublishPhaseSteps.tsx`、`GameDistributionPublishPanel.tsx`、`App.tsx` | 既有 `game-package-upload-progress` 事件扩展出 `phase`(`prepare` / `upload` / `verify` / `submit`)与 `message`,上传阶段仍带 `receivedBytes` / `totalBytes`;`/complete`(重算摘要 + 展开清单)之前由上传器回调切到「校验」。渲染层在全屏进度弹窗显示「构建」步骤,在发布面板显示「构建 → 准备 → 上传 → 校验 → 送审」步骤条与上传百分比。 |
|
||||
| 根幂等键落盘 | 新增 `src-tauri/src/game_publish_attempt.rs`(应用数据目录 `game-publish-attempts.json`,原子写 + 进程内锁) | 键按「账号 + origin + 本地项目 + 归一化包摘要」解析:同一份包重发、响应丢失、进程重启与分片续传复用同一根键(服务端因此只认一次尝试);送审成功后清除记录,下一次发布会新增版本。渲染层不再铸键,`publishLocalProjectGame` 只在显式传入时才带 `idempotencyKey`。账本只存账号标识、origin、本地项目标识、包摘要与根键,不含 token 与本地绝对路径。 |
|
||||
| 发布前工程栈校验 | `src-tauri/src/project/export.rs`(`ensure_publish_project_stack`,导出与发布两条入口都调用) | 存在 npm 构建工作区时要求 Phaser 4 + Vite:缺 `phaser` 依赖、声明的主版本不是 4(含 `package-lock.json` 回退判定)、以及既没有 `vite` 依赖也没有 `vite.config.*` 都给出可操作中文错误(指明缺什么、当前声明、怎么修)。没有 npm 工作区的老单文件项目保持原有发布能力。 |
|
||||
|
||||
## 已知限制
|
||||
|
||||
- 作者自有游戏列表与新增的作者详情共享同一个单次条数上限(48):单作者作品数超过上限时,详情页拿不到版本记录。放量前需要补一条按 `gameId` 精确列版本的 procedure。
|
||||
- 客户端不暴露 `localProjectId`:本地项目与线上作品的对应关系由客户端本地账本维护,服务端只在发布时用它复用 `gameId`。
|
||||
- 发布尝试账本按「本地项目 + 包摘要」判同一尝试:改了工程或重新导出了不同内容的包就是新尝试(新建版本),旧版本的半成品包仍需走网页作者侧的恢复/重置入口。
|
||||
- 发布阶段条按「本次订阅窗口」收敛(事件的 `versionId` 在命令返回前对渲染层不可知);同一窗口同一时刻只有一次发布在跑。
|
||||
- 工程栈校验按首版「只支持 Phaser 4」执行:npm 工程(含 Three.js 等三维工程)未声明 `phaser` 会被拦下并提示安装 Phaser 4。若产品决定放行其它 npm 技术栈,需要在这里改成「phaser 声明存在时必须是 4,其余技术栈按白名单放行」。
|
||||
|
||||
## 尚未完成
|
||||
|
||||
- AGC 真机 GUI 端到端发布取证。
|
||||
- 生产环境发布第一个作品并开闸。
|
||||
- 非 Phaser(Godot / Cocos / Unity)发布的主动拦截:这些工程没有 npm 构建工作区,仍只给泛化错误文案(单 HTML 项目同理)。
|
||||
- 发布包清理策略的上线验收。
|
||||
@@ -49,6 +49,8 @@ AGC 发布面板完成三项收敛:
|
||||
## 6. 本次缺陷修复记录
|
||||
|
||||
- 2026-09-23:AGC 生成游戏封面请求补充 `generationInputs.source = "ai-game-creator-client"`。队列 worker 依据该来源选择 `GameCreatorResourceEditor` 结果契约;未标记来源时会按 `Standard` 紧凑化并省略 `result`,导致生成完成后无法回传 `assetObjectId`。对应前端定向测试已锁定请求字段与平台素材 ID 回填链路。
|
||||
- 2026-10-02:生成结果中的 `imageSrc/objectKey` 是私有素材引用,不再直接交给 WebView `<img>`;AGC Rust 发布 facade 经鉴权 `read-url` 有界下载为 `data:` 图片预览,预览失败不阻断已登记素材发布。
|
||||
|
||||
## 7. 本轮核对(2026-09-28)
|
||||
|
||||
六项交付结果都在合并后的工作树里,并有本轮实测:
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
# 【里程碑】AGC 发布版本以工程内部版本为准
|
||||
|
||||
| 字段 | 值 |
|
||||
| --- | --- |
|
||||
| Version | 1.0 |
|
||||
| Status | proposed |
|
||||
| Date | 2026-10-03 |
|
||||
| Parent Spec | `docs/【玩法创作】平台入口与玩法链路-2026-05-15.md`(「身份、状态、审核与更新」章) |
|
||||
|
||||
## 目标
|
||||
|
||||
让 AGC 发布面板的「项目版本」只有一个权威来源:AGC 工程内部版本记录 `manifest.versions[]`(即资源总览「项目版本」栏目里的版本卡)。标签等于当前存活的内部版本条数(最新卡的「版本 N」),只读、不可手填、不被平台 `version_number` 回填或覆盖,与 `publicationRevision` 无关。
|
||||
|
||||
## 边界
|
||||
|
||||
- 不改服务端能力:`publicationRevision` 继续严格 CAS;平台 `versionNumber` 继续接受正整数、重复与回退(网页端与历史客户端依赖该兼容口径)。
|
||||
- 不新增或修改 SpacetimeDB 表、字段与 procedure;`game_distribution_version.version_number` 不动。
|
||||
- 不重写平台历史版本行;不改公开地址、审核状态机与发行网关。
|
||||
- 不做版本历史页、版本对比、一键回滚 UI。
|
||||
- 不删除本地清单字段 `projectVersion`(Rust DTO 带 `deny_unknown_fields`,删除会让存量清单解析失败),它降级为不再读写的兼容位。
|
||||
|
||||
## 验收标准
|
||||
|
||||
- [ ] 发布面板显示的「项目版本」等于当前 `manifest.versions` 的条数(`versions` 为空时为 1),与平台 `version_number`、`publicationRevision` 均无关。
|
||||
- [ ] 面板不提供任何修改该值的入口;提交时 `versionNumber` 逐字等于该派生值。
|
||||
- [ ] 打开已有线上作品(线上最近提交 v6、内部版本 4 条)时,面板显示 v4,且仍并列显示「线上最近提交 v6 · 审核中」。
|
||||
- [ ] AGC 任何路径都不再写入 `projectVersion`(含发布成功回写、绑定回读回填、面板失焦写回)。
|
||||
- [ ] 存量清单里已有的 `projectVersion` 值不影响展示与提交。
|
||||
- [ ] 内部版本被截尾删除(长度 4 → 3)后,面板显示 v3 且能正常提交,不需要任何本地冲突处理。
|
||||
|
||||
## 依赖
|
||||
|
||||
- 无外部依赖;与「AGC 已发布游戏版本更新(2026-10-02)」是**取代**关系(见该文档内的取代标注)。
|
||||
@@ -0,0 +1,33 @@
|
||||
# 【里程碑】AGC 已发布游戏版本更新
|
||||
|
||||
| 字段 | 值 |
|
||||
| --- | --- |
|
||||
| Version | 1.0 |
|
||||
| Status | proposed |
|
||||
| Date | 2026-10-02 |
|
||||
| Parent Spec | `docs/【玩法创作】平台入口与玩法链路-2026-05-15.md#AGC 游戏分发与在线游玩合同` |
|
||||
|
||||
## 目标
|
||||
|
||||
让 AGC 区分首次发布与已有作品更新:已有作品继续使用原 `gameId`;用户维护唯一项目发行版本标签,同一标签可以重复提交或回退,具体提交由不可变 `versionId` 标识。
|
||||
- 同一 `gameId` 的新版本上传、校验、送审和结果回写。
|
||||
|
||||
## 不在范围内
|
||||
|
||||
- AGC 完整版本历史页、版本对比和一键回滚 UI;回退版本标签的发布路径属于本里程碑。
|
||||
- 原地替换已发布 `versionId`;已发布提交保持不可变。
|
||||
- 新增 SpacetimeDB 持久表或修改 `game_distribution_version.version_number` 类型。
|
||||
- 改变公开 URL、审核状态机、发行网关或后台审核权限。
|
||||
|
||||
## 验收标准
|
||||
|
||||
- [ ] 首次发布完成后项目清单保存 `gameId`、`versionId`、版本号、状态和 `publicationRevision`。
|
||||
- [ ] 重新打开同一项目显示“更新游戏”,不再显示“创建平台游戏”。
|
||||
- [ ] 项目清单只有一个用户发行版本字段,发布面板编辑它,不存在独立 targetVersion。**(2026-10-03 取代:发布标签改由 AGC 工程内部 `versions[]` 派生且只读,面板不再编辑;见 `【里程碑】AGC发布版本以工程内部版本为准-2026-10-03.md`。)**
|
||||
- [ ] 同一 `gameId`、同一 `versionNumber` 可以重复提交,生成新的 `versionId`,不覆盖旧公开实例。
|
||||
- [ ] 项目版本可以低于线上最新版本,服务端允许回退标签,但仍校验为正整数。**(2026-10-03 收窄:平台侧继续成立;AGC 侧不再由用户手填回退,派生标签只在内部版本被截尾删除时变小。)**
|
||||
- [ ] 同版本旧 pending 提交被取消或被最新提交替代,审核队列不产生重复有效任务。
|
||||
- [ ] `publicationRevision` 仍用于并发 CAS,与用户版本号规则独立。
|
||||
- [ ] 更新使用同一 `gameId`,只增加一个新 `versionId`,公开地址保持不变。
|
||||
- [ ] 旧项目没有发布绑定时能按作者和 `localProjectId` 恢复;恢复失败时明确回到首次发布。
|
||||
- [ ] 上传响应丢失、重复提交、版本号冲突和切换账号不会创建重复游戏或错误接管作品。
|
||||
@@ -0,0 +1,51 @@
|
||||
# 【里程碑】后台游戏审核详情与待审版本试玩
|
||||
|
||||
| 字段 | 值 |
|
||||
| --- | --- |
|
||||
| Version | 1.0 |
|
||||
| Status | in-progress |
|
||||
| Date | 2026-10-02 |
|
||||
| Parent Spec | `docs/【玩法创作】平台入口与玩法链路-2026-05-15.md#后台游戏审核详情与待审版本试玩合同` |
|
||||
|
||||
## 目标
|
||||
|
||||
把后台游戏版本审核从“列表操作”补成可复核的审核详情工作台:审核员能确认发布者和冻结游戏资料,能试玩当前待审版本,并能在同一详情上下达审核决定。
|
||||
|
||||
## 范围
|
||||
|
||||
- 待审版本详情回读。
|
||||
- 发布者、游戏资料、版本包摘要和冻结资料展示。
|
||||
- 单个待审版本的短期隔离试玩会话。
|
||||
- 试玩资源、Cookie、sandbox、CSP 和版本绑定边界。
|
||||
- 版本级审核动作(通过、拒绝)与现有 CAS/幂等规则对齐;游戏级安全下架入口留在「游戏管理」页。
|
||||
- admin-web、api-server、shared-contracts 和相关测试的契约同步。
|
||||
|
||||
## 不在范围内
|
||||
|
||||
- 新增游戏审核、发布者、试玩会话或游戏资料持久化表。
|
||||
- 审核员分派、SLA、批量审核和精选推荐。
|
||||
- 后台修改游戏资料、重新构建或重新上传发行包。
|
||||
- 公开发行接口、作者发布链路和 `/api/external/v1`。
|
||||
|
||||
## 依赖与前置条件
|
||||
|
||||
- 现有管理员版本详情接口继续返回游戏投影和版本冻结资料。
|
||||
- 现有 SpacetimeDB `game_distribution_game` 与 `game_distribution_version` 字段满足详情展示。
|
||||
- 现有发行 ZIP 校验、静态资源白名单和 HTML storage 兼容层可以抽取复用。
|
||||
- 现有游戏审核权限映射作为第一版预览权限,不新增权限角色。
|
||||
|
||||
## 验收标准
|
||||
|
||||
- [ ] 审核详情显示发布者、完整游戏资料、版本摘要和审核状态。
|
||||
- [ ] 详情使用待审版本冻结资料,不被后续 game 行资料修改污染。
|
||||
- [ ] 审核员可以打开当前 `versionId` 试玩,且 JS/CSS/图片/音频等同包资源可加载。
|
||||
- [ ] 预览 Token 绑定版本、短期有效、过期和越权读取均失败。
|
||||
- [ ] 预览不读取平台 Cookie,不授予 `allow-same-origin`,保留发行 sandbox/CSP/storage 约束。
|
||||
- [ ] 审核页的通过/拒绝继续执行理由、CAS、幂等和刷新规则;行内不出现游戏级安全下架。
|
||||
- [ ] 无 SpacetimeDB schema、migration、公开契约破坏性变化。
|
||||
|
||||
## 证据要求
|
||||
|
||||
- 自动化:admin-web 详情/动作测试、api-server 预览会话和权限测试、DTO/类型检查、编码和 diff 检查。
|
||||
- 运行时:本地管理员打开待审版本,确认资料、封面/截图和待审包试玩;确认旧公开版本不会被误播。
|
||||
- 边界:过期 Token、错误 versionId、Cookie、越权管理员、缺入口、资源 404、CAS 冲突和幂等重放。
|
||||
Reference in New Issue
Block a user