落地方洞挑战图片与运行态交互
Some checks failed
CI / verify (push) Has been cancelled

This commit is contained in:
kdletters
2026-05-06 12:51:28 +08:00
parent 60b667a9d1
commit d06107f2c6
51 changed files with 2590 additions and 989 deletions

View File

@@ -21,6 +21,8 @@ SpacetimeDB 表结构变更、自动迁移边界和保留旧数据的分阶段
创作 Agent 问答流式失败时保留已显示回复、并透出更具体上游错误的契约见 [CREATION_AGENT_STREAM_FAILURE_RETENTION_FIX_2026-05-05.md](./technical/CREATION_AGENT_STREAM_FAILURE_RETENTION_FIX_2026-05-05.md)。
`maincloud` 相关脚本、环境变量、测试名和文档要求已统一判定为历史残留,后续禁止新增、运行或引用;当前后端 smoke 使用 `npm run api-server``/healthz`,详细规则见 [MAINCLOUD_REFERENCE_REMOVAL_POLICY_2026-05-06.md](./technical/MAINCLOUD_REFERENCE_REMOVAL_POLICY_2026-05-06.md)。
## 推荐阅读顺序
1. 先看 [经验沉淀](./experience/README.md),快速建立这个项目的开发共识。

View File

@@ -187,9 +187,12 @@ Agent 需要把玩家一句灵感收束为上述锚点,不允许逐项盘问
2. 创作者上传入口保留;上传图片可以覆盖生成图片。
3. 图片生成失败时保留草稿和可编辑配置,结果页展示缺失槽位,允许创作者重试生成或上传替代图。
4. 结果页必须展示每个形状选项及其图片、背景图、封面图和洞口选项配置。
5. 运行态当前形状优先显示 `imageSrc`,没有图片时才回退到 CSS 形状
6. 运行态背景优先显示 `backgroundImageSrc`,没有图片时才回退到默认渐变
7. 运行态顶部不显示“方洞是唯一解”或等价真实规则提示;只保留时间、进度、分数和连击
5. 每个图片槽位点击后进入查看模式;查看模式内同时提供历史图片、上传图片和 AI 生成图片入口
6. 查看模式里的 AI 生成只能重生成当前槽位,不触发整份草稿重新编译,也不切换到草稿生成进度页
7. 洞口图使用独立历史素材类型 `square_hole_hole_image`,需要和封面、背景、形状图一样支持历史图片选择
8. 运行态当前形状优先显示 `imageSrc`,没有图片时才回退到 CSS 形状。
9. 运行态背景优先显示 `backgroundImageSrc`,没有图片时才回退到默认渐变。
10. 运行态顶部不显示“方洞是唯一解”或等价真实规则提示;只保留时间、进度、分数和连击。
## 6.5 前端表现
@@ -199,6 +202,8 @@ Agent 需要把玩家一句灵感收束为上述锚点,不允许逐项盘问
4. 不默认展示长篇规则说明。
5. 错误反馈用短促动画、颜色闪烁和轻量文字状态,不堆解释。
6. 点击按钮弹出的配置或结算必须使用独立面板,不在当前面板下方展开。
7. 运行态必须同时支持拖拽和点击投放:拖动当前选项到洞口松开即提交该洞口,点击当前选项后点击洞口也提交该洞口;直接点击洞口时若当前局可操作,也提交该洞口。
8. `difficulty` 当前不参与运行态裁决、计时、计分或队列生成;前端不应把它作为显性玩法调参展示,后端仅保留兼容字段。
---
@@ -325,4 +330,4 @@ Agent 需要把玩家一句灵感收束为上述锚点,不允许逐项盘问
8. 后端裁决命中规则、连击、失败和胜利。
9. 刷新后可恢复作品与运行态快照。
10. `docs/technical/NEW_WORK_ENTRY_CONFIG_2026-05-01.md` 记录该入口开放状态。
11. 后端改动完成后必须执行 `npm run api-server:maincloud`,以 `GET /healthz` 返回 `200` 作为主云配置启动 smoke 通过标准,并在 smoke 后清理本次启动进程。
11. 后端改动完成后必须执行 `npm run api-server`,以 `GET /healthz` 返回 `200` 作为主云配置启动 smoke 通过标准,并在 smoke 后清理本次启动进程。

View File

@@ -49,7 +49,7 @@ npm run build
npm run check:content
```
后端代码变更后,按项目约束还需要用 `npm run api-server:maincloud` 做一次启动验证。
后端代码变更后,按项目约束还需要用 `npm run api-server` 做一次启动验证。
本轮最终结果:
@@ -58,7 +58,7 @@ npm run check:content
- `cargo test --manifest-path server-rs\Cargo.toml` 已通过,结果同 `api-server` 默认测试。
- `npm test` 已通过,结果为 `160 passed` 个测试文件、`704 passed` 个用例。
- `npm run typecheck``npm run build``npm run check:content``npm run check:encoding``git diff --check` 已通过。
- `npm run api-server:maincloud` 已完成启动烟测,`/healthz` 返回 `200`;期间 Maincloud 订阅恢复出现 `503` warning但未阻止服务启动。
- `npm run api-server` 已完成启动烟测,`/healthz` 返回 `200`;期间 Maincloud 订阅恢复出现 `503` warning但未阻止服务启动。
仍需单独处理的非本轮阻塞:

View File

@@ -0,0 +1,41 @@
# Maincloud 残留引用移除策略
## 背景
项目后端、发布和本地联调已经切到 `server-rs + Axum + SpacetimeDB` 当前基线,并以本地或显式配置的 SpacetimeDB 服务为运行目标。历史上用于连接 SpacetimeDB Maincloud 的脚本、环境变量、测试名和文档口径已经不再代表当前工程约束。
## 决策
- `maincloud` / `Maincloud` / `MAINCLOUD` 相关命名、脚本、测试、环境变量、文档要求和启动命令全部视为历史残留。
- 后续禁止新增、运行或引用 `maincloud` 相关代码、测试、脚本、文档要求、环境变量和命令。
- 旧文档若要求执行 `npm run api-server:maincloud``npm.cmd run api-server:maincloud` 或读取 `GENARRATIVE_SPACETIME_MAINCLOUD_*`,一律以本策略和 `AGENTS.md` 最新约束为准,并在触碰该文档或代码时同步修正。
- 后端 API smoke 统一使用当前非 Maincloud 启动入口:`npm run api-server`。服务就绪以 `GET /healthz` 返回成功为准。
- SpacetimeDB 运行目标必须来自本地开发服务、生产自托管服务,或显式 `SERVER_URL` 配置;不得再回退到 Maincloud 默认值。
## 落地规则
1. 修改后端代码后,按对应 DDD 文档执行定向测试;涉及 API smoke 时执行 `npm run api-server` 并探测 `/healthz`
2. 触碰历史脚本、测试支撑或文档时,优先删除或改名其中的 `maincloud` 口径,改为当前本地或显式服务配置口径。
3. 新增文档不得把 `api-server:maincloud` 写成验收命令,也不得要求配置 `GENARRATIVE_SPACETIME_MAINCLOUD_*`
4. 新增测试不得使用 `DEFAULT_MAINCLOUD_*` 这类历史命名;测试辅助应使用通用 `api-server``healthz` 或明确的本地 SpacetimeDB 命名。
5. 如需保留历史文档中的旧执行记录,只能作为归档事实存在,不得作为当前执行清单、验收命令或开发约束继续引用。
## 验证方式
常规检查:
```bash
rg -n "maincloud|Maincloud|MAINCLOUD|api-server:maincloud|GENARRATIVE_SPACETIME_MAINCLOUD" AGENTS.md docs .hermes package.json scripts server-rs -S
```
验收口径:
- `AGENTS.md``.hermes/shared-memory/` 和当前任务相关文档不得要求使用 Maincloud。
- 活跃脚本、测试和配置不得依赖 `GENARRATIVE_SPACETIME_MAINCLOUD_*`
- 后端启动和 smoke 以 `npm run api-server``/healthz` 为准。
## 关联文档
- [SPACETIMEDB_CLOUD_CONFIG_REMOVAL_2026-05-02.md](./SPACETIMEDB_CLOUD_CONFIG_REMOVAL_2026-05-02.md)
- [PRODUCTION_DEPLOYMENT_PLAN_2026-05-02.md](./PRODUCTION_DEPLOYMENT_PLAN_2026-05-02.md)
- [SPACETIMEDB_SCHEMA_CHANGE_CONSTRAINTS.md](./SPACETIMEDB_SCHEMA_CHANGE_CONSTRAINTS.md)

View File

@@ -72,4 +72,4 @@ APIMART_IMAGE_REQUEST_TIMEOUT_MS=180000
5. 选择 APIMart 模型时,请求 `POST {APIMART_BASE_URL}/images/generations`,使用 `Authorization: Bearer {APIMART_API_KEY}``model` 等于请求值,`size = 1:1`
6. “生成草稿”和关卡详情生图按钮展示 `消耗2光点`;关卡详情确认后展示 30 秒预计剩余进度条。
7. 不改 SpacetimeDB 表结构,因此无需更新 `migration.rs` 或重新生成 bindings。
8. 后端改动后运行对应 Rust 测试,并按项目约束用 `npm run api-server:maincloud` 重启验证。
8. 后端改动后运行对应 Rust 测试,并按项目约束用 `npm run api-server` 重启验证。

View File

@@ -5,6 +5,8 @@
## 文档列表
- [PROFILE_TASK_AND_TRACKING_SYSTEM_2026-05-03.md](./PROFILE_TASK_AND_TRACKING_SYSTEM_2026-05-03.md):冻结个人任务与埋点系统首版方案,明确 `tracking_event``tracking_daily_stat``profile_task_config`、任务进度、领奖记录和光点钱包流水的边界。
- [SQUARE_HOLE_IMAGE_SLOT_AND_RUNTIME_INTERACTION_FIX_2026-05-06.md](./SQUARE_HOLE_IMAGE_SLOT_AND_RUNTIME_INTERACTION_FIX_2026-05-06.md):记录方洞挑战结果页图片槽位局部生成、洞口图历史素材、运行态拖拽与点击投放交互的修正口径。
- [MAINCLOUD_REFERENCE_REMOVAL_POLICY_2026-05-06.md](./MAINCLOUD_REFERENCE_REMOVAL_POLICY_2026-05-06.md):冻结 Maincloud 历史残留引用禁用策略,明确后续不得新增、运行或引用 `api-server:maincloud``GENARRATIVE_SPACETIME_MAINCLOUD_*` 和相关测试/文档口径。
- [PRODUCTION_DEPLOYMENT_PLAN_2026-05-02.md](./PRODUCTION_DEPLOYMENT_PLAN_2026-05-02.md):冻结单机生产部署目标,从旧一体化启动脚本切到 Nginx、systemd 托管 SpacetimeDB 与 Rust `api-server`,并记录生产 Jenkins 流水线拆分计划和首批部署骨架。
- [PUZZLE_RUNTIME_FRONTEND_LOGIC_REHOME_2026-05-02.md](./PUZZLE_RUNTIME_FRONTEND_LOGIC_REHOME_2026-05-02.md):记录拼图正式平台入口移动、交换、合并、拆分和通关裁决收回前端即时运行态,排行榜、下一关和游玩记录继续由后端持久化处理。
- [RPG_FOUNDATION_DRAFT_ROLE_DOSSIER_TIMEOUT_FALLBACK_2026-05-02.md](./RPG_FOUNDATION_DRAFT_ROLE_DOSSIER_TIMEOUT_FALLBACK_2026-05-02.md):记录 `agent-foundation-*-dossier-batch-*` 无搜索 Responses 请求超时后的本地养成档案兜底,避免底稿主链被尾部角色润色阶段阻断。
@@ -21,7 +23,7 @@
- [SERVER_RS_DDD_WP_RS_RUNTIME_STORY_CLOSURE_2026-05-01.md](./SERVER_RS_DDD_WP_RS_RUNTIME_STORY_CLOSURE_2026-05-01.md):记录 `WP-RS Runtime Story` 写链路收尾,补齐 `/api/story/sessions/runtime``/api/story/sessions/{storySessionId}/actions/resolve`,统一返回 `StoryRuntimeMutationResponse.projection`,并保持旧 `/api/runtime/story/*` 未挂载。
- [SERVER_RS_DDD_WP_CW_ACTION_AND_DOMAIN_SPLIT_2026-04-30.md](./SERVER_RS_DDD_WP_CW_ACTION_AND_DOMAIN_SPLIT_2026-04-30.md):记录 `WP-CW Custom World` 的领域拆分与 Agent action 收口,将 `module-custom-world``lib.rs` 拆入 DDD 骨架,并移除 Custom World 运行代码中的最小兼容占位动作。
- [SERVER_RS_DDD_WP_BF_AND_G2_DRIFT_CLEANUP_2026-04-30.md](./SERVER_RS_DDD_WP_BF_AND_G2_DRIFT_CLEANUP_2026-04-30.md):记录 `WP-BF Big Fish` 物理拆分漂移和 G2 迁移期口径清理,将 Big Fish 创作域类型、命令、应用规则和错误层拆入 DDD 文件,并清理剩余 `过渡落位` 注释。
- [SERVER_RS_DDD_TESTS_SUPPORT_CRATE_CLOSURE_2026-04-30.md](./SERVER_RS_DDD_TESTS_SUPPORT_CRATE_CLOSURE_2026-04-30.md):记录 `tests-support` 从目录占位收口为 `server-rs` workspace 共享测试支撑 crate,首版提供 Maincloud healthz 与 HTTP smoke 通用断言
- [SERVER_RS_DDD_TESTS_SUPPORT_CRATE_CLOSURE_2026-04-30.md](./SERVER_RS_DDD_TESTS_SUPPORT_CRATE_CLOSURE_2026-04-30.md):记录 `tests-support` 从目录占位收口为 `server-rs` workspace 共享测试支撑 crate;该历史文档中的旧 Maincloud 口径不再作为当前执行依据,当前 smoke 通用 `/healthz` 为准
- [SERVER_RS_DDD_WP_BF_RUNTIME_BACKEND_TRUTH_2026-04-29.md](./SERVER_RS_DDD_WP_BF_RUNTIME_BACKEND_TRUTH_2026-04-29.md):记录 `WP-BF Big Fish` 运行态从前端本地规则切到 Rust 领域真相源、SpacetimeDB run 表、API facade 和前端新接口接入的关闭口径。
- [SERVER_RS_DDD_WP_PF_PLATFORM_ERROR_CLASSIFICATION_2026-04-29.md](./SERVER_RS_DDD_WP_PF_PLATFORM_ERROR_CLASSIFICATION_2026-04-29.md):记录 `WP-PF platform side effects` 平台副作用收口,统一 LLM、OSS、SMS、微信平台错误分类与 API 映射,并将微信 OAuth provider 下沉到 `platform-auth`
- [SERVER_RS_DDD_WP_RT_ADAPTER_API_CLOSURE_2026-04-29.md](./SERVER_RS_DDD_WP_RT_ADAPTER_API_CLOSURE_2026-04-29.md):记录 `WP-RT Runtime/Profile/Save` Adapter/API 收口,将 checkpoint、profile/save archive meta、充值/邀请/兑换/钱包等剩余纯规则迁入 `module-runtime`,移除 `/api/runtime/profile/*` 旧兼容挂载并对齐前端 `/api/profile/*` 请求路径。

View File

@@ -42,4 +42,4 @@ Your account has not activated web search.
2. 降级重试请求体不再包含 `tools` / `web_search`
3. `GENARRATIVE_CREATION_AGENT_LLM_WEB_SEARCH_ENABLED=false`foundation draft 全流程直接不带搜索工具。
4. `cargo test -p api-server custom_world_foundation_draft --manifest-path server-rs/Cargo.toml` 通过。
5. 修改后按项目约束使用 `npm run api-server:maincloud` 重启后端。
5. 修改后按项目约束使用 `npm run api-server` 重启后端。

View File

@@ -386,8 +386,8 @@ node scripts/check-server-rs-ddd-boundaries.mjs
cargo fmt --all --check --manifest-path server-rs/Cargo.toml
cargo test --workspace --manifest-path server-rs/Cargo.toml
cargo check -p spacetime-module --manifest-path server-rs/Cargo.toml
npm run api-server:maincloud
npm run api-server
npm run check:encoding
```
`npm run api-server:maincloud` 因本机未配置 Maincloud 数据库或令牌失败,必须记录具体错误;不能改用旧后端重启命令。
`npm run api-server` 因本机未配置 Maincloud 数据库或令牌失败,必须记录具体错误;不能改用旧后端重启命令。

View File

@@ -1818,7 +1818,7 @@ npm.cmd run api-server:maincloud
npm.cmd run api-server:maincloud
```
结果:命令在 60 秒观察窗口内超时。随后探测 `http://127.0.0.1:3100/healthz` 未连通;进程检查发现存在两组遗留的 `npm run api-server:maincloud -> scripts/api-server-maincloud.mjs -> cargo run -p api-server` 链路,同时还有并行 `module-assets` 测试和 `spacetime-module` 检查在运行。该结果不是本次 WP-API route 编译错误,需清理本次遗留 api-server 启动链后再做一次干净启动。
结果:命令在 60 秒观察窗口内超时。随后探测 `http://127.0.0.1:3100/healthz` 未连通;进程检查发现存在两组遗留的 `npm run api-server -> scripts/api-server-maincloud.mjs -> cargo run -p api-server` 链路,同时还有并行 `module-assets` 测试和 `spacetime-module` 检查在运行。该结果不是本次 WP-API route 编译错误,需清理本次遗留 api-server 启动链后再做一次干净启动。
### 2026-04-29 WP-API runtime projection 接线

View File

@@ -29,4 +29,56 @@
1. `platform-llm` 测试覆盖请求级 timeout 会让慢响应提前超时。
2. `creation_agent_llm_turn` 测试覆盖流式 JSON 请求带创作 Agent timeout。
3. `cargo test -p platform-llm -p api-server creation_agent --manifest-path server-rs/Cargo.toml` 通过。
4. 后端代码变更后按项目约束运行 `npm run api-server:maincloud` 并确认 `/healthz`
4. 后端代码变更后按项目约束运行 `npm run api-server` 并确认 `/healthz`
## 5. 追加:视觉资产动作 503 降级
现场后续日志:
```text
status=503 method=POST uri=/api/creation/square-hole/sessions/{sessionId}/actions
```
该请求落在方洞 `/actions`,草稿编译成功后前端会自动追加执行 `square_hole_generate_visual_assets`。视觉资产生成依赖 APIMart OpenAI 兼容图片入口;当本地或部署环境缺少 `APIMART_API_KEY` 时,后端会在 `require_openai_image_settings()` 阶段快速返回 `503 SERVICE_UNAVAILABLE`,因此日志 latency 只有个位毫秒。
这类错误只表示“图片自动生成服务不可用”,不代表方洞草稿编译失败。前端处理规则:
1. `square_hole_compile_draft` 成功后,如果自动图片生成失败,保留错误横幅。
2. 立即进入方洞结果页,展示已生成的形状/洞口配置。
3. 保留封面图、背景图、形状贴图和洞口选项图上传入口。
4. 进度页仍可通过“重新生成图片”在配置补齐后重试。
## 6. 追加:结果页图片重生成入口
方洞结果页需要保留用户上传入口,同时提供 `AI重生成图片` 操作。该按钮先保存当前编辑内容,再复用 `/api/creation/square-hole/sessions/{sessionId}/actions``square_hole_generate_visual_assets` 动作,并额外传入 `regenerateVisualAssets=true`
后端收到该标记后,不再按已有 `coverImageSrc``backgroundImageSrc` 或形状 `imageSrc` 跳过图片生成,而是重新生成封面图、背景图和所有形状贴图。自动编译后的图片补齐流程仍保持默认 `false`,只补缺失图片,避免覆盖创作者刚上传的素材。
## 7. 追加:图片槽位查看模式与历史素材
方洞结果页的封面图、背景图、每个形状贴图和每个洞口选项图不再把上传入口直接散落在卡片上。点击任一图片槽位后打开独立查看面板,面板内负责:
1. 展示当前槽位图片。
2. 展示当前账号历史生成的方洞图片素材。
3. 提供本地上传入口,上传后只替换当前槽位。
4. 提供 `AI生成图片` 入口,触发 `square_hole_generate_visual_assets` 并带 `regenerateVisualAssets=true``visualAssetSlot` 与可选 `visualAssetOptionId`
5. 后端按槽位定向生成:封面面板只替换封面图,背景面板只替换背景图,形状贴图面板只替换当前形状选项的贴图,洞口选项图面板只替换当前洞口选项图。草稿编译后的自动图片补齐仍不传槽位,保持“只补缺失图片”的原逻辑。
历史素材来源必须是真实资产索引不允许只从前端当前草稿拼假列表。方洞图片生成成功后API 层需要像拼图封面一样写入 OSS 与 `asset_object`
1. 封面图使用 `asset_kind = square_hole_cover_image`
2. 背景图使用 `asset_kind = square_hole_background_image`
3. 形状贴图使用 `asset_kind = square_hole_shape_image`
4. 洞口选项图使用 `asset_kind = square_hole_hole_image`
5. 资产历史接口 `/api/assets/history` 与 SpacetimeDB 侧历史素材白名单同步放行这四类。
6. 如果 OSS 或 SpacetimeDB 资产索引不可用,本次生成仍允许以 Data URL 回写作品,历史素材列表只降级为空或缺少本次记录。
## 8. 追加:选项图片不再局限于形状
方洞挑战的可展示图片不再只挂在 `shapeOptions`。创作者配置中的 `holeOptions` 也需要具备:
1. `imagePrompt`:洞口选项图的生成提示词,默认由题材主题和洞口标签补齐。
2. `imageSrc`:洞口选项图地址,可来自 AI 生成、历史素材套用或本地上传 Data URL。
3. 结果页需要把洞口选项图做成与形状贴图相同的图片槽位,打开查看面板后支持历史、上传和 AI 生成。
4. 运行态洞口按钮优先展示 `hole.imageSrc`,没有图片时再回落到几何剪影。
5. `visualAssetSlot = hole` 时必须携带 `visualAssetOptionId = holeId`,后端只重生成该洞口选项图;未传槽位的自动补齐需要同时补缺失的形状贴图和洞口选项图。

View File

@@ -0,0 +1,49 @@
# 方洞挑战拖拽玩法重构 2026-05-05
## 1. 目标
把方洞挑战从“按洞口按钮点选”改成“拖拽形状到目标洞口”的玩法,同时把洞口选项与形状选项的编辑关系改成稳定 ID + 名称联动。
## 2. 编辑态规则
1. 洞口选项不再暴露 `square / circle / triangle` 之类的下拉框。
2. 每个洞口选项只保留稳定 `holeId`、可编辑名称 `label`,以及可选图片字段。
3. 洞口名称改动后,所有引用该洞口的形状选项下拉框必须同步显示新名称。
4. 形状选项不再直接绑定洞口“形状类型”,而是绑定一个目标洞口 `targetHoleId`
5. 形状选项下拉框展示的是洞口名称,底层值是 `targetHoleId`
6. 形状选项仍保留自己的视觉配置字段,如 `shapeKind``imagePrompt``imageSrc`
7. 去掉加分选项,所有洞口选项一律平权。
## 3. 运行态规则
1. 运行态上半区展示全部洞口,布局成一块平面。
2. 下半区展示当前轮次的形状选项。
3. 每轮随机选择一个形状选项作为当前轮显示项,并以它绑定的 `targetHoleId` 作为目标洞口。
4. 箭头动画只负责给出随机引导洞口,不绑定正确答案;多洞口时优先避开当前正确洞口,避免直接剧透。
5. 用户把当前形状拖到任意洞口上松开后,前端把该洞口的 `holeId` 提交给后端。
6. 后端以 `holeId === currentShape.targetHoleId` 作为唯一判定标准。
7. 命中后进入下一轮;未命中时后端返回错误反馈、清空连击并保留当前运行态。
8. 计分不再包含任何加分洞口分支。
9. 游戏模式下洞口和当前选项只展示图片卡片,不再按 `shapeKind` / `holeKind` 裁剪成圆形、三角形、星形等几何形状。
## 4. 图片槽位
1. 封面图、背景图、形状图、洞口图都使用独立图片槽位。
2. 洞口图对应新的历史素材类型 `square_hole_hole_image`
3. 图片槽位查看面板内保留历史图片、上传入口和 AI 生成入口。
## 5. 后端契约要求
1. 共享契约里补充形状到洞口的目标引用字段。
2. 共享契约里补充洞口图片字段。
3. 运行态快照里必须包含当前形状对应的目标洞口信息,便于前端画箭头。
4. 作品和草稿返回的洞口数据必须和运行态保持同一组 ID 与名称。
## 6. 验收标准
1. 编辑洞口名称后,形状下拉框立即显示新名称。
2. 洞口编辑不再出现 `square / circle / triangle` 下拉框。
3. 运行态不再是按钮点选洞口,而是拖拽命中。
4. 每轮都能看到箭头或高亮引导洞口,但该引导不等同于正确答案。
5. 计分中不再出现 `bonus` 相关加分。
6. 游戏模式中洞口、当前选项和拖拽影子不再显示几何形状,只显示对应图片或中性图片占位。

View File

@@ -0,0 +1,31 @@
# 方洞挑战图片槽位与运行态交互修正
## 背景
方洞挑战结果页把封面图、背景图、形状图和洞口图统一放进查看模式后图片面板里的“AI生成图片”仍复用了 Agent action`square_hole_generate_visual_assets`。这条链路会进入生成进度页,并按草稿视觉资产流程更新会话,用户点击任意图片槽位时看起来像触发了整份草稿重编译。
同时,洞口图已经有独立资产类型 `square_hole_hole_image`,但 HTTP 历史素材白名单未放通,导致洞口图片面板无法读取历史图片。运行态方面,预期是拖拽当前选项到洞口松开,移动端同时支持点击当前选项后点洞口;现有洞口按钮没有点击提交,拖拽也缺少稳定的释放兜底。
## 修正决策
1. 结果页图片查看模式里的“AI生成图片”只允许生成当前图片槽位不切换到草稿生成进度页。
2. 新增作品级槽位重生成接口,前端传 `slot.kind` 和对应 option id后端只更新当前作品的目标图片字段。
3. `square_hole_hole_image` 必须加入资产历史 HTTP 白名单,与 SpacetimeDB 侧历史素材白名单保持一致。
4. 洞口图片查看模式必须和封面、背景、形状一样支持历史图片、上传图片和 AI 生成图片。
5. 运行态交互统一为:
- 拖动下方当前选项到上方任一洞口松开,提交该洞口 `holeId`
- 点击下方当前选项进入待投放状态,再点击任一洞口,也提交该洞口 `holeId`
- 直接点击洞口时,如果当前局正在运行且没有待处理操作,也提交该洞口 `holeId`
6. 箭头和高亮只表示随机引导洞口,不表示正确答案;多洞口时优先避开当前正确洞口。
7. 游戏模式只展示图片卡片,不再按形状字段裁剪出几何图形;没有图片时使用中性图片占位。
8. `difficulty` 当前不参与运行态裁决、计时、计分或队列生成,不应作为结果页显性玩法调参继续误导创作者;后端字段保留兼容,前端不再突出展示和编辑。
## 验收
1. 在结果页点击任一图片槽位,只打开图片查看面板,不触发生成进度页。
2. 图片面板点击“AI生成图片”后只刷新当前槽位图片结果页仍停留在当前面板。
3. 洞口图片面板可以读取 `square_hole_hole_image` 历史图片。
4. 运行态拖拽当前选项到洞口松开会调用 drop API。
5. 运行态点击当前选项后点击洞口、或直接点击洞口,都会调用 drop API。
6. 运行态洞口、当前选项和拖拽影子只显示图片或图片占位,不显示圆形、三角形、星形等几何形状。
7. 运行态箭头和高亮不会默认指向当前正确洞口。