Refine play type integration flow and docs

This commit is contained in:
2026-06-03 00:57:24 +08:00
parent dbe4c902b4
commit 67ba40c678
35 changed files with 2226 additions and 619 deletions

View File

@@ -23,6 +23,7 @@
- 影响范围:`src/services/payment/paymentPlatform.ts``src/components/rpg-entry/RpgEntryHomeView.tsx``miniprogram/pages/wechat-pay/``server-rs/crates/api-server/src/runtime_profile.rs``server-rs/crates/shared-contracts/src/runtime.rs``packages/shared/src/contracts/runtime.ts`、微信登录态存储。
- 验证方式:泥点和会员商品在小程序运行态都请求 `wechat_mp_virtual`;小程序页能按 payload 调用 `wx.requestVirtualPayment` / `wx.requestPayment``cargo check -p api-server --manifest-path server-rs/Cargo.toml` 与支付相关前端测试通过。
- 关联文档:`docs/【技术方案】微信虚拟支付接入-2026-05-26.md`
## 2026-05-30 Linux 本地 dev 端口段按系统级注册表分配
- 背景:同一台 Linux 开发机上有多个用户同时跑 `npm run dev` 时,单纯靠各自 `GENARRATIVE_DEV_PORT_RANGE` 容易撞段,且同一用户并发起两个 dev 会话时也会把相同端口段重复拿走。
@@ -104,6 +105,7 @@
- 影响范围:`src/components/rpg-entry/RpgEntryHomeView.tsx``src/components/rpg-entry/RpgEntryHomeView.recharge.test.tsx``docs/【项目基线】当前产品与工程约束-2026-05-15.md`
- 验证方式:`npm run test -- src/components/rpg-entry/RpgEntryHomeView.recharge.test.tsx` 应断言任务卡显示 `1 / 1`、领取后显示已完成,且新用户账号也没有 `次级入口` / `填邀请码` 常驻按钮;`npm run typecheck``npm run check:encoding` 通过。
- 关联文档:`docs/【项目基线】当前产品与工程约束-2026-05-15.md`
## 2026-05-26 生成页总进度圆弧逆时针回调 5 度
- 背景:创作生成页的总进度圆弧在 `160deg` 位置仍需轻微向左微调,用户要求向左逆时针回调 `5deg`
@@ -213,11 +215,19 @@
## 2026-05-23 拼图生成页按后端真实进度推进阶段
- 背景:拼图生成页原先会按本地耗时自动推进步骤,容易在后端真实生成尚未完成时跳到后续阶段,导致页面状态和会话进度脱节。
- 决策:拼图生成页的跨步骤推进只认后端会话 `progressPercent` 的真实里程碑,当前步骤内部再用本地耗时假进度平滑展示;总进度初始必须为 `0%`,之后按 `0-88``88-94``94-96``96-98` 的真实里程碑区间平滑推进。只要当前步骤生成内容未完成,就必须停留在当前步骤。页面只展示当前步骤标题和进度,不展示步骤详细描述。`生成拼图首图` 单独按 4 分钟估算,完整 AI 重绘路径约 448 秒;上传图且关闭 AI 重绘路径跳过首图生成,仍约 208 秒。
- 决策:拼图生成页的跨步骤推进只认后端会话 `progressPercent` 的真实里程碑,当前步骤内部再用本地耗时假进度平滑展示;`88/94/96` 只切换当前步骤,不直接作为总进度地板。总进度按已完成步骤权重加当前步骤内假进度推导,非完成态最多停在 `98%`。恢复持久化生成中草稿时,展示态 `startedAtMs` 使用后端 session `updatedAt` 或作品摘要 `updatedAt`,保证已耗时不因重新进入页面清零。只要当前步骤生成内容未完成,就必须停留在当前步骤。页面只展示当前步骤标题和进度,不展示步骤详细描述。`生成拼图首图` 单独按 4 分钟估算,完整 AI 重绘路径约 448 秒;上传图且关闭 AI 重绘路径跳过首图生成,仍约 208 秒。
- 影响范围:`src/services/miniGameDraftGenerationProgress.ts``src/components/platform-entry/PlatformEntryFlowShellImpl.tsx``src/components/CustomWorldGenerationView.tsx`、拼图生成页相关测试与玩法链路文档。
- 验证方式:拼图生成页恢复、轮询和测试都应以 `puzzleProgressPercent` 驱动阶段推进;`npm run test -- src/services/miniGameDraftGenerationProgress.test.ts src/components/CustomWorldGenerationView.test.tsx``npm run typecheck``npm run check:encoding` 通过。
- 关联文档:`docs/【玩法创作】拼图生成页进度口径-2026-05-23.md``docs/【玩法创作】平台入口与玩法链路-2026-05-15.md`
## 2026-06-02 生成失败草稿必须留在作品架并覆盖生成中摘要
- 背景:生成页收到失败回包后会进入重试态,但返回草稿 Tab 时,后端作品摘要可能仍短暂保持 `generationStatus=generating`,导致用户看到“生成中”;连续触发多个拼图生成时,失败后如果清掉 pending 条目,还会少显示新增草稿。后台失败如果只写局部生成页错误,用户离开生成页后也收不到通知。
- 决策:平台壳在生成失败时必须同时标记草稿 notice 和 pending 作品架条目为 `failed`,不得删除 pending 条目。失败 notice 要保存错误消息并在用户离开生成页后触发带来源的 `PlatformErrorDialog`;作品架本地失败 notice 要覆盖持久化生成中摘要,失败草稿仍显示为草稿卡但不显示“生成中”。点击失败草稿必须优先恢复失败 / 重试页,不能按持久化 `generating` 重新启动生成;拼图契约已允许 `generationStatus=failed`pending 拼图和后端失败回写都按 session 独立落失败态,跳一跳 / 木鱼 / 抓大鹅等也直接映射为 `failed` 或对应失败态。
- 影响范围:`src/components/platform-entry/PlatformEntryFlowShellImpl.tsx``src/components/custom-world-home/creationWorkShelf.ts``src/components/custom-world-home/CustomWorldCreationHub.tsx`、玩法链路文档和失败态交互测试。
- 验证方式:`node node_modules/vitest/vitest.mjs run src/components/rpg-entry/RpgEntryFlowShell.agent.interaction.test.tsx -t "failed parallel puzzle|background match3d"`;失败后返回草稿 Tab 应看到对应新增草稿,且没有“生成中”标记;后台失败应弹出错误来源,点击失败草稿应进入失败 / 重试页。
- 关联文档:`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md``.hermes/shared-memory/pitfalls.md`
## 2026-05-23 所有玩法生成页统一圆环主视觉
- 背景:多个玩法生成页分别展示横向总进度条、步骤列表或三槽位列表,和最新参考图里的陶泥儿圆环等待态不一致,也让移动端信息密度偏高。
@@ -333,7 +343,6 @@
- 验证方式:执行 `cargo test -p api-server match3d --manifest-path server-rs\Cargo.toml``npm run test -- src/components/match3d-result/Match3DResultView.test.tsx src/components/match3d-runtime/Match3DRuntimeShell.test.tsx src/services/match3dSpritesheetParser.test.ts src/services/match3dGeneratedModelCache.test.ts``npm run typecheck``npm run check:encoding`
- 关联文档:`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md`
## 2026-05-18 Rust 手写模块入口统一不用 mod.rs
- 背景Rust 目录模块同时存在 `mod.rs` 与同名 `.rs` 两种入口形式,前次拆分已让 `spacetime-client/src/mapper.rs` 采用同名入口;继续新增 `mod.rs` 会让文件定位和评审口径不一致。
@@ -572,7 +581,7 @@
- 验证方式:草稿页作品卡与分类页列表视觉口径保持一致;`npm run test -- src/components/custom-world-home/CustomWorldCreationHub.test.tsx src/components/custom-world-home/CustomWorldCreationHub.interaction.test.tsx``npm run typecheck``npm run check:encoding`
- 关联文档:`docs/design/MOBILE_CREATION_WORK_LIST_TWO_COLUMN_LAYOUT_2026-04-29.md``docs/experience/MOBILE_UI_DEV_EXPERIENCE.md`
2026-05-14 补充:草稿页作品卡不再用“草稿 / 已发布”文字标识状态,改为图标化 UI 状态点;作品封面直接铺到卡片右半区并从右向左渐隐;已发布作品右上角常驻分享图标;草稿长按弹出删除面板,已发布长按弹出分享和删除面板。
2026-05-14 补充:草稿页作品卡不再用“草稿 / 已发布”文字标识状态,改为图标化 UI 状态点;作品封面直接铺到卡片右半区并从右向左渐隐;已发布作品右上角常驻分享图标;草稿长按弹出删除面板,已发布长按弹出分享和删除面板。2026-06-02 追加:作品卡片右上角不再放删除按钮;删除只通过左滑、键盘展开或长按 / 右键展开的右侧操作区出现,避免与卡片主点击和分享入口抢占标题区。
## 2026-05-13 认证运行期同步直接导入正式认证表
@@ -759,6 +768,7 @@
- 验证方式:执行 `npx vitest run src/services/useMocapInput.test.ts src/components/child-motion-demo/ChildMotionWarmupDemo.test.tsx src/components/child-motion-demo/childMotionWarmupModel.test.ts src/services/child-motion-demo/childMotionDebugInput.test.ts src/routing/appRoutes.test.ts``npx eslint ...``npm run typecheck``npm run check:encoding`,并确认 `http://127.0.0.1:8876/stream` WebSocket 可握手、`http://127.0.0.1:3000/child-motion-demo` 可访问。
## 2026-05-18 寓教于乐频道补充热身关入口
- 背景:用户希望在发现页的寓教于乐板块里直接看到热身关入口,而不是只依赖独立直达路由。
- 决策:`child-motion-demo` 作为寓教于乐频道的独立卡片展示,点击后直接进入 `/child-motion-demo`;该入口与 `宝贝爱画` 并列,仍复用现有独立热身关路由,不新增新的创作模板或运行态壳层。
- 影响范围:`src/components/rpg-entry/RpgEntryHomeView.tsx``src/components/platform-entry/PlatformEntryFlowShellImpl.tsx``src/components/rpg-entry/RpgEntryHomeView.recharge.test.tsx``docs/【玩法创作】平台入口与玩法链路-2026-05-15.md`
@@ -1171,13 +1181,14 @@
- 影响范围:`module-auth``api-server` 作品作者解析、`AppState` 启动初始化、历史孤儿作品离线回填脚本与相关文档。
- 验证方式:`cargo test -p module-auth --manifest-path server-rs/Cargo.toml``cargo test -p api-server --manifest-path server-rs/Cargo.toml work_author``npm run test -- scripts/rebind-orphan-work-owners.test.ts`
- 关联文档:`server-rs/crates/module-auth/src/domain.rs``server-rs/crates/module-auth/src/lib.rs``server-rs/crates/api-server/src/work_author.rs``scripts/rebind-orphan-work-owners.mjs`
## 2026-05-26 敲木鱼发布后作品架与推荐流刷新口径
- 背景:敲木鱼已具备公开广场投影,但草稿 Tab 的作品架没有当前用户作品列表接口,导致已发布作品在发布后不能立即出现在“已发布”筛选和推荐流里。
- 决策:新增 `GET /api/creation/wooden-fish/works` 作为当前用户木鱼作品架事实源,返回 `WoodenFishWorksResponse.items` 摘要;平台壳在发布成功后必须同时刷新作品架和公开广场列表。
- 影响范围:`server-rs/crates/api-server/src/wooden_fish.rs``server-rs/crates/api-server/src/modules/wooden_fish.rs``src/services/wooden-fish/woodenFishClient.ts``src/components/custom-world-home/creationWorkShelf.ts``src/components/platform-entry/PlatformEntryFlowShellImpl.tsx`
- 验证方式:发布一个木鱼作品后,草稿 Tab 的已发布筛选应立刻出现 `WF-*` 作品卡,推荐 / 最新流也应立即刷新出公开卡片。
- 关联文档:`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md``docs/prd/【玩法创作】敲木鱼玩法模板PRD-2026-05-20.md`
- 关联文档:`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md``docs/prd/【玩法创作】敲木鱼玩法模板PRD-2026-05-20.md`
## 2026-05-27 认证快照完全去文件化并仅保留行级备查

View File

@@ -158,7 +158,6 @@
- 验证:`PlatformEntryFlowShellImpl.tsx` 中不应再出现四个旧工作台的入口渲染分支,创作 Tab 与 `/creation/<play>` 仍能正常进入对应工作台。
- 关联:`src/components/unified-creation/UnifiedCreationWorkspace.tsx``src/components/platform-entry/PlatformEntryFlowShellImpl.tsx``docs/【玩法创作】平台入口与玩法链路-2026-05-15.md`
## Jenkinsfile 开头不能带 UTF-8 BOM
- 现象:`Genarrative-Stdb-Module-Publish``Pipeline script from SCM` 读取 `jenkins/Jenkinsfile.production-stdb-module-publish` 后,流水线还未进入任何 stage 就失败,报 `java.lang.NoSuchMethodError: No such DSL method 'pipeline'`,堆栈位置是 `WorkflowScript.run(WorkflowScript:1)`
@@ -362,7 +361,6 @@
- 验证:`tr '\0' '\n' < /proc/$(systemctl show genarrative-api.service -p MainPID --value)/environ | grep GENARRATIVE_TRACKING_OUTBOX_DIR` 应指向 `/var/lib/genarrative/tracking-outbox`;重启后当前 PID 不再出现 `Permission denied (os error 13)`
- 关联:`scripts/deploy/production-api-deploy.sh``scripts/jenkins-server-provision.sh``docs/【开发运维】本地开发验证与生产运维-2026-05-15.md`
## 外部 API 失败没法追溯先查 external_api_call_failure
- 现象VectorEngine 图片生成 / 编辑接口对前端只表现为 `502` / `504` 或“上游服务请求失败”,但难以区分是请求发送失败、上游 429/5xx、响应解析失败、未返回图片还是下载图片失败。
@@ -562,10 +560,18 @@
- 现象:用户通过“忘记密码”重设密码后,接口返回成功或页面进入登录态,但再次使用新密码登录仍提示“手机号或密码错误”;重启后还可能出现 `Bearer JWT 版本已失效`,日志里的 token version 与本地快照不一致。
- 原因:重置/修改密码会更新 `password_hash``password_login_enabled``token_version`,如果 API 层只更新本地 `InMemoryAuthStore`,没有调用 `sync_auth_store_snapshot_to_spacetime()``api-server` 重启时可能从旧的 SpacetimeDB 表或旧快照恢复账号状态。
- 处理:`POST /api/auth/password/change``POST /api/auth/password/reset` 成功后必须同步认证快照。2026-05-27 起,启动恢复只允许从 SpacetimeDB 正式认证表恢复;`auth_store_snapshot` 只保留行级记录,不再写 `default` 聚合单行,也不再把本地文件 `auth-store.json` / `GENARRATIVE_AUTH_STORE_PATH` 当作恢复源。若启动时连不上 SpacetimeDB`api-server` 等待启动恢复超时后进入依赖不可用模式,所有请求返回 `503 SERVICE_UNAVAILABLE``details.reason = "spacetime_startup_unavailable"`
- 处理:`POST /api/auth/password/change``POST /api/auth/password/reset` 成功后必须同步认证快照。2026-05-27 起,启动恢复只允许从 SpacetimeDB 正式认证表恢复;`auth_store_snapshot` 只保留行级记录,不再写 `default` 聚合单行,也不再把本地文件 `auth-store.json` / `GENARRATIVE_AUTH_STORE_PATH` 当作恢复源。认证创建、登录会话、刷新、退出、改密、重置密码、绑定和资料变更等写操作必须在返回客户端前成功同步 SpacetimeDB同步失败时接口返回错误不允许把只存在于当前进程内存的账号或会话当成成功结果。新用户注册奖励、邀请码绑定和登录埋点必须排在认证同步成功之后避免认证没落库时先写出钱包或邀请关系。若启动时连不上 SpacetimeDB`api-server` 等待启动恢复超时后进入依赖不可用模式,所有请求返回 `503 SERVICE_UNAVAILABLE``details.reason = "spacetime_startup_unavailable"`
- 验证:执行 `cargo test -p module-auth password --manifest-path server-rs/Cargo.toml``cargo test -p api-server password --manifest-path server-rs/Cargo.toml`;手测时重设密码后旧密码应失败,新密码应成功,重启后仍应保持。
- 关联:`server-rs/crates/api-server/src/password_management.rs``server-rs/crates/api-server/src/state.rs``docs/technical/PASSWORD_LOGIN_CHANGE_RESET_DESIGN_2026-04-24.md`
## 密码登录失败且短信登录提示手机号已存在先查孤儿手机号索引
- 现象:老账号用密码登录提示“手机号或密码错误”,改用短信验证码登录又提示“手机号已存在 / 已注册”,用户卡在既不能登录也不能重新创建的状态。
- 原因:历史版本或停服务时认证同步不完整,可能在 SpacetimeDB `auth_identity(provider=phone)``module-auth` 快照里留下 `phone_to_user_id` 映射,但对应 `user_account` / `users_by_username` 用户行已经不存在。密码登录按手机号索引找不到真实用户,短信登录尝试创建新用户时又被孤儿手机号索引挡住。
- 处理:`export_auth_store_snapshot_from_tables` 导出时必须过滤没有 `user_account` 的 phone / wechat identity、union 索引和 refresh session`module-auth` 从 JSON 快照恢复时也必须二次丢弃指向不存在用户的索引。运行时创建手机号用户前若发现手机号映射指向不存在的用户,应删除孤儿映射后继续创建,避免死锁态继续扩散。
- 验证:`cargo test -p module-auth snapshot_json_drops_orphan_phone_index_before_phone_login --manifest-path server-rs/Cargo.toml``cargo test -p module-auth phone --manifest-path server-rs/Cargo.toml``cargo test -p spacetime-module auth --manifest-path server-rs/Cargo.toml``cargo test -p api-server phone_login_reuses_existing_user_for_same_phone_number --manifest-path server-rs/Cargo.toml`
- 关联:`server-rs/crates/module-auth/src/lib.rs``server-rs/crates/spacetime-module/src/auth/procedures.rs``docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md`
## 认证本地文件快照已废弃,旧 procedure 也已删
- 现象:有些旧代码和生成 bindings 里还会残留 `get_auth_store_snapshot``upsert_auth_store_snapshot``import_auth_store_snapshot`,或者把 `auth-store.json` 误当成认证恢复源。
@@ -1542,14 +1548,22 @@
- 验证:`npm run test -- src/components/rpg-entry/rpgEntryWorldPresentation.test.ts src/components/rpg-entry/RpgEntryHomeView.recharge.test.tsx``npm run typecheck``npm run check:encoding`
- 关联:`src/index.css``src/components/rpg-entry/RpgEntryHomeView.tsx``src/components/rpg-entry/rpgEntryWorldPresentation.ts``docs/【玩法创作】平台入口与玩法链路-2026-05-15.md`
## 生成中草稿刷新后不要复用旧 updatedAt 当展示起点
## 生成中草稿恢复要按后端时间戳计时
- 现象:拼图或抓大鹅草稿生成中刷新网页后,作品架卡片能显示等待遮罩,但进入生成页时总进度首帧直接跳到 80%+,看起来像已经跑了一大半
- 原因:前端只把持久化 `generationStatus=generating` 当作恢复生成页的条件,但恢复展示时仍沿用了作品摘要 `updatedAt` 作为伪 `startedAtMs`;同时拼图总进度把后端 `progressPercent` 直接当作 floor导致 `86%` 之类未到首个里程碑的会话一进页就抬到 80%+
- 处理:恢复生成中的草稿时,展示起点改用“进入生成页的当前时间”;`updatedAt` 只保留给作品架排序和摘要,不再参与生成页假进度起算。拼图总进度还要忽略 `88` 以下的后端进度 floor拼图保留后端里程碑推进抓大鹅等非拼图玩法则从 `0%` 平滑起步,避免刚进页就看到 4% / 88% / 80%+
- 验证:`npm test -- src/components/rpg-entry/RpgEntryFlowShell.agent.interaction.test.tsx -t "persisted generating"``npm run test -- src/services/miniGameDraftGenerationProgress.test.ts -t "match3d draft generation starts total progress from zero"`
- 现象:拼图或抓大鹅草稿生成中刷新网页后,进入生成页的“已耗时”从 `0 秒` 重新开始;另一类旧问题是后端 `progressPercent=88` 时总进度首帧直接跳到 `88%`
- 原因:生成页恢复曾把展示态 `startedAtMs` 重置为进入页面的当前时间,导致计时不跟随后端真实生成时刻;拼图总进度也曾把后端里程碑当作百分比地板,导致步骤刚切换就抬高总进度
- 处理:恢复生成中的草稿时,展示起点使用后端 session `updatedAt` 或作品摘要 `updatedAt``88/94/96` 只切换当前步骤,不直接作为总进度地板。总进度按已完成步骤权重加当前步骤内假进度推导,非完成态最多停在 `98%`
- 验证:`node node_modules/vitest/vitest.mjs run src/components/rpg-entry/RpgEntryFlowShell.agent.interaction.test.tsx -t "persisted generating"``node node_modules/vitest/vitest.mjs run src/services/miniGameDraftGenerationProgress.test.ts`
- 关联:`src/components/platform-entry/PlatformEntryFlowShellImpl.tsx``src/components/rpg-entry/RpgEntryFlowShell.agent.interaction.test.tsx``src/services/miniGameDraftGenerationProgress.ts``docs/【玩法创作】拼图生成页进度口径-2026-05-23.md`
## 生成失败草稿回到作品架不能继续显示生成中
- 现象:拼图生成页已经收到 VectorEngine 图片编辑失败并进入重试态,但用户返回草稿 Tab 后同一草稿仍显示“生成中”连续触发多个拼图生成时失败后还可能只剩一条新增草稿或者只看到标题为“第1关”的半成品空壳抓大鹅后台失败时也可能没有任何通知点击草稿又像重新开始生成。
- 原因:前端失败 notice 只更新生成页局部状态pending 作品架条目在失败时被清掉或被非 `generating` 状态误映射为 `ready`;后端作品摘要也可能短暂仍是 `generationStatus=generating`。如果失败消息没有写入 notice用户离开生成页后不会弹出 `PlatformErrorDialog`;如果打开草稿只看持久化 `generating`,就会绕过失败态恢复。
- 处理:失败时按 session 保留 pending 作品架条目并标记 `failed`,失败 notice 保存错误消息并触发带来源的 `PlatformErrorDialog`;拼图契约没有 `failed` 枚举pending 拼图映射为 `idle`,同时用本地失败 notice 覆盖持久化生成中状态和旧的“正在生成”摘要。点击失败草稿应优先用 notice / 后端 session / fallback payload 组装失败生成页,不能重新从 0 秒启动新进度;拼图失败半成品没有有效 `workTitle` 时,作品架标题回退为“拼图草稿”。
- 验证:`node node_modules/vitest/vitest.mjs run src/components/rpg-entry/RpgEntryFlowShell.agent.interaction.test.tsx -t "failed parallel puzzle|background match3d"`
- 关联:`src/components/platform-entry/PlatformEntryFlowShellImpl.tsx``src/components/custom-world-home/creationWorkShelf.ts``docs/【玩法创作】平台入口与玩法链路-2026-05-15.md`
## 汪汪声浪草稿试玩不要写正式 run
- 现象:如果草稿结果页试玩和发布后 runtime 共用同一写成绩路径,未发布或未确认资源的草稿试玩会污染正式单局、排行榜和作品统计。