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.
 
 
 

6.1 KiB

W2-T4 修复复审报告

状态

完成。本轮仅复审修复提交 52751e5,对照第一轮报告 W2-T4.md,未修改任何实现、测试、迁移或配置文件;仅新增本报告。

Verdict

PASS

第一轮阻断项 W2-T4-I1 已关闭。两个投影查询均已保证技能分类的 occupation_id 与职位技能关系的 occupation_id 一致,新增测试真实构造了跨职位分类错配数据并验证查询排除该数据。规定回归集全部通过,未发现新的 Critical、Important 或阻断项。

Finding 关闭状态

W2-T4-I1:分类过滤查询未强制 category 与 occupation 属于同一职位

状态:已关闭。

关闭证据:

  • 整职位查询在分类关联后增加了 c.occupationId = os.occupationId: D:\1\zhi\zhilai\mydreamjob-server\src\main\java\com\mydreamjob\skill\repository\OccupationSkillRepository.java:36-40
  • 职位加分类查询同样增加了该约束,并保留 os.occupationId = :occupationId 与 os.categoryId = :categoryId: D:\1\zhi\zhilai\mydreamjob-server\src\main\java\com\mydreamjob\skill\repository\OccupationSkillRepository.java:63-69
  • 两个查询均继续通过 os.skillId = s.id 和 os.categoryId = c.id 连接技能及分类,未改变投影字段或原过滤条件。

独立测试结果

环境:

  • JAVA_HOME=D:\java\jdk
  • Java:OpenJDK 17.0.16
  • Maven:D:\maven\apache-maven-3.9.7\bin\mvn.cmd
  • 工作目录:D:\1\zhi\zhilai\mydreamjob-server

命令:

$env:JAVA_HOME='D:\java\jdk'
& 'D:\maven\apache-maven-3.9.7\bin\mvn.cmd' '-Dtest=SkillTaxonomyMigrationTest,SkillCloudSeedDataIntegrationTest,SkillTaxonomyRepositoryTest' test

结果:

SkillCloudSeedDataIntegrationTest: Tests run: 8, Failures: 0, Errors: 0, Skipped: 0
SkillTaxonomyMigrationTest:       Tests run: 2, Failures: 0, Errors: 0, Skipped: 0
SkillTaxonomyRepositoryTest:      Tests run: 6, Failures: 0, Errors: 0, Skipped: 0
Total:                            Tests run: 16, Failures: 0, Errors: 0, Skipped: 0
BUILD SUCCESS
Total time: 40.769 s

必须检查项逐项结论

1. 两个投影查询均约束 category 所属 occupation,且保留过滤:通过

两个查询都在连接 os.categoryId = c.id 后增加:

AND c.occupationId = os.occupationId

整职位查询继续只按目标 occupationId 过滤;职位加分类查询继续同时按目标 occupationId 和 categoryId 过滤。因此:

  • 不会再通过职位 A 的关系读取仅属于职位 B 的分类;
  • 分类参数仍必须与关系中的分类 ID 完全相等;
  • 职位参数语义未改变。

位置:

  • OccupationSkillRepository.java:36-43
  • OccupationSkillRepository.java:63-72

2. 新增测试真实插入跨职位错配关系,且可证伪修复:通过

新增测试位于 D:\1\zhi\zhilai\mydreamjob-server\src\test\java\com\mydreamjob\skill\SkillTaxonomyRepositoryTest.java:123-152。

测试通过 JdbcTemplate 向真实 occupation_skills 表插入:

  • occupation_id = 1
  • category_id = 201
  • skill_id = 1
  • source_version_id = 2

其中分类 201 在 V36 中明确属于职位 2,见 V36__skill_cloud_seed.sql:67;技能 1 存在,见 V36__skill_cloud_seed.sql:129。插入使用合法外键值和完整来源字段,因此构造的是数据库允许保存、但职位与分类不属于同一节点的逻辑错配关系。

该测试没有断言 SQL 文本,而是调用真实 Repository 方法并检查返回结果。修复前的查询缺少同职位约束,插入关系会满足 os.skillId = s.id、os.categoryId = c.id 和 os.occupationId = 1,因此:

  • 整职位查询会包含技能 1,在第 142 行 doesNotContain(1L) 失败;
  • occupation=1, category=201 查询会包含该关系,在第 144-146 行失败。

修复后该关系被 c.occupationId = os.occupationId 排除,测试通过,可证伪性成立。

测试方法带 @Transactional,见 SkillTaxonomyRepositoryTest.java:123-124,插入数据在测试结束后回滚,不污染其他测试或 V36 计数。

3. 三项断言均正确覆盖:通过

SkillTaxonomyRepositoryTest.java:136-151 分别验证:

  • 整职位查询仍包含正常技能 3,且不包含错配技能 1;当前断言在 139-142 行。
  • 错误分类组合 occupation=1, category=201 返回空列表;当前断言在 144-146 行。
  • 正确组合 occupation=2, category=201 仍返回技能 1,证明修复没有误伤合法数据;当前断言在 148-151 行。

三项断言覆盖了第一轮要求的安全边界和正常路径。

4. 正常查询、空 Importance、来源字段和计数:通过

  • 原整职位和分类过滤测试继续验证职位 1 返回 15 项、分类 101 返回精确技能集合,以及错误职位分类返回空:SkillTaxonomyRepositoryTest.java:95-120。
  • O*NET 来源字段、importance、importanceSourceCode、importanceElementId、代理标记和排序字段的原断言仍通过:SkillTaxonomyRepositoryTest.java:154-188。
  • Figma 的空 Importance 场景仍通过:SkillTaxonomyRepositoryTest.java:176-188。
  • V36 计数仍为来源版本 2、行业 3、职位 10、分类 68、技能 72、别名 72、职位技能关系 139:SkillTaxonomyRepositoryTest.java:72-81。
  • 指定回归集 16 项全部通过,未观察到由新增约束造成的正常查询、投影字段或种子数据回归。

5. 提交范围与 T5 边界:通过

git diff --name-only 0c77824..52751e5 仅列出:

  • mydreamjob-server/src/main/java/com/mydreamjob/skill/repository/OccupationSkillRepository.java
  • mydreamjob-server/src/test/java/com/mydreamjob/skill/SkillTaxonomyRepositoryTest.java

未修改 V35/V36、生产配置、安全配置或其他模块,也未实现任何 T5 排名、匹配或学习路径代码。git diff --check 0c77824..52751e5 通过。

剩余阻断项

无。

非阻断备注

V35 仍允许数据库层面写入 occupation_id 与 category_id 逻辑不一致的关系,因为当前外键是单列外键;本次修复保证 Repository 查询不会返回此类错配数据。是否需要增加数据库复合完整性约束属于独立的数据模型变更,不影响 T4 通过。