Files
opendance-web/web-server/package.json
T
zijunchiang d1c0dd6e7a test(scenes): 加带真实数据库的端到端用例(sql.js 内存库),把生产根因钉死
新增 test/scenes-e2e.spec.ts(4 项,全部真实 SQL,不是 mock):

1. Scene 在 DataSource 里有 metadata、getRepository 不抛错;
2. **反向验证生产根因**:当 ENTITIES 漏掉 Scene 时,`getRepository(Scene)` **不会抛**
   (TypeORM 0.3 是惰性的——这正是"启动完全正常"的原因),而**第一次查询**会 reject
   并抛出与生产完全一致的 `No metadata for "Scene" was found.`;
3. **上传→归档→落库→发布→目录导出 全链路**(真实 StorageService + 真实仓储):
   - 用 multer diskStorage 的文件形状(只有 path、没有 buffer)上传 .glb;
   - 断言 GLB 已归档进 storage、临时目录不再残留该文件(验证 diskStorage 修复);
   - 落 pending;`published()` 为空;发布后能取到完整物理参数(重力/风/地面/相机);
   - `CatalogService.exportBundle()` 的 `scenes[]` 含该场景且参数完整;
   - `catalog/version` 指纹为 64 位十六进制;`scenes.diagnostics()` 报告可用;
   - 删除后 `published()` 不再返回(软删除生效);
4. 越界/非法参数在**真实落库往返**(jsonText transformer)后仍是收敛值
   (重力 -200、摩擦 1、colliders auto、相机 follow)。

实现细节:库内用 `sql.js`(WASM,无原生依赖,devDependency)跑 TypeORM 的 sqljs 驱动;
SQLite 本身对列类型名宽松,但 TypeORM 的 sqlite 驱动会校验 normalizeType 的结果,
因此测试里加了一处**有注释的兼容垫片**:`char→varchar`、`mediumtext/longtext/tinytext→text`、
`enum→varchar`,以及 `bigint` 自增主键→`integer`(SQLite 的 AUTOINCREMENT 只允许
INTEGER PRIMARY KEY)。只影响本测试进程,不改动任何实体定义。

验证:npm run verify 通过(24 文件 / 289 项测试 + 契约/路由/版本一致 + 启动冒烟)。
2026-09-17 03:52:33 +08:00

57 lines
1.9 KiB
JSON

{
"name": "opendance-web-server",
"version": "0.7.4",
"description": "OpenDance Studio Web 管理服务端(NestJS + TypeORM + 现有 MySQL 实例)",
"license": "MIT",
"private": true,
"engines": {
"node": ">=22.0.0"
},
"scripts": {
"build": "nest build",
"start": "nest start",
"start:dev": "nest start --watch",
"start:prod": "node dist/main.js",
"typecheck": "tsc --noEmit",
"test": "vitest run",
"test:watch": "vitest",
"test:smoke": "node test/smoke.mjs",
"contracts:check": "node scripts/check-contracts.mjs && node scripts/check-routes.mjs && node scripts/check-version.mjs",
"verify": "npm run contracts:check && npm run typecheck && npm run test && npm run build && npm run bootstrap:check",
"typeorm": "node scripts/migrate.mjs",
"migration:generate": "node scripts/migrate.mjs generate",
"migration:run": "node scripts/migrate.mjs run",
"migration:revert": "node scripts/migrate.mjs revert",
"migration:show": "node scripts/migrate.mjs show",
"version:check": "node scripts/check-version.mjs",
"bootstrap:check": "node scripts/check-bootstrap.mjs"
},
"dependencies": {
"@nestjs/common": "^11.0.12",
"@nestjs/config": "^4.0.2",
"@nestjs/core": "^11.0.12",
"@nestjs/platform-express": "^11.0.12",
"@nestjs/typeorm": "^11.0.0",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.1",
"dotenv": "^16.4.7",
"mysql2": "^3.12.0",
"reflect-metadata": "^0.2.2",
"rxjs": "^7.8.2",
"typeorm": "^0.3.21"
},
"devDependencies": {
"@nestjs/cli": "^11.0.5",
"@nestjs/schematics": "^11.0.2",
"@types/express": "^5.0.0",
"@types/multer": "^1.4.12",
"@types/node": "^22.13.10",
"source-map-support": "^0.5.21",
"sql.js": "^1.14.2",
"ts-node": "^10.9.2",
"tsconfig-paths": "^4.2.0",
"typescript": "^5.7.3",
"vitest": "^3.0.8"
}
}