Files
opendance-web/contracts/database.md
T
opendance 584b7eaca9 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 场景选择留待下一轮。
2026-09-17 00:27:08 +08:00

87 lines
3.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# contracts/database.md - 数据库契约 v0.1.0
## 环境
- 类型:MySQL 兼容实例(外部提供,含 MariaDB 10.5+),TypeORM
使用 `mysql` driver(`mysql2`)连接,SQL 语法限制在 MySQL 5.7 / MariaDB 10.5+
共同子集内,不使用 MySQL 8 专有语法(窗口函数 CTE 递归除外)。
- 数据库名:由部署方提供,通过 `DB_NAME` 注入(本文档示例统一用 `opendance`)
- 字符集:`utf8mb4` / `utf8mb4_general_ci`(沿用现有实例默认排序规则)
- 迁移工具:TypeORM migration, **不使用 `DB_SYNCHRONIZE`**
## 连接信息(由部署方提供)
host / port / user / password 一律通过环境变量注入,**不入库、不入仓**。
```bash
DB_HOST=<数据库主机>
DB_PORT=3306
DB_USER=opendance_app
DB_PASS=<数据库口令>
DB_NAME=opendance
DB_SYNCHRONIZE=false
DB_LOGGING=false
```
## 约定
- 所有表名使用 `snake_case`,复数形式(`songs` / `motions` / `models`)
- 主键统一为 `BIGINT AUTO_INCREMENT`,字段名 `id`
- 时间字段统一 `DATETIME`, `created_at` / `updated_at`, `updated_at` 由应用层维护
- 软删除统一使用 `deleted_at DATETIME NULL`(`@DeleteDateColumn`)
- 布尔字段使用 `TINYINT(1)`
- 来源(出处)字段为 5 元组,任何资产入库必须齐备:
`source_type` / `source_name` / `source_url` / `license` / `author`
- 不使用 `DB_SYNCHRONIZE`,所有表结构变更走 migration
- 每个 migration 必须可逆(提供 `down` 方法)
- 迁移文件名格式:`<timestamp>-<kebab-name>.ts`
## 增量迁移(v0.2.0 / v0.4.0)
| 迁移 | 变更 |
|--|--|
| `AddModelConversionFields` | `models` 增加 `source_asset_id BIGINT NULL`(上传的压缩包,用于溯源)与 `conversion_note VARCHAR(500) NULL`(转换说明,见 model-formats.md 1.1) |
| `AddModelStats` | `models` 增加 `stats TEXT NULL`(模型分析结果:面数、骨骼树、humanoid 覆盖、可驱动性),供审核界面展示 |
## 表清单(v0.1.0)
| 表 | 用途 | 任务 |
|--|--|--|
| `songs` | 曲目元数据 | T-WEB-003 |
| `assets` | 上传文件元数据(去重、sha256、物理路径) | T-WEB-004 |
| `motions` | 动作数据(BVH/FBX...)+ 来源 + 预处理产物 | T-WEB-004 / 006 |
| `models` | 角色模型(VRM 优先)+ 来源 + 压缩包转换溯源 | T-WEB-005 |
| `review_records` | 上传审核流水 | T-WEB-007 |
## 状态机(`status` 列,v0.1.0)
```
draft ──submit──▶ pending ──approve──▶ published
│
└──reject──▶ rejected ──submit──▶ pending
```
- `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`)。