Files
opendance-web/DSH.md
T
zijunchiang 75498db1c0 feat(web): 部署方式由 Docker 改为 Linux 原生站点(nginx + systemd)
需求变更:Web 服务端不再使用 Docker,改为直接运行在 Linux 上的网站。

- 移除 deploy/docker-compose.yml、web-server/Dockerfile、
  web-server/admin/Dockerfile、web-server/.dockerignore
- 新增 deploy/install.sh:建服务用户与目录 → 装运行期依赖 → 迁移
  → 注册 systemd 服务 → 配置 nginx 站点 → 健康检查,一键完成
- 新增 deploy/systemd/opendance-api.service:ProtectSystem=strict 等
  安全加固,ReadWritePaths 限定为上传目录
- 新增 deploy/nginx/opendance.conf:同站点托管管理端静态资源 +
  反代 /api /health /static,client_max_body_size 512m,SPA 回退
- 新增 deploy/uninstall.sh:默认保留数据,--purge 才删除
- 新增配置项 HOST(AppConfig.bindHost):原生部署下 Node 只监听
  127.0.0.1,不直接对外暴露,实测外部 IP 不可达
- 同步更新 contracts/rest-api.yaml、DSH.md、project.yaml、README.txt、
  tasks/008、tasks/010 与发布打包脚本
2026-09-14 22:42:56 +08:00

157 lines
5.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.
# 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. 单次会话加载范围
允许加载:
1. 本文件 `DSH.md`
2. `project.yaml`
3. 当前 `tasks/xxx.md`
4. 该任务文件中 `load` 列出的文件
5. `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 / check-routes.mjs
├── deploy/ # ★ Linux 原生站点部署(不含 MySQL)
│ ├── install.sh # 一键部署(systemd + nginx)
│ ├── uninstall.sh
│ ├── .env.example
│ ├── systemd/opendance-api.service
│ └── nginx/opendance.conf
├── scripts/package-release.sh # 发布产物打包
└── THIRD_PARTY.md
```
## 6. 硬性约束
1. **不部署 MySQL**。数据库为部署方提供的现有实例,连接信息只经环境变量注入。
**也不使用 Docker**:以 nginx 站点 + systemd 服务的形式直接跑在 Linux 上。
2. **`DB_SYNCHRONIZE` 生产必须为 `false`**,所有表结构变更走 migration;每个
migration 必须可逆。
3. **绝不把凭证写入仓库**。`.env` 已在 `.gitignore` 中,只提交 `.env.example`。
4. **来源五元组强制必填**:`source_type` / `source_name` / `source_url` / `license`
/ `author`。任何资产入库缺一即 400。
5. **契约先行**:改接口先改 `contracts/`,再提升 `contracts/VERSION`,同步
`web-server/src/config/contract-versions.ts`,最后才改实现。
`npm run contracts:check` 在构建前拦截漂移。
6. **不使用 SMPL** 及其衍生拓扑(许可风险),统一 MediaPipe 33 点。
7. **上传文件永不使用原始文件名作为路径**,一律 `sha256` 去重后归档。
## 7. 每任务的执行步骤
```bash
# 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 任务只调用已定义接口 |
| 测试与实现同任务 | 测试单独任务,共享接口摘要 |