feat: add wooden fish play template

This commit is contained in:
2026-05-21 23:34:07 +08:00
parent ef09a23c35
commit 5b0f9f3763
121 changed files with 11580 additions and 159 deletions

View File

@@ -113,6 +113,30 @@
- 验证方式:新增玩法 PRD 必须显式声明单图资产槽位和系列素材槽位;新增工作台测试确认没有默认聊天式 Agent 输入skill 通过 `quick_validate.py`
- 关联文档:`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md``.codex/skills/genarrative-play-type-integration/SKILL.md``.hermes/skills/genarrative-play-type-integration/SKILL.md`
## 2026-05-20 敲木鱼玩法按完整平台纵切接入
- 背景:敲木鱼玩法需要对齐拼图 / 跳一跳的创作闭环,不能做成孤立 demo 或前端本地计数工具。
- 决策:新增 `wooden-fish` 玩法,采用表单 / 图片输入工作台、单图敲击物资产槽位、敲击音效资产槽位和最多 8 条飘字配置;公开作品号前缀为 `WF-*`;运行态只在单次 run 内累计总敲击次数和词条计数。后端新增独立 `module-wooden-fish`、shared contracts、SpacetimeDB `wooden_fish_*` 表 / public views、`spacetime-client` facade 和 `/api/creation/wooden-fish/*``/api/runtime/wooden-fish/*` 路由,前端接入平台入口、生成页、结果页、运行态、公开详情和推荐试玩。
- 影响范围:`CONTEXT.md``docs/prd/【玩法创作】敲木鱼玩法模板PRD-2026-05-20.md``docs/【玩法创作】平台入口与玩法链路-2026-05-15.md``docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md``packages/shared/src/contracts/woodenFish.ts``server-rs/crates/shared-contracts/src/wooden_fish.rs``server-rs/crates/module-wooden-fish/``server-rs/crates/spacetime-module/src/wooden_fish*``server-rs/crates/spacetime-client/src/wooden_fish.rs``src/components/wooden-fish-*`
- 验证方式:执行敲木鱼契约 / module / facade / runtime model / platform entry 定向测试、`npm run typecheck``npm run check:encoding``npm run check:spacetime-schema``cargo check -p api-server --manifest-path server-rs\Cargo.toml`,本地 smoke 使用 mock 短信配置后检查 `/healthz`
- 关联文档:`docs/prd/【玩法创作】敲木鱼玩法模板PRD-2026-05-20.md``docs/【玩法创作】平台入口与玩法链路-2026-05-15.md``docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md`
## 2026-05-21 敲木鱼敲击音效复用通用 Vidu 音效链路
- 背景:敲木鱼创作需要通过“敲击音效”描述生成真实短音频,不能继续由 `spacetime-client` 合成 `/generated-wooden-fish-assets/...` 假路径;同时拼图和抓大鹅音频生成入口仍需保持关闭。
- 决策:通用 `/api/creation/audio/sound-effect` 提交 Vidu 音效任务;`/api/creation/audio/sound-effect/{task_id}/asset` 只对木鱼 `hit_sound` 目标开放完成查询、下载、OSS 私有对象、`asset_object` 和 entity binding 写入。木鱼 `compile-draft` / `generate-hit-sound``api-server` 内复用同一 helper 生成并注入 `hitSoundAsset``spacetime-client` 缺少真实 `hitSoundAsset` 时拒绝编译。拼图和抓大鹅相关目标继续返回 `410 Gone`
- 影响范围:`server-rs/crates/api-server/src/vector_engine_audio_generation.rs``server-rs/crates/api-server/src/wooden_fish.rs``server-rs/crates/spacetime-client/src/wooden_fish.rs``shared-contracts` / `packages/shared``creationAudio` 契约、敲木鱼 PRD 与平台链路文档。
- 验证方式:执行 `cargo test -p shared-contracts creation_audio --manifest-path server-rs\Cargo.toml``cargo test -p spacetime-client wooden_fish --manifest-path server-rs\Cargo.toml``cargo test -p api-server wooden_fish --manifest-path server-rs\Cargo.toml``cargo test -p api-server disabled_creation_audio_targets_return_gone_except_wooden_fish_sound_effects --manifest-path server-rs\Cargo.toml``npm run typecheck``npm run check:encoding`,本地 smoke 检查 `/healthz`;真实生成需同时配置 VectorEngine 与 OSS AccessKey。
- 关联文档:`docs/prd/【玩法创作】敲木鱼玩法模板PRD-2026-05-20.md``docs/【玩法创作】平台入口与玩法链路-2026-05-15.md``docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md`
## 2026-05-21 敲木鱼默认敲击物使用内置透明 PNG
- 背景默认敲木鱼图案若继续用“木鱼”关键词临时生成image2 容易语义化重画并改变用户认可的原始造型。
- 决策:默认模板使用内置资源 `/wooden-fish/default-hit-object.png` 写回 `bundled-default` 敲击物资产;仅当用户输入自定义关键词、上传参考图或主动重生成敲击物时,才走 image2 -> OSS -> asset object -> entity binding 链路。创作入口卡片、结果页、运行态和公开列表兜底统一使用该 PNG。
- 影响范围敲木鱼工作台默认提示词、api-server 木鱼默认资产编排、创作入口种子与迁移、平台公开卡片兜底、PRD 与平台链路文档。
- 验证方式:默认 `compile-draft` 返回的 `hitObjectAsset.generationProvider` 应为 `bundled-default``imageSrc=/wooden-fish/default-hit-object.png`;自定义关键词或参考图仍走 image2前端静态资源可通过 Vite 直接访问。
- 关联文档:`docs/prd/【玩法创作】敲木鱼玩法模板PRD-2026-05-20.md``docs/【玩法创作】平台入口与玩法链路-2026-05-15.md`
## 2026-05-19 系列素材 n*n 图集抽为 api-server 通用模块
- 背景:抓大鹅物品 sheet 已包含 prompt 组装、固定网格切图、绿幕 / 近白底透明化、切片 PNG 持久化和 prompt 追踪;继续留在 Match3D 私有模块会让跳一跳、后续地块 / 道具类玩法重复复制同一套算法和 OSS 元数据口径。

View File

@@ -179,6 +179,14 @@
- 验证:执行 `node scripts/generate-edutainment-tv-map-concepts.mjs --dry-run`,输出应只显示 `imageReferenceCount: 1`,不出现完整 base64。
- 关联:`scripts/generate-edutainment-tv-map-concepts.mjs``docs/design/【前端体验】寓教于乐电视端乐园地图入口概念图-2026-05-18.md`
## 生成图资产不能只拼 generated legacy path
- 现象:结果页或运行态拿到 `/generated-*-assets/.../image.png` 后图片不显示;前端 `ResolvedAssetImage` 会先调用 `/api/assets/read-url?legacyPublicPath=...`,但换签后的 OSS URL 仍指向不存在对象。
- 原因:后端只写了看起来像生成图的 legacy path没有真正调用 image2、上传 OSS、登记 `asset_object` 并绑定实体。`/api/assets/read-url` 只负责签名读取,不会凭空生成或补写对象。
- 处理:玩法生成链路必须在 `api-server` 完成外部副作用:调用 VectorEngine `gpt-image-2-all`,用 `GeneratedImageAssetAdapter` 准备 `PutObject`,上传 OSS 私有对象,调用 `confirm_asset_object``bind_asset_object_to_entity`,再把返回的 `legacyPublicPath` 写入玩法 profile。
- 验证:`cargo check -p api-server --manifest-path server-rs/Cargo.toml`;契约测试应断言前端 JSON 自带的 `hitObjectAsset` 会被忽略spacetime-client 定向测试应断言缺少服务端注入的真实 `hitObjectAsset` 时不能编译;浏览器 Network 中 generated 图片应先换签,签名 URL 指向已存在对象。
- 关联:`server-rs/crates/api-server/src/wooden_fish.rs``server-rs/crates/spacetime-client/src/wooden_fish.rs``src/components/ResolvedAssetImage.tsx``src/services/assetReadUrlService.ts`
## 忘记密码后仍提示手机号或密码错误先查认证快照同步
- 现象:用户通过“忘记密码”重设密码后,接口返回成功或页面进入登录态,但再次使用新密码登录仍提示“手机号或密码错误”;重启后还可能出现 `Bearer JWT 版本已失效`,日志里的 token version 与本地快照不一致。
@@ -558,7 +566,7 @@
- 现象:登录弹窗可以进入短信页签,但点击“获取验证码”后,手机没有收到短信。
- 原因:本地 `.env.local` 里如果是 `SMS_AUTH_PROVIDER="mock"`,后端不会发真实短信,只会返回固定 mock 验证码;真实阿里云链路已经改为普通短信 `SendSms`,验证码由当前 `api-server` 进程本地生成、哈希存储和校验,旧 `SendSmsVerifyCode` / `CheckSmsVerifyCode` 托管验证码参数不再参与真实校验。若接口直接返回“手机号登录暂未启用”,说明当前运行中的 `api-server` 进程内 `sms_auth_enabled=false`:常见原因是修改 `.env.local` 后没有重启后端,或外层 shell 已经设置了非空 `SMS_AUTH_ENABLED` 导致 dotenv 不覆盖。历史上 cmd 里 `set SMS_AUTH_ENABLED="true"` 会把引号也传进进程Rust bool 解析失败后保持默认 false。
- 处理:真实短信联调时把 `.env.local``SMS_AUTH_ENABLED=true``SMS_AUTH_PROVIDER=aliyun` 显式打开,并确认 `ALIYUN_SMS_ENDPOINT=dysmsapi.aliyuncs.com``ALIYUN_SMS_SIGN_NAME=北京亓盒网络科技``ALIYUN_SMS_TEMPLATE_CODE=SMS_506245486``ALIYUN_SMS_TEMPLATE_PARAM_KEY=code` 后重启 `api-server`;如果只想验证 UI账号链路,则保留 `mock` 并使用 `SMS_AUTH_MOCK_VERIFY_CODE`。Shell 临时覆盖时 PowerShell 用 `$env:SMS_AUTH_ENABLED="true"`cmd 用 `set SMS_AUTH_ENABLED=true`,不要把引号作为值的一部分。`api-server` 重启会清掉未校验的本地验证码。
- 处理:真实短信联调时把 `.env.local``SMS_AUTH_ENABLED=true``SMS_AUTH_PROVIDER=aliyun` 显式打开,并确认 `ALIYUN_SMS_ENDPOINT=dysmsapi.aliyuncs.com``ALIYUN_SMS_SIGN_NAME=北京亓盒网络科技``ALIYUN_SMS_TEMPLATE_CODE=SMS_506245486``ALIYUN_SMS_TEMPLATE_PARAM_KEY=code` 后重启 `api-server`;如果只想验证 UI账号链路`/healthz`,则保留 / 切换为 `mock` 并使用 `SMS_AUTH_MOCK_VERIFY_CODE`注意 `npm run dev:api-server` 会先合并 `.env.local`,且 `SMS_AUTH_ENABLED``SMS_AUTH_PROVIDER``SMS_AUTH_MOCK_VERIFY_CODE` 属于允许本地文件覆盖的键;如果 `.env.local` 写着 `SMS_AUTH_PROVIDER=aliyun` 但没有 `ALIYUN_SMS_ACCESS_KEY_*`,单纯在 PowerShell 里临时设置 mock 仍可能被覆盖health smoke 会在启动阶段报“阿里云短信 AccessKey 未配置”。不改 `.env.local` 的临时 smoke 可以直接运行 `cargo run -p api-server --manifest-path server-rs\Cargo.toml` 并在同一 shell 中显式设置 `SMS_AUTH_PROVIDER=mock``GENARRATIVE_API_HOST``GENARRATIVE_API_PORT``GENARRATIVE_SPACETIME_SERVER_URL``GENARRATIVE_SPACETIME_DATABASE`Shell 临时覆盖时 PowerShell 用 `$env:SMS_AUTH_ENABLED="true"`cmd 用 `set SMS_AUTH_ENABLED=true`,不要把引号作为值的一部分。`api-server` 重启会清掉未校验的本地验证码。
- 验证:分别请求浏览器域名和 Rust API 直连的 `/api/auth/login-options`,都应返回 `["phone","password"]``api-server` 日志里 `provider=aliyun` 才说明真实短信链路已生效。需要直接确认平台层真实调用阿里云时,配置 `ALIYUN_SMS_ACCESS_KEY_ID``ALIYUN_SMS_ACCESS_KEY_SECRET``ALIYUN_SMS_REAL_TEST_PHONE_NUMBER` 后手动执行 `cargo test -p platform-auth --manifest-path server-rs/Cargo.toml aliyun_send_sms_real_provider_sends_verify_code -- --ignored --nocapture`
- 关联:`server-rs/crates/api-server/src/config.rs``scripts/dev-utils.mjs``docs/technical/AUTH_LOGIN_OPTIONS_DESIGN_2026-04-21.md``docs/technical/PHONE_SMS_REAL_PROVIDER_MANUAL_VERIFICATION_RUNBOOK_2026-04-23.md`

View File

@@ -10,6 +10,7 @@ Genarrative / 陶泥儿是一个 AI 原生互动内容与小游戏平台,把 A
- RPG / 自定义世界创作与运行时。
- 拼图玩法创作、草稿、发布、运行态和排行榜。
- 敲木鱼玩法创作、草稿、发布、运行态、公开详情和分享码。
- 抓大鹅 Match3D 创作、2D 多视角素材生成、发布和运行态。
- 大鱼吃小鱼、方洞挑战、视觉小说、汪汪声浪和儿童向寓教于乐玩法。
- 账号、短信 / 密码 / 微信登录、个人资料、任务、钱包、邀请码、充值、反馈、法律信息和后台管理。