diff --git a/.hermes/shared-memory/decision-log.md b/.hermes/shared-memory/decision-log.md index 72809eda..83bd37c1 100644 --- a/.hermes/shared-memory/decision-log.md +++ b/.hermes/shared-memory/decision-log.md @@ -16,6 +16,14 @@ --- +## 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 切片。 diff --git a/.hermes/shared-memory/pitfalls.md b/.hermes/shared-memory/pitfalls.md index ebdffc89..a4c67529 100644 --- a/.hermes/shared-memory/pitfalls.md +++ b/.hermes/shared-memory/pitfalls.md @@ -2042,3 +2042,19 @@ - 处理:含中文提示词的 live 验证优先写成 UTF-8 `.mjs` 文件再执行,或使用能确认 UTF-8 的运行入口;执行后先检查本次 `request.json` 是否保留真实中文,再判断生图质量。不要基于 `????` prompt 生成的图片调整项目提示词。 - 验证:生成前后检查 `request.json`,其中 `prompt` 字段应显示中文而不是问号;同一提示词在 UTF-8 文件脚本下应能得到符合主题的图。 - 关联:`.codex/skills/gpt-image-2-apimart/SKILL.md`、`server-rs/crates/api-server/src/jump_hop.rs`。 + +## 自动试玩退出不要回到生成页 + +- 现象:拼图草稿生成完成后自动进入试玩,用户从试玩退出或使用系统返回时落回生成进度页,页面还暴露“重新生成”按钮。 +- 原因:自动试玩前如果没有先把 `/creation/puzzle/result` 写成 `/runtime/puzzle` 的浏览器历史前一站,系统返回会命中旧的生成页历史项;仅靠运行态内部 `returnStage='puzzle-result'` 只能覆盖运行态按钮返回,不能覆盖浏览器 / WebView 系统返回。 +- 处理:所有“生成完成后自动进入草稿试玩”的分支在 `openPuzzleRuntimeStage(...)` 前都必须调用结果页历史写入 helper,把 `/creation/puzzle/result` 与当前 `sessionId/profileId/workId` 写入历史;运行态按钮返回到 `puzzle-result` 时也同步写回创作恢复 query。 +- 验证:`npm run test -- src/components/rpg-entry/RpgEntryFlowShell.agent.interaction.test.tsx -t "puzzle draft generation auto starts trial and runtime back opens draft result"`。 +- 关联:`src/components/platform-entry/PlatformEntryFlowShellImpl.tsx`、`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md`。 + +## CreativeImageInputPanel 主图点击默认预览 + +- 现象:复用 `CreativeImageInputPanel` 的结果页 / 编辑页已有主图时,用户点击图片却触发上传,无法直接查看大图;不同玩法若各自手写上传按钮会让主图、历史图、AI 重绘和参考图行为再次分叉。 +- 原因:旧主图卡整卡是上传 label,缺少主图预览模式和上传 / 历史入口的显式控制参数。 +- 处理:通用面板已有主图时默认点击主图打开全屏预览,上传 / 更换收口到右下角 `ImagePlus` 图标按钮;无图时仍允许点击空图卡上传。调用方用 `canUploadMainImage` 和 `canUseImageHistory` 分别控制上传与历史按钮,不要复制面板或用样式遮挡按钮。 +- 验证:`npm run test -- src/components/common/CreativeImageInputPanel.test.tsx src/components/puzzle-result/PuzzleResultView.test.tsx`。 +- 关联:`src/components/common/CreativeImageInputPanel.tsx`、`src/components/puzzle-result/PuzzleResultView.tsx`、`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md`。 diff --git a/docs/test-cases/【测试用例】敲木鱼音频延迟上传与本地标准化-2026-06-06.md b/docs/test-cases/【测试用例】敲木鱼音频延迟上传与本地标准化-2026-06-06.md new file mode 100644 index 00000000..0df29319 --- /dev/null +++ b/docs/test-cases/【测试用例】敲木鱼音频延迟上传与本地标准化-2026-06-06.md @@ -0,0 +1,81 @@ +# 敲木鱼音频延迟上传与本地标准化测试用例 + +## 覆盖目标 + +- 选择上传或录音结束后只在浏览器本地处理,不请求 OSS 上传凭证。 +- 用户点击 `生成` 时才上传处理后的音频 Blob/File,并把确认后的 `WoodenFishAudioAsset` 放入创建 session payload。 +- 上传和录音统一执行前后声音过小片段裁切、最长 1 秒限制、近似 `-15 LKFS` 响度平衡和峰值保护。 +- 音频面板明确显示 `最长 1 秒`,并正确处理上传、录音、重置、禁用和错误状态。 +- OSS 上传 client 只接收 Blob/File,不接受 Data URL,并覆盖上传凭证、OSS POST、资产确认和错误分支。 + +## 音频处理 helper + +- 空文件:`size=0`,报 `音频文件为空,请重新选择。` +- 非音频 MIME:`text/plain`,报 `请选择音频文件。` +- 浏览器没有 `AudioContext`:报 `当前浏览器不支持音频处理。` +- `decodeAudioData` 失败:报 `音频解码失败,请重新选择。` +- 全静音或声音全低于阈值:报 `音频声音过小,请重新录制或上传。` +- 前后静音裁切:低于阈值的头尾帧被裁掉,`startFrame` 和 `frameCount` 正确。 +- 裁切后刚好 `1000ms`:允许通过。 +- 裁切后超过 `1000ms`:报 `音频最长 1 秒。` +- 上传来源 `uploaded` 与录音来源 `recorded`:返回 pending asset 保留对应 source。 +- 原文件名有扩展名:输出 `.wav` 文件名;无扩展名补 `.wav`;空白文件名输出 `creative-audio.wav`。 +- `URL.createObjectURL` 存在:`audioSrc` / `previewUrl` 为 blob URL;不存在时返回空字符串且不阻断处理。 +- 近似响度平衡:低 RMS 样本被拉向 `-15 LKFS` 目标。 +- 峰值保护:高峰值样本增益后不超过 `peakCeiling`。 +- 零能量 section:归一化阶段报声音过小。 +- WAV 编码:写入 RIFF/WAVE/data header、PCM16 数据长度和采样值。 + +## 音频输入面板 + +- 传入 `limitLabel` 时显示 `最长 1 秒`;未传入时不显示限制标签。 +- 无资产时显示默认音效文案。 +- 有资产且 `audioSrc` 存在时渲染 `