docs: add generated asset prefix baseline

This commit is contained in:
2026-04-21 00:13:17 +08:00
parent 0e454b889b
commit be5a1b51ed
4 changed files with 256 additions and 6 deletions

View File

@@ -12,7 +12,8 @@
交付物:[M0_MODULE_MIGRATION_BASELINE_2026-04-20.md](./M0_MODULE_MIGRATION_BASELINE_2026-04-20.md)
- [x] 整理当前所有 SSE 接口与事件格式
交付物:[M0_SSE_INTERFACE_BASELINE_2026-04-20.md](./M0_SSE_INTERFACE_BASELINE_2026-04-20.md)
- [ ] 整理当前所有 `/generated-*` 静态资源前缀
- [x] 整理当前所有 `/generated-*` 静态资源前缀
交付物:[M0_GENERATED_STATIC_PREFIX_BASELINE_2026-04-20.md](./M0_GENERATED_STATIC_PREFIX_BASELINE_2026-04-20.md)
- [ ] 整理当前前端直接依赖的响应头、envelope、错误格式
### 仓库边界

View File

@@ -0,0 +1,245 @@
# M0`/generated-*` 静态资源前缀冻结基线
日期:`2026-04-20`
依据来源:
- [../docs/technical/NODE_BACKEND_MODULE_AND_API_INDEX.md](../docs/technical/NODE_BACKEND_MODULE_AND_API_INDEX.md)
- `server-node/src/modules/assets/characterAssetRoutes.ts`
- `server-node/src/modules/assets/qwenSpriteRoutes.ts`
- `server-node/src/services/sceneImageService.ts`
- `server-node/src/services/customWorldCoverAssetService.ts`
- `server-node/src/services/customWorldAgentAutoAssetService.ts`
- [../docs/technical/SPACETIMEDB_AXUM_OSS_BACKEND_REWRITE_DESIGN_2026-04-20.md](../docs/technical/SPACETIMEDB_AXUM_OSS_BACKEND_REWRITE_DESIGN_2026-04-20.md)
## 1. 文档目的
这份文档用于完成 `M0` 的第五条任务:
- 整理当前所有 `/generated-*` 静态资源前缀
这里的“整理”不是只列出几个目录名,而是要求冻结以下信息:
1. 当前哪些 `/generated-*` 前缀是正式业务前缀。
2. 每个前缀由哪条后端链路产出。
3. 每个前缀对应的当前路径模板是什么。
4. 哪些前缀只是未来设计名或测试噪音,不能误当成当前正式兼容面。
## 2. 冻结结论
当前工程里,正式业务使用的 `/generated-*` 静态资源前缀固定为以下 `6` 个:
| 前缀 | 当前状态 | 当前主要生产链路 | 当前典型路径模板 | 重写后兼容要求 |
| --- | --- | --- | --- | --- |
| `/generated-character-drafts/*` | 正式前缀 | 角色主形象草稿、动作草稿、导入参考素材 | `/generated-character-drafts/{characterId}/{kind}/{jobId}/{file}` | 必须保留 |
| `/generated-characters/*` | 正式前缀 | 角色主形象正式发布、Agent 自动角色图回填 | `/generated-characters/{characterId}/visual/{assetId}/{file}` | 必须保留 |
| `/generated-animations/*` | 正式前缀 | 角色基础动作正式发布 | `/generated-animations/{characterId}/{animationSetId}/{action}/{file}` | 必须保留 |
| `/generated-custom-world-scenes/*` | 正式前缀 | 世界场景图生成、Agent 自动场景图回填 | `/generated-custom-world-scenes/{world}/{landmarkOrAct}/{assetId}/{file}` | 必须保留 |
| `/generated-custom-world-covers/*` | 正式前缀 | 世界封面图生成、封面上传 | `/generated-custom-world-covers/{world}/{assetId}/{file}` | 必须保留 |
| `/generated-qwen-sprites/*` | 正式前缀 | Qwen 主图草稿、精灵表草稿、修帧草稿、最终保存 | `/generated-qwen-sprites/{assetKeyOrDraftScope}/{actionOrKind}/{assetId}/{file}` | 必须保留 |
额外结论:
1. 当前仓库里真实业务前缀是 `6` 个,不是 `4` 个也不是 `5` 个。
2. 其中 `generated-animations``generated-custom-world-covers` 是当前代码已正式使用、但早期重写设计里容易漏掉的两个前缀。
3. 当前 `public/` 目录下已存在:
- `generated-character-drafts`
- `generated-characters`
- `generated-qwen-sprites`
4. `generated-animations``generated-custom-world-scenes``generated-custom-world-covers` 当前按需惰性创建,不代表它们不是正式前缀。
## 3. 正式前缀清单
### 3.1 `/generated-character-drafts/*`
当前用途:
1. 角色主形象候选图草稿。
2. 角色动作草稿帧、草稿视频、导入参考素材。
3. 角色资产工作流缓存与任务记录。
当前主要生产链路:
1. `POST /api/assets/character-visual/generate`
2. `POST /api/assets/character-animation/generate`
3. `POST /api/assets/character-animation/import-video`
4. `POST /api/assets/character-workflow-cache`
当前典型路径模板:
1. `/generated-character-drafts/{characterId}/visual/{jobId}/candidate-01.png`
2. `/generated-character-drafts/{characterId}/animation/{action}/{jobId}/preview.mp4`
3. `/generated-character-drafts/{characterId}/animation/{action}/{jobId}/frame-01.png`
4. `/generated-character-drafts/{characterId}-{cacheKey}/workflow-cache.json`
冻结要求:
1. 它是“草稿态真相路径”,不是正式发布路径。
2. 重写为 OSS 后仍要保留这一层 HTTP 兼容前缀,哪怕底层已不是本地磁盘。
### 3.2 `/generated-characters/*`
当前用途:
1. 角色主形象正式发布路径。
2. Custom World Agent 自动回填的角色主图。
当前主要生产链路:
1. `POST /api/assets/character-visual/publish`
2. `customWorldAgentAutoAssetService`
当前典型路径模板:
1. `/generated-characters/{characterId}/visual/{assetId}/master.png`
2. `/generated-characters/{characterId}/visual/{assetId}/preview-01.png`
冻结要求:
1. 它是角色正式视觉资产前缀,不允许与草稿前缀混用。
2. 后续即使内部改成 OSS也必须继续对前端暴露这一前缀。
### 3.3 `/generated-animations/*`
当前用途:
1. 角色基础动作正式发布路径。
2. `CharacterAnimator` 侧消费的核心动画资源前缀。
当前主要生产链路:
1. `POST /api/assets/character-animation/publish`
当前典型路径模板:
1. `/generated-animations/{characterId}/{animationSetId}/{action}/frame-01.png`
2. `/generated-animations/{characterId}/{animationSetId}/{action}/preview.mp4`
3. `/generated-animations/{characterId}/{animationSetId}/{action}/manifest.json`
冻结要求:
1. 当前正式动画并不挂在 `/generated-characters/.../animation/...` 下,而是独立前缀 `/generated-animations/*`
2. 后续重写若想合并对象键,也必须先做兼容别名,不能直接改掉公开路径。
### 3.4 `/generated-custom-world-scenes/*`
当前用途:
1. 自定义世界场景图生成结果。
2. Agent 自动生成的场景图回填结果。
当前主要生产链路:
1. `POST /api/custom-world/scene-image`
2. `customWorldAgentAutoAssetService`
当前典型路径模板:
1. `/generated-custom-world-scenes/{worldSegment}/{landmarkSegment}/{assetId}/scene.png`
2. `/generated-custom-world-scenes/{sceneSegment}/{actSegment}/{assetId}/scene.png`
冻结要求:
1. 前缀里当前显式带 `custom-world-scenes`,不是通用 `generated-scenes`
2. 后续世界资料库、世界编辑器和 Agent 卡片仍会依赖这一命名习惯。
### 3.5 `/generated-custom-world-covers/*`
当前用途:
1. 自定义世界封面图生成结果。
2. 自定义世界封面图上传后规范化结果。
当前主要生产链路:
1. `POST /api/custom-world/cover-image`
2. `POST /api/custom-world/cover-upload`
当前典型路径模板:
1. `/generated-custom-world-covers/{worldSegment}/{assetId}/cover.png`
2. `/generated-custom-world-covers/{worldSegment}/{assetId}/manifest.json`
冻结要求:
1. 当前正式前缀是 `/generated-custom-world-covers/*`,不是 `/generated-cover-images/*`
2. 后续重写设计和 OSS key 规划必须以这个现状兼容面为准。
### 3.6 `/generated-qwen-sprites/*`
当前用途:
1. Qwen 精灵主图草稿。
2. Qwen 精灵表草稿。
3. Qwen 修帧草稿。
4. Qwen 精灵表最终保存结果。
当前主要生产链路:
1. `POST /api/assets/qwen-sprite/master`
2. `POST /api/assets/qwen-sprite/sheet`
3. `POST /api/assets/qwen-sprite/frame-repair`
4. `POST /api/assets/qwen-sprite/save`
当前典型路径模板:
1. `/generated-qwen-sprites/_drafts/master/{draftId}/candidate-01.png`
2. `/generated-qwen-sprites/_drafts/sheet/{draftId}/candidate-01.png`
3. `/generated-qwen-sprites/_drafts/repair/{draftId}/candidate-01.png`
4. `/generated-qwen-sprites/{assetKey}/{actionKey}/{assetId}/sheet.png`
冻结要求:
1. 这个前缀当前既承载草稿,也承载正式保存结果。
2. 如果未来要把草稿与正式对象拆桶,也必须先保留同一公开前缀兼容。
## 4. 非正式前缀与噪音项
以下命名当前不能当成“正式兼容前缀”:
| 名称 | 当前来源 | 处理结论 |
| --- | --- | --- |
| `/generated-cover-images/*` | 仅出现在重写设计文档旧草案里 | 这是未来提案名,不是当前工程真实前缀。 |
| `/generated-role*` | 测试数据或示例 ID | 不是正式静态资源前缀。 |
| `/generated-world*` | 测试数据或对象 ID | 不是正式静态资源前缀。 |
| `/generated-ruins*` | 测试数据或对象 ID | 不是正式静态资源前缀。 |
结论:
1. 后续做 Axum 静态资源兼容层时,只能以第 2 节和第 3 节里的 `6` 个前缀为正式基线。
2. 不能把测试里的字符串误判成真实资源入口。
## 5. 与重写设计的对齐要求
为避免后续按错路径重写,当前冻结以下对齐规则:
1. Axum 第一阶段必须兼容这 `6` 个公开资源前缀。
2. OSS 内部对象键可以调整,但对前端暴露的 URL 前缀不能少于这 `6` 个。
3. 设计文档里的对象键规划如果与这份基线冲突,以这份“当前工程冻结基线”为准,然后再在设计文档中补兼容说明。
## 6. 本轮冻结后的硬约束
后续迁移中,不允许出现以下情况:
1.`/generated-animations/*` 直接并入 `/generated-characters/*` 却不保留兼容别名。
2.`/generated-custom-world-covers/*` 擅自改成 `/generated-cover-images/*`
3. 在未做兼容层前,删除 `/generated-character-drafts/*``/generated-qwen-sprites/*` 的草稿访问习惯。
4. 仅因为某个目录在当前仓库里尚未生成,就把它从正式前缀清单里删掉。
## 7. 本任务完成定义
当以下条件成立时,这条任务视为完成:
1. 当前正式 `/generated-*` 前缀已经有书面冻结清单。
2. 每个前缀都已明确:
- 当前用途
- 当前生产链路
- 当前路径模板
- 后续兼容要求
3. 已明确哪些“generated-*”字符串只是噪音,不属于正式前缀。
## 8. 后续直接依赖这份基线的任务
1. 设计 Axum 静态资源兼容层
2. 设计 OSS 对象键与 CDN 别名
3. 做 assets / custom world / editor 的路径回归测试

View File

@@ -18,6 +18,7 @@
- [M0_ROUTE_MIGRATION_MATRIX_2026-04-20.md](./M0_ROUTE_MIGRATION_MATRIX_2026-04-20.md):当前 `96` 条后端路由的“旧接口 -> 新实现”迁移矩阵,用于 Axum 路由树和 application service 落位。
- [M0_MODULE_MIGRATION_BASELINE_2026-04-20.md](./M0_MODULE_MIGRATION_BASELINE_2026-04-20.md):当前 `12` 个内部模块的迁移归属基线,用于锁定 Rust crate、SpacetimeDB bounded context 与 Axum/application 分工。
- [M0_SSE_INTERFACE_BASELINE_2026-04-20.md](./M0_SSE_INTERFACE_BASELINE_2026-04-20.md):当前 `6` 条 SSE 接口及其事件格式冻结基线,用于 Axum SSE 兼容和前端 contract 回归。
- [M0_GENERATED_STATIC_PREFIX_BASELINE_2026-04-20.md](./M0_GENERATED_STATIC_PREFIX_BASELINE_2026-04-20.md):当前正式 `/generated-*` 静态资源前缀冻结基线,用于 Axum 静态资源兼容层与 OSS 对象键规划。
## 维护规则

View File

@@ -133,9 +133,10 @@ SpacetimeDB Module
Aliyun OSS
├─ generated-character-drafts
├─ generated-characters
├─ generated-animations
├─ generated-custom-world-scenes
├─ generated-custom-world-covers
├─ generated-qwen-sprites
├─ generated-cover-images
└─ editor-exports / temp-uploads / workflow-cache
```
@@ -468,10 +469,10 @@ Axum 第一阶段需要兼容当前项目的这些约定:
```text
generated-character-drafts/{character_id}/{job_id}/{file}
generated-characters/{character_id}/visual/{asset_id}/{file}
generated-characters/{character_id}/animation/{asset_id}/{action}/{file}
generated-animations/{character_id}/{animation_set_id}/{action}/{file}
generated-custom-world-scenes/{profile_id}/{landmark_id}/{asset_id}/{file}
generated-qwen-sprites/{role_id}/{sheet_id}/{file}
generated-cover-images/{profile_id}/{asset_id}/{file}
generated-custom-world-covers/{profile_id}/{asset_id}/{file}
editor-cache/{resource_type}/{resource_id}/{file}
workflow-cache/{workflow_type}/{workflow_id}.json
```
@@ -522,8 +523,10 @@ workflow-cache/{workflow_type}/{workflow_id}.json
1. `/generated-character-drafts/*`
2. `/generated-characters/*`
3. `/generated-custom-world-scenes/*`
4. `/generated-qwen-sprites/*`
3. `/generated-animations/*`
4. `/generated-custom-world-scenes/*`
5. `/generated-custom-world-covers/*`
6. `/generated-qwen-sprites/*`
## 12. 关键业务流设计