5.5 KiB
5.5 KiB
DSH.md —— opendance-web(OpenDance Studio 项目一:Web 管理服务端)
0. 本文件的作用
本文件是 opendance-web 仓库内的 DSH 执行约束。顶层说明书见用户提供的 《DSH 开发文档:OpenDance Studio》,二者冲突时以顶层文档为准。
1. 项目定位
Web 管理服务端是另两端(Windows 客户端、Android 辅助 App)的唯一数据源与 契约权威。它管理歌曲、VRM 模型与动作来源,并输出冻结的 REST / WebSocket / 数据模型契约。
现有 MySQL 实例(外部,本项目不部署)
│
▼
opendance-web ←── 本仓库
│ 冻结 REST API + 数据模型 + WebSocket 关键点协议
├──▶ opendance-windows
└──▶ opendance-android
2. 技术栈
| 组件 | 选型 |
|---|---|
| 后端 | NestJS 11 |
| ORM | TypeORM 0.3 |
| 数据库 | 现有 MySQL 兼容实例(当前部署为 MariaDB 10.11.19),mysql2 驱动 |
| 管理前端 | React 18 + Vite + TypeScript |
| 3D 预览 | three.js + @pixiv/three-vrm |
| 多格式解析 | BVH 内置纯 TS 解析器;FBX/glTF 走可选外部 Assimp |
| 认证 | 本版本不含认证(内网部署);上线前须补 ≥ T-WEB-011 |
3. 单次会话加载范围
允许加载:
- 本文件
DSH.md project.yaml- 当前
tasks/xxx.md - 该任务文件中
load列出的文件 contracts/中被明确引用的锚点片段
禁止加载:
opendance-windows/opendance-android的任何源码- 非当前任务的
tasks/*.md - 完整
contracts/目录(只引用锚点) node_modules/、dist/、构建产物、二进制、模型文件、上传存储
4. 上下文预算
| 项 | 建议值 |
|---|---|
| 单任务文件数 | ≤ 6 |
| 单任务代码行数 | ≤ 1500 |
| 单任务 Token | ≤ 12K |
| 契约引用 | 只引用锚点,不加载全文 |
5. 目录结构
opendance-web/
├── project.yaml # 任务清单与状态
├── DSH.md # 本文件
├── tasks/ # 单任务说明书(001~010)
├── contracts/ # ★ 跨端契约(权威)
│ ├── VERSION # 契约版本(唯一来源)
│ ├── rest-api.yaml # OpenAPI 3.0
│ ├── websocket-keypoints.md # 239 字节关键点帧 + 控制消息
│ ├── data-models.md # 资源字段与 VRM 优先规则
│ ├── skeleton-topology.md # MediaPipe 33 点拓扑 + 关节角
│ ├── model-formats.md # 支持格式、预处理产物、上传限制
│ ├── database.md # 现有 MySQL 连接与迁移约定
│ └── open-source-credits.md # 开源声明锚点(三端共用)
├── web-server/ # NestJS 服务端
│ ├── src/ # 源码(entities / modules / preprocess)
│ ├── admin/ # React 管理端(构建上下文)
│ ├── test/ # 单元测试 + 端到端冒烟
│ ├── scripts/ # migrate.mjs / check-contracts.mjs
│ └── Dockerfile
├── deploy/ # ★ 部署(不含 MySQL)
│ ├── docker-compose.yml
│ ├── install.sh
│ └── .env.example
├── scripts/package-release.sh # 发布产物打包
└── THIRD_PARTY.md
6. 硬性约束
- 不部署 MySQL。数据库为部署方提供的现有实例,连接信息只经环境变量注入。
DB_SYNCHRONIZE生产必须为false,所有表结构变更走 migration;每个 migration 必须可逆。- 绝不把凭证写入仓库。
.env已在.gitignore中,只提交.env.example。 - 来源五元组强制必填:
source_type/source_name/source_url/license/author。任何资产入库缺一即 400。 - 契约先行:改接口先改
contracts/,再提升contracts/VERSION,同步web-server/src/config/contract-versions.ts,最后才改实现。npm run contracts:check在构建前拦截漂移。 - 不使用 SMPL 及其衍生拓扑(许可风险),统一 MediaPipe 33 点。
- 上传文件永不使用原始文件名作为路径,一律
sha256去重后归档。
7. 每任务的执行步骤
# 1. 静态与单元校验
cd web-server
npm run contracts:check
npm run typecheck
npm run test
# 2. 构建
npm run build
# 3. 端到端冒烟(需数据库可连通)
npm run start:prod &
npm run test:smoke
# 4. 数据库迁移
npm run migration:run
# 5. 提交
git checkout -b task/T-WEB-0XX
git add . && git commit -m "feat(web): <scope>"
git push origin task/T-WEB-0XX
# Gitea 创建 PR → 合并到 dev
8. 环境变量
见 web-server/.env.example 与 deploy/.env.example。生产关键项:
DB_HOST DB_PORT DB_USER DB_PASS DB_NAME
DB_SYNCHRONIZE=false
STORAGE_DIR=/data/storage
UPLOAD_MAX_BYTES=536870912
ASSIMP_BIN=assimp # 可选
CONTRACTS_DIR=/contracts # 可选,读取实时契约版本
9. 上下文超标时的拆分策略
| 超标原因 | 拆分方式 |
|---|---|
| 单任务涉及多个端点 | 按端点拆 |
| 单文件过大 | 按类/函数拆,先生成接口再分实现 |
| 契约全文加载 | 改用锚点引用 |
| 需要参考其他项目 | 只读契约,不读源码 |
| UI 与逻辑耦合 | UI 任务只调用已定义接口 |
| 测试与实现同任务 | 测试单独任务,共享接口摘要 |