📦 docs: tag-library 私人标签库 6 接口真实化完成 + QA 验证通过

变更:

- 新增 changelogs-v2/2026-05/21_tag-library真实化完成QA验证通过-修改接口-管理后台.md
- 关联 19 号骨架版 changelog
- 通知前端:接口契约 0 变化,可正式进入真实联调时机

QA 结果:33/33 全通过(覆盖创建/列表/更新/删除/排序/置顶 6 接口 × 各场景)

错误码契约(581421/581423/581424/581425/581427)全部按设计触发,多用户隔离、事务回滚、软删后同名复用、Long ID 字符串序列化均已验证。
这个提交包含在:
yaosutu 2026-05-21 12:07:15 +08:00
父节点 751ed717d3
当前提交 c2aef2a3d3

查看文件

@ -0,0 +1,101 @@
# tag-library: 私人标签库 6 接口真实化完成 + QA 验收通过
> **存放目录**: `changelogs-v2/2026-05/`v3 二期)
> **服务**: hl-order-service-v3
> **关联**: 19 号已发布骨架版([`19_2045_tag-library模块私人标签库管理-新增接口-管理后台.md`](./19_2045_tag-library模块私人标签库管理-新增接口-管理后台.md)
> **真实化 PR**: #2606DB 业务实现)
> **关联 PR**: #2777(不直接相关,仅同会话)
> **日期**: 2026-05-21
> **影响范围**: 管理后台「我的标签库」管理页 + 创建订单时的标签下拉
---
## ⚠️ 关键变化
**接口契约 0 变化**。19 号骨架版发布时承诺的「契约本次发布后不再变」**已兑现** —— 字段名 / 类型 / 必填 / 路径 / 错误码全部与 19 号一致。
本次变化仅是**实现状态**
| 项 | 19 号骨架版 | 本次2026-05-21 |
|---|---|---|
| ServiceImpl | **Mock 硬编码样例** | **真实 DB**`tag_library` 表) |
| 数据持久化 | ❌ 不落库,每次返样例 | ✅ INSERT / UPDATE / SOFT DELETE 真实生效 |
| 错误码 581421/581423/581424/581425/581427 | 未触发Mock 永远成功) | **全部按设计触发**QA 已验证) |
| 多用户隔离 | 未生效Mock 不区分 userId | **生效**user_id 隔离 + 越权拦截) |
| 排序持久化 | 仅返样例数据,不响应排序请求 | **真实持久化**sort_order 列) |
| 软删后同名复用 | N/A | **支持**(唯一索引 `(user_id, tag_name, deleted_at)` |
**前端意义**:之前按 19 号骨架对接的代码**无需任何改动**,但**联调时机解锁** —— 现在可以真实创建 / 修改 / 删除 / 排序 / 置顶并看到数据持久化和正确的错误码反馈。
---
## 一、背景
19 号 6 接口骨架版上线时 ServiceImpl 是 Mock 实现,前端可按契约对接但无法真实联调(数据不落库、错误码不触发)。
本次 PR #2606 完成 DB 真实化,今天通过 33 项 QA 用例全量验收。
---
## 二、变更清单
| # | 接口 | 方法 | 路径 | 本次变更 |
|---|------|------|------|----------|
| 1 | 查我的标签库 | GET | `/v3/admin/tag-library` | Mock → 真实 DB 查询,支持 keyword 模糊 / pinnedOnly 过滤 / 后端固定排序 |
| 2 | 新增标签库预设 | POST | `/v3/admin/tag-library` | Mock → 真实 INSERT,sortOrder=MAX+1 / 重名 581421 触发 / 默认色 `#5B8FF9` 生效 |
| 3 | 修改(重命名/换色) | PUT | `/v3/admin/tag-library/{id}` | Mock → 真实 UPDATE,越权 581423 / 改名重名 581421 / 排除自身校验生效 |
| 4 | 删除(软删) | DELETE | `/v3/admin/tag-library/{id}` | Mock → 真实软删(`deleted_at=NOW()`),越权 581424 / 软删后同名可复用 |
| 5 | 批量排序 | PUT | `/v3/admin/tag-library/sort` | Mock → 真实事务包裹 UPDATE,含他人 id 581425 整批回滚 / 重复 id 581427 |
| 6 | 置顶 toggle | PUT | `/v3/admin/tag-library/{id}/pin` | Mock → 真实 UPDATE,越权 581424 |
---
## 三、接口契约
**未变更**,详见 [`19_2045_tag-library模块私人标签库管理-新增接口-管理后台.md`](./19_2045_tag-library模块私人标签库管理-新增接口-管理后台.md):入参 / 出参 / 枚举 / 字段约束 / 路径全部一致。
---
## 四、错误码契约(全部经 QA 验证)
| Code | 触发场景 | 接口 |
|---|---|---|
| 581421 | 同用户已有同名标签 | POST 新增 / PUT 改名 |
| 581423 | 标签不存在 / 已软删 / 非本人 | PUT 更新 |
| 581424 | 标签不存在 / 已软删 / 非本人 | DELETE 删除 / PUT 置顶 |
| 581425 | 排序 items 含他人 id**整批回滚,不部分成功** | PUT 排序 |
| 581427 | 排序 items 含重复 id | PUT 排序 |
| 400 | 参数校验失败tagName 空 / 超 50 字 / tagColor 格式非法 / pinned 缺失 / items 空数组) | 全部 |
| 401 | 未登录 | 全部 |
---
## 五、QA 验收结果
- **覆盖**6 接口 × 33 用例(创建 7 / 列表 5 / 更新 7 / 删除 4 / 排序 5 / 置顶 5
- **通过率**33 / 33 = **100%**
- **验证维度**
- 字段校验(必填 / 长度 ≤50 / `#RRGGBB` 格式)
- 错误码契约5 个业务错误码全部按设计触发)
- 多用户隔离user_id=9999 脏数据无法被 user_id=1001 修改 / 删除 / 排序 / 置顶)
- 事务一致性(排序含他人 id 时,本人 id 也未被改)
- 软删行为(删后立即同名 create 成功)
- 排序规则(`is_pinned DESC, sort_order ASC, last_used_at DESC`
- Long ID 序列化(响应中为字符串,无 JS 精度丢失)
---
## 六、注意事项
1. **前端不需要做任何代码改动**。19 号骨架对接的请求 / 响应解析 / 错误码处理逻辑直接复用。
2. **联调时机**:本次发布后可正式进入真实联调(之前 Mock 期不能验持久化和错误码)。
3. **路径**`/v3/admin/tag-library` 前缀,**带 `/v3`**,经 Gateway 转发到 hl-order-service-v3。
4. **userId 自动派生**:前端不传操作人,后端从 JWT 注入。
---
## 七、关联
- 骨架版 changelog`19_2045_tag-library模块私人标签库管理-新增接口-管理后台.md`
- 真实化 PRhttps://git.1814.love:8443/wx/HL/pulls/2606
- v5.14 §14 章节规范:详见 SRS v5.14
- 负责人yst