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.
 
 
 

12 KiB

N03 行业技能词云与学习路径执行契约

Intent Lock

问题:学生无法从行业和职位维度查看招聘市场热门技能,无法量化自己相对 TOP10 的掌握程度,也没有针对缺失技能的优先级建议。

意图:基于 ESCO + ONET 开源知识底座,通过 Flyway 建立可追溯的行业—职位—技能分类—技能数据。ESCO 作为职位、通用技能和分类主表,ONET software_skills 仅补充 ESCO 缺失的具体技术;O*NET Importance 提供热度及机器可追溯来源。系统提供仅 STUDENT 可访问的词云、个人匹配度和学习路径三个确定性接口。

完成证明:V35/V36 迁移成功执行;三个接口按同一热度列表工作;权限、排序、别名、匹配分母、空数据和通用学习建议均通过自动化测试;OpenAPI 与文档一致。

Scope Fence

允许范围

  • 新增 mydreamjob-server/src/main/resources/db/migration/V35__skill_cloud_taxonomy.sql 和 V36__skill_cloud_seed.sql。
  • 新增 com.mydreamjob.skill 领域包、Repository、Service、DTO 和三个 Controller。
  • 修改安全配置以保护 /skills/**,仅允许已登录 STUDENT。
  • 新增 ESCO/ONET 来源说明、接口文档、OpenAPI 契约和测试。\n- 新增从 ONET 31.0 官方 CSV 提取的测试证据快照,仅用于全量核对种子来源和 Importance,不参与运行时。
  • 首版数据只覆盖互联网、金融、教育及代表性职位。
  • 具体技术无可靠 ESCO 节点时,允许使用 O*NET software_skills 作为补充来源。
  • 词云热度只取 O*NET Importance;无映射时 heat=null。
  • 匹配度使用当前 TOP10 和实际技能数;学习路径只返回缺失技能、优先级和通用建议。

禁止范围

  • 不修改 V1–V34 历史迁移,不改变已有接口语义。
  • 不接 AI、课程平台、第三方运行时接口或在线词库同步。
  • 不按平台岗位 jobId、发布量或用户行为计算热度。
  • 不实现后台词库维护、学习进度、提醒、历史快照或前端页面。
  • 不向 COMPANY/ADMIN 返回个人匹配或学习路径。
  • 不在响应或日志中输出原始 skills_json、手机号、邮箱、简历内容。

Approved Behavior

ID 已批准行为 批次
REQ-SC-1 /skills/word-cloud、/skills/match、/skills/learning-path 只允许已登录 STUDENT;匿名返回 401,COMPANY/ADMIN 返回 403。 B3
REQ-SC-2 industryId、occupationId 必填且必须互为关联;categoryId 可选,存在时必须属于目标职位;非法组合返回 400。 B2、B3
REQ-SC-3 词云返回筛选范围内全部技能,按 heat DESC, nameZh ASC, skillId ASC 排序;heat=null 排在有值技能之后。 B2
REQ-SC-4 TOP10 不单独存储或返回,前端取词云前十条;少于十条时全部结果构成实际 TOP10。 B2、B3
REQ-SC-5 每个技能项包含技能 ID、名称、分类、heat、稳定排名和可追溯来源标识;响应使用 ApiResponse。 B2、B3
REQ-SM-1 个人匹配只使用当前筛选结果的 min(10, actualSize) 个技能,不另建排序。 B2
REQ-SM-2 学生技能只从 JWT 对应学生的 student_profiles.skills_json 读取;缺失、空数组或损坏 JSON 按无技能处理。 B2
REQ-SM-3 匹配使用标准技能和别名,执行 NFKC、首尾空白、大小写、连字符转空格、连续空白折叠和句点移除归一化;+、# 不得删除。 B2
REQ-SM-4 匹配度为 round(matched * 100 / min(10, actualSize));actualSize=0 时返回 0;重复命中同一技能只计一次。 B2
REQ-SM-5 响应分别返回命中与缺失技能,缺失列表保持 TOP10 顺序,两者并集等于实际 TOP10。 B2、B3
REQ-LP-1 学习路径只包含当前 TOP10 的未命中技能,不包含已命中或 TOP10 之外的技能。 B2
REQ-LP-2 学习路径沿用词云顺序,优先级从 1 连续编号;空热度技能仍在有权重技能之后。 B2
REQ-LP-3 学习建议由编程语言、框架、工具、通用四类确定性模板生成;不调用 AI 或外部服务,不含课程链接、时长或价格。 B2
REQ-LP-4 每项只返回技能 ID、名称、分类、优先级和简化建议;无缺口时返回空列表和总数 0。 B2、B3

需求覆盖结果:三份 spec 中全部 14 条 MUST/SHALL 行为均已映射,无未映射需求。

Architecture and Interface Constraints

  • 使用 ESCO 作为职位、通用技能和分类主关系;具体技术无可靠 ESCO 节点时,允许使用 O*NET software_skills 作为补充技能来源。
  • O*NET Importance 作为 heat;项目维护中文名称、别名和细粒度分类。
  • 数据模型固定为 skill_industries、skill_occupations、skill_categories、skills、skill_aliases、occupation_skills、skill_source_versions 七张表。
  • skill_aliases.normalized_alias 全局唯一;occupation_skills(occupation_id, skill_id) 唯一;分类必须属于职位,职位必须属于行业。
  • occupation_skills 必须保存 importance_source_code、importance_element_id 和 importance_is_proxy;非空 importance 必须可追溯到 O*NET 31.0 CSV。
  • 三个接口共享同一个只读排名管道和技能投影;不得复制三套排序规则。
  • 接口路径固定为:
    • GET /api/v1/skills/word-cloud
    • GET /api/v1/skills/match
    • GET /api/v1/skills/learning-path
  • 三个接口查询参数均为 industryId、occupationId 必填,categoryId 可选。
  • 计算按请求实时完成,不持久化匹配或学习路径。
  • 学生技能解析异常记录不含原始内容的告警,接口返回 200 和空技能匹配结果。
  • 首版只使用代表性数据;迁移编号以当前仓库下一个可用版本为准。若合并前 V35/V36 已被其他变更占用,必须回退规划阶段刷新编号和契约。

Execution Batches

Batch B1: 数据与来源基础

  • 覆盖任务:T1、T2、T3,T3 在第 1 次评审后执行来源与分类修复。
  • 交付物:来源清单、V35__skill_cloud_taxonomy.sql、V36__skill_cloud_seed.sql、迁移测试。
  • 完成定义:代表性数据包含三类行业和约定职位;所有入选技能有中文标准名;ESCO 职位来源、ONET 补充技术、每个 Importance 的 SOC/Element ID 均可机器追溯;自动化测试通过版本化证据快照全量核对 ONET 来源和数值。
  • 依赖:无。
  • 评审门:B1 完成并由 code-reviewer 记录 pass 后才能开始 B2。

Batch B2: 排名、匹配与学习路径

  • 覆盖任务:T4、T5、T6、T7。
  • 交付物:实体/Repository、共享词云查询排名服务、别名归一化、个人匹配服务、学习路径模板服务及单元测试。
  • 完成定义:REQ-SC-2 至 REQ-SC-5、REQ-SM-1 至 REQ-SM-5、REQ-LP-1 至 REQ-LP-4 的领域行为可重复且确定。
  • 依赖:B1 通过评审。
  • 评审门:B2 完成并由 code-reviewer 记录 pass 后才能开始 B3。

Batch B3: 接口、权限、契约与回归

  • 覆盖任务:T8、T9、T10。
  • 交付物:三个 Controller、权限配置、MockMvc/H2 集成测试、docs/skill-cloud-api.md、OpenAPI 和前端联调文档更新。
  • 完成定义:REQ-SC-1 至 REQ-SC-5、REQ-SM-5、REQ-LP-4 的接口行为通过;匿名 401、非 STUDENT 403、非法参数 400;文档与运行时一致。
  • 依赖:B2 通过评审。
  • 评审门:B3 完成并由 code-reviewer 记录 pass 后才能进入验证和收尾。

Test Obligations

ID 测试义务 批次 证据
TO-1 Flyway 创建七张表、外键、唯一约束和索引,中文名与来源 ID 完整。 B1 mvn -Dtest=SkillTaxonomyMigrationTest test
TO-2 行业/职位/分类关系校验,非法组合返回 400。 B2、B3 Repository/Service 单测与 MockMvc
TO-3 热度降序、空热度末位、同热度稳定排序、空范围列表。 B2 mvn -Dtest=SkillCloudQueryServiceTest test
TO-4 TOP10 少于十条时使用实际数量,匹配分母为实际数量,1/3 四舍五入为 33。 B2 mvn -Dtest=SkillMatchServiceTest test
TO-5 大小写、空格、连字符、句点、C++、C# 和重复别名匹配。 B2 归一化与匹配单测
TO-6 无技能、无资料、损坏 JSON、全部命中和全部未命中场景。 B2、B3 Service 与 MockMvc 测试
TO-7 学习路径只含未命中技能,优先级连续,无缺口返回空列表。 B2 mvn -Dtest=SkillLearningPathServiceTest test
TO-8 四类建议模板稳定、行业无关,不含链接、时长、价格或 AI 内容。 B2 模板单测
TO-9 三个接口权限、响应结构和参数错误符合契约。 B3 mvn -Dtest=SkillCloudControllerTest test
TO-10 三个接口复用同一 TOP10,响应不含原始 skills_json。 B3 H2 集成测试
TO-11 全量回归、打包和静态 OpenAPI 契约通过。 B3 mvn test、mvn clean verify、python docs\verify_openapi.py

Build Rules

  • 每个 Batch 按 TDD 先写失败测试,再实现最小行为,不得跳过测试。
  • 只修改范围内文件;发现需要修改已验收接口或历史迁移时立即停止并触发 Rewind。
  • 迁移和种子数据必须可在 H2(MODE=MySQL)与真实 MySQL 执行,不依赖外部文件路径。
  • 所有排序、匹配和建议必须确定性;禁止随机、当前时间或请求次数影响结果。
  • 任何新增日志不得包含个人技能 JSON、Token、手机号、邮箱或简历文本。
  • OpenAPI 注解、示例和实际响应必须一致,不能只改文档不改运行时行为。

Review Gates

  • DP-3:本契约必须由用户明确批准并记录后,才能开始任何实现。
  • Batch Review:B1、B2、B3 每个 Batch 完成后由 code-reviewer 按规范符合性和代码质量评审,记录 pass 或 fail。
  • DP-4:批准契约后由 build-executor 给出执行模式与 wave 计划,用户确认后开始执行。
  • Verification Gate:实现完成后执行全量测试、OpenAPI 校验和必要的 MySQL/Docker 黑盒验证。
  • DP-7:由 release-archivist 完成最终验证与关闭,不在本契约内自动完成。

Rewind Conditions

出现以下任一情况必须停止执行并回到规划阶段刷新工件和本契约:

  • 需要新增、删除或改变用户可见接口、筛选参数、权限或响应语义。
  • TOP10、匹配度分母、排序规则或空数据处理发生改变。
  • 需要引入 AI、课程平台、实时岗位热度或后台维护接口。
  • 需要导入全量词库或扩大首版行业/职位范围。
  • 需要新增除 ESCO、O*NET 之外的其他技能来源。
  • V35/V36 被其他变更占用,或历史迁移需要修改。
  • ESCO/O*NET 许可、中文映射策略或数据来源发生实质变化。
  • 发现某个已批准 MUST/SHALL 无法映射到测试或执行批次。

DP-3 Approval Gate

执行者确认:本契约完整覆盖已批准的 14 条必需行为,无未映射需求,B1→B2→B3 依赖清晰,所有测试义务均有证据命令。

批准方式:用户明确回复批准本执行契约后,记录 dp_3_result、dp_3_timestamp,再执行 specifying → bridging → approved-for-build 状态转换。DP-3 记录前禁止进入 build-executor。