1.6 KiB
1.6 KiB
T-WEB-003 /api/songs CRUD
- 状态:done
- 依赖:T-WEB-002
目标
曲目的增删改查与分页检索,字段语义符合 contracts/data-models.md §2。
load
DSH.md
contracts/rest-api.yaml # 锚点:#/paths/~1api~1songs
contracts/data-models.md # 锚点:§1 通用约定、§2 Song
web-server/src/songs/*
web-server/src/common/source.dto.ts
web-server/src/common/pagination.ts
端点
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/songs |
分页 + q/artist/status 过滤 |
| POST | /api/songs |
新建(来源五元组必填) |
| GET | /api/songs/:id |
详情 |
| PATCH | /api/songs/:id |
更新(来源需五元组同时提交) |
| DELETE | /api/songs/:id |
软删除 |
| POST | /api/songs/:id/audio |
上传音频(multipart,字段名 file) |
| POST | /api/songs/:id/cover |
上传封面 |
关键实现
likePattern()转义%_\,用户输入不会被当作 LIKE 模式。assertSourceTupleComplete()实现「全有或全无」:PATCH 只给部分来源字段 → 400。- PATCH 直接改
status时校验状态机;非法流转 → 409 并提示改用/api/reviews。 toDtos()批量解析 asset → URL,避免 N+1。
验收
npm run test:smoke
冒烟脚本 [1] 段落覆盖:创建 201、id 为 number、来源回显、tags 往返、bpm 为 number、
分页结构、模糊查询命中、音频上传后 audioUrl 以 /static/ 开头、PATCH 生效、
部分来源字段 400、软删除后不再出现在列表。
结果
全部通过(见 web-server/test/smoke.mjs)。