feat(scenes): 场景管理后端 + 契约 0.5.0/0.7.0/0.4.0(T-WEB-015)

契约先行(三端逐字节一致,已同步 windows/android):
- rest-api -> 0.5.0:新增 GET/POST /api/scenes、GET/PATCH/DELETE /api/scenes/{id}
- data-models -> 0.7.0:新增 §7 Scene 与 7.1 SceneConfig(物理/环境/出生点/相机)
- database -> 0.4.0:新增 scenes 表(config/stats 用 MEDIUMTEXT,迁移可逆)

后端:
- entities/scene.entity.ts + 迁移 AddScenes1789650000000(scenes 表)
- scenes/scene-config.ts:SceneConfig 定义 + 默认值 + **边界收敛**(越界夹紧、
  非法枚举回退),保证客户端拿到的参数一定可解释;服务端只存参数不跑物理
- scenes/scenes.service.ts:上传(.glb/.gltf 直接导入;.zip/.pmx/.fbx 转 GLB,
  场景不做 humanoid 重绑定、不转 VRM)、列表/详情/更新/软删除、缩略图复用模型
  光栅化器、分析复用模型检查器、config 同时接受 JSON 字符串与平铺字段
- scenes/scenes.controller.ts + scenes.module.ts(app.module 注册)
- 审核复用 /api/reviews/:type/:id:TargetType.Scene 接入待审列表与状态流转
- catalog/export 增 scenes[],目录指纹纳入场景变更
- 枚举:TargetType.Scene、AssetKind.Scene / SceneThumbnail

测试:新增 test/scene-config.spec.ts 6 项(默认值/夹紧/枚举回退/出生点上限/颜色/
序列化);规模 19 文件 / 243 项;check-routes 35 条一致。版本 0.6.0。

注:管理端场景页(GLB 预览 + 物理参数可视化)与 Windows 场景选择留待下一轮。
This commit is contained in:
opendance
2026-09-17 00:27:08 +08:00
parent aad60cbd2e
commit 584b7eaca9
25 changed files with 1020 additions and 35 deletions
+22 -1
View File
@@ -36,7 +36,7 @@ DB_LOGGING=false
- 每个 migration 必须可逆(提供 `down` 方法)
- 迁移文件名格式:`<timestamp>-<kebab-name>.ts`
## 增量迁移(v0.2.0 / v0.3.0)
## 增量迁移(v0.2.0 / v0.4.0)
| 迁移 | 变更 |
|--|--|
@@ -63,3 +63,24 @@ draft ──submit──▶ pending ──approve──▶ published
- `published` 才可被 Windows 客户端 / Android App 消费
- `/api/catalog/export` 只导出 `published` 记录
---
## 场景表 `scenes`(v0.4.0 / T-WEB-015)
| 列 | 类型 | 说明 |
|--|--|--|
| `id` | bigint PK | |
| `name` | varchar(200) | 场景名称 |
| `glb_asset_id` | bigint NULL | 场景 GLB(以 GLB 为主,不转 VRM) |
| `thumbnail_asset_id` | bigint NULL | 缩略图 |
| `config` | **mediumtext** NULL | `SceneConfig` JSON(物理 / 环境 / 出生点 / 相机) |
| `stats` | **mediumtext** NULL | 场景 GLB 分析结果(复用模型检查器) |
| `file_size` / `file_sha256` / `conversion_note` | - | 与 models 同义 |
| `source_type` `source_name` `source_url` `license` `author` | - | 来源五元组(必填) |
| `status` | varchar(16) | 上传一律 `pending`,审核后 `published`/`rejected` |
| `created_at` `updated_at` `deleted_at` | datetime | 软删除 |
* `config` / `stats` 用 **MEDIUMTEXT**(TEXT 的 64KB 上限在 `models.stats` 上踩过坑);
* 迁移:`AddScenes1789650000000`(可逆,`down` 为 `DROP TABLE scenes`);
* 状态机与审核复用既有约定(审核走 `/api/reviews/scene/:id/approve|reject`)。