From 7d24b0ac50b48cbd58132d889f31bb56f423b9fa Mon Sep 17 00:00:00 2001 From: Suzumiya Date: Mon, 5 Oct 2026 16:36:13 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=B8=B8=E6=88=8F=E4=B9=B0?= =?UTF-8?q?=E6=96=AD=E5=88=B6=E6=B3=A5=E7=82=B9=E4=BB=98=E8=B4=B9=E8=A7=84?= =?UTF-8?q?=E8=8C=83=EF=BC=9A=E4=B8=BB=E8=A7=84=E8=8C=83=E5=90=88=E5=90=8C?= =?UTF-8?q?=E3=80=81=E9=87=8C=E7=A8=8B=E7=A2=91=E4=B8=8E=E5=AE=9E=E6=96=BD?= =?UTF-8?q?=E8=AE=A1=E5=88=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 主规范《平台入口与玩法链路》解除“不做交易”排除,新增“游戏买断制泥点付费与播放鉴权合同”章节,明确定价冻结、买断所有权、播放鉴权、后台审核展示与幂等边界 - 新增【里程碑】游戏买断制泥点付费与播放鉴权-2026-10-05.md:范围、不在范围内、依赖、验收标准与证据要求 - 新增【实施计划】游戏买断制泥点付费与播放鉴权-2026-10-05.md:修改边界、实现顺序、验证命令与回滚点 - docs/README.md 登记新合同、里程碑与实施计划入口 --- docs/README.md | 1 + ...划】游戏买断制泥点付费与播放鉴权-2026-10-05.md | 48 ++++++++++ ...¢‘】游戏买断制泥点付费与播放鉴权-2026-10-05.md | 52 ++++++++++ ...�玩法创作】平台入口与玩法链路-2026-05-15.md | 95 ++++++++++++++++++- 4 files changed, 195 insertions(+), 1 deletion(-) create mode 100644 docs/project-memory/plans/【实施计划】游戏买断制泥点付费与播放鉴权-2026-10-05.md create mode 100644 docs/project-memory/plans/【里程碑】游戏买断制泥点付费与播放鉴权-2026-10-05.md diff --git a/docs/README.md b/docs/README.md index 65d144aa8..d91dda5a0 100644 --- a/docs/README.md +++ b/docs/README.md @@ -24,6 +24,7 @@ - [后台游戏评价管理合同](./【玩法创作】平台入口与玩法链路-2026-05-15.md#后台游戏评价管理合同):查找、分页、隐藏/恢复/删除、必填原因、统计与个人状态联动;已实现并通过本地验证,待用户验收,未部署。 - [后台游戏评价管理里程碑](./project-memory/plans/【里程碑】后台游戏评价管理-2026-10-01.md)与[实施计划](./project-memory/plans/【实施计划】后台游戏评价管理-2026-10-01.md):单里程碑范围、接口/schema 边界及验收要求;本地证据已回写主规范。 - [游戏广场评分展示合同](./【玩法创作】平台入口与玩法链路-2026-05-15.md#游戏广场评分展示合同)、[里程碑](./project-memory/plans/【里程碑】游戏广场评分展示-2026-10-01.md)与[实施计划](./project-memory/plans/【实施计划】游戏广场评分展示-2026-10-01.md):已实现并通过本地定向验证,待用户验收,未部署;公开列表/详情携带真实摘要,卡片显示一位小数均分与人数,复用有效评价统计。 +- [游戏买断制泥点付费与播放鉴权合同](./【玩法创作】平台入口与玩法链路-2026-05-15.md#游戏买断制泥点付费与播放鉴权合同)、[里程碑](./project-memory/plans/【里程碑】游戏买断制泥点付费与播放鉴权-2026-10-05.md)与[实施计划](./project-memory/plans/【实施计划】游戏买断制泥点付费与播放鉴权-2026-10-05.md):proposed;作者可选买断制泥点付费,购买后永久可玩,后台审核可见价格且审核员不限次试用;未实现。 - [游戏游玩次数计数](./adr/【ADR】游戏游玩次数计数-2026-10-03.md):点「开始游戏」前端上报一次游玩,api-server 纯内存聚合(5s flush、30min 去重、`IP+game` 限流、关停不强制 flush),批量 procedure 自增现有 `game_distribution_game.play_count`,不 bump `updated_at`。 - [外部 OpenAPI 与 API Key 接入方案](./【后端架构】外部OpenAPI与APIKey接入方案-2026-06-19.md) - [外部 MCP 语义工具说明与参数设计](./technical/【技术方案】外部MCP语义工具说明与参数设计-2026-09-23.md):15 个新增语义工具与全部原工具并存,复用现有 External API;包含工具说明、action、参数、幂等和兼容合同。 diff --git a/docs/project-memory/plans/【实施计划】游戏买断制泥点付费与播放鉴权-2026-10-05.md b/docs/project-memory/plans/【实施计划】游戏买断制泥点付费与播放鉴权-2026-10-05.md new file mode 100644 index 000000000..9e8c77922 --- /dev/null +++ b/docs/project-memory/plans/【实施计划】游戏买断制泥点付费与播放鉴权-2026-10-05.md @@ -0,0 +1,48 @@ +# 【实施计划】游戏买断制泥点付费与播放鉴权 + +| 字段 | 值 | +| --- | --- | +| Milestone | `docs/project-memory/plans/【里程碑】游戏买断制泥点付费与播放鉴权-2026-10-05.md` | +| Status | ready | +| Owner | Genarrative Agent | + +## 修改边界 + +- 允许修改: + - `server-rs/crates/module-game-distribution`:定价、购买与播放授权的领域规则与纯内存测试。 + - `server-rs/crates/module-runtime`:新增 `game_purchase` 流水来源类型。 + - `server-rs/crates/spacetime-module`:游戏表价格字段、购买表、相关 procedure、`migration.rs`。 + - `server-rs/crates/spacetime-client`:facade 与 row mapper。 + - `server-rs/crates/api-server`:创建/更新版本接受价格、购买接口、播放会话接口、公开详情与发行网关鉴权、admin 展示。 + - `server-rs/crates/shared-contracts`、`packages/shared`:价格、购买态、购买与播放会话 DTO 及钱包文案。 + - 主站 `src/components/game-distribution`、`src/services/gameDistributionClient.ts` 与发布/详情/游玩/广场相关组件。 + - `apps/admin-web`:审核详情与待审列表价格展示。 + - 文档、后端表目录、生成绑定与定向测试。 +- 明确不修改:`/api/external/v1` 及其 OpenAPI;AGC 发布面板;评分/评价;免费游戏公开链路行为。 + +## 实现顺序 + +1. 主规范与里程碑评审确认;主规范已解除“不做交易”排除并新增合同章。 +2. 领域与 schema:游戏表末尾追加 `price_mud_points`;新增 `game_distribution_purchase`;`module-game-distribution` 定价/购买/授权规则与纯内存测试;同步 `migration.rs`、表目录、生成绑定并运行 schema 检查。 +3. 钱包:`RuntimeProfileWalletLedgerSourceType` 追加 `game_purchase`;购买时原子扣费并写流水;同步 Rust/TS 契约与前端/后台文案。 +4. API 与鉴权:创建/更新版本接受并校验价格;购买接口(`Idempotency-Key` + `(user_id, game_id)` 唯一);播放会话接口;公开详情返回价格与购买态并按需隐藏入口;发行网关对付费游戏拒绝公开路径;admin 详情与列表展示价格。 +5. 前端:发布页定价字段与校验;详情页价格与购买(复用泥点确认弹窗与钱包 store);游玩页经播放会话挂载 iframe;广场角标(可选)。 +6. 后台:审核详情与待审列表价格展示。 +7. 回写主规范、产出真实栈 smoke 与验收证据矩阵,删除本实施计划。 + +## 验证命令 + +1. `cargo test -p module-game-distribution` +2. `cargo test -p api-server game_distribution` +3. `npm run spacetime:generate && npm run check:spacetime-schema` +4. `npm run typecheck` +5. 定向 `npx vitest run src/components/game-distribution` 与 `apps/admin-web` 相关用例 +6. `npm run check:encoding`、`git diff --check` +7. 真实本地栈 smoke(见里程碑“证据要求”) + +## 风险与回滚点 + +- schema:游戏表只末尾追加带默认值字段,购买为新独立表;如迁移不可用,回滚点是不开放定价选项,保留领域与接口的非持久化部分。 +- 付费鉴权:播放会话未就绪时,回滚点是付费游戏只做“购买态 + 平台页隐藏入口”,但不得对外宣称已具备防绕过能力。 +- 钱包:扣费与购买记录必须同事务;无法原子时回滚到不开放购买,只保留价格展示。 +- 免费链路:若改动影响免费游戏,优先回滚该分支,保证免费回归为绿。 diff --git a/docs/project-memory/plans/【里程碑】游戏买断制泥点付费与播放鉴权-2026-10-05.md b/docs/project-memory/plans/【里程碑】游戏买断制泥点付费与播放鉴权-2026-10-05.md new file mode 100644 index 000000000..506c2ec93 --- /dev/null +++ b/docs/project-memory/plans/【里程碑】游戏买断制泥点付费与播放鉴权-2026-10-05.md @@ -0,0 +1,52 @@ +# 【里程碑】游戏买断制泥点付费与播放鉴权 + +| 字段 | 值 | +| --- | --- | +| Version | 1.0 | +| Status | proposed | +| Date | 2026-10-05 | +| Parent Spec | `docs/【玩法创作】平台入口与玩法链路-2026-05-15.md`(「游戏买断制泥点付费与播放鉴权合同」章) | + +## 目标 + +把游戏分发从“公开即免费可玩”扩展为“作者可选买断制泥点付费;其他用户购买后永久可玩;后台审核可见价格且审核员不限次试玩”。 + +## 范围 + +- 作者端定价:网页 `/games/publish` 新建与更新模式选择“免费 / 买断制 N 泥点”。 +- 玩家端:公开详情展示价格与购买态、泥点购买、购买后游玩。 +- 付费游玩鉴权:未购买不得游玩,直连公开发行路径必须失败。 +- 泥点钱包扣费与 `game_purchase` 流水。 +- 后台审核详情与待审列表展示价格。 + +## 不在范围内 + +- AGC 发布面板的定价入口(后续切片,不与本里程碑同批验收)。 +- 创作者分成与结算、退款/撤销购买、促销/限时免费、订阅或游戏内购、价格运营审批流。 +- 评分/评论与付费的耦合、外部 OpenAPI。 +- 免费游戏现有链路的任何行为变化。 + +## 依赖与前置条件 + +- 现有游戏分发状态机、审核 CAS/幂等与版本冻结资料机制。 +- runtime profile 钱包的原子写与 `profile_wallet_ledger` 流水。 +- 现有发行网关 sandbox/CSP/Cookie 约束,以及后台待审版本预览会话(token 前缀承载相对资源)模式。 +- 主规范“游戏买断制泥点付费与播放鉴权合同”与本文档评审通过。评审前不写业务代码。 + +## 验收标准 + +- [ ] 作者网页发布可选「免费」或「买断制 N 泥点」;负数/超上限/非整数被前后端同时拦截。 +- [ ] 后台审核详情展示该版本价格;无价格的历史版本按免费展示。 +- [ ] 审核员不限次数试玩待审付费版本,不校验购买、不扣泥点。 +- [ ] 未购买用户详情可见资料但无可播放入口;直连 `/games//` 返回 404。 +- [ ] 余额不足购买失败,余额、账单与购买记录都不变。 +- [ ] 购买成功:余额减少 N、账单出现 `game_purchase` 流水、购买记录唯一、可反复游玩不再扣费。 +- [ ] 双击、并发与响应丢失重试只扣一次。 +- [ ] 作者本人与管理员免购买即可游玩付费作品且不扣费。 +- [ ] 免费游戏的发布、详情、游玩与计数链路无行为变化。 + +## 证据要求 + +- 自动化:Rust 定向测试(定价校验、购买幂等与并发、授权判定、状态机)、Vitest(发布表单定价、详情购买态、游玩页会话挂载、审核价格展示)、schema/绑定与编码门禁。 +- 运行时:真实本地栈跑通「发布付费游戏 → 后台审核可见价格并试玩 → 通过 → 未购买访问失败 → 购买 → 游玩 → 重复游玩不扣费」。 +- 边界:并发购买、余额不足、下架/封禁后播放会话失效、猜测 URL 直连、免费游戏回归。 diff --git a/docs/【玩法创作】平台入口与玩法链路-2026-05-15.md b/docs/【玩法创作】平台入口与玩法链路-2026-05-15.md index bac2dd9bc..ff27cc0dd 100644 --- a/docs/【玩法创作】平台入口与玩法链路-2026-05-15.md +++ b/docs/【玩法创作】平台入口与玩法链路-2026-05-15.md @@ -64,7 +64,7 @@ 交付“AGC 一键提交游戏 / 网页上传游戏 ZIP → 后端收取真实发行包 → 校验与人工审核 → 主站发现、详情、游客在线游玩 → 更新与下架”的完整闭环。验收必须使用真实上传、真实存储、真实审核状态和隔离发行域名;静态演示卡片、metadata-only 请求或前端本地发布状态不能作为完成证据。 -首版支持可以离线运行的静态 Web 游戏:HTML、JavaScript、CSS、JSON 与图片、字体、音视频。AGC 首先支持现有 npm/Vite Web 工程;网页入口允许上传符合相同包合同的 ZIP,不以游戏引擎名称限制普通静态产物。Godot/Cocos 工程源码、原生可执行文件、Wasm、服务端进程、外部 API、多人联机、云存档和跨版本存档迁移不在首版内。本发行合同 Version 0.2 不包含用户评分与评论,其扩展范围见下文“网站游戏评分与评价合同”;关注、榜单、推荐算法、交易和创作者收入仍不在范围内。 +首版支持可以离线运行的静态 Web 游戏:HTML、JavaScript、CSS、JSON 与图片、字体、音视频。AGC 首先支持现有 npm/Vite Web 工程;网页入口允许上传符合相同包合同的 ZIP,不以游戏引擎名称限制普通静态产物。Godot/Cocos 工程源码、原生可执行文件、Wasm、服务端进程、外部 API、多人联机、云存档和跨版本存档迁移不在首版内。本发行合同 Version 0.2 不包含用户评分与评论,其扩展范围见下文“网站游戏评分与评价合同”;买断制泥点付费与付费游玩鉴权见下文“游戏买断制泥点付费与播放鉴权合同”。关注、榜单、推荐算法、创作者收入与结算仍不在范围内。 ### 入口与产品体验 @@ -550,3 +550,96 @@ - 管理员权限继续复用现有游戏审核权限映射,还是单独增加 `game-review-preview` 动作权限;第一里程碑默认复用现有审核权限,不扩大权限模型。 - 预览 Token 的单次 HTML 读取与同包静态资源多次读取需要统一 TTL 和失效规则;第一里程碑使用短 TTL 的版本绑定会话。 + +## 游戏买断制泥点付费与播放鉴权合同 + +| 字段 | 值 | +| --- | --- | +| Version | 1.0 | +| Status | proposed | +| Date | 2026-10-05 | +| 适用边界 | 主站游戏分发(`/games`)的作者买断制定价、泥点购买、付费游玩鉴权与后台审核价格展示;不含创作者结算 | +| 里程碑 | [游戏买断制泥点付费与播放鉴权](./project-memory/plans/【里程碑】游戏买断制泥点付费与播放鉴权-2026-10-05.md) | +| 实施计划 | [实施计划](./project-memory/plans/【实施计划】游戏买断制泥点付费与播放鉴权-2026-10-05.md) | + +### 目标 + +- 作者发布游戏时可选择“免费”或“买断制 N 泥点”;付费作品对其他用户在完成购买前不可游玩。 +- 买断制:购买一次永久拥有,重复进入不再扣费;换设备、重新登录或更新版本都不清除所有权。 +- 后台审核详情展示该版本价格;审核员试玩待审版本不受购买限制、不限次数、不扣泥点。 + +### 非目标 + +- 不做创作者分成与结算、退款与撤销购买、促销/限时免费、订阅或游戏内购、价格运营审批流。 +- 不扩展 `/api/external/v1` 及其 OpenAPI。 +- 不新建第二套账号、钱包或发行通道;泥点沿用 runtime profile 域。 + +### 入口与边界 + +- 作者入口:网页 `/games/publish`(新建与更新模式)。AGC 发布面板的定价入口列为后续切片,不与网页同批验收。 +- 玩家入口:`/games`、`/games/detail`、`/games/play`。 +- 审核入口:后台 `#game-distribution` 审核页(详情与待审列表)。 +- 正式状态来源:SpacetimeDB 的游戏价格、购买记录与钱包余额/流水;前端只负责表现与请求编排。 + +### 必须成立的行为 + +#### 定价与冻结 + +- 价格是版本冻结资料的一部分:作者提交新版本时携带价格,与封面/截图一样在审核通过时整体生效到游戏行;未通过审核的价格不改变当前公开价格。 +- 价格是整数泥点数,`0` 表示免费,取值域由服务端约束(上限待评审,初值 `1_000_000`);免费与付费共用同一条发布与审核链路。 +- 展示资料编辑(`PATCH /my-games/{gameId}`)不得直接变更公开价格;调整价格必须走新版本审核。 + +#### 购买与所有权 + +- `price_mud_points = 0` 的游戏对所有人免费可玩,行为与现状一致。 +- 付费游戏对未购买用户:详情可见资料与价格,但不返回可播放入口。 +- 每账号每游戏最多一条购买记录;重复购买幂等返回既有记录且不再扣费。 +- 购扣泥点必须与购买记录写入处于同一原子事务:不允许“扣了没记录”或“记录了没扣”。 +- 余额不足时明确失败,不变更余额、不写购买记录。 +- 作者本人与管理员免购买即可游玩付费作品,且不扣费。 + +#### 播放鉴权 + +- 付费游戏的发行入口不经公开同源路径对外开放;未购买者直接访问 `/games//` 必须失败(404),不能靠猜测 `gameId` 绕过。 +- 允许游玩时由服务端签发绑定“`gameId` + 用户 + 短时效”的播放会话,游戏入口与包内资源经会话前缀读取;会话过期、游戏下架/封禁或目标版本失效后不可继续播放。 +- 播放会话沿用现有发行沙箱与网关约束:`sandbox="allow-scripts"` 不透明来源、拒绝真实平台 Cookie、CSP/MIME/`nosniff`/CORP 与运行期 storage 兼容层不变;会话响应按现有发行缓存口径(≤60s)或 `no-store`。 +- 免费游戏继续使用现有 `/games//` 公开入口,播放鉴权不得改变免费链路。 +- 游玩计数只在真正进入游戏后上报;未购买或被拒绝的访问不计数。 + +#### 后台审核 + +- 审核详情必须展示该版本价格(“免费”或“N 泥点”);无价格的历史版本按免费口径展示。 +- 审核员试玩待审版本维持现有预览会话语义:不校验购买、不扣泥点、不限次数。 +- 审核通过后公开价格随版本生效;拒绝不影响当前公开价格。 + +#### 失败、重试与幂等 + +- 购买请求携带 `Idempotency-Key`:同 key 同请求返回原结果,同 key 不同请求返回冲突。 +- 并发或重复点击只产生一条购买记录、只扣一次。 +- 服务端不可用时购买失败关闭,不出现“未扣费却已解锁”或“已扣费却未解锁”的中间态。 + +### 契约与迁移 + +- SpacetimeDB:`game_distribution_game` 末尾追加 `price_mud_points: u64`(明确默认 0);新增私有 `game_distribution_purchase`(`purchase_id` 主键,含 `game_id`、`user_id`、成交价快照、钱包流水 ID 与创建时间,`(user_id, game_id)` 唯一);同步 `migration.rs`、后端表目录与生成绑定,并运行 `npm run check:spacetime-schema`。 +- 泥点流水新增来源类型 `game_purchase`(`RuntimeProfileWalletLedgerSourceType`),同步 Rust `shared-contracts`、`packages/shared`、前端与后台文案。 +- 游戏 DTO 增加 `priceMudPoints` 与购买态;新增购买与播放会话 DTO。免费游戏必须能忽略这些新字段而不改变行为。 +- 不修改已有表字段的类型或顺序;新增字段一律末尾追加并带明确默认值。 + +### 验收标准与证据 + +| 条款 | 验收方式 | 证据 | +| --- | --- | --- | +| 定价 | 网页发布可选「免费/买断制」并拦截非法值,前后端口径一致 | 待补 | +| 后台可见 | 审核详情与待审列表显示该版本价格 | 待补 | +| 审核试玩 | 审核员不限次试玩待审付费版本,不校验购买、不扣泥点 | 待补 | +| 购买 | 余额不足失败且不变更;成功扣 N、账单出现 `game_purchase` 流水、购买记录唯一 | 待补 | +| 幂等 | 双击、并发、响应丢失重试只扣一次 | 待补 | +| 播放鉴权 | 未购买直连公开入口 404;购买后可反复游玩且不再扣费 | 待补 | +| 免购买游玩 | 作者与管理员可游玩付费作品且不扣费 | 待补 | +| 免费回归 | 免费游戏发布/详情/游玩/计数无行为变化 | 待补 | +| 工程门禁 | schema/绑定、两端类型、定向测试、编码与 diff 检查通过 | 待补 | + +### 待评审决策 + +1. 价格上限取值,以及是否允许作者在作品已公开后通过新版本随意调价(对已购买用户不再收费的口径已确定)。 +2. “免购买游玩”的判定范围:仅限作者本人与现有管理员身份,还是需要单独运营角色。