fix(user-service): 补回 review_report_reason 字典 (PR #1739)

测试服 dict_type review_report_reason 缺失,前端举报弹窗下拉空。
三 PR 叠加 (#1667 加 V007 / #1681 oneshot 跳过 V007 / #1684 Flyway
baseline=20260505.009 屏蔽 V007 自动 apply) 导致永久漏空。
新发 V20260507_001 重做字典初始化 (版本号 > baseline → Flyway apply)。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
这个提交包含在:
wx 2026-05-06 19:22:02 +08:00
父节点 2ae056d5de
当前提交 88dc320976

查看文件

@ -0,0 +1,82 @@
# 补回 review_report_reason 字典 (Flyway baseline 屏蔽 V007 漏空)
**日期**: 2026-05-06
**类型**: fix (后端 DB 字典补漏,无代码改动,无前端影响)
**PR**: wx/HL #1739 (已合并 dev)
**关联工单**: 无独立工单 (历史漏空,前端反馈"测试服 review_report_reason 字典没有"后直接修)
**引入**: 三 PR 叠加 — #1667 + #1681 + #1684
## 问题
测试服评价举报原因字典 `review_report_reason` 缺失,前端举报弹窗下拉框拉空(或显示英文 enum value 像乱码)。
实测证据(测试服 admin token round-trip):
- `/admin/dict/all` 返回 156 条字典类型,**不含** `review_report_reason`
- `/admin/dict/type/10080``code=404, 字典类型不存在`
- `/admin/dict/data/review_report_reason``code=200, data=[]`
## 根因(三 PR 叠加导致永久漏空)
| PR | 动作 |
|---|---|
| #1667 (wx-security Phase 2B) | 加入 `V20260505_007__init_review_report_reason_dict.sql` 字典初始化 SQL |
| #1681 (oneshot 补漏) | 手工跑 V001/V002/V004/V008/V009 V*.sql,**oneshot 文件第 16 行注释明确跳过 V007**(`V007 init_review_report_reason_dict (sys_dict_data INSERT, 评估后再决定)`) |
| #1684 (Flyway 阶段 2) | `application.yml``baseline-version: 20260505.009` + `baseline-on-migrate: true`,首次启动写 baseline,**所有 ≤ baseline 的 V*.sql 永远不会被 Flyway 自动 apply**,包括 V20260505_007 |
净结果:V20260505_007 既没被 oneshot 手工跑,也被 Flyway baseline 屏蔽自动 apply,字典数据从未落库。
## 修复
新增 `V20260507_001__init_review_report_reason_dict.sql`(版本号 > baseline 20260505.009 → Flyway 自动 apply)。
| 项 | 取值 |
|---|---|
| `dict_type_id` | 10080(V007 原计划占用,测试服 type/10080 返 404 已确认空闲) |
| `dict_data_id` | 100801~100807(7 条) |
| 幂等 | `INSERT IGNORE` — prod 若曾手工跑过 V007 则静默跳过不抛错 |
字典值集与代码 `ReviewReportReason.ALLOWED` 严格一致:`SPAM`/`INSULT`/`PORN`/`POLITICS`/`FAKE`/`LEAK_PRIVACY`/`OTHER`
## 影响范围
- **后端**: hl-user-service 一服务部署即生效
- **前端**: 无代码改动需求 — mmg/yst 不用动
- **数据**: 仅 `sys_dict_type` 加 1 条 + `sys_dict_data` 加 7 条
- **回滚**: 删除 sys_dict_type/sys_dict_data 对应行 + 删 flyway_schema_history 中 V20260507_001 行
## 验证
### 测试服 round-trip(dev 部署后)
```bash
# 期望: data 含 7 条字典数据
curl -sk -H "Authorization: Bearer <admin-token>" \
"https://api.test.1814.love:9443/admin/dict/data/review_report_reason"
# 期望返回: {"code":200,"data":[{"dictValue":"SPAM","dictLabel":"广告/营销",...}, ...7 条]}
```
### Redis 缓存清理(必要)
直接 SQL INSERT 字典不会触发应用层 D3 反向索引 invalidate,user-service 部署完成后需清三件:
```bash
redis-cli -n 0 DEL cache:dict:data:list
redis-cli -n 0 DEL cache:dict:data:by-type
redis-cli -n 0 DEL "cache:dict:data:review_report_reason"
```
## 部署计划
- ✅ dev 测试服: PR 合并后自动部署(本 changelog 写时正在 deploy panel 部署中)
- ⏳ prod: 用户手动合 dev → main 后,通过 Deploy Panel 触发 hl-user-service prod 部署。Flyway 会自动 apply V20260507_001;若 prod 此前已手工跑过 V007,`INSERT IGNORE` 兜底跳过
## 经验沉淀
`memory/experience/backend-dev/flyway-baseline-version-permanently-skips-old-v-sql.md`(若不存在则新建):
**Flyway baseline-version 永久屏蔽 ≤ baseline 的 V*.sql**:接入 Flyway 时 baseline 写哪个版本,就意味着该版本 + 之前的 V*.sql 即使在 migration 目录里也永远不会被自动 apply。**接入 Flyway 前必须确认 baseline 之前的 V*.sql 在 prod/test 是否真的全部跑过**,任何一条漏跑就要么先补跑,要么发新版本号 > baseline 的 V*.sql 重做(本次踩坑)。
## 通知
- mmg(前端): 测试服部署 + 缓存清理后,举报弹窗下拉框应显 7 项中文(广告/营销、辱骂/人身攻击 等),不再空/英文
- 用户: 部署完成 + round-trip 验收通过后告知,可挂 prod 部署