5.2 KiB
W2-T5 独立评审报告
- 评审对象:
e3eecfe feat: add skill cloud query service - 评审基线:
52751e5(T4 复审通过提交) - 结论:FAIL
- 评审范围:仅检查提交
e3eecfe的 5 个文件;未修改实现文件。
独立测试结果
环境:JAVA_HOME=D:\java\jdk,Maven D:\maven\apache-maven-3.9.7\bin\mvn.cmd。
执行:
mvn -Dtest=SkillTaxonomyMigrationTest,SkillCloudSeedDataIntegrationTest,SkillTaxonomyRepositoryTest,SkillCloudQueryServiceTest test
结果:
Tests run: 24, Failures: 0, Errors: 0, Skipped: 0
BUILD SUCCESS
测试数量拆分为:迁移 2、种子数据 8、Repository 6、词云 Service 8。
Important
[I-1] 响应项遗漏技能自身的来源标识,违反 T5 的“来源字段”和可追溯要求
SkillCloudSkillProjection 已查询并携带技能来源字段:
D:\1\zhi\zhilai\mydreamjob-server\src\main\java\com\mydreamjob\skill\dto\SkillCloudSkillProjection.java:10-11sourceTypesourceCode
D:\1\zhi\zhilai\mydreamjob-server\src\main\java\com\mydreamjob\skill\repository\OccupationSkillRepository.java:25-26- 查询投影包含
s.sourceType和s.sourceCode
- 查询投影包含
D:\1\zhi\zhilai\mydreamjob-server\src\main\java\com\mydreamjob\skill\repository\OccupationSkillRepository.java:52-53- 分类查询同样包含这两个来源字段
但 Service 转换成响应 DTO 时丢弃了这两个字段:
D:\1\zhi\zhilai\mydreamjob-server\src\main\java\com\mydreamjob\skill\SkillCloudQueryService.java:102-115toItem(...)没有传入projection.sourceType()或projection.sourceCode()
D:\1\zhi\zhilai\mydreamjob-server\src\main\java\com\mydreamjob\skill\dto\SkillCloudItem.java:5-17- Item 只有
heatSourceCode、heatElementId、heatProxy,没有技能来源类型或技能来源编码
- Item 只有
这会使返回结果无法在接口层区分某个技能来自 ESCO 还是 O*NET software_skills,只剩通过数据库内部 ID 才能反查来源。T5 明确要求返回“来源字段”:
D:\1\zhi\zhilai\changes\n03-skill-cloud\tasks.md:21D:\1\zhi\zhilai\changes\n03-skill-cloud\execution-contract.md:41D:\1\zhi\zhilai\changes\n03-skill-cloud\specs\skill-cloud\spec.md:86-93
当前测试也没有覆盖该缺口:SkillCloudQueryServiceTest 只断言了 React 的 heatSourceCode、heatElementId 和 heatProxy(SkillCloudQueryServiceTest.java:198-223),没有断言 Item 中应携带 sourceType/sourceCode。因此该遗漏是可复现但不可被现有测试发现的。
修复要求:在 SkillCloudItem 中补齐技能来源字段,在 toItem 中映射,并增加至少一个 ESCO 技能和一个 O*NET software_skills 技能的精确断言;同时确认无 heat 的技能仍保留其技能来源。
Minor
[M-1] heatSource 的响应形态与设计文档不一致,需在 T8 前统一
设计文档将词云项描述为包含 heatSource:
D:\1\zhi\zhilai\changes\n03-skill-cloud\design.md:131
当前实现使用三个扁平字段表达同一语义:
D:\1\zhi\zhilai\mydreamjob-server\src\main\java\com\mydreamjob\skill\dto\SkillCloudItem.java:13-16heatSourceCodeheatElementIdheatProxy
这不是当前 T5 的运行时错误,但 T8 必须明确 OpenAPI 和接口文档采用扁平字段还是嵌套 heatSource 对象,避免契约漂移。
[M-2] T5 服务测试对 null heat 的来源字段覆盖不足
SkillCloudQueryServiceTest 对 React 的非空 heat 来源做了精确断言,但没有对无 heat 技能(如当前种子数据中的 Figma)断言 heatSourceCode、heatElementId 和 heatProxy 的最终 DTO 值。T4 投影测试覆盖了该场景,因此暂不阻断;修复 I-1 时应顺带补齐服务层断言。
已通过检查
- 行业存在性、职位存在性、行业—职位归属校验均使用
BusinessException(ErrorCode.BAD_REQUEST)。 - 非法
industryId、occupationId、categoryId(null、0、负数)均返回 400 语义;未知节点和跨行业/跨职位节点同样返回 400。 categoryId缺省时调用整职位查询;传入时调用职位+分类查询,并保留 Repository 的职位—分类归属约束。- 排序实现为
heat DESC、null heat 最后、nameZh ASC、skillId ASC;当前种子数据测试能捕获名称比较器和 skillId 比较器写错,也覆盖了 null heat 末位和连续 rank。 - 空分类返回成功、
total=0、空 items。 SkillCloudResponse对列表执行List.copyOf,响应列表不可变。- 提交范围仅包含 T5 的 Service、3 个 DTO 和测试文件,没有实现 T6/T7/T8,也没有修改 V35/V36、安全配置或既有接口。
- 未发现事务、空指针、可变集合、随机性或明显性能问题;当前静态词库规模下三次校验查询加一次投影查询是合理的。
未决问题
- 技能来源字段的最终 JSON 名称应为
sourceType/sourceCode,还是采用带skillSource前缀的名称;需在修复 I-1 和 T8 OpenAPI 时统一。 heatSource是否需要改成嵌套对象;若保持扁平字段,应同步修订设计文档和后续接口文档。- I-1 修复后必须重新执行本报告使用的 24 项联合回归,并重新评审;T5 评审通过前不得进入 T6。