From df9c32b5ea3981c05a4a8ae60bc71fed551a2fc8 Mon Sep 17 00:00:00 2001 From: Suzumiya Date: Thu, 10 Sep 2026 21:19:19 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AE=B0=E5=BD=95=20kind=20=E5=88=AB=E5=90=8D?= =?UTF-8?q?=E5=8F=AA=E6=95=91=E6=96=B0=E7=99=BB=E8=AE=B0=E4=B8=8D=E6=95=91?= =?UTF-8?q?=E5=AD=98=E9=87=8F=20category=20=E7=9A=84=E9=99=B7=E9=98=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 补记 ui 资产落待归类的完整成因链:kind 兜底 image 再经 image → unclassified 误分 - 写明 register_local_asset_entry 命中同路径时不重算 category,故存量 57 条无法自愈 - 写明读取侧必须信任落盘 category 的原因:存在用户手动改分类的正式链路 - 列出三个根治选项供拍板:读时重派生 / 一次性回填 / 只改写入侧 - 记录别名表在 TS 与 Rust 各有一份实现、必须成对维护,以及交叉守卫位置 --- docs/project-memory/shared-memory/pitfalls.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/project-memory/shared-memory/pitfalls.md b/docs/project-memory/shared-memory/pitfalls.md index 757ab3769..5f9efad2e 100644 --- a/docs/project-memory/shared-memory/pitfalls.md +++ b/docs/project-memory/shared-memory/pitfalls.md @@ -5144,3 +5144,14 @@ - 门禁为什么抓不到:单测夹具本身就是毫秒值(`createdAt: 1_760_000_000_000`),断言用 `new Date(夹具值)` 反推期望,**夹具和实现一起错**,用例自洽却失真。 - 验收口径:夹具必须与落盘口径一致(真实秒值),并用已知秒值断言渲染出的年月日(`1788075047` → `2026/8/30`),而不是只断言"不等于 1970"。改成 `new Date(createdAt)` 时该用例会失败(已实测)。 - 关联:`apps/ai-game-creator-shell/src/features/resource-canvas/resourceCanvasVersionBindingModel.ts`、`packages/shared/src/contracts/gameCreationApp.ts`、`apps/ai-game-creator-shell/src-tauri/src/project/manifest.rs`。 + +## 资源 kind 别名只救新登记,不救存量 category(2026-09-10) + +- 现象:真机 `What do u wanna do kitten` 的 66 项资源里 58 项落「待归类」,其中 57 项是 `kind:"ui"` 的 UI 资产,本该在「UI 交互」。 +- 成因链:`ui` 不在 `GAME_CREATION_APP_CANONICAL_ASSET_KINDS` 里、也没有别名,于是走 `canonicalGameCreationAppAssetKind` 的 `image` 兜底,再经 `image → unclassified` 被误分到「待归类」。它并不是历史遗留值——`assets.rs:1656` 的 `infer_canvas_export_asset_kind`(画板导出导入)**现在仍在写出** `ui` / `animation` / `asset`。 +- **关键陷阱**:补别名只影响「今后新登记」的资产。`register_local_asset_entry`(`assets.rs:1748-1757`)命中同 `localPath` 的既有资产时只覆盖 `kind` / `media_type` / `source`,**不重算 `category`**;而读取侧 `gameCreationAppAssetCategory` 优先信任落盘 `category`、只在它缺失或非法时才按 `kind` 派生。所以这 57 条的落盘 `category: "unclassified"` 会一直有效,重导入也自愈不了。 +- 为什么读取侧要信任落盘值:存在用户手动改分类的正式链路 `update_manifest_asset_classification_at`(`project/manifest.rs:1110`),读时无条件重派生会吃掉用户的手动设置。 +- 根治选项(需产品拍板):① 读时把 `unclassified` 当作「未设置」再按 kind 派生(简单但失去"我就是要 unclassified"的表达力);② 一次性回填这 57 条(保留人工设置语义,需迁移脚本);③ 只改写入侧让新素材 canonical 化(治不了存量)。 +- 另一处必须成对维护:别名表有**两份实现**——TS 侧 `packages/shared/src/contracts/gameCreationApp.ts` 的 `GAME_CREATION_APP_LEGACY_ASSET_KINDS`(读投影用)与 Rust 侧 `server-rs/crates/shared-contracts/src/game_creation_app.rs` 的 `canonical_game_creation_app_asset_kind`(写入侧按 kind 派生 category 用)。只改一边就会让落盘 category 与读侧栏目互相矛盾。交叉守卫见 `apps/ai-game-creator-shell/tests/assetKindCanonicalMapping.test.ts`(直接解析 Rust 源码比对)。 +- 真机计数守卫见 `apps/ai-game-creator-shell/tests/resourceCardPreviewRealManifest.test.ts`。 +- 关联:`apps/ai-game-creator-shell/src-tauri/src/assets.rs`、`apps/ai-game-creator-shell/src-tauri/src/project/manifest.rs`、`packages/shared/src/contracts/gameCreationApp.ts`、`server-rs/crates/shared-contracts/src/game_creation_app.rs`。