You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

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-11
    • sourceType
    • sourceCode
  • 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-115
    • toItem(...) 没有传入 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,没有技能来源类型或技能来源编码

这会使返回结果无法在接口层区分某个技能来自 ESCO 还是 O*NET software_skills,只剩通过数据库内部 ID 才能反查来源。T5 明确要求返回“来源字段”:

  • D:\1\zhi\zhilai\changes\n03-skill-cloud\tasks.md:21
  • D:\1\zhi\zhilai\changes\n03-skill-cloud\execution-contract.md:41
  • D:\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-16
    • heatSourceCode
    • heatElementId
    • heatProxy

这不是当前 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、安全配置或既有接口。
  • 未发现事务、空指针、可变集合、随机性或明显性能问题;当前静态词库规模下三次校验查询加一次投影查询是合理的。

未决问题

  1. 技能来源字段的最终 JSON 名称应为 sourceType/sourceCode,还是采用带 skillSource 前缀的名称;需在修复 I-1 和 T8 OpenAPI 时统一。
  2. heatSource 是否需要改成嵌套对象;若保持扁平字段,应同步修订设计文档和后续接口文档。
  3. I-1 修复后必须重新执行本报告使用的 24 项联合回归,并重新评审;T5 评审通过前不得进入 T6。