@@ -16,10 +16,83 @@
---
## 2026-06-08 微信能力按领域收口
- 背景:微信登录、订阅消息、普通微信支付和小程序虚拟支付能力曾分散在 `api-server` 根模块、`platform-auth` 与 `platform-wechat` ,支付协议细节和业务 handler 边界不够清晰。
- 决策:`api-server` 内微信相关 HTTP/BFF 适配统一收在 `server-rs/crates/api-server/src/wechat.rs` 与 `wechat/*` ; `platform-wechat` 负责微信订阅消息、微信支付 V3、虚拟支付消息推送的协议 client、header、签名、验签、解密、mock 和 payload 解析;`api-server::wechat` 只负责 AppConfig 映射、Axum handler、用户 / 订单 / 钱包 / SSE / 错误 envelope 编排。微信 OAuth / 小程序登录 provider 暂继续在 `platform-auth` ,通过 `api-server::wechat::provider` 作为组合根 adapter 接入。
- 影响范围:`server-rs/crates/api-server/src/wechat.rs` 、`server-rs/crates/api-server/src/wechat/*` 、`server-rs/crates/platform-wechat/src/*` 、微信支付 / 订阅消息 / 小程序消息推送文档。
- 验证方式:执行 `cargo check --manifest-path server-rs/Cargo.toml -p platform-wechat` 、`cargo check --manifest-path server-rs/Cargo.toml -p api-server` 、微信相关定向测试和编码检查;新增微信协议细节优先落到 `platform-wechat` 。
- 关联文档:`docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md` 、`docs/【技术方案】微信虚拟支付接入-2026-05-26.md` 。
## 2026-06-07 推荐页运行态先封面预载再 ready 渐隐
- 背景:移动端推荐页上下切换公开作品时,如果运行态和封面资源没有明确准备边界,用户会看到未加载完成的 runtime、黑底闪动, 或切卡后反向回弹。
- 决策:推荐页拿到推荐作品列表后预加载每个作品的卡片封面、主封面和玩法兜底封面;嵌入 runtime 的启动遮罩必须复用带玩法标签和标题的作品卡面视觉, 不能再切到一层单独的纯封面图。作品切换后遮罩接手当前卡面时必须瞬时显示, 不允许从旧预览卡面再淡入到同一张卡面; runtime 统一通过 ready 门控等待 run / profile、lazy 组件和 runtime DOM 内图片资源准备完成, ready 返回 true 后再由外层露出游戏画面并只让卡面遮罩渐隐。遮罩层级必须隔离下层 runtime, 防止高 z-index HUD、canvas 或子运行态穿透到封面上; ready 前保留无说明文案的加载条 / 动效,不展示“加载中”文案。推荐 rail 切换完成后归零不能走反向过渡动画。
- 影响范围:`src/components/rpg-entry/RpgEntryHomeView.tsx` 、推荐页 runtime 生命周期、平台玩法链路文档。
- 验证方式:`npm run test -- src/components/rpg-entry/RpgEntryHomeView.recharge.test.tsx` 。
- 关联文档:`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md` 。
## 2026-06-07 登录态身份边界变更后刷新当前页
- 背景:推荐页运行态、作品架、个人数据和私有 query 都可能在页面内缓存当前身份;如果登录或退出只改 React 上下文,当前页可能继续拿旧身份的局部状态渲染。
- 决策: H5 登录态从未登录变为已登录,或从已登录变为未登录后,前端必须刷新当前页面一次,让平台壳和运行态按新身份重新初始化。普通 access token refresh、账号资料更新、主题或音量设置变化不触发整页刷新。
- 影响范围:`src/components/auth/AuthGate.tsx` 、平台入口身份初始化、项目基线文档。
- 验证方式:`npm run test -- src/components/auth/AuthGate.test.tsx` 。
- 关联文档:`docs/【项目基线】当前产品与工程约束-2026-05-15.md` 。
## 2026-06-07 多端登录以 refresh session 为粒度互不顶号
- 背景:同一账号在多端登录后,若单设备退出或请求被打到尚未见过该 session 的 api-server 进程,旧设备会被误判为登录态失效。
- 决策:普通登录只新增当前设备 refresh session, 不撤销其它 active session; `POST /api/auth/logout` 只撤销当前 refresh session, 不再提升账号级 `token_version` ; `POST /api/auth/logout-all` 、改密和重置密码继续吊销全端 session 并提升 `token_version` 。api-server 鉴权和 refresh cookie 轮换在本进程工作集未命中 session 时,先从 SpacetimeDB 正式认证表按需刷新一次工作集再复查,支持多实例和滚动重启下的新会话被所有进程识别。
- 影响范围:`module-auth` refresh session 语义、`api-server` Bearer 鉴权和 `/api/auth/refresh` 、账号安全页多端会话。
- 验证方式:`cargo test -p module-auth logout_current_session --manifest-path server-rs/Cargo.toml` 、`cargo test -p module-auth refresh_from_snapshot_json_merges_session_created_by_another_process --manifest-path server-rs/Cargo.toml` 、`cargo test -p api-server logout_current_device_keeps_other_device_session_alive --manifest-path server-rs/Cargo.toml` 。
- 关联文档:`docs/【项目基线】当前产品与工程约束-2026-05-15.md` 、`docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md` 。
## 2026-06-07 跳一跳排行榜展示名禁止泄露内部身份键
- 背景:跳一跳排行榜曾在结果页和运行态失败弹窗里直接展示 `playerId` / `user_id` ,用户可见内容暴露了内部身份键。
- 决策:`jump_hop_leaderboard_entry.player_id` 只作为 SpacetimeDB read model 的去重和 `viewerBest` 匹配字段, HTTP 契约新增并强制使用 `displayName` 作为排行榜展示字段。api-server 出口按账号 `displayName` 补齐展示名;匿名 runtime guest 固定展示“游客玩家”;账号失效或不可解析时展示“失效玩家”;前端排行榜 UI 禁止兜底展示 `playerId` / `user_id` 。
- 影响范围:`packages/shared/src/contracts/jumpHop.ts` 、`server-rs/crates/shared-contracts/src/jump_hop.rs` 、`server-rs/crates/api-server/src/jump_hop.rs` 、跳一跳结果页和运行态排行榜组件、跳一跳 PRD 与后端契约文档。
- 验证方式:`npm run test -- src/components/jump-hop-runtime/JumpHopRuntimeShell.test.tsx -t "排行榜"` 、`npm run test -- src/components/jump-hop-result/JumpHopResultView.test.tsx -t "排行榜"` 、`cargo test -p api-server jump_hop_leaderboard_display_name_never_falls_back_to_player_id --manifest-path server-rs/Cargo.toml` 。
- 关联文档:`docs/prd/【玩法创作】跳一跳俯视角玩法模板PRD-2026-05-19.md` 、`docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md` 。
## 2026-06-07 generated 图片读取坚持 OSS 源站与签名缓存链路
- 背景:生成图片如果以完整 OSS 私有 bucket URL 进入前端,浏览器会裸连 OSS 并遇到 403 或绕过现有 `/api/assets/read-url` 签名缓存;同时旧对象缺少 `Cache-Control` 时只能走 `ETag` / `Last-Modified` 协商缓存,容易被误解为需要 api-server 本地磁盘缓存。
- 决策: OSS 继续作为 generated 私有资产源站, api-server 只签发短期读 URL, 不做本地磁盘静态资源兜底。前端收到同 bucket 的 `https://*.oss-*.aliyuncs.com/generated-*` 地址时,必须先归一为 legacy public path, 再复用 `/api/assets/read-url` 和本地 signed URL 缓存。新上传 generated 私有对象默认写入 `Cache-Control: public, max-age=31536000, immutable` ,缓存职责交给 OSS 对象头、浏览器 / WebView HTTP 缓存和后续 CDN。
- 影响范围:`src/services/assetReadUrlService.ts` 、`server-rs/crates/platform-oss` 、`shared-contracts` direct upload form fields、`api-server` assets DTO 映射、后端契约文档和开发运维排障口径。
- 验证方式:完整 OSS generated URL 应触发 `/api/assets/read-url?legacyPublicPath=...` ,同一路径、同一 `refreshKey` 版本且未临近过期时复用本地 signed URL; `platform-oss` 的 `PostObject` policy / form fields 和 `PutObject` 请求头都应包含 immutable `Cache-Control` ,且 `PutObject` V4 签名的 `AdditionalHeaders` 包含该普通请求头。
- 关联文档:`docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md` 、`docs/【开发运维】本地开发验证与生产运维-2026-05-15.md` 、`server-rs/crates/platform-oss/README.md` 。
## 2026-06-06 小程序微信绑定展示使用原生昵称组件
- 背景:账号信息面板需要显示“绑定的是哪个微信号”。微信小程序登录 `jscode2session` 不返回昵称或个人微信号,但小程序提供 `input type="nickname"` 原生昵称填写 / 选择能力,可在登录前收集微信昵称用于展示。
- 决策:小程序登录页先展示原生 `input type="nickname"` ,将昵称作为 `displayName` 随 `/api/auth/wechat/miniprogram-login` 提交;若还需要绑定手机号,再随 `/api/auth/wechat/bind-phone` 一并提交。`wechatDisplayName` 只能来自微信平台 profile、历史已保存的微信身份资料或小程序原生昵称组件, 不能用系统账号显示名或“微信旅人”兜底。小程序侧拿不到昵称时, 前端使用后端下发的 `wechatAccount` ( openid / provider_uid) 尾号展示, 避免只显示裸“已绑定”。
- 影响范围:`platform-auth` 小程序登录 profile、`module-auth` 微信身份持久化、`api-server` 小程序登录 / 绑定响应、账号信息面板、项目基线和后端契约文档。
- 验证方式:`npm run test -- src/components/auth/AccountModal.test.tsx` 、`cargo test -p platform-auth --manifest-path server-rs/Cargo.toml` 、`cargo test -p module-auth --manifest-path server-rs/Cargo.toml` 、`cargo test -p api-server --manifest-path server-rs/Cargo.toml wechat_miniprogram` 、`npm run typecheck` 、`npm run check:encoding` 。
- 关联文档:`docs/【项目基线】当前产品与工程约束-2026-05-15.md` 、`docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md` 。
## 2026-06-03 拼消消收敛为单关 6x6 与 4-sheet 素材策略
- 背景:最初 4 关 / 135 次消除 / 单张大 atlas 方案生图数量和空间一致性成本过高,真实 image2 结果容易被布局提示词诱导成带文字、边框或编号的说明图,不适合运行态 1x1 切片。
- 决策:拼消消运行态收敛为单关 `6x6 / 35 次消除 / 600 秒` ,直接解锁 `1x2` 、`1x3` 、`2x2` 、`2x3` ;素材生成改为 4 张 `1024x1536` 竖版 sheet, 每张按 `4x6` 、每格 `256x256` 切片,再由服务端合成 `10x10 / 2560x2560` 最终 atlas。形状配比固定为 `1x2=23` 、`1x3=5` 、`2x2=4` 、`2x3=3` ,总计 35 个复合图案组和 95 个 1x1 卡牌切片。
- 影响范围:`module-puzzle-clear` 关卡与图案组规划、api-server 拼消消素材生成编排、前端草稿试玩本地 runtime、结果页 atlas 预览、拼消消 PRD / 技术方案 / 平台链路文档。
- 验证方式:`cargo test -p module-puzzle-clear --manifest-path server-rs/Cargo.toml` 、`cargo test -p api-server puzzle_clear --manifest-path server-rs/Cargo.toml -- --nocapture` 、`npm run test -- src/services/puzzle-clear/puzzleClearLocalRuntime.test.ts` 、`npm run test -- src/components/puzzle-clear-result/PuzzleClearResultView.test.tsx src/components/puzzle-clear-runtime/PuzzleClearRuntimeShell.test.tsx` 。
- 关联文档:`docs/prd/【玩法创作】拼消消玩法模板PRD-2026-05-30.md` 、`docs/technical/【玩法创作】拼消消玩法模板技术方案-2026-05-30.md` 、`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md` 、`docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md` 。
## 2026-05-30 拼消消按独立玩法公开闭环接入
- 背景:拼消消以拼图交换手感为基础,但核心规则从“拼完整单图过关”变为“拼成多个复合图案组后逐个消除”,同时需要顶部补牌、防死局、半锁定局部拼接组和正式统计,不能继续复用拼图运行态规则本体。
- 决策:`puzzle-clear` 作为独立玩法域接入,公开作品码前缀固定为 `PC-` ;创作链路采用表单 / 图片输入工作台 -> 独立生成页 -> 结果页 -> 试玩 -> 发布 -> 统一作品详情 -> 正式 runtime。领域规则落在 `module-puzzle-clear` , SpacetimeDB 新增 `puzzle_clear_*` 表 / procedure / view, 并接入统一 `public_work_gallery_entry` / `public_work_detail_entry` ;前端只表现后端 snapshot/action 结果,不把胜负、补牌或消除裁决做成前端事实源。
- 补充约束:草稿编译和发布都必须拒绝缺失或 `placeholder` atlas / card assets, 不允许后端 facade 或 SpacetimeDB 合成临时素材;当前单关正式 runtime 终态事件使用 `run-finished` 、`level-failed` ,并写入包含 `status` 、`level` 、`clears` 、`clearDelta` 、`elapsedMs` 的结果 JSON。
- 补充约束:拼消消结果页草稿试玩使用前端本地 `runtimeMode=draft` snapshot, 不调用 `/api/runtime/puzzle-clear/runs` ,不写正式 run 统计;公开详情和推荐流正式运行继续走后端 `/api/runtime/puzzle-clear/*` ,客户端需要区分创作详情 `/api/creation/puzzle-clear/works/{profileId}` 与公开运行态详情 `/api/runtime/puzzle-clear/works/{profileId}` 。
- 影响范围:`CONTEXT.md` 、拼消消 PRD / 技术方案、平台玩法链路文档、`shared-contracts` / `packages/shared` 、`api-server` 、`spacetime-module` 、`spacetime-client` 、作品架 / 广场 / 统一作品详情 / runtime 前端分流。
- 验证方式: PRD 和技术方案必须覆盖资产槽位、素材工作表风险、切片验证、恢复语义、API 命名空间和验证命令;实现侧至少运行 `npm run spacetime:generate` 、`npm run check:spacetime-schema` 、`npm run check:spacetime-runtime-access` 、`npm run check:server-rs-ddd` 、`npm run typecheck` 、`npm run check:encoding` 、相关前端测试和 `cargo test -p module-puzzle-clear --manifest-path server-rs/Cargo.toml` 。
- 关联文档:`docs/prd/【玩法创作】拼消消玩法模板PRD-2026-05-30.md` 、`docs/technical/【玩法创作】拼消消玩法模板技术方案-2026-05-30.md` 、`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md` 、`docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md` 。
## 2026-06-05 Server-Provision 全程在目标部署 agent 执行且不安装构建链
- 背景:`Genarrative-Server-Provision` 的 `DEPLOY_TARGET=development` 语义是部署到 dev 服务器,不是构建机 dry-run。旧流水线把 development 映射到 `linux && genarrative-build` ,还先在 build 节点准备 `provision-tools/` 再 stash 给后续阶段,导致真实 dev 初始化可能跑到 Jenkins controller / build 节点;脚本还安装 clang / lld / pkg-config / OpenSSL headers / sccache 等构建链依赖,超出了服务器初始化职责。
- 决策: Server-Provision 只做服务器初始化,全程运行在目标部署 agent: development 使用 `linux && genarrative-dev-deploy` , release 使用 `linux && genarrative-release-deploy` 。`Prepare Provision Tools` 与 `Provision Server` 在同一个目标 agent workspace 顺序执行,不再切到 `linux && genarrative-build` ,不再 `stash/unstash` 工具包。`scripts/jenkins-server-provision.sh` 不再安装 clang / lld / pkg-config / libssl-dev / sccache; 非 dry-run 仍要求目标 dev / release agent 具备 root 权限,因为 provision 会写 systemd、Nginx、`/etc` 和系统用户。Job 的 `Pipeline script from SCM` 与 Jenkinsfile 参数 `SOURCE_GIT_REMOTE_URL` 都必须使用本机路径或目标 agent 可访问的内网 Git 源,不允许公网 Git fallback。
- 决策: Server-Provision 只做服务器初始化,全程运行在目标部署 agent: development 使用 `linux && genarrative-dev-deploy` , release 使用 `linux && genarrative-release-deploy` 。`Prepare Provision Tools` 与 `Provision Server` 在同一个目标 agent workspace 顺序执行,不再切到 `linux && genarrative-build` ,不再 `stash/unstash` 工具包。`scripts/jenkins-server-provision.sh` 不再安装 clang / lld / pkg-config / libssl-dev / sccache; 当前 OpenSSL 3.2 独立运行时自举会安装 `build-essential` 等最小工具,这是满足 api-server/libcurl 运行时符号的受控例外,不代表 provision 承担 api-server 构建职责。 非 dry-run 仍要求目标 dev / release agent 具备 root 权限,因为 provision 会写 systemd、Nginx、`/etc` 和系统用户。Job 的 `Pipeline script from SCM` 与 Jenkinsfile 参数 `SOURCE_GIT_REMOTE_URL` 都必须使用本机路径或目标 agent 可访问的内网 Git 源,不允许公网 Git fallback。
- 影响范围:`jenkins/Jenkinsfile.production-server-provision` 、`scripts/jenkins-server-provision.sh` 、生产运维文档、Server-Provision 排障口径。
- 验证方式: Jenkins 日志中 Server-Provision 的 `Prepare` 、`Checkout Provision Files` 、`Prepare Provision Tools` 和 `Provision Server` 都在目标 dev / release agent 上执行;日志不出现 `Running on Jenkins` 、`linux && genarrative-build` 、`stash 'server-provision-tools'` 、`Git 主地址拉取失败...改用备用地址` 、`https://git.genarrative.world/GenarrativeAI/Genarrative.git` 或构建依赖 / sccache 安装步骤;`bash -n scripts/jenkins-server-provision.sh` 和编码检查通过。
- 关联文档:`docs/【开发运维】本地开发验证与生产运维-2026-05-15.md` 。
@@ -40,6 +113,14 @@
- 验证方式:`cargo test -p platform-oss --manifest-path server-rs/Cargo.toml` ;真实联调时按 `provider=aliyun-oss` 与 `operation` 过滤日志,确认只出现对象定位和状态字段,不出现签名材料。
- 关联文档:`server-rs/crates/platform-oss/README.md` 、`docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md` 、`docs/【开发运维】本地开发验证与生产运维-2026-05-15.md` 。
## 2026-06-05 跳一跳返回按钮改为独立主题资产
- 背景:跳一跳运行态曾把左上角返回按钮视觉锚点写进背景 image2 prompt, 导致返回按钮像静态背景元素, 不能替代真实可点击按钮。
- 决策:跳一跳背景 prompt 禁止生成任何 UI 或左上角图标;返回按钮由 `backButtonAsset` 单独生成 1:1 纯绿 key 图,后端去绿后作为透明 PNG 持久化到作品 profile, 运行态左上角真实按钮优先渲染该资产。顶部得分 HUD 复用拼图模板结构,包含陶泥儿 IP logo、标题牌和下挂数字卡。
- 影响范围:`packages/shared/src/contracts/jumpHop.ts` 、`shared-contracts` 、`spacetime-module` / `spacetime-client` bindings、`api-server` 跳一跳生成链路、`JumpHopRuntimeShell` 、玩法链路文档和后端数据契约文档。
- 验证方式:`npm run spacetime:generate` 、`cargo test -p api-server jump_hop --manifest-path server-rs/Cargo.toml` 、`npm run test -- src/components/jump-hop-runtime/JumpHopRuntimeShell.test.tsx` 、`npm run check:spacetime-schema` 。
- 关联文档:`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md` 、`docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md` 。
## 2026-06-03 创作入口关闭不下架已发布作品
- 背景:`creation_entry_disabled` 曾由 api-server 按 runtime 路由前缀统一熔断,导致用户进入平台首页或启动已发布作品时也可能看到“创作入口已关闭”错误。
@@ -52,11 +133,166 @@
- 背景:拼图首图、图集、音频等外部生成链路长期占用 `api-server` HTTP handler, 导致扩容只能放大 API 进程,且 HTTP 超时和外部 provider 波动会直接影响创作入口。
- 决策:外部生成任务统一进入 SpacetimeDB `external_generation_job` 持久队列,由 `api-server` 的 `external-generation-worker` 进程角色 claim lease 后执行; HTTP 角色只做鉴权、表单/状态初始化、入队和返回 `queued/running/completed/failed` 操作状态。生产通过 systemd worker 模板增加实例数或提高 `GENARRATIVE_EXTERNAL_GENERATION_WORKER_CONCURRENCY` 动态扩缩容,`GENARRATIVE_PROCESS_ROLE=all` 仅用于本地 smoke。拼图 `compile_puzzle_draft` 、结果页 `generate_puzzle_images` 与 `generate_puzzle_ui_background` 已接入 worker; 业务写回必须在 SpacetimeDB transaction 内校验 `external_generation_job` 的 `job_id + worker_id + lease_token` 、job kind、owner 和 source entity, 其中首图 worker 的前置 `compile_puzzle_agent_draft` 也必须带 guard。worker 核心业务写回失败不能返回内存快照并把 job 标成 completed; 失败态业务写回成功后才能把 job 标成 failed, 失败态未写回则保留租约等待后续重领。拼图业务失败不自动重试, 只保留 lease 过期后的崩溃重领,避免钱包扣退费幂等漂移。生产发布会启用默认 `genarrative-external-generation-worker@1.service` 并等待 worker active, worker 停机时停止 claim 新任务并 drain 当前任务。
- 2026-06-07 追加:`GENARRATIVE_EXTERNAL_GENERATION_MODE` 新增 `queue|inline` 显式策略,默认和生产仍为 `queue` ; `inline` 只用于本地或小流量同步排查 ,由 HTTP handler 复用同一 worker executor 直接返回 `completed` ,不创建 `external_generation_job` ,不支持 worker 动态扩缩容。拼图写回 guard 字段改为可选, queue 路径仍必须完整校验 `job_id + worker_id + lease_token` ; inline 路径只允许三项同时为空,半空 guard 仍拒绝。
- 2026-06-07 追加:`GENARRATIVE_EXTERNAL_GENERATION_MODE` 使用 `queue|inline` 显式策略;生产和容器扩缩容验证保持 `queue` 。本地开发若需要同步等待结果,应通过 `.env.local` 或本机环境显式配置为 `inline` ,由 HTTP handler 复用同一 worker executor 直接返回 `completed` ,不创建 `external_generation_job` ,不支持 worker 动态扩缩容;脚本不得硬编码该策略 。拼图写回 guard 字段改为可选, queue 路径仍必须完整校验 `job_id + worker_id + lease_token` ; inline 路径只允许三项同时为空,半空 guard 仍拒绝。
- 影响范围:`server-rs/crates/spacetime-module/src/external_generation.rs` 、`server-rs/crates/spacetime-client/src/external_generation.rs` 、`server-rs/crates/api-server/src/external_generation_worker.rs` 、`deploy/systemd/genarrative-external-generation-worker@.service` 、`scripts/deploy/production-api-deploy.sh` 、`scripts/jenkins-server-provision.sh` 、拼图 `compile_puzzle_draft` 、拼图 `generate_puzzle_images` 、拼图 `generate_puzzle_ui_background` 、生产 env 模板和运维文档。
- 验证方式:`npm run spacetime:generate` 、`npm run check:spacetime-schema` 、`npm run check:server-rs-ddd` 、`cargo check -p api-server --manifest-path server-rs/Cargo.toml` ,并用 `GENARRATIVE_PROCESS_ROLE=all npm run dev` smoke 至少一次 queued -> worker 完成链路。
- 验证方式:`npm run spacetime:generate` 、`npm run check:spacetime-schema` 、`npm run check:server-rs-ddd` 、`cargo check -p api-server --manifest-path server-rs/Cargo.toml` ,并在 queue 模式下 用 `GENARRATIVE_PROCESS_ROLE=all npm run dev` smoke 至少一次 queued -> worker 完成链路;本地 inline 排查只确认不创建 `external_generation_job` 。
- 关联文档:`docs/technical/【后端架构】外部生成Worker化方案-2026-06-03.md` 、`docs/【开发运维】本地开发验证与生产运维-2026-05-15.md` 、`docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md` 。
## 2026-06-03 外部生成 worker lease 使用 SpacetimeDB 时间和 token 栅栏
- 背景:外部生成 worker 支持多进程动态缩扩容后,长任务超过单次 lease、worker 本机时钟漂移或复用 worker id 都可能导致同一任务被重复领取并被过期执行者回写。
- 决策:`external_generation_job` 新增末尾字段 `lease_token` ; `claim` 使用 SpacetimeDB `ctx.timestamp` 计算 lease, 生成本次 claim token; worker 执行期间调用 `renew_external_generation_job_lease_and_return` 续租;`complete/fail` 必须带 `worker_id + lease_token` 才能回写。拼图 `compile_puzzle_draft` 的 dedupe key 包含本次 `extgen-` job id, 避免同一 session 的失败或完成 job 吞掉后续重新生成。拼图首图前置 `compile_puzzle_agent_draft` 、图片保存、UI 背景与失败态业务写回同样必须携带 lease guard, 并在 `compile_puzzle_agent_draft` 、`save_puzzle_generated_images` 、`save_puzzle_ui_background` 、`mark_puzzle_draft_generation_failed` 、`mark_puzzle_level_generation_failed` 的 SpacetimeDB 事务内校验。
- 影响范围:`server-rs/crates/spacetime-module/src/external_generation.rs` 、`server-rs/crates/spacetime-module/src/puzzle.rs` 、`server-rs/crates/module-puzzle/src/commands.rs` 、`server-rs/crates/spacetime-client/src/external_generation.rs` 、`server-rs/crates/spacetime-client/src/puzzle.rs` 、`server-rs/crates/api-server/src/external_generation_worker.rs` 、`server-rs/crates/api-server/src/puzzle/handlers.rs` 、`server-rs/crates/api-server/src/puzzle/draft.rs` 、`server-rs/crates/api-server/src/puzzle/generation.rs` 。
- 验证方式:`npm run spacetime:generate` 、`npm run check:spacetime-schema` 、`cargo test -p spacetime-module external_generation --manifest-path server-rs/Cargo.toml` 、`cargo test -p api-server external_generation_worker --manifest-path server-rs/Cargo.toml` 、`GENARRATIVE_PROCESS_ROLE=all npm run dev` 后检查 `/healthz` 。
- 关联文档:`docs/technical/【后端架构】外部生成Worker化方案-2026-06-03.md` 、`docs/【开发运维】本地开发验证与生产运维-2026-05-15.md` 。
## 2026-06-04 Draft Generation Shelf 剩余草稿打开 intent 收口
- 背景:拼图 / 抓大鹅草稿打开 intent 已归入 `platformDraftGenerationShelfModel.ts` ,但方洞挑战、大鱼吃小鱼和视觉小说仍在平台壳层内联判断已发布详情、缺 session、active generating、当前结果页和普通草稿恢复。
- 决策:继续扩展 `src/components/platform-entry/platformDraftGenerationShelfModel.ts` ,新增 `resolveSquareHoleDraftOpenIntent(...)` 、`resolveBigFishDraftOpenIntent(...)` 与 `resolveVisualNovelDraftOpenIntent(...)` ;平台壳只按 intent 执行 notice seen、详情打开、恢复 session、读取 work detail、清生成态和切 stage 副作用。
- 追加决策:跳一跳与敲木鱼草稿打开也归入同一 Draft Generation Shelf Model, 新增 `resolveJumpHopDraftOpenIntent(...)` 与 `resolveWoodenFishDraftOpenIntent(...)` ;壳层只按 intent 执行已发布详情、失败生成页恢复、持久化 generating 恢复、读取 detail 和敲木鱼失败 fallback stage 副作用。
- 影响范围:创作中心作品架打开方洞挑战 / 大鱼吃小鱼 / 视觉小说 / 跳一跳 / 敲木鱼草稿、创作 URL 恢复时强制打开草稿、生成中回到生成页和视觉小说结果页恢复。
- 验证方式:`npm run test -- src/components/platform-entry/platformDraftGenerationShelfModel.test.ts` 、针对 Draft Shelf Module 与平台壳执行 ESLint、`npm run typecheck` 、`npm run check:encoding` 。
- 关联文档:`docs/technical/【前端架构】DraftGenerationShelfModel收口计划-2026-06-03.md` 。
## 2026-06-04 Platform Public Code Search matcher / DTO 收口
- 背景:`resolvePlatformPublicCodeSearchPlan(...)` 已收口公开搜索顺序,但 `PlatformEntryFlowShellImpl.tsx` 仍内联 RPG by-code DTO 构造,以及拼图、大鱼吃小鱼、跳一跳、敲木鱼、宝贝识物、抓大鹅、方洞挑战、视觉小说和汪汪声浪的 `isSame*PublicWorkCode` 匹配、公开可见性过滤与详情卡映射。
- 决策:扩展 `src/components/platform-entry/platformPublicCodeSearchModel.ts` ,以 `mapRpgPublicCodeSearchDetailToGalleryCard(...)` 和各 `resolve*PublicCodeSearchMatch(...)` 收口 per-play 公开码匹配与 DTO 映射;壳层只保留 gallery 刷新、详情打开、Bark Battle runtime 特例、用户查询和错误归航副作用。`M3D-*` 旧抓大鹅前缀在 `isSameMatch3DPublicWorkCode(...)` 中继续匹配。
- 影响范围:平台首页搜索框、初始 `publicWorkCode` 恢复、各玩法公开作品号命中、RPG 公开作品 by-code 详情映射、Bark Battle runtime 内搜索启动。
- 验证方式:`npm run test -- src/components/platform-entry/platformPublicCodeSearchModel.test.ts src/services/publicWorkCode.test.ts` 、针对搜索 Module / 壳层 / publicWorkCode 执行 ESLint、`npm run typecheck` 、`npm run check:encoding` 。
- 关联文档:`docs/technical/【前端架构】PlatformPublicCodeSearchModel收口计划-2026-06-04.md` 、`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md` 。
## 2026-06-04 Draft Generation Shelf 草稿打开 intent 收口
- 背景:`openPuzzleDraft` / `openMatch3DDraft` 在平台壳内重复判断已发布作品、缺 session、ready 未读、失败 notice、active / background 生成中、持久化 generating 和普通草稿恢复,导致壳层继续理解拼图稳定 ID、抓大鹅 notice key 与生成状态优先级。
- 决策:扩展 `src/components/platform-entry/platformDraftGenerationShelfModel.ts` ,以 `resolvePuzzleDraftOpenIntent(...)` 与 `resolveMatch3DDraftOpenIntent(...)` 返回纯打开计划和 notice keys; 壳层只按 intent 执行网络读取、生成态 rebase、试玩启动、错误写入、路由 / stage 和 notice seen 副作用。
- 影响范围:创作中心作品架打开拼图 / 抓大鹅草稿、公开码搜索强制打开抓大鹅草稿、生成完成后 ready 未读试玩、失败草稿恢复和后续 pending / persisted generating 判定。
- 验证方式:`npm run test -- src/components/platform-entry/platformDraftGenerationShelfModel.test.ts` 、针对 Draft Shelf Module 与平台壳执行 ESLint、`npm run typecheck` 、`npm run check:encoding` 。
- 关联文档:`docs/technical/【前端架构】DraftGenerationShelfModel收口计划-2026-06-03.md` 。
## 2026-06-04 Bark Battle Work Cache 草稿状态收口
- 背景:`PlatformEntryFlowShellImpl.tsx` 仍内联维护 Bark Battle 草稿三图完整性、生成状态归一、作品架摘要恢复草稿配置,以及草稿 / 已发布作品进入 runtime 前的 `BarkBattlePublishedConfig` 字段映射,导致结果页试玩、作品架启动、草稿恢复和公开详情启动都要理解同一份资产字段清单。
- 决策:扩展 `src/components/platform-entry/barkBattleWorkCache.ts` ,以 `hasBarkBattleDraftRequiredImages` 、`resolveBarkBattleDraftGenerationStatus` 、`buildBarkBattleDraftConfigFromWorkSummary` 、`buildBarkBattlePublishedConfigFromDraft` 、`buildBarkBattlePublishedConfigFromWork` 、`buildBarkBattlePublishSnapshot` 和 `mergeBarkBattlePublishedConfigAssets` 收口 Bark Battle 纯规则。平台壳只保留 API、缓存刷新、React state、URL 和 stage 副作用。
- 影响范围: Bark Battle 草稿生成完成、结果页保存、作品架摘要恢复草稿、草稿试玩、作品架 / 公开详情启动正式 runtime, 以及后续 Bark Battle 资产字段或 ruleset 默认值调整。
- 验证方式:`npm run test -- src/components/platform-entry/barkBattleWorkCache.test.ts` 、针对 Bark Battle Work Cache Module 与平台壳执行 ESLint、`npm run typecheck` 、`npm run check:encoding` 。
- 关联文档:`docs/technical/【前端架构】BarkBattleWorkCache草稿状态收口计划-2026-06-04.md` 。
## 2026-06-04 Platform Recommend Runtime Auth Model 收口
- 背景:平台推荐 runtime 的 embedded 启动需要在匿名 Runtime Guest Token、已登录 background auth 和非 embedded 默认鉴权之间分流,拼图还额外维护 `isolated` / `default` runtime auth mode; 旧规则散在顶层 helper 与多个启动 callback。
- 决策:新增 `src/components/platform-entry/platformRecommendRuntimeAuthModel.ts` ,以 `resolvePlatformRecommendRuntimeAuthPlan(input)` 和 `shouldUsePlatformRecommendRuntimeGuestAuth(input)` 收口纯鉴权计划。壳层仍负责读取 `getStoredAccessToken()` 、申请 `ensureRuntimeGuestToken()` 、拼装 request options 和写入拼图 runtime auth mode。
- 影响范围:推荐 Tab 内嵌 runtime 启动、拼图公开详情 isolated 入口、推荐运行态后续 action 的局部鉴权口径,以及后续新增可嵌入推荐 runtime 的玩法。
- 验证方式:`npm run test -- src/components/platform-entry/platformRecommendRuntimeAuthModel.test.ts` 、针对新 Module 与平台壳执行 ESLint、`npm run typecheck` 、`npm run check:encoding` 。
- 关联文档:`docs/technical/【前端架构】PlatformRecommendRuntimeAuthModel收口计划-2026-06-04.md` 。
## 2026-06-04 Platform Recommend Runtime Auto Start 收口
- 背景:推荐 runtime 自动启动 effect 同时判断桌面断点、stage、Tab、loading、推荐列表、active entry、ready 状态和启动中状态,导致壳层 effect 依赖过长且混合推荐流状态机知识。
- 决策:扩展 `src/components/platform-entry/platformPublicGalleryFlow.ts` ,新增 `resolvePlatformRecommendRuntimeAutoStartDecision(input)` ,只返回 `noop` 、`clear` 或 `start(entry)` 。平台壳只执行清空 active runtime state 或调用 `selectRecommendRuntimeEntry(entry)` 。
- 影响范围:移动端首页推荐 runtime 自动启动、推荐列表为空时清空状态、active entry ready 判定,以及后续新增推荐 runtime 玩法的启动时机。
- 验证方式:`npm run test -- src/components/platform-entry/platformPublicGalleryFlow.test.ts` 、针对 Flow Module 与平台壳执行 ESLint、`npm run typecheck` 、`npm run check:encoding` 。
- 关联文档:`docs/technical/【前端架构】PlatformRecommendRuntimeAutoStart收口计划-2026-06-04.md` 。
## 2026-06-04 Platform Creation Launch Model 收口
- 背景:平台创作入口点击回调曾在 `PlatformEntryFlowShellImpl.tsx` 内联判断 `airp` 占位、隐藏的 `baby-object-match` 、未知入口和各玩法工作台启动目标,壳层同时承接入口 ID 规则、启动前准备顺序和副作用。
- 决策:新增 `src/components/platform-entry/platformCreationLaunchModel.ts` ,以 `resolvePlatformCreationLaunchIntent({ type, isBabyObjectMatchVisible })` 收口创作入口启动意图。`airp` 返回 `noop` 且不触发 `prepareCreationLaunch()` ;隐藏 `baby-object-match` 返回 blocked intent 且仍在 prepare 后显示 `EDUTAINMENT_HIDDEN_MESSAGE` ;未知入口保持旧语义,先 prepare 后 no-op; 已知入口返回稳定 launch target。壳层只执行 prepare、错误提示和 `runProtectedAction(...)` 。
- 影响范围:底部加号创作入口模板卡点击、入口可见性拦截、后续新增可启动模板的 launch target 接入。
- 验证方式:`npm run test -- src/components/platform-entry/platformCreationLaunchModel.test.ts` 、针对新 Module 与壳层执行 ESLint、`npm run typecheck` 、`npm run check:encoding` 。
- 关联文档:`docs/technical/【前端架构】PlatformCreationLaunchModel收口计划-2026-06-04.md` 。
## 2026-06-04 Platform Selection Stage Model 收口
- 背景:平台入口在受保护数据失效后会清空当前用户私有作品、草稿、运行态和生成状态,但哪些 `SelectionStage` 可保留、哪些必须回首页曾以内联长否定串散在 `PlatformEntryFlowShellImpl.tsx` 。
- 决策:新增 `src/components/platform-entry/platformSelectionStageModel.ts` ,以 `resolveSelectionStageAfterProtectedDataLoss(stage)` 收口受保护数据失效后的 stage 去留判定。模型内部使用 `satisfies Record<SelectionStage, boolean>` 全量分类,新增 stage 时必须明确保留或回首页。壳层仍负责检测权限变化、清 state 和调用 `setSelectionStage` 。
- 追加决策:缺失草稿 / 作品 / run 时的阶段回退也归入 `platformSelectionStageModel.ts` ,由 `resolveSelectionStageAfterMissingCreationState(params)` 统一判断 big-fish、match3d、square-hole、visual-novel 和 baby-object-match 的 result / runtime / gallery-detail 是否还能被当前状态支撑。壳层只汇总布尔事实并按输出 stage 跳转; big-fish、match3d、square-hole 的草稿事实固定来自 `Boolean(session?.draft)` , visual-novel 的 session draft 与 work draft 可独立支撑结果页, baby-object-match runtime 缺 draft 时直接回首页。
- 影响范围:退出登录、鉴权上下文收回、平台入口公开页 / 工作台 / 结果页 / 生成页 / 运行态的阶段恢复规则,以及后续新增 `SelectionStage` 。
- 验证方式:`npm run test -- src/components/platform-entry/platformSelectionStageModel.test.ts` 、针对新 Module 与壳层执行 ESLint、`npm run typecheck` 、`npm run check:encoding` 。
- 关联文档:`docs/technical/【前端架构】PlatformSelectionStageModel收口计划-2026-06-04.md` 。
## 2026-06-04 Creation Work Delete Flow 收口
- 背景:平台入口作品架删除入口在 RPG、拼图、抓大鹅、方洞挑战、大鱼吃小鱼、视觉小说和宝贝识物 handler 内重复计算确认标题、删除说明、草稿 notice key 与拼图派生稳定 ID, 导致删除确认规则散在巨型壳层。
- 决策:新增 `src/components/platform-entry/platformCreationWorkDeleteFlow.ts` ,以 `resolvePlatformCreationWorkDeleteConfirmationModel(input)` 收口作品架删除确认纯模型;输出 `id/title/detail/noticeKeys` 。`PlatformEntryFlowShellImpl.tsx` 仍作为副作用 Adapter, 保留删除 API、刷新作品架 / 公开广场、错误状态、`markDraftNoticeSeen` 和页面跳转。
- 影响范围:创作中心作品架删除确认弹窗、删除后生成 notice 清理、拼图稳定 result ID 清理、宝贝识物已发布删除说明,以及后续新增玩法作品架删除接入。
- 验证方式:`npm run test -- src/components/platform-entry/platformCreationWorkDeleteFlow.test.ts` 、`npm run test -- src/components/platform-entry/platformDraftGenerationShelfModel.test.ts` 、针对新 Module 与平台壳执行 ESLint、`npm run typecheck` 、`npm run check:encoding` 。
- 关联文档:`docs/technical/【前端架构】CreationWorkDeleteFlow收口计划-2026-06-04.md` 。
## 2026-06-03 平台入口公开作品详情 Strategy 收口
- 背景:平台壳层直接判断公开作品详情入口的玩法类型、是否需要补读完整详情,以及自有作品按钮显示“编辑”还是“改造”,导致统一作品详情的纯决策散落在巨型 Implementation 内。
- 决策:新增 `src/components/platform-entry/platformPublicWorkDetailFlow.ts` ,以 `getPlatformPublicWorkDetailKind` 、`resolvePlatformPublicWorkDetailOpenStrategy` 、`resolvePlatformPublicWorkActionMode` 、`resolvePlatformPublicWorkDetailOpenDecision` 和 `resolveActivePlatformPublicWorkAuthorEntry` 收口公开作品详情 Strategy。`PlatformEntryFlowShellImpl.tsx` 只按 Strategy 调用现有详情读取 / 直接展示 Adapter, 并保留作者请求竞态控制; 启动、点赞、remix 和编辑副作用不搬入 Module。
- 追加决策:公开详情 entry 映射与公开详情反推玩法 work 摘要也归入 `platformPublicWorkDetailFlow.ts` ,包括 RPG、拼图、大鱼吃小鱼、方洞挑战、视觉小说、跳一跳、敲木鱼和汪汪声浪的通用映射。抓大鹅 `mapMatch3DWorkToPublicWorkDetail` 归入 `platformMatch3DRuntimeProfile.ts` ,继续委托 `normalizeMatch3DWorkForRuntimeUi` 做素材归一和背景资产提升,避免把 Match3D 运行态规则复制到公开详情 Flow Module。
- 追加决策:拼图公开详情封面解锁数由 `resolveVisiblePuzzleDetailCoverCount(entry, run)` 收口;非拼图、无当前 run 或 run 不匹配当前公开详情时只展示首图,匹配当前公开详情时按 `clearedLevelCount + 1` 解锁且至少为 1。`PlatformWorkDetailView` 只接收 `visibleCoverCount` 展示,不读取 run。
- 追加决策:公开详情点赞能力矩阵由 `resolvePlatformPublicWorkLikeIntent(entry)` 收口; Module 只返回大鱼吃小鱼、拼图、旧 RPG gallery fallback 或不可用文案, 壳层仍执行鉴权、API 调用、缓存同步、错误展示和 busy 状态。
- 追加决策:公开详情改造能力矩阵由 `resolvePlatformPublicWorkRemixIntent(entry)` 收口; Module 只返回大鱼吃小鱼、拼图、旧 RPG gallery fallback 或不可用文案, 壳层仍执行鉴权、remix API、session / 缓存写入、stage 切换、错误展示和 busy 状态。
- 追加决策:公开详情启动分流由 `resolvePlatformPublicWorkStartIntent(entry, deps)` 收口; Module 只返回大鱼吃小鱼、拼图、跳一跳、敲木鱼、抓大鹅、方洞挑战、视觉小说、汪汪声浪、宝贝识物或旧 RPG gallery 记录游玩的 intent。壳层仍执行登录保护、运行态启动、RPG 游玩记录、详情更新、busy 状态和错误展示;抓大鹅 public detail -> work mapper 作为 Adapter 注入,继续由 Match3D Runtime Profile Module 维护素材归一与背景资产提升。
- 追加决策:自有公开作品编辑分流由 `resolvePlatformPublicWorkEditIntent(entry, deps)` 收口; Module 只返回可编辑草稿目标、需解析宝贝识物本地草稿 intent、旧 RPG gallery 编辑 intent 或原阻断文案。壳层仍执行登录保护、草稿恢复、宝贝识物异步草稿解析、RPG 编辑导航和错误展示;抓大鹅 public detail -> work mapper 仍作为 Adapter 注入,不复制 Match3D 素材归一规则。
- 影响范围:统一作品详情入口、公开详情打开策略、自有公开作品编辑 / 改造动作模式,以及后续新增玩法公开详情接入。
- 验证方式:`npm run test -- src/components/platform-entry/platformPublicWorkDetailFlow.test.ts` 、`npm run test -- src/components/platform-entry/platformMatch3DRuntimeProfile.test.ts` 、公开详情壳层交互回归、`npm run typecheck` 、`npm run check:encoding` 。
- 关联文档:`docs/technical/【前端架构】PlatformPublicWorkDetailFlow收口计划-2026-06-03.md` 。
## 2026-06-03 平台入口弹窗状态规则收口
- 背景:`PlatformEntryFlowShellImpl.tsx` 曾同时持有平台级错误 / 完成弹窗的文案归一、来源格式、候选择一、dismiss key、后台生成 still-running 识别和任务完成文案,导致壳层 Interface 偏浅,测试面不稳定。
- 决策:新增 `src/components/platform-entry/platformDialogStateModel.ts` 作为 Platform Dialog State Module, 统一导出 `normalizePlatformDialogMessage` 、`formatPlatformDialogSource` 、`resolvePlatformErrorDialog` 、dismiss key builder、`resolveActivePlatformDialog` 、`isBackgroundGenerationStillRunningMessage` 和 `PLATFORM_TASK_COMPLETION_MESSAGE` 。平台壳只汇总候选、持有 React state, 并在关闭弹窗时作为 Adapter 清理对应副作用 setter。
- 影响范围:平台入口错误弹窗、任务完成弹窗、后台生成仍在处理识别、草稿生成完成 / 失败通知。
- 验证方式:`npm run test -- src/components/platform-entry/platformDialogStateModel.test.ts` 、`npm run test -- src/components/platform-entry/PlatformErrorDialog.test.tsx` 、相关壳层交互测试、`npm run typecheck` 、`npm run check:encoding` 。
- 关联文档:`docs/technical/【前端架构】PlatformDialogStateModel收口计划-2026-06-03.md` 。
## 2026-06-03 前端 SSE 客户端传输层统一收口
- 背景:创作 Agent、创意互动 Agent、视觉小说运行态和微信充值订单状态等多个前端 client 曾各自手写 SSE 边界扫描、`TextDecoder` 解码、JSON 解析和流结束 flush, 导致 CRLF / LF、UTF-8 尾部、多行 `data:` 和提前停止释放 reader 的处理容易漂移。
- 决策:前端 SSE 传输层统一使用 `src/services/sseStream.ts` ; `readSseStream` 负责事件边界、解码 flush、多行 data 和提前停止取消 reader, `readSseJsonStream` 负责 JSON object 事件解析与异常 JSON 静默跳过。业务 client 只保留领域事件归一化、结果聚合和中文错误文案, OpenAI 兼容文本流通过 `readSseStream` 处理 `[DONE]` 哨兵,后续不得复制 `findSseEventBoundary` 、`parseSseEventBlock` 或手写 reader 循环。
- 影响范围:`src/services/sseStream.ts` 、`src/services/aiService.ts` 、`src/services/llmClient.ts` 、`src/services/creation-agent/creationAgentSse.ts` 、`src/services/creative-agent/creativeAgentSse.ts` 、`src/services/visual-novel-runtime/visualNovelRuntimeSse.ts` 、`src/services/rpg-entry/rpgProfileClient.ts` 、前端 SSE 相关测试与架构文档。
- 验证方式:`npm run test -- src/services/sseStream.test.ts src/services/llmClient.test.ts src/services/creation-agent/creationAgentSse.test.ts src/services/creative-agent/creativeAgentSse.test.ts src/services/visual-novel-runtime/visualNovelRuntimeSse.test.ts src/services/rpg-entry/rpgProfileClient.test.ts src/services/ai.test.ts` 、`npm run typecheck` 、`npm run check:encoding` 、相关文件 `npx eslint ... --max-warnings 0` 通过。
- 关联文档:`docs/technical/【前端架构】SSE客户端传输层收口约定-2026-06-03.md` 。
## 2026-06-03 平台入口公开作品流身份规则收口
- 背景:平台入口公开作品推荐流需要同时处理 RPG、拼图、抓大鹅、跳一跳、敲木鱼、视觉小说、Bark Battle、宝贝识物等卡片, 公开作品身份、跨玩法去重、排序和推荐运行态 kind 判定曾放在 `PlatformEntryFlowShellImpl.tsx` 巨型实现里。
- 决策:公开作品身份、排序规则、公开作品流聚合矩阵、推荐 runtime 启动意图和 ready 判定统一收口到 `src/components/platform-entry/platformPublicGalleryFlow.ts` ;入口壳层只调用该 Module 的 `getPlatformPublicGalleryEntryKey` 、`getPlatformRecommendRuntimeKind` 、`buildPlatformPublicGalleryFeeds` 、`resolvePlatformRecommendRuntimeStartIntent` 、`isPlatformRecommendRuntimeReadyForEntry` 、`isSamePlatformPublicGalleryEntry` 和 `mergePlatformPublicGalleryEntries` 。`edutainment` key 必须带 `templateId` , RPG 卡片回退为 `rpg` 。公开作品流聚合负责 featured / latest、玩法可见性 gate、汪汪声浪 works fallback 和首屏 `slice(0, 6)` ;推荐 runtime 启动 intent 只返回启动目标、`embedded` / `returnStage` 参数、阻断文案和错误落点; ready 判定只接布尔值与拼图 profile id, 避免把各玩法 run snapshot 类型拖入 Module。壳层仍执行 request key、运行态 API、错误 setter 与 UI 状态。
- 影响范围:平台入口推荐流、最新公开作品流、公开作品详情、推荐 runtime 启动、跨玩法公开作品合并,以及后续新增玩法的入口接入。
- 验证方式:`npm run test -- src/components/platform-entry/platformPublicGalleryFlow.test.ts` 、`npm run typecheck` 、`npm run check:encoding` 、相关文件 ESLint 通过。
- 关联文档:`docs/technical/【前端架构】平台入口PublicGalleryFlowModule收口计划-2026-06-03.md` 。
## 2026-06-03 Work Shelf 打开动作交由 item Adapter
- 背景:`creationWorkShelf.ts` 已经为每个 `CreationWorkShelfItem` 生成 `actions.open` ,但 `CustomWorldCreationHub.tsx` 点击卡片后仍按 `item.source.kind` 重复分发 RPG、拼图、抓大鹅、方洞、跳一跳、敲木鱼、视觉小说、Bark Battle 和宝贝识物的打开逻辑。
- 决策:`CreationWorkShelfItem.actions.open` 作为作品架打开动作的正式 Interface; Hub 只保留 `onOpenShelfItem` 通知和 `item.actions.open()` 调用,不再读取玩法 kind 做打开分支。`buildCreationWorkShelfItemsFromSources` 与 `CreationWorkShelfSourceAdapter` 作为 source registry Interface, 统一执行 flatten、运行态覆盖、持久化生成态兜底和更新时间排序; 旧 `buildCreationWorkShelfItems` 保留兼容,但内部改为组装 source adapters。
- 影响范围:创作中心作品架卡片点击、作品架动作 Adapter、source registry、后续新增玩法作品架接入。
- 验证方式:`npm run test -- src/components/custom-world-home/creationWorkShelf.test.ts src/components/custom-world-home/CustomWorldCreationHub.interaction.test.tsx` 、`npm run typecheck` 、`npm run check:encoding` 、相关文件 ESLint 通过。
- 关联文档:`docs/technical/【前端架构】WorkShelfModule收口计划-2026-06-03.md` 。
## 2026-06-03 Runtime Client Family 请求骨架收口
- 背景: Match3D、SquareHole、Puzzle、Jump Hop 等 runtime client 重复手写 path segment 编码、JSON header / body、runtime guest token、auth options 和 retry options, 新增玩法容易遗漏同一请求骨架。
- 决策:新增 `src/services/runtimeRequest.ts` ,以 `buildRuntimeApiPath` 统一 runtime path 编码,以 `requestRuntimeJson` 统一 JSON 请求、runtime guest auth 和 retry 合并。Match3D 与 SquareHole runtime client 已先迁移,保留原导出函数名、错误文案、返回契约和重试常量。
- 追加决策: Big Fish 与 Bark Battle runtime client 也迁入 `runtimeRequest.ts` ;玩法专属 payload 归一化(如 Bark Battle start / finish 自动补 `workId` 、`runId` )仍留在各玩法 client, 通用 Module 只承接请求骨架。
- 追加决策: Puzzle 的 start / get / swap / drag / next-level / leaderboard 与 Jump Hop 的 start / jump / restart 也迁入 `runtimeRequest.ts` ; Puzzle `pause` 与 `props` 仍保留原账号态 auth options, 不直接接入 runtime guest auth。
- 追加决策: Wooden Fish 的 start / checkpoint / finish 与 Visual Novel 的 gallery / run / history / regenerate JSON 请求也迁入 `runtimeRequest.ts` ; Wooden Fish 的 `clientEventId` 生成仍留在木鱼 client, Visual Novel start 因 `timeoutMs` 、SSE 因流式 `fetchWithApiAuth` 仍暂留原实现。
- 影响范围:`src/services/runtimeRequest.ts` 、Match3D / SquareHole / Big Fish / Bark Battle / Puzzle / Jump Hop / Wooden Fish / Visual Novel runtime client。
- 验证方式:`npm run test -- src/services/runtimeRequest.test.ts src/services/recommendedRuntimeGuestLaunch.test.ts src/services/match3d-runtime/match3dRuntimeAdapter.test.ts` 、`npm run typecheck` 、`npm run check:encoding` 、相关文件 ESLint 通过。
- 关联文档:`docs/technical/【前端架构】RuntimeClientFamily收口计划-2026-06-03.md` 。
## 2026-06-03 Public Gallery ViewModel 收口
- 背景:`RpgEntryHomeView.tsx` 巨型页面内混合了公开作品分类、跨来源去重、搜索归一化、作品号匹配、时间戳解析和排序规则,新增玩法时页面与 ViewModel 规则容易纠缠。
- 决策:新增 `src/components/rpg-entry/rpgEntryPublicGalleryViewModel.ts` ,把 `buildPublicGalleryCardKey` 、`buildPublicCategoryGroups` 、`getPlatformPublicEntries` 、`getAllPlatformPublicEntries` 、`getPlatformSearchableWorkIds` 、`filterPlatformWorkSearchResults` 、`isExactPublicWorkCodeSearch` 、`filterTodayPublishedEntries` 、公开卡片指标 getter、`buildPlatformRankingEntries` 、`getPlatformRankingMetricValue` 、`getPlatformCategoryKindFilter` 、`matchesPlatformCategoryKindFilter` 、`sortPlatformCategoryEntries` 、`getPlatformCategoryPrimaryMetric` 、`parsePlatformEntryTimestamp` 和 `getPlatformWorldTimestamp` 收口为公开作品 ViewModel Interface。公开作品 key 复用平台入口身份规则,补齐 jump-hop / wooden-fish 等玩法区分。
- 影响范围: RPG 首页公开作品发现、分类、搜索、排行数据准备,以及后续新增玩法公开卡片接入。
- 验证方式:`npm run test -- src/components/rpg-entry/rpgEntryPublicGalleryViewModel.test.ts` 、`npm run typecheck` 、`npm run check:encoding` 、相关文件 ESLint 通过。
- 关联文档:`docs/technical/【前端架构】PublicGalleryViewModel收口计划-2026-06-03.md` 。
## 2026-06-03 Profile Task ViewModel 收口
- 背景:`RpgEntryHomeView.tsx` 同时持有每日任务卡片和任务中心弹窗的任务选择、进度 clamp、奖励兜底、状态标签和按钮文案, 导致任务展示规则和 JSX 缠在一起。
- 决策:新增 `src/components/rpg-entry/rpgEntryProfileTaskViewModel.ts` ,把 `selectProfileTaskCenterTasks` 、`selectProfileTaskCardTask` 、`buildProfileTaskCardSummary` 、`buildProfileTaskProgressLabel` 、`getProfileTaskStatusLabel` 和 `getProfileTaskClaimButtonLabel` 收口为每日任务 ViewModel Interface。任务中心仍只展示一条 claimable / incomplete 优先任务, 任务卡按可操作、claimed、非 disabled 的顺序兜底。
- 影响范围: RPG 首页“每日任务”卡片、任务中心弹窗、后续任务状态和任务展示文案调整。
- 验证方式:`npm run test -- src/components/rpg-entry/rpgEntryProfileTaskViewModel.test.ts` 、`npm run typecheck` 、`npm run check:encoding` 、相关文件 ESLint 通过。
- 关联文档:`docs/technical/【前端架构】ProfileTaskViewModel收口计划-2026-06-03.md` 。
## 2026-06-03 最近创作只复用创作模板入口
- 背景:底部加号创作入口的“最近创作”最初由真实作品架摘要驱动,但页面曾按作品标题、摘要和生成状态渲染独立最近创作卡,和其它模板页签的卡片样式及点击语义不一致。
@@ -216,7 +452,7 @@
## 2026-05-26 推荐页拼图下一关 pending 时保留当前运行态
- 背景:推荐页嵌入拼图在点击“下一关”时,`advancePuzzleNextLevel` 的服务端请求会短暂处于 pending。旧逻辑把推荐卡的 `isStartingRecommendEntry` 和拼图局部 busy 混在一起,导致外层直接切回“加载中...”,把当前 `PuzzleRuntimeShell` 一起卸载,视觉上像是切关闪回。
- 决策:推荐页嵌入拼图切关 pending 期间必须保留当前运行态与棋盘,只让拼图壳内部 busy 表现承接同步;`isStartingRecommendEntry` 只表示推荐作品尚未真正启动出来,不再把已有嵌入拼图 run 的局部 busy 一并当成整卡加载态。若下一关落到相似作品,前端还必须把新作品写回推荐缓存并同步 `activeRecommendEntryKey` ,避免运行态进入新作品但推荐卡元信息、分享 / 点赞 / 改造和后续“下一个”仍锚定旧作品;但这个同步仍属于同一个 run 内部推进,不得触发推荐 rail 切卡动画、纵向位移或启动封面重置 。
- 决策:推荐页嵌入拼图切关 pending 期间必须保留当前运行态与棋盘,只让拼图壳内部 busy 表现承接同步;`isStartingRecommendEntry` 只表示推荐作品尚未真正启动出来,不再把已有嵌入拼图 run 的局部 busy 一并当成整卡加载态。若下一关落到相似作品,前端还必须把新作品写回推荐缓存并同步 `activeRecommendEntryKey` ,避免运行态进入新作品但推荐卡元信息、分享 / 点赞 / 改造和后续“下一个”仍锚定旧作品。
- 影响范围:`src/components/platform-entry/PlatformEntryFlowShellImpl.tsx` 、`src/components/rpg-entry/RpgEntryHomeView.tsx` 、推荐页拼图切关测试与平台链路文档。
- 验证方式:点击推荐页拼图“下一关”后,在 `advancePuzzleNextLevel` 未返回前,页面仍应保留 `puzzle-board` ,且不出现 `加载中...` 占位;返回相似作品后,当前推荐卡的 `作品信息` 应显示新作品标题。
- 关联文档:`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md` 。
@@ -257,7 +493,6 @@
- 背景: 创作页顶部、banner 奖池和玩法卡消耗口径曾经混在一起,容易把活动奖池误认成账号余额,也让横向空间被外部边框和过大的卡片高度挤占。
- 决策:移动端创作 Tab 顶栏与 `陶泥儿` 品牌同一行只显示真实账户泥点数,数据直接取 `profileDashboard.walletBalance` ; banner 内只展示赛事奖池,新增拼图主题创作赛和抓大鹅主题创作赛,两个主题奖池各 `1000` 泥点数;玩法卡封面右下角固定展示 `10-20泥点数` ,列表外框取消,卡片高度和横向间距一起收紧。
- 追加决策:创作页和草稿页顶栏右上泥点余额胶囊是补足泥点入口;当前环境开启充值入口时直接打开账户充值弹窗,否则打开运营兑换码弹窗,不再跳到账户面板或泥点账单。
- 影响范围:`src/components/custom-world-home/CustomWorldCreationStartCard.tsx` 、`src/components/rpg-entry/RpgEntryHomeView.tsx` 、创作页相关测试和玩法链路文档。
- 验证方式:移动端浏览器检查应看到创作顶栏余额、卡内分页点、内嵌横向 banner 和更紧凑的玩法卡;`CustomWorldCreationHub.test.tsx` 与 `RpgEntryHomeView.recharge.test.tsx` 的定向断言应保持通过。
- 关联文档:`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md` 。
@@ -467,7 +702,7 @@
- 背景: Windows 本机直连极高 VU 压测会放大本地连接与发送缓冲行为,和线上 Linux + Nginx + systemd 拓扑不一致;需要一个更接近生产网络层的模拟方案,但不能扰动当前生产发布链路。
- 决策:新增 `deploy/container/` 容器化方案,使用 Docker Compose 组合 Linux release `api-server` 、容器 SpacetimeDB、容器 Nginx、`otelcol-contrib` debug exporter 和可选 k6。该方案只用于本机或预发压测模拟, 不替换当前生产 `systemd + Nginx + Jenkins` 路径。
- 服务器模拟参数: 2026-05-18 通过 `ssh genarrative-release` 采样,目标机器为 2 vCPU / 约 2 GiB RAM / Ubuntu 24.04 / Nginx `worker_connections=768` ;容器方案按待发布运行口径使用 `nofile=4096` ,并在 compose 中限制 `spacetimedb cpus=1.0 mem_limit=768 m` 、`api-server cpus=2.0 mem_limit=1g` 、`nginx cpus=0.2 5 mem_limit=128m` 、`otelcol cpus=0.25 mem_limit=128m` 、`k6 cpus=0.5 mem_limit=512m` ; Collector 镜像默认使用 `otel/opentelemetry-collector-contrib:0.151.0` 。
- 服务器模拟参数: 2026-05-18 通过 `ssh genarrative-release` 采样,目标机器为 2 vCPU / 约 2 GiB RAM / Ubuntu 24.04 / Nginx `worker_connections=768` ;容器方案按待发布运行口径使用 `nofile=4096` ,并在 compose 中限制 `spacetimedb cpus=1.0 mem_limit=896 m` 、`api-server cpus=2.0 mem_limit=1g` 、`external-generation-worker cpus=2.0 mem_limit=1g` 、`nginx cpus=0.5 mem_limit=128m` 、`otelcol cpus=0.25 mem_limit=128m` 、`k6 cpus=1.0 mem_limit=512m` ; Collector 镜像默认使用 `otel/opentelemetry-collector-contrib:0.151.0` 。
- 隔离边界:容器方案使用独立 `deploy/container/api-server.env` 、独立 Nginx 配置、独立 compose 命令和默认 `18080` 端口;真实 token 不进入镜像、不提交 Git; 生产 systemd 单元、Jenkins 发布脚本和 `deploy/nginx/` 模板仍是正式线上来源。
- 生产 Collector: server-provision 可安装 `otelcol-contrib.service` 和本机 debug exporter 配置,但二进制由 Jenkins 构建机先准备 `provision-tools/otelcol-contrib` 再上传到 release 部署 agent, 目标机不从 GitHub 下载; api-server 是否发送 OTLP 仍由 `GENARRATIVE_OTEL_ENABLED` 控制。
- 影响范围:`deploy/container/` 、`scripts/container-compose.mjs` 、`package.json` 容器命令、开发运维文档和容器 build context 排除规则。
@@ -476,7 +711,7 @@
## 2026-05-19 生产 provision 改为 Windows 下载包后由目标机本地安装
- 后续更新:该口径先 被 2026-06-01 Linux 优先方案取代,又在 2026-06-05 被 Server-Provision 专用口径覆盖 ;当前 `Genarrative-Server-Provision` 不走 Windows 下载阶段,也不 在 Linux build 节点中转工具包,而是在目标 dev / release agent 内 准备 `provision-tools/` 。
- 后续更新:该口径已 被 ` 2026-06-01 生产 Jenkins 流水线统一改为 Linux 优先并先查 localhost` 取代 ;当前 `Genarrative-Server-Provision` 不再 走 Windows 下载阶段,而是 在 Linux build 节点直接 准备 `provision-tools/` 。
- 背景:当前 `development` provision 目标实际就是 Linux agent `genarrative-build-01` ,之前把 `Prepare Provision Tools` 放在 `linux && genarrative-build` 会让目标机自己连 GitHub 和 `install.spacetimedb.com` , 违背“Windows 本机先下载再传到目标机”的运维要求。
- 决策:`Genarrative-Server-Provision` 拆成 Windows 下载阶段和 Linux 目标机安装阶段。Windows 节点的 `Download Provision Tool Archives` 只下载 `spacetime-x86_64-unknown-linux-gnu.tar.gz` 和 `otelcol-contrib_0.151.0_linux_amd64.tar.gz` ,通过 `stash/unstash` 传到目标 Linux 节点;目标机执行 `scripts/prepare-server-provision-tools.sh` 时设置 `PROVISION_REQUIRE_LOCAL_DOWNLOADS=true` ,只消费已下载件生成 `provision-tools/` ,缺包直接失败,不回退外网下载。
- 追加决策: Server-Provision 的 Windows helper 不再对 Jenkins `writeFile` 刚写出的 `.ps1` 做原地 UTF-8 BOM 重写,而是由显式 `powershell.exe` 按 UTF-8 读入脚本文本,并用 `ScriptBlock::Create(...)` 在内存中执行;这样既保留中文脚本内容,又避免同一个 workspace 脚本被立即重写时触发 `拒绝访问` 。
@@ -675,7 +910,7 @@
## 2026-05-13 refresh_session 会话组后端聚合与远端踢下线
- 背景:账号安全页中同设备同 IP 的多条 active `refresh_session` 会重复展示;退出登录没有稳定撤销当前 refresh session; 前端“踢下线”只做本地状态变化, 未真正让远端设备失效。
- 决策:`GET /api/auth/sessions` 由后端按“同设备 + 同 IP”聚合 active refresh sessions, 响应保留代表 `sessionId` 并新增 `sessionIds/sessionCount` ;组内包含当前 refresh hash 或 Bearer `sid` 时整组视为当前设备组,前端不展示踢下线。新增 `POST /api/auth/sessions/{session_id}/revoke` ,只允许撤销当前用户自己的非当前会话,不递增 `token_version` ,但认证中间件会校验 access token `sid` 对应 active refresh session, 使被踢设备立即失效。`/api/auth/logout` 在 refresh cookie 缺失时回退用 Bearer `sid` 撤销当前 session,并继续递增 `token_version` 。
- 决策:`GET /api/auth/sessions` 由后端按“同设备 + 同 IP”聚合 active refresh sessions, 响应保留代表 `sessionId` 并新增 `sessionIds/sessionCount` ;组内包含当前 refresh hash 或 Bearer `sid` 时整组视为当前设备组,前端不展示踢下线。新增 `POST /api/auth/sessions/{session_id}/revoke` ,只允许撤销当前用户自己的非当前会话,不递增 `token_version` ,但认证中间件会校验 access token `sid` 对应 active refresh session, 使被踢设备立即失效。`/api/auth/logout` 在 refresh cookie 缺失时回退用 Bearer `sid` 撤销当前 session;自 2026-06-07 起单设备退出也不再递增 `token_version` ,避免误伤其它设备,只有退出全部设备和改密类安全动作提升账号级版本 。
- 影响范围:`module-auth` refresh session service、`api-server` auth middleware/logout/sessions route、`shared-contracts` /TS auth contract、`AuthGate` 、`AccountModal` 、认证会话技术文档和路由/埋点索引。
- 验证方式:执行 `cargo test -p module-auth --manifest-path server-rs/Cargo.toml refresh_session` 、`cargo test -p api-server --manifest-path server-rs/Cargo.toml auth_sessions -- --nocapture` 、`cargo test -p api-server --manifest-path server-rs/Cargo.toml revoke_auth_session -- --nocapture` 、`cargo test -p api-server --manifest-path server-rs/Cargo.toml logout_succeeds_without_refresh_cookie_when_bearer_token_is_valid -- --nocapture` 、`npm run test -- AuthGate.test.tsx AccountModal.test.tsx authService.test.ts` 、`npm run check:encoding` 、`git diff --check` ,并用 `npm run dev:api-server` 检查 `/healthz` 。
- 关联文档:`docs/technical/AUTH_SESSIONS_QUERY_DESIGN_2026-04-21.md` 、`docs/technical/SPACETIMEDB_REFRESH_SESSION_TABLE_DESIGN_2026-04-21.md` 、`docs/technical/SERVER_RS_DDD_G1_CONTRACT_AND_ROUTE_MATRIX_2026-04-29.md` 。
@@ -1134,7 +1369,6 @@
## 2026-06-01 生产 Jenkins 流水线统一改为 Linux 优先并先查 localhost
- 后续更新:该条仍适用于常规构建 / 发布流水线;`Genarrative-Server-Provision` 已在 2026-06-05 改为目标部署 agent 全程执行,并禁止公网 Git fallback 与 build 节点工具包中转。
- 背景:生产流水线长期混用 Windows、Linux 和公网 Git 入口,导致构建 / 发布 / provision 的 checkout 口径分叉;同时 `Genarrative-Server-Provision` 还残留过 Windows 下载 helper, 和当前 Linux 构建 / 发布部署路径不一致。
- 决策:生产 Jenkins 流水线统一把执行节点收口到 Linux label, `Pipeline script from SCM` 仍保留公网域名,但所有生产流水线首次 `GitSCM checkout` 先尝试 `http://127.0.0.1:3000/GenarrativeAI/Genarrative.git` ,失败后再回退到 `https://git.genarrative.world/GenarrativeAI/Genarrative.git` ; `Genarrative-Stdb-Module-Build` 、`Genarrative-Server-Provision` 、`Genarrative-Notify-Email` 也都切到 Linux 节点。`Genarrative-Server-Provision` 的工具准备不再依赖 Windows helper, 而是在 Linux build 节点直接生成 `provision-tools/` 后交给后续 Linux 发布阶段。
- 影响范围:`jenkins/Jenkinsfile.production-*` 、`scripts/jenkins-checkout-source.sh` 、`scripts/prepare-server-provision-tools.sh` 、生产运维文档。
@@ -1173,13 +1407,38 @@
- 验证方式:从平台推荐或公开详情进入跳一跳作品时,路由 source type 为 `jump-hop` 、public code 为 `JH-*` ,运行态启动消费后端返回的完整 profile / run 数据;后端 smoke 统一使用 `npm run dev:api-server` 启动并检查 `/healthz` 。
- 关联文档:`docs/prd/【玩法创作】跳一跳俯视角玩法模板PRD-2026-05-19.md` 、`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md` 、`docs/【开发运维】本地开发验证与生产运维-2026-05-15.md` 。
## 2026-05-26 跳一跳地块图集改为专用 2x3 六格切分
## 2026-05-28 跳一跳重设计为 5x5 地块图集与弹弓拖拽
- 背景:跳一跳创作在地块生图阶段误用了通用系列素材图集 helper, `item_names.len() > grid_size` 的校验会让 6 个地块类型在 `grid_size = 3` 时直接失败;即使绕过校验,通用 helper 仍以“每物品多视图”语义切图,不符合跳一跳地块的一次性六格资产模型 。
- 决策:跳一跳地块图集固定采用专用 `2行*3列` 六格布局,按 `start / normal / target / finish / bonus / accent` 顺序切分并分别持久化为独立 PNG 资产;图集 prompt 不再调用通用系列素材 `build_generated_asset_sheet_prompt` 。
- 影响范围:`server-rs/crates/api-server/src/jump_hop.rs` 、`docs/prd/【玩法创作】跳一跳俯视角玩法模板PRD-2026-05-19.md` 、`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md` 。
- 验证方式:`cargo test -p api-server jump_ hop_tile_atlas -- --nocapture` 通过;六张切片都应有独立 OSS 对象与 `JumpHopTileAsset` 记录,不再只有 atlas 预览路径 。
- 关联文档:`docs/prd/【玩法创作】跳一跳俯视角玩法模板PRD-2026-05-19.md` 。
- 背景:旧 跳一跳模板仍保留角色生图、有限路径、score/combo 和 `2x3` 地块图集口径,和当前“俯视角平台跳跃 + 主题生成地块池 + 无限路径”的产品需求不一致 。
- 决策:`jump-hop` v1 创作端只保留主题输入; image2 生成一张 `5x5` 、共 25 个 2D 地块图标的图集,后端按均匀网格切出 25 个 `JumpHopTileAsset` 。角色不再单独生图,运行态使用陶泥儿 logo 透明 PNG 角色;运行态输入为按住后拉蓄力、松手反向弹出,前端提交 `chargeMs + dragVectorX + dragVectorY` ,后端裁决落点。草稿试玩必须使用 `runtimeMode=draft` ,正式作品使用 `runtimeMode=published` ;排行榜按作品维度每玩家只保留 1 条最佳记录,排序为成功跳跃次数降序、游戏时长升序、更新时间升序 。
- 决策补充:跳一跳创作入口的事实源仍是 SpacetimeDB `creation_entry_type_config` 。默认种子和旧默认行都必须同步迁移到 `subtitle=主题驱动平台跳跃` 、`image_src=/creation-type-references/jump-hop.webp` ;后端只在系统默认旧值命中时自动纠偏,避免覆盖后台手动配置 。
- 影响范围:`jump-hop` PRD、`api-server` 生成编排、`module- jump- hop` 领域规则、`spacetime-module` / `spacetime-client` 跳一跳契约、前端工作台 / 结果页 / runtime / 平台壳调用链 。
- 验证方式:`cargo check -p spacetime-module --manifest-path server-rs/Cargo.toml` 、`cargo check -p spacetime-client --manifest-path server-rs/Cargo.toml` 、`cargo check -p api-server --manifest-path server-rs/Cargo.toml` 、`npm run check:spacetime-schema` 、跳一跳工作台和 runtime 定向前端测试 。
- 关联文档:`docs/prd/【玩法创作】跳一跳俯视角玩法模板PRD-2026-05-19.md` 、`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md` 、`docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md` 。
## 2026-06-01 跳一跳运行态地块视觉尺寸和命中半径统一放大一倍
- 背景:当前跳一跳运行态里地块视觉尺寸偏小,玩家反馈“很难跳上去”,但仅放大前端展示会造成画面和后端裁决脱节。
- 决策:`jump-hop` 运行态的地块视觉尺寸、`width/height` 玩法世界尺寸以及 `landingRadius/perfectRadius` 同步乘以 2; 前端平台渲染抽成统一尺寸 helper, 保证单测可以直接校验放大结果。
- 影响范围:`server-rs/crates/module-jump-hop/src/application.rs` 、`src/services/jump-hop/jumpHopRuntimeModel.ts` 、`src/components/jump-hop-runtime/JumpHopRuntimeShell.tsx` 、对应定向测试。
- 验证方式:`npm test -- src/services/jump-hop/jumpHopRuntimeModel.test.ts src/components/jump-hop-runtime/JumpHopRuntimeShell.test.tsx` 、`cargo test -p module-jump-hop --manifest-path server-rs/Cargo.toml -- --nocapture` 。
- 关联文档:`docs/prd/【玩法创作】跳一跳俯视角玩法模板PRD-2026-05-19.md` 、`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md` 。
## 2026-06-02 跳一跳起跳距离减半并加入飞行动画缓冲
- 背景:用户反馈当前跳跃到目标位置需要拖得太远,且松手后缺少角色翻腾到目标地块的过渡动画,导致跳跃手感偏硬。
- 决策:`jump-hop` 的 `chargeToDistanceRatio` 统一从 `0.004` 提升到 `0.008` ,让同等跳跃距离所需拖动距离减半;前端 runtime 把“后端真实 run”和“当前屏幕显示态”拆开, 松手瞬间先生成 `visualJump` ,用当前角色位置作为起点、前端预测落点作为终点,播放约 `560ms` 的飞行动画;该路径不得等待后端新 run。角色弹到预测落点后若新 run 尚未返回,必须停在预测落点等待,再进入约 `1440ms` 的相机层推进过渡。推进期间地块 DOM 层和 DOM 角色层统一包在同一个 camera layer 下移动,旧当前地块自然离开视野,新预览地块从上方露出,避免 p1/p2 单独 top/left 过渡导致角色和地块不同步。相机推进必须同时使用 X/Y 偏移,从旧目标地块位置斜向滑到新当前地块聚焦位置,不能先横向瞬切居中再纵向推进。地块保留当前 / 目标 / 预览的深度尺寸差异,但该差异通过固定基准宽高上的 CSS transform scale 表达,并在相机推进期间同样使用 `1440ms` 缓动;当前态不再额外叠 CSS scale。
- 影响范围:`server-rs/crates/module-jump-hop/src/application.rs` 、`src/services/jump-hop/jumpHopRuntimeModel.ts` 、`src/components/jump-hop-runtime/JumpHopRuntimeShell.tsx` 、跳一跳运行态定向测试。
- 验证方式:`npm test -- src/services/jump-hop/jumpHopRuntimeModel.test.ts src/components/jump-hop-runtime/JumpHopRuntimeShell.test.tsx` 、`cargo test -p module-jump-hop --manifest-path server-rs/Cargo.toml -- --nocapture` 、`npm run check:encoding` 。
- 关联文档:`docs/prd/【玩法创作】跳一跳俯视角玩法模板PRD-2026-05-19.md` 、`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md` 。
## 2026-06-03 跳一跳角色形象改为陶泥儿 logo 透明 PNG
- 背景:跳一跳运行态此前仍使用旧内置 / CSS 角色形象,和用户要求的陶泥儿 logo 角色不一致,也容易和 DOM 地块层出现遮挡层级问题。
- 决策:`jump-hop` v1 不再渲染内置 3D 角色几何体;运行态和结果页统一使用 `public/branding/jump-hop-taonier-character.png` ,该文件由陶泥儿 logo 处理为透明 PNG 后接入。蓄力时角色沿拖拽方向明显拉长,落地后向反方向回弹两次。`characterAsset` 继续仅作为历史兼容描述字段,不能重新打开角色生图槽或把角色图片作为创作者可配置输入。
- 影响范围:`src/components/jump-hop-runtime/JumpHopRuntimeShell.tsx` 、`src/components/jump-hop-result/JumpHopResultView.tsx` 、跳一跳 PRD 和平台链路文档。
- 验证方式:跳一跳运行态 / 结果页测试需要断言角色图片 src 为 `/branding/jump-hop-taonier-character.png` ,并确认旧默认角色 fallback 不再出现。
- 关联文档:`docs/prd/【玩法创作】跳一跳俯视角玩法模板PRD-2026-05-19.md` 、`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md` 。
# 2026-05-20 陶泥儿主视觉配色回收为暖白/陶土橙
@@ -1225,6 +1484,186 @@
- 验证方式:工作台首屏不再出现标题 / 简介 / 标签输入;结果页修改后点试玩或发布会先写回当前作品信息。
- 关联文档:`docs/prd/【玩法创作】敲木鱼玩法模板PRD-2026-05-20.md` 、`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md` 。
## 2026-06-03 Profile Dashboard Presentation 收口
- 背景:`RpgEntryHomeView.tsx` 同时承载个人数据卡、钱包 chip 与“玩过”弹窗,计数压缩、累计时长、单作品时长、玩法标签和作品号兜底散在页面 Implementation 内,修改展示口径时缺少稳定测试面。
- 决策:新增 `src/components/rpg-entry/rpgEntryProfileDashboardPresentation.ts` 作为个人数据展示 Module, Interface 收口为 `buildProfileDashboardPresentation` 、计数 / 时长格式化和“玩过”列表标签 / 作品号格式化函数;页面只消费结果并保留 UI 编排与点击处理。
- 影响范围: RPG 首页“我的数据”卡片、移动端 / 桌面端钱包 chip、个人数据弹窗与“玩过”列表。
- 验证方式:`npm run test -- src/components/rpg-entry/rpgEntryProfileDashboardPresentation.test.ts` 、针对变更文件执行 ESLint、`npm run typecheck` 、`npm run check:encoding` 。
- 关联文档:`docs/technical/【前端架构】ProfileDashboardPresentation收口计划-2026-06-03.md` 。
## 2026-06-03 Recommend Feed ViewModel 收口
- 背景:推荐 feed 与正式 runtime 的上一条 / 下一条选择分别在 `RpgEntryHomeView.tsx` 和 `PlatformEntryFlowShellImpl.tsx` 手写公开作品去重、隐藏内容过滤、active key 兜底和相邻回环,存在推荐预览与 runtime 口径漂移风险。
- 决策:在 `src/components/rpg-entry/rpgEntryPublicGalleryViewModel.ts` 追加推荐 feed Module Interface: `dedupePlatformPublicGalleryEntries` 、`buildPlatformRecommendFeedEntries` 、`selectPlatformRecommendFeedWindow` 、`selectAdjacentPlatformRecommendEntry` ;首页与 FlowShell 均消费该 Interface。
- 影响范围:移动端首页推荐 swipe、发现页推荐频道、桌面推荐格、推荐 runtime 队列与上一条 / 下一条跳转。
- 验证方式:`npm run test -- src/components/rpg-entry/rpgEntryPublicGalleryViewModel.test.ts` 、`npm run test -- src/components/rpg-entry/RpgEntryHomeView.recharge.test.tsx -t "recommend|edutainment"` 、`npm run test -- src/components/rpg-entry/RpgEntryFlowShell.agent.interaction.test.tsx -t "logged out home recommendation next starts the next puzzle work"` 、针对变更文件执行 ESLint、`npm run typecheck` 、`npm run check:encoding` 。
- 关联文档:`docs/technical/【前端架构】RecommendFeedViewModel收口计划-2026-06-03.md` 。
## 2026-06-03 Recommend Swipe Deck Model 收口
- 背景:移动端推荐首页 swipe deck 的拖拽阈值、offset clamp、commit 方向、rail class 和分享文案仍留在 `RpgEntryHomeView.tsx` 页面 Implementation 内,页面同时承载 DOM pointer 副作用和纯规则。
- 决策:新增 `src/components/rpg-entry/rpgEntryRecommendSwipeDeckModel.ts` 作为 Recommend Swipe Deck Module, Interface 收口 `hasRecommendDragStarted` 、`clampRecommendDragOffset` 、`resolveRecommendDragCommitDirection` 、`resolveRecommendCommitOffset` 、`buildRecommendSwipeRailClassName` 、`shouldAnimateRecommendSwipe` 与 `buildRecommendShareText` ;页面仅保留 pointer capture、DOM 高度读取、动画 timer、clipboard 与 like/remix/open 副作用 Adapter。
- 影响范围:移动端推荐首页 swipe 手势、上一条 / 下一条动画、推荐分享文案与未登录时的直接切换行为。
- 验证方式:`npm run test -- src/components/rpg-entry/rpgEntryRecommendSwipeDeckModel.test.ts` 、`npm run test -- src/components/rpg-entry/RpgEntryHomeView.recharge.test.tsx -t "recommend|edutainment"` 、`npm run test -- src/components/rpg-entry/rpgEntryPublicGalleryViewModel.test.ts -t "recommend"` 、针对新 Module 执行 ESLint、`npm run typecheck` 、`npm run check:encoding` 。
- 关联文档:`docs/technical/【前端架构】RecommendSwipeDeckModel收口计划-2026-06-03.md` 。
## 2026-06-03 Ranking ViewModel 收口
- 背景:排行 tab 的文案、metric label 与空态文案在 `RpgEntryHomeView.tsx` ,排序和 metric value 在 `rpgEntryPublicGalleryViewModel.ts` ,同一 `PlatformRankingTab` 的 Interface 分散且页面需要类型断言取 active config。
- 决策:在 `src/components/rpg-entry/rpgEntryPublicGalleryViewModel.ts` 收口 `DEFAULT_PLATFORM_RANKING_TAB` 、`PLATFORM_RANKING_TABS` 、`getPlatformRankingTabConfig` 与 `getPlatformRankingMetric` ;页面仅保留 active tab 状态和渲染。
- 影响范围:发现页排行频道 tab 顺序、tab 文案、空态文案、排行项指标 label/value。
- 验证方式:`npm run test -- src/components/rpg-entry/rpgEntryPublicGalleryViewModel.test.ts` 、`npm run test -- src/components/rpg-entry/RpgEntryHomeView.recharge.test.tsx -t "bottom category tab becomes ranking and switches ranking metrics|ranking"` 、针对变更文件执行 ESLint、`npm run typecheck` 、`npm run check:encoding` 。
- 关联文档:`docs/technical/【前端架构】RankingViewModel收口计划-2026-06-03.md` 。
## 2026-06-03 Category Option ViewModel 收口
- 背景: 分类频道的筛选选项、排序选项、默认值、active label fallback 和排序循环仍留在 `RpgEntryHomeView.tsx` 页面 Implementation 内,而玩法过滤、排序和主指标已经在 `rpgEntryPublicGalleryViewModel.ts` ,同一分类 Interface 被拆成两处。
- 决策:在 `src/components/rpg-entry/rpgEntryPublicGalleryViewModel.ts` 收口 `DEFAULT_PLATFORM_CATEGORY_KIND_FILTER` 、`DEFAULT_PLATFORM_CATEGORY_SORT_MODE` 、`PLATFORM_CATEGORY_KIND_FILTERS` 、`PLATFORM_CATEGORY_SORT_OPTIONS` 、`getPlatformCategoryKindFilterOption` 、`getPlatformCategorySortOption` 与 `getNextPlatformCategorySortMode` ;页面仅保留当前筛选 / 排序状态和渲染。
- 影响范围:发现页分类频道筛选弹窗、筛选按钮 label、排序按钮 label 与排序循环。
- 验证方式:`npm run test -- src/components/rpg-entry/rpgEntryPublicGalleryViewModel.test.ts` 、`npm run test -- src/components/rpg-entry/RpgEntryHomeView.recharge.test.tsx -t "category"` 、针对变更文件执行 ESLint、`npm run typecheck` 、`npm run check:encoding` 。
- 关联文档:`docs/technical/【前端架构】PublicGalleryViewModel收口计划-2026-06-03.md` 。
## 2026-06-03 Match3D Runtime Profile 收口
- 背景:`PlatformEntryFlowShellImpl.tsx` 内仍直接承载抓大鹅公开详情转 work、session draft 转 profile、生成背景资产提升、runtime active profile 选择和 run / profile / public detail 素材优先级,平台壳需要理解抓大鹅生成素材内部结构。
- 决策:新增 `src/components/platform-entry/platformMatch3DRuntimeProfile.ts` 作为抓大鹅 runtime profile Module, Interface 收口 `mapPublicWorkDetailToMatch3DWork` 、`buildMatch3DProfileFromSession` 、`normalizeMatch3DWorkForRuntimeUi` 、`mapMatch3DWorksForRuntimeUi` 、`promoteMatch3DGeneratedBackgroundAsset` 、`hasMatch3DRuntimeAsset` 、`hasMatch3DRuntimeBackgroundAsset` 、`resolveActiveMatch3DRuntimeProfile` 与 runtime item/background/backgroundImage 解析函数;平台壳只保留启动 run、预加载、路由、错误和 state 编排。
- 影响范围:抓大鹅作品架、公开详情试玩、推荐 runtime、正式 runtime 与草稿结果页试玩前素材规范化。
- 验证方式:`npm run test -- src/components/platform-entry/platformMatch3DRuntimeProfile.test.ts` 、`npm run test -- src/components/rpg-entry/RpgEntryFlowShell.agent.interaction.test.tsx -t "match3d|抓大鹅"` 、针对新 Module 执行 ESLint、`npm run typecheck` 、`npm run check:encoding` 。
- 关联文档:`docs/technical/【前端架构】Match3DRuntimeProfile收口计划-2026-06-03.md` 。
## 2026-06-03 Draft Generation Shelf Model 收口
- 背景:平台壳内散落创作生成 notice key、pending 作品架占位、作品详情更新回填、失败文案覆盖、拼图稳定 ID、持久化 generating/failed 判断与草稿 Tab 未读点,新增或调整玩法时需要在多处理解 `workId` / `profileId` / `sourceSessionId` / `draftId` 形状。
- 决策:新增 `src/components/platform-entry/platformDraftGenerationShelfModel.ts` 作为 Draft Generation Shelf Module, Interface 收口 `collectDraftNoticeKeys` 、`getGenerationNoticeShelfKeys` 、`createPendingDraftShelfState` 、各玩法 `buildPending*Works` 、`buildCreationWorkShelfRuntimeState` 、`collectVisibleDraftNoticeKeys` 、`hasUnreadDraftGenerationUpdates` 、`mergePuzzleWorkSummary` 、`mergeBigFishWorkSummary` 、拼图稳定 ID 与持久化状态判断;`PlatformEntryFlowShellImpl.tsx` 仅作为 React state、网络刷新、路由和弹窗副作用 Adapter。
- 影响范围:创作中心草稿 Tab 未读点、作品架生成中遮罩、作品详情更新回填、失败草稿摘要、pending 草稿占位、拼图 / 抓大鹅生成恢复和各玩法生成完成通知。
- 验证方式:`npm run test -- src/components/platform-entry/platformDraftGenerationShelfModel.test.ts` 、`npm run test -- src/components/custom-world-home/creationWorkShelf.test.ts -t "generation state|failure notice|failed puzzle"` 、`npm run test -- src/components/rpg-entry/RpgEntryFlowShell.agent.interaction.test.tsx -t "persisted generating puzzle draft|persisted generating match3d draft|completed baby object match draft"` 、针对新 Module 执行 ESLint、`npm run typecheck` 、`npm run check:encoding` 。
- 关联文档:`docs/technical/【前端架构】DraftGenerationShelfModel收口计划-2026-06-03.md` 。
## 2026-06-03 Creation Hub Shelf Items Interface 收口
- 背景:`creationWorkShelf.ts` 已把各玩法作品映射为 `CreationWorkShelfItem.actions` ,但 `CustomWorldCreationHub.tsx` 的生产 Interface 仍接收 raw items 与 open/delete/claim 回调列阵,新增玩法时 Hub props 继续膨胀。
- 决策:`CustomWorldCreationHub.tsx` 生产 Interface 收敛为 `shelfItems: CreationWorkShelfItem[]` 与少量 UI 状态;`PlatformEntryFlowShellImpl.tsx` 在外层作为 Adapter 调用 `buildCreationWorkShelfItems` 注入完整 actions; Hub 测试改经 `CustomWorldCreationHub.testAdapter.tsx` 把旧 fixture 转成 shelf items, 不让测试继续依赖旧浅 Interface。
- 影响范围:创作 Tab / 草稿 Tab 作品架、RPG / 拼图 / 抓大鹅 / 方洞 / 跳一跳 / 敲木鱼 / 视觉小说 / Bark Battle / 宝贝识物作品打开、删除、生成态与拼图奖励领取。
- 验证方式:`npm run test -- src/components/custom-world-home/creationWorkShelf.test.ts` 、`npm run test -- src/components/custom-world-home/CustomWorldCreationHub.test.tsx` 、`npm run test -- src/components/custom-world-home/CustomWorldCreationHub.interaction.test.tsx` 、相关 FlowShell creation hub 交互片段、针对变更文件执行 ESLint、`npm run typecheck` 、`npm run check:encoding` 。
- 关联文档:`docs/technical/【前端架构】WorkShelfModule收口计划-2026-06-03.md` 。
## 2026-06-03 Creation URL State Model 收口
- 背景:平台壳内散落各玩法创作恢复 URL 的 `sessionId` / `profileId` / `draftId` / `workId` 组装、空值归一化、拼图 runtime query key 与拼图稳定身份互推,导致刷新恢复规则缺少稳定测试面。
- 决策:新增 `src/components/platform-entry/platformCreationUrlStateModel.ts` 作为 Creation URL State Module, Interface 收口各玩法 `build*CreationUrlState` 、拼图 `buildPuzzle*RuntimeUrlState` 、URL state 非空判断和 runtime state key; 新增 `src/components/platform-entry/platformPuzzleIdentityModel.ts` 作为拼图稳定身份 Module, `platformDraftGenerationShelfModel.ts` 仅 re-export 旧入口以保持兼容。`PlatformEntryFlowShellImpl.tsx` 只保留路由、URL 写入和网络副作用 Adapter。
- 追加决策:初始创作 URL 恢复的已处理、非创作路径、无私有 query、平台配置加载中、受保护数据暂不可读与可恢复判定也收口到 `resolveInitialCreationUrlRestoreDecision` ;壳层只按 `skip` 、`mark-handled` 、`wait` 、`restore` 执行 ref 标记或进入原恢复副作用。
- 追加决策:创作直达恢复目标解析收口到 `resolveCreationUrlRestoreTarget(pathname, state)` ; Module 统一识别 big-fish、match3d、square-hole、puzzle、visual-novel、bark-battle、baby-object-match、jump-hop、wooden-fish 的 path、私有 query 归一化、生成路径标记和 big-fish workId 到 sessionId 兜底。壳层仍执行作品列表读取、草稿恢复、错误处理、stage 切换和 URL 写回;`/creation/rpg` 继续保持无具体恢复目标,后续要接入需先补规则与测试。
- 追加决策:创作 URL 恢复的作品 / 草稿身份匹配谓词、以及跳一跳 / 敲木鱼恢复后的阶段落点也归入 `platformCreationUrlStateModel.ts` 。身份匹配只允许非空目标值命中,避免 query 缺失时用空值误开草稿; 壳层只把已读取的列表项、session 或 work 交给 Module 判定,然后执行对应打开 / restore 副作用。
- 影响范围:创作流程刷新恢复、拼图草稿 / 发布 runtime 深链、作品架打开试玩、跳一跳 / 敲木鱼 work-backed 恢复、Bark Battle / 宝贝识物本地草稿恢复。
- 验证方式:`npm run test -- src/components/platform-entry/platformCreationUrlStateModel.test.ts src/components/platform-entry/platformPuzzleIdentityModel.test.ts` 、`npm run test -- src/services/creationUrlState.test.ts` 、`npm run test -- src/components/platform-entry/platformDraftGenerationShelfModel.test.ts` 、针对新 Module 执行 ESLint、`npm run typecheck` 、`npm run check:encoding` 。
- 关联文档:`docs/technical/【前端架构】CreationUrlStateModel收口计划-2026-06-03.md` 。
## 2026-06-04 Platform Public Code Search Model 收口
- 背景:`PlatformEntryFlowShellImpl.tsx` 的公开搜索回调内联判断内部用户 ID、陶泥号、RPG 作品号、各玩法公开作品号前缀和 fallback 顺序,壳层同时承担纯搜索计划与网络 / 打开副作用。
- 决策:新增 `src/components/platform-entry/platformPublicCodeSearchModel.ts` ,以 `resolvePlatformPublicCodeSearchPlan(keyword)` 返回 `normalizedKeyword` 与 `steps` 。`user_` / `user-` 只查用户 ID; 玩法前缀直达对应作品; `CW` / 纯数字先查 RPG 作品再查陶泥号;普通关键词和 `SY` 保持既有用户号、RPG 作品、汪汪声浪、用户号兜底顺序。壳层只按 step 执行既有查找、详情打开、Bark Battle runtime 特例和 missing work 归航。
- 影响范围:发现页 / 推荐页公开搜索、作品详情深链初始搜索、陶泥号命中面板、各玩法公开作品号直达。
- 验证方式:`npm run test -- src/components/platform-entry/platformPublicCodeSearchModel.test.ts` 、针对新 Module 和 `PlatformEntryFlowShellImpl.tsx` 执行 ESLint、`npm run typecheck` 、`npm run check:encoding` 。
- 关联文档:`docs/technical/【前端架构】PlatformPublicCodeSearchModel收口计划-2026-06-04.md` 、`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md` 。
## 2026-06-04 Platform Played Work Open Model 收口
- 背景:`PlatformEntryFlowShellImpl.tsx` 的个人“玩过作品”点击回调内联判断 `worldType` 、`worldKey` 前缀、玩法别名、目标 ID、RPG fallback 详情和大鱼吃小鱼 fallback work, 壳层同时承担打开意图与异步副作用。
- 决策:新增 `src/components/platform-entry/platformPlayedWorkOpenModel.ts` ,以 `resolvePlatformPlayedWorkOpenIntent(work)` 返回 `noop` 、各玩法公开详情打开意图、`open-big-fish` 或 `open-rpg` 。Module 负责玩法别名、`worldKey` 前缀兜底、big-fish gallery miss `fallbackWork` 和 RPG `CustomWorldGalleryCard` payload; 壳层继续负责关闭面板、刷新 gallery、命中真实作品、打开详情和错误提示。
- 影响范围:个人“玩过作品”面板点击打开、拼图 / 抓大鹅 / 方洞 / 跳一跳 / 敲木鱼 / 大鱼吃小鱼 / RPG 公开详情入口。
- 验证方式:`npm run test -- src/components/platform-entry/platformPlayedWorkOpenModel.test.ts` 、针对新 Module 和 `PlatformEntryFlowShellImpl.tsx` 执行 ESLint、相关 profile 面板交互片段、`npm run typecheck` 、`npm run check:encoding` 。
- 关联文档:`docs/technical/【前端架构】PlatformPlayedWorkOpenModel收口计划-2026-06-04.md` 、`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md` 。
## 2026-06-04 Platform Generation Progress Tick Model 收口
- 背景:`PlatformEntryFlowShellImpl.tsx` 的生成页进度 tick effect 内联维护 stage 到小游戏生成状态的三元链,并额外手写视觉小说 `startedAtMs` / `phase` 特例,壳层同时承担纯判定与 interval 副作用。
- 决策:新增 `src/components/platform-entry/platformGenerationProgressTickModel.ts` ,以 `resolvePlatformGenerationProgressTickDecision(input)` 返回 `{ activeKind, shouldTick }` 。Module 负责 stage 到 kind 映射、小游戏状态缺失 / 终态判定、视觉小说轻量生成判定;壳层继续负责 `Date.now()` 、`window.setInterval` 、progress now state 写入和 cleanup。
- 影响范围:拼图、抓大鹅、大鱼吃小鱼、方洞挑战、跳一跳、敲木鱼、宝贝识物和视觉小说生成页进度 tick。
- 验证方式:`npm run test -- src/components/platform-entry/platformGenerationProgressTickModel.test.ts` 、针对新 Module 和 `PlatformEntryFlowShellImpl.tsx` 执行 ESLint、`npm run typecheck` 、`npm run check:encoding` 。
- 关联文档:`docs/technical/【前端架构】PlatformGenerationProgressTickModel收口计划-2026-06-04.md` 、`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md` 。
## 2026-06-04 Platform Mini Game Session Mapping Model 收口
- 背景:`PlatformEntryFlowShellImpl.tsx` 顶部仍保留拼图 runtime 恢复、方洞 session draft 转 profile、视觉小说 work detail 转 Agent session、跳一跳 pending session、敲木鱼 detail 恢复、敲木鱼生成中作品摘要和敲木鱼 pending session 等纯 DTO 映射,壳层需要理解 sessionId 优先级、拼图稳定 ID、方洞草稿 profile 默认值、视觉小说 work/session fallback、敲木鱼生成中摘要和 pending draft 默认值。
- 决策:新增 `src/components/platform-entry/platformMiniGameSessionMappingModel.ts` ,收口 `buildPuzzleRuntimeWorkFromSession` 、`buildSquareHoleProfileFromSession` 、`buildVisualNovelSessionFromWorkDetail` 、`buildJumpHopPendingSession` 、`buildWoodenFishSessionFromWorkDetail` 、`buildWoodenFishGeneratingWorkSummary` 与 `buildWoodenFishPendingSession` 。Module 复用 `normalizeCreationUrlValue` 与 `platformPuzzleIdentityModel` ; 壳层只保留网络读取、React state、URL 写入和 stage 切换副作用。
- 影响范围:拼图 runtime URL 恢复、方洞挑战草稿 profile 构造、视觉小说草稿作品架恢复、跳一跳生成中作品架打开、敲木鱼生成中作品架摘要 / 作品架打开和敲木鱼草稿 detail 恢复。
- 验证方式:`npm run test -- src/components/platform-entry/platformMiniGameSessionMappingModel.test.ts` 、针对新 Module 和 `PlatformEntryFlowShellImpl.tsx` 执行 ESLint、`npm run typecheck` 、`npm run check:encoding` 。
- 关联文档:`docs/technical/【前端架构】PlatformMiniGameSessionMappingModel收口计划-2026-06-04.md` 、`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md` 。
## 2026-06-04 Platform RPG Agent Result Preview Model 收口
- 背景:`PlatformEntryFlowShellImpl.tsx` 内联维护 RPG Agent 结果页发布门禁展示修正和 result preview source label 映射,壳层需要理解 `CustomWorldProfile` 顶层字段、`creatorIntent` 、`anchorContent` 、章节蓝图和首幕 acts。
- 决策:新增 `src/components/platform-entry/platformRpgAgentResultPreviewModel.ts` ,收口 `buildPlatformRpgAgentResultPublishGateView` 与 `resolvePlatformRpgAgentResultPreviewSourceLabel` 。Module 只做展示层纯判定;壳层继续负责 session/profile 编排、发布副作用和结果页 props 传递。
- 影响范围: RPG Agent 结果页发布按钮门禁 blockers、publishReady 展示修正和预览来源 label。
- 验证方式:`npm run test -- src/components/platform-entry/platformRpgAgentResultPreviewModel.test.ts` 、针对新 Module 和 `PlatformEntryFlowShellImpl.tsx` 执行 ESLint、`npm run typecheck` 、`npm run check:encoding` 。
- 关联文档:`docs/technical/【前端架构】PlatformRpgAgentResultPreviewModel收口计划-2026-06-04.md` 、`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md` 。
## 2026-06-04 Platform Mini Game Draft Generation State Model 收口
- 背景:`PlatformEntryFlowShellImpl.tsx` 内联维护小游戏生成状态恢复、失败 / 完成收尾、展示 rebase、拼图后端进度合并和 ready / generating 判定,壳层同时承担 API / background task 副作用和 `MiniGameDraftGenerationState` 生命周期细节。
- 决策:新增 `src/components/platform-entry/platformMiniGameDraftGenerationStateModel.ts` ,收口恢复态、失败态、完成态、展示 rebase、拼图 progress phase 阈值和进度 metadata 合并。壳层继续负责 API、后台任务、React state 写入、作品架刷新、URL 和 stage 切换。
- 追加决策:抓大鹅轮询作品素材时的旁路进度合并也归入该 Module, 由 `mergeMatch3DGeneratedAssetsIntoGenerationState(state, assets)` 统一统计可用图片素材、至少 5 个总素材计数、`match3d-generate-views` phase 推进和首个素材错误传播;壳层只负责轮询 session / work detail 与写入 state。
- 影响范围:拼图 / 抓大鹅 / 大鱼吃小鱼 / 方洞 / 跳一跳 / 敲木鱼 / 宝贝识物生成状态恢复、完成失败收尾、生成页返回展示和拼图轮询进度合并。
- 验证方式:`npm run test -- src/components/platform-entry/platformMiniGameDraftGenerationStateModel.test.ts` 、针对新 Module 和 `PlatformEntryFlowShellImpl.tsx` 执行 ESLint、`npm run typecheck` 、`npm run check:encoding` 。
- 关联文档:`docs/technical/【前端架构】PlatformMiniGameDraftGenerationStateModel收口计划-2026-06-04.md` 、`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md` 。
## 2026-06-04 Platform Mini Game Draft Payload Model 收口
- 背景:`PlatformEntryFlowShellImpl.tsx` 内联维护拼图 / 抓大鹅表单 payload、拼图作品更新 payload、拼图编译 action、跳一跳 / 敲木鱼生成 action、作品摘要回填 payload 和 pending 草稿 metadata, 壳层需要理解描述字段优先级、formDraft 回退、结果页 draft 到作品更新字段的映射、跳一跳 / 敲木鱼 payload 与 draft 优先级、Match3D config / draft / anchorPack 优先级和数字解析。
- 决策:新增 `src/components/platform-entry/platformMiniGameDraftPayloadModel.ts` ,收口 `buildPuzzleFormPayloadFromWork` 、`buildPuzzleFormPayloadFromSession` 、`buildPuzzleFormPayloadFromAction` 、`buildPuzzleCompileActionFromFormPayload` 、`buildPuzzleWorkUpdatePayloadFromDraft` 、`buildJumpHopDraftActionPayload` 、`buildWoodenFishDraftActionPayload` 、`buildPendingPuzzleDraftMetadata` 、`isPuzzleFormOnlyDraft` 、`isEmptyPuzzleFormOnlyDraft` 、`buildMatch3DFormPayloadFromSession` 、`buildMatch3DFormPayloadFromWork` 与 `buildPendingMatch3DDraftMetadata` ; `parseOptionalFiniteNumber` 留在 Module 内部。
- 影响范围:拼图 action 完成 / 执行前 / 失败恢复、拼图结果页试玩前作品更新、跳一跳 / 敲木鱼生成与重生成 action、拼图表单直生草稿、拼图 form-only 草稿恢复 / 分流 / 结果页渲染、拼图草稿架恢复、抓大鹅表单直生草稿与失败恢复。
- 验证方式:`npm run test -- src/components/platform-entry/platformMiniGameDraftPayloadModel.test.ts` 、针对新 Module 和 `PlatformEntryFlowShellImpl.tsx` 执行 ESLint、`npm run typecheck` 、`npm run check:encoding` 。
- 关联文档:`docs/technical/【前端架构】PlatformMiniGameDraftPayloadModel收口计划-2026-06-04.md` 、`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md` 。
## 2026-06-04 Platform Puzzle Draft Recovery Model 收口
- 背景:`PlatformEntryFlowShellImpl.tsx` 的拼图恢复链路只要 cover 或候选图存在就会把恢复 session 抬为 ready, 可能让缺关卡画面、UI spritesheet 或关卡背景的半成品直接进入结果页完成态。
- 决策:新增 `src/components/platform-entry/platformPuzzleDraftRecoveryModel.ts` ,收口 `normalizeRecoveredPuzzleDraftSession` 与 `hasRecoverableGeneratedPuzzleDraft` 。恢复完成态必须同时具备首图、`levelSceneImage*` 、`uiSpritesheetImage*` 与 `levelBackgroundImage*` ;只有完整资产包成立时才把 draft 与首关 `generationStatus` 抬为 `ready` 。
- 影响范围:拼图生成完成后刷新恢复、拼图 background compile task 完成态写入和结果页自动打开。
- 验证方式:`npm run test -- src/components/platform-entry/platformPuzzleDraftRecoveryModel.test.ts` 、针对新 Module 和 `PlatformEntryFlowShellImpl.tsx` 执行 ESLint、`npm run test -- src/components/rpg-entry/RpgEntryFlowShell.agent.interaction.test.tsx -t "persisted generating puzzle draft"` 、`npm run typecheck` 、`npm run check:encoding` 。
- 关联文档:`docs/technical/【前端架构】PlatformPuzzleDraftRecoveryModel收口计划-2026-06-04.md` 、`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md` 。
## 2026-06-04 Platform Puzzle Runtime State Model 收口
- 背景:`PlatformEntryFlowShellImpl.tsx` 在拼图排行榜提交回包后内联合并服务端 run 快照,壳层需要理解 `PuzzleRunSnapshot` 中哪些字段由前端即时裁决、哪些字段只由服务端补齐。
- 决策:新增 `src/components/platform-entry/platformPuzzleRuntimeStateModel.ts` ,以 `mergePuzzleServiceRuntimeState(currentRun, serviceRun)` 收口服务端 run 合并规则。Module 保留当前前端关卡状态、棋盘和计时,只合并服务端 run 身份、`clearedLevelCount` 上限、排行榜与下一关 handoff; 任一 run 缺 `currentLevel` 时直接返回当前 run。
- 影响范围:拼图排行榜提交、推荐 runtime isolated / default 运行态回包合并、下一关同作品 / 相似作品 handoff, 以及后续 Puzzle runtime 快照字段调整。
- 验证方式:`npm run test -- src/components/platform-entry/platformPuzzleRuntimeStateModel.test.ts` 、针对新 Module 和 `PlatformEntryFlowShellImpl.tsx` 执行 ESLint、`npm run typecheck` 、`npm run check:encoding` 。
- 关联文档:`docs/technical/【前端架构】PlatformPuzzleRuntimeStateModel收口计划-2026-06-04.md` 、`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md` 。
## 2026-06-04 Puzzle Publish Asset Gate 收紧
- 背景:后端拼图待发布门槛与前端历史恢复逻辑一样偏弱,只要求标题、描述、标签、关卡名和 cover, 导致缺关卡画面、UI spritesheet 或关卡背景的半成品可能被标为 `publishReady` / `ready_to_publish` 。
- 决策:`module-puzzle::validate_publish_requirements` 新增三类资产 blocker, 要求每关具备 `level_scene_image_*` 、`ui_spritesheet_image_*` 与 `level_background_image_*` ; `api-server::puzzle::tags::is_puzzle_session_snapshot_publish_ready` 同步使用完整资产包判定。
- 影响范围:拼图 result preview blockers、publishReady、标签生成后 session stage、从 action payload 构造 fallback session 的 ready 判定。
- 验证方式:`cargo test -p module-puzzle --manifest-path server-rs/Cargo.toml validate_publish_requirements` 、`cargo test -p api-server --manifest-path server-rs/Cargo.toml puzzle_image_generation_builds_fallback_session_from_levels_snapshot` 、`cargo test -p api-server --manifest-path server-rs/Cargo.toml puzzle_image_generation_fallback_session_ready_when_asset_pack_complete` 、`npm run check:encoding` 。
- 关联文档:`docs/technical/【后端架构】PuzzlePublishAssetGate收紧计划-2026-06-04.md` 、`docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md` 、`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md` 。
## 2026-06-04 Platform Profile Wallet Delta Model 收口
- 背景:`PlatformEntryFlowShellImpl.tsx` 内联维护钱包余额归一、本地 delta 乐观更新和服务端 dashboard 刷新后的 delta 抵消,壳层需要理解余额非负、整数截断、借贷方向和服务端快照对账。
- 决策:新增 `src/components/platform-entry/platformProfileWalletDeltaModel.ts` ,收口 `resolveProfileWalletBalance` 、`adjustProfileDashboardWalletBalance` 与 `reconcileProfileWalletLocalDeltaWithServerDashboard` 。壳层只保留 API 请求、React ref、state 写入和刷新触发副作用。
- 影响范围:创作入口泥点展示、生成前泥点校验、扣点 / 返还后的个人 dashboard 乐观更新、后台刷新 dashboard 时的本地 delta 对账。
- 验证方式:`npm run test -- src/components/platform-entry/platformProfileWalletDeltaModel.test.ts` 、针对新 Module 和 `PlatformEntryFlowShellImpl.tsx` 执行 ESLint、`npm run typecheck` 、`npm run check:encoding` 。
- 关联文档:`docs/technical/【前端架构】PlatformProfileWalletDeltaModel收口计划-2026-06-04.md` 、`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md` 。
## 2026-06-03 Public Work Presentation 收口
- 背景:作品卡、推荐 runtime meta、排行项、分类项、搜索结果和桌面 hero 共用玩法类型 label 与紧凑计数格式,但规则仍在 `RpgEntryHomeView.tsx` 页面 Implementation 内。
- 决策:在 `src/components/rpg-entry/rpgEntryWorldPresentation.ts` 追加单作品展示 Interface: `describePlatformPublicWorkKind` 、`formatPlatformCompactCount` 、`resolvePlatformPublicWorkAuthorLookup` 与 `formatPlatformPublicAuthorAvatarLabel` ;页面删除本地玩法类型、紧凑计数、公开作者 lookup 和头像首字实现。集合筛选、排序和指标选择继续留在 `rpgEntryPublicGalleryViewModel.ts` 。
- 影响范围:公开作品卡片 aria label、推荐点赞 / 改造文案、排行数值、分类主指标、搜索结果、桌面 hero 玩法 label、公开作者摘要缓存 key 与无头像首字兜底。
- 验证方式:`npm run test -- src/components/rpg-entry/rpgEntryWorldPresentation.test.ts` 、`npm run test -- src/components/rpg-entry/RpgEntryHomeView.recharge.test.tsx -t "recommend|ranking|category"` 、针对变更文件执行 ESLint、`npm run typecheck` 、`npm run check:encoding` 。
- 关联文档:`docs/technical/【前端架构】PublicWorkPresentation收口计划-2026-06-03.md` 。
## 2026-06-03 Profile Funds ViewModel 收口
- 背景:个人资金展示规则散在 `RpgEntryHomeView.tsx` ,且账单来源 label 表漏掉后端契约已有的 `puzzle_author_incentive_claim` ,会把原始枚举值直接外显。
- 决策:新增 `src/components/rpg-entry/rpgEntryProfileFundsViewModel.ts` 作为个人资金展示 Module, Interface 收口账单来源文案、金额正负号、余额兜底、充值价格、商品主值与会员摘要;页面保留弹窗布局、支付流程、微信渠道和订单轮询副作用。
- 影响范围:泥点账单弹窗、充值商品卡片、账户充值弹窗会员摘要。
- 验证方式:`npm run test -- src/components/rpg-entry/rpgEntryProfileFundsViewModel.test.ts` 、`npm run test -- src/components/rpg-entry/RpgEntryHomeView.recharge.test.tsx -t "wallet ledger|profile recharge modal shows native qr code"` 、针对变更文件执行 ESLint、`npm run typecheck` 、`npm run check:encoding` 。
- 关联文档:`docs/technical/【前端架构】ProfileFundsViewModel收口计划-2026-06-03.md` 。
## 2026-05-26 前端不外露图片模型名
- 背景:拼图与相关结果页、生成进度和错误提示里直接显示 `gpt-image-2` 、`gemini-3.1-flash-image-preview` 、`image-2` 等名称,会把内部模型路由暴露给普通用户。
@@ -1257,10 +1696,27 @@
- 验证方式:`cargo check -p module-auth --manifest-path server-rs/Cargo.toml` 、`cargo check -p api-server --manifest-path server-rs/Cargo.toml` 、`cargo test -p module-auth password --manifest-path server-rs/Cargo.toml -- --nocapture` 、`npm run check:spacetime-schema` 、`npm run check:encoding` 、`cargo test -p api-server spacetime_unavailable_router_returns_service_unavailable_for_requests --manifest-path server-rs/Cargo.toml -- --nocapture` 。
- 关联文档:`docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md` 、`docs/【开发运维】本地开发验证与生产运维-2026-05-15.md` 。
## 2026-06-03 外部生成 worker lease 使用 SpacetimeDB 时间和 token 栅栏
## 2026-06-07 创作入口泥点消耗改由统一契约驱动
- 背景:外部生成 worker 支持多进程动态缩扩容后,长任务超过单次 lease、worker 本机时钟漂移或复用 worker id 都可能导致同一任务被重复领取并被过期执行者回写 。
- 决策:`external_generation_job` 新增末尾字段 `lease_token` ; `claim` 使用 SpacetimeDB `ctx.timestamp` 计算 lease, 生成本次 claim token; worker 执行期间调用 `renew_external_generation_job_lease_and_return` 续租;`complete/fail` 必须带 `worker_id + lease_token` 才能回写。拼图 `compile_puzzle_draft` 的 dedupe key 包含本次 `extgen-` job id, 避免同一 session 的失败或完成 job 吞掉后续重新生成。拼图首图前置 `compile_puzzle_agent_draft` 、图片保存、UI 背景与失败态业务写回同样必须携带 lease guard, 并在 `compile_puzzle_agent_draft` 、`save_puzzle_generated_images` 、`save_puzzle_ui_background` 、`mark_puzzle_draft_generation_failed` 、`mark_puzzle_level_generation_failed` 的 SpacetimeDB 事务内校验 。
- 影响范围:`server-rs/crates/spacetime-module/src/external_generation.rs` 、`server-rs/crates/spacetime-module/src/puzzle.rs` 、`server-rs/crates/module-puzzle/src/commands.rs` 、`server-rs/crates/spacetime-client/src/external_generation.rs` 、`server-rs/crates/spacetime-client/src/puzzle.rs` 、`server-rs/crates/api-server/src/external_generation_worker.rs` 、`server-rs/crates/api-server/src/puzzle/handlers.rs` 、`server-rs/crates/api-server/src/puzzle/draft.rs` 、`server-rs/crates/api-server/src/puzzle/generation.rs` 。
- 验证方式:`npm run spacetime:generate` 、`npm run check:spacetime-schema` 、`cargo test -p spacetime-module external_generation --manifest-path server-rs/Cargo.toml` 、`cargo test -p api-server external_generation_worker --manifest-path server-rs/Cargo.toml` 、`GENARRATIVE_PROCESS_ROLE=all npm run dev` 后检查 `/healthz` 。
- 关联文档:`docs/technical/【后端架构】外部生成Worker化方案-2026-06-03.md` 、`docs/【开发运维】本地开发验证与生产运维-2026-05-15.md ` 。
- 背景:创作入口玩法卡封面右下角长期固定显示 `10-20泥点数` ,无法在后台按玩法调整,也容易和真实钱包余额或活动奖池混淆 。
- 决策:`creationTypes[].unifiedCreationSpec.mudPointCost` 作为入口卡泥点消耗数量字段,旧契约缺失时后端和前端都兜底为 `10` ;入口卡由前端格式化为 `X泥点数` 展示,后端和后台不保存单位文案。该字段同时作为玩法新建草稿初始生成的扣费真相源,前端余额前置校验、拼图首图生成、抓大鹅完整草稿生成和汪汪声浪初始三图生成必须读取同一份后台入口配置;结果页单图重生成、发布、道具使用和其它独立资产操作继续使用各自业务成本 。
- 决策补充:后台创作入口开关页不再直接暴露统一创作契约 JSON textarea; 页面按契约结构展示为卡片和字段列表, 点击“修改契约”后通过弹窗表单编辑 `title` 、`mudPointCost` 和 fields, 再组装回统一契约 payload 保存。`workspaceStage` 、`generationStage` 和 `resultStage` 属于内部阶段标识,后台不展示也不允许编辑;保存时沿用已有契约值,新增契约时按 `playId` 的固定阶段映射自动带出 。
- 影响范围:`shared-contracts` 的 `UnifiedCreationSpecResponse` 、`/api/creation-entry/config` 响应、前端入口卡派生、后台入口开关页、玩法链路文档和创作入口回归测试 。
- 验证方式:后台修改 `mudPointCost` 后保存,`GET /api/creation-entry/config` 返回同名数字字段;底部加号创作入口卡显示前端格式化后的泥点消耗;创作表单泥点不足提示和后端实际钱包扣费都使用该数字;关闭态卡片仍只显示 `暂未开放 ` 。
- 关联文档:`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md` 。
## 2026-05-31 拼消消底图 prompt 与 atlas 切片提示词收口
- 背景:拼消消生成资产检查时,用户需要区分主题词、场地底图主题词和复合图 atlas prompt 的职责;若小图案显式画出切分线或边框,运行态 1x1 切片会显得像错误素材。
- 决策:`boardBackgroundPrompt` 成为中央场地底图的优先 prompt 来源,只有该字段为空时才回退读取 `themePrompt` ;用户上传底图时只执行平台资产持久化和换签,不用主题词重写上传资产。复合图 atlas prompt 只描述“可被服务端按等大 1x1 方格切分”,禁止模型在图案上绘制切分线、边框、网格线或裁切参考线。
- 影响范围:拼消消工作台 payload、`shared-contracts` / `packages/shared` 契约、api-server 生成编排、SpacetimeDB session/work snapshot、文档与生成进度展示。
- 验证方式:`npm run spacetime:generate` 、`npm run check:encoding` 、`npm run check:server-rs-ddd` 、`cargo test -p module-puzzle-clear` 、`cargo test -p spacetime-client puzzle_clear -- --nocapture` 、`npm run test -- src/components/puzzle-clear-creation/PuzzleClearWorkspace.test.tsx src/services/miniGameDraftGenerationProgress.test.ts src/routing/appPageRoutes.test.ts src/services/publicWorkCode.test.ts` 。
- 关联文档:`docs/prd/【玩法创作】拼消消玩法模板PRD-2026-05-30.md` 、`docs/technical/【玩法创作】拼消消玩法模板技术方案-2026-05-30.md` 、`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md` 。
## 2026-06-06 统一创作页表头按契约 title 原样显示
- 背景:统一创作页长期使用固定表头 `想做个什么玩法?` ,导致跳一跳等玩法希望按自身语义展示标题时只能改前端或默认契约。
- 决策:`creationTypes[].unifiedCreationSpec.title` 继续作为统一创作页表头传输字段,但读取和保存时都按契约内容原样显示和持久化,不再用入口 `title` 自动覆盖。默认 spec 可以给出玩法中文名;旧库中已经持久化为 `想做个什么玩法?` 的契约也保持原样,若需要改表头应在后台契约结构卡片中点击修改并编辑 `title` 字段。
- 影响范围:`shared-contracts` 默认 spec、`module-runtime` 入口配置响应、`spacetime-module` 后台保存校验、后台入口开关页摘要和前端 fallback spec。
- 验证方式:`GET /api/creation-entry/config` 中各玩法 `unifiedCreationSpec.title` 等于已保存契约内容;后台只修改入口名称时不应隐式改写已保存的统一创作页表头。
- 关联文档:`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md` 。