15 KiB
N04 入职清单与公司知识介绍执行契约
Intent Lock
问题:产品一期要求提供入职清单和公司知识介绍,但当前后端没有对应表、接口、权限或测试。学生无法获得“通用准备项 + 企业自定义项”的有效清单,无法保存个人完成状态,也无法集中查看企业基础资料、文化制度、入职指南和公开评价摘要;企业无法维护本公司差异内容。
意图:新增最小可用的 onboarding 后端模块。通过 V38/V39 建立三张业务表和通用清单种子;提供 9 个确定性接口;STUDENT 读取有效清单、更新本人完成状态、读取公司知识,COMPANY 仅维护本企业自定义清单与知识内容;公司知识使用企业基础资料、企业维护内容及公开评价摘要,其中公开评价少于 3 条时不返回均值。不调用 AI,不引入 ADMIN 内容治理。
完成证明:V38/V39 在 H2 与真实 MySQL 成功执行;9 个接口的权限、所有权、幂等、并发、回退、排序、完成率、评价摘要和小样本保护均通过自动化测试;OpenAPI、接口文档和前端联调文档与运行时一致;mvn clean verify 与 python docs/verify_openapi.py 通过。
Scope Fence
允许范围
- 新增
mydreamjob-server/src/main/resources/db/migration/V38__onboarding_checklist_and_company_knowledge.sql和V39__onboarding_standard_checklist_seed.sql。 - 新增
com.mydreamjob.onboarding领域包,包括实体、Repository、Service、Controller、DTO 和测试。 - 修改
SecurityConfig.java,使/onboarding/**仅允许认证访问,并在服务层执行 STUDENT/COMPANY 角色与公司所有权校验。 - 修改
ErrorCode.java,新增 9701-9706。 - 更新
docs/openapi-rc.json、docs/onboarding-api.md、docs/frontend-integration.md、docs/backend-development-roadmap.md和README.md。 - 只读复用
Company、CompanyRepository、Job、JobReview、JobReviewDimensionScore及其 Repository。 - 采用 9 个固定接口:
GET /api/v1/onboarding/companies/{companyId}/checklistPUT /api/v1/onboarding/companies/{companyId}/checklist/items/{itemId}/completionGET /api/v1/onboarding/companies/{companyId}/knowledgeGET /api/v1/onboarding/company/checklist-itemsPOST /api/v1/onboarding/company/checklist-itemsPUT /api/v1/onboarding/company/checklist-items/{itemId}DELETE /api/v1/onboarding/company/checklist-items/{itemId}?version={version}GET /api/v1/onboarding/company/knowledgePUT /api/v1/onboarding/company/knowledge
禁止范围
- 不修改 V1-V37 历史迁移或既有表结构。
- 不修改既有企业、岗位、Offer、评价和维度评分接口的路径、请求、响应或权限语义。
- 不实现 ADMIN 模板管理、审核发布、版本回滚、CMS 或内容治理后台。
- 不实现通知、内容推荐、试用期提醒、入职回访、在职反馈或前端页面。
- 不按岗位、投递或 Offer 生成个性化清单,不引入入职资格门槛。
- 不接 AI、第三方内容平台、外部搜索或实时同步。
- 不存储或渲染 HTML/富文本;知识字段按纯文本处理并限制长度。
- 不在响应或日志中输出
ownerUserId、员工用户 ID、手机号、邮箱、Token、IP、User-Agent、评价哈希或审核原因。 - 不启动或停止 Docker;真实 MySQL/Docker 黑盒验收需要用户单独授权。
Approved Behavior
| ID | 已批准行为 | 批次 |
|---|---|---|
| REQ-OC-1 | STUDENT 按存在的 companyId 获取有效清单;响应包含通用项与企业活动自定义项、排序、分类、必填标记、个人完成状态、完成数、总数、完成率和 customized;企业不存在返回 404。 |
B1、B2 |
| REQ-OC-2 | STUDENT 通过 PUT 将本人对有效条目的状态设置为完成或未完成;相同状态重复提交幂等;取消完成清除 completedAt;跨企业或非活动 itemId 返回 404;响应返回版本和最新完成率。 |
B1、B2、B3 |
| REQ-OC-3 | COMPANY 创建本企业自定义项;请求校验标题、说明、分类、排序和必填标记;相同 idempotencyKey 与相同请求体返回原条目,不同请求体返回 409 ONBOARDING_IDEMPOTENCY_CONFLICT;活动自定义项达到 50 条后返回 409 ONBOARDING_ITEM_LIMIT_EXCEEDED。 |
B1、B2、B3 |
| REQ-OC-4 | COMPANY 查询本企业全部自定义项;使用当前 version 更新标题、说明、分类、排序、必填和活动状态;过期版本返回 409 ONBOARDING_CHECKLIST_ITEM_CONCURRENT_UPDATE;不得读取或修改其他企业条目。 |
B1、B2、B3 |
| REQ-OC-5 | COMPANY 使用当前 version 软删除本企业条目;条目从学生有效清单消失,历史和完成记录保留;重复删除幂等成功;跨企业删除返回 404 且状态不变。 |
B1、B2、B3 |
| REQ-OC-6 | 学生接口仅允许 STUDENT;企业配置接口仅允许 COMPANY 且只能操作当前用户拥有的企业;未登录返回 401,角色不符返回 403,无企业资料返回 404;所有响应使用白名单 DTO。 | B2、B3 |
| REQ-CK-1 | STUDENT 按存在的 companyId 读取公司知识;企业有知识记录返回 CONFIGURED,无记录返回 BASIC_ONLY 和企业基础资料;不得返回 ownerUserId 等内部字段;企业不存在返回 404。 |
B1、B2 |
| REQ-CK-2 | 公司评价摘要只使用该公司岗位下 PUBLISHED 且审核为 AUTO_APPROVED/APPROVED 的评价;无评价返回 EMPTY;少于 3 条返回 INSUFFICIENT 和不含均值的真实数量;至少 3 条返回平均分、评分分布、热门标签和八维摘要,维度返回样本数和 SUFFICIENT/INSUFFICIENT。 |
B1、B2、B3 |
| REQ-CK-3 | COMPANY 读取本企业知识配置;无记录返回 configured=false、空内容和版本 0;有记录返回内容、更新时间和当前版本。 |
B1、B2 |
| REQ-CK-4 | COMPANY Upsert 本企业知识内容;文化最多 2000 字符,工作制度和入职指南最多 4000 字符,至少一个字段非空,按纯文本处理;已有记录使用当前版本,冲突返回 409 ONBOARDING_KNOWLEDGE_CONCURRENT_UPDATE。 |
B1、B2、B3 |
| REQ-CK-5 | 公司知识学生读取仅允许 STUDENT;企业配置仅允许 COMPANY 且只操作本企业;非角色访问返回 401/403;不存在的公司返回 404。 | B2、B3 |
| REQ-CK-6 | 本变更只读复用既有企业、岗位、评价和维度数据,不修改历史表结构和既有接口语义;既有测试与 OpenAPI 路径必须回归通过。 | B3 |
需求覆盖结果:两份 spec 中全部 12 条 Requirement 的 MUST/SHALL 行为均已映射到 Approved Behavior、至少一个测试义务和至少一个执行批次,无未映射需求。
Architecture and Interface Constraints
- 数据模型固定为
onboarding_checklist_items、student_onboarding_progress、company_knowledge三张表。 onboarding_checklist_items使用scope_type/scope_id/item_key区分并唯一化 STANDARD 与 COMPANY 条目;company_id仅对企业项建立外键。student_onboarding_progress(student_user_id, item_id)唯一;完成状态采用绝对值 Upsert,completedAt仅在完成时存在。company_knowledge.company_id唯一;知识内容按纯文本存储并使用@Version。- 通用清单由 V39 固定种子提供,企业自定义项只增量追加,不允许覆盖或裁剪通用项。
- 学生有效清单必须在一次查询中合并活动通用项和企业项,并使用
sortOrder ASC, id ASC稳定排序。 - 完成率计算为
completedItems * 100.0 / totalItems,保留一位小数并最大为 100.0;空清单为 0.0。 - 创建清单项使用
idempotencyKey和规范化请求体 SHA-256;更新、删除、完成状态和知识内容使用乐观锁语义。 - 公司评价摘要必须通过公司下所有岗位聚合,不得只使用单个岗位汇总;热门标签从公开评价 tags 中计数,按次数降序、字典序升序,最多 10 个。
- 八维摘要复用
ReviewDimension,八个维度均返回,缺失维度样本数为 0、dataState=INSUFFICIENT。 - 所有响应使用
ApiResponse<T>;请求 ID 从X-Request-Id读取。 - 新增错误码固定为:
9701 ONBOARDING_CHECKLIST_ITEM_NOT_FOUND9702 ONBOARDING_CHECKLIST_ITEM_CONCURRENT_UPDATE9703 ONBOARDING_ITEM_LIMIT_EXCEEDED9704 ONBOARDING_IDEMPOTENCY_CONFLICT9705 ONBOARDING_PROGRESS_CONCURRENT_UPDATE9706 ONBOARDING_KNOWLEDGE_CONCURRENT_UPDATE
- 复用
FORBIDDEN、UNAUTHORIZED、BAD_REQUEST和COMPANY_NOT_FOUND。 - 迁移编号以当前仓库下一个可用版本为准;若 V38/V39 被其他变更占用,必须回退规划阶段刷新编号和契约。
Execution Batches
Batch B1: 数据模型、迁移与只读聚合基础
- 覆盖任务:T1、T2。
- 交付物:V38/V39 迁移、三个实体、三个模块 Repository、现有评价跨岗位聚合查询、迁移和 Repository 集成测试。
- 完成定义:H2/MySQL 可创建三张表、约束和索引;通用种子数量和排序稳定;活动通用项与企业项可合并查询;学生完成记录可批量读取;公司公开评价可按评分、维度和 tags 聚合。
- 依赖:无。
- 评审门:B1 完成并由
code-reviewer记录pass后才能开始 B2。
Batch B2: 学生清单、企业配置与公司知识接口
- 覆盖任务:T3、T4、T5。
- 交付物:两个 Controller、两个 Service、全部 DTO、清单合并与完成状态、自定义项 CRUD、知识 Upsert、基础信息和评价摘要组装、Service 与 MockMvc 专项测试。
- 完成定义:REQ-OC-1 至 REQ-OC-6、REQ-CK-1 至 REQ-CK-5 的接口和服务行为实现;企业无自定义项时回退通用清单;无知识时返回基础信息;公开评价少于 3 条不返回均值。
- 依赖:B1 通过评审。
- 评审门:B2 完成并由
code-reviewer记录pass后才能开始 B3。
Batch B3: 权限、并发、契约、全量测试与文档
- 覆盖任务:T6、T7、T8。
- 交付物:
SecurityConfig与ErrorCode更新、角色和所有权集成测试、幂等与乐观锁冲突测试、隐私断言、端到端测试、OpenAPI、接口文档和前端联调文档。 - 完成定义:匿名 401、非角色 403、企业不存在 404、跨企业 404、版本冲突 409、幂等冲突 409、活动项上限 409 均符合契约;OpenAPI 包含 9 个路径并运行时一致;
mvn clean verify与python docs/verify_openapi.py通过。 - 依赖:B2 通过评审。
- 评审门:B3 完成并由
code-reviewer记录pass后才能进入验证和收尾。
Test Obligations
| ID | 测试义务 | 批次 | 证据 |
|---|---|---|---|
| TO-1 | V38/V39 创建三张表、主外键、唯一键和索引;通用种子内容、分类和排序稳定。 | B1 | mvn -Dtest=OnboardingMigrationTest,OnboardingSeedDataIntegrationTest test |
| TO-2 | 企业无自定义项回退通用清单;有项时合并排序、来源和 category 正确。 | B1、B2 | Repository 集成测试、OnboardingChecklistServiceTest |
| TO-3 | 完成状态首次设置、重复相同状态、取消完成、跨企业 itemId 和完成率。 | B2 | mvn -Dtest=OnboardingChecklistServiceTest,OnboardingChecklistControllerTest test |
| TO-4 | 创建校验、幂等重放、请求体哈希冲突和 50 条活动项上限。 | B2、B3 | OnboardingCompanyChecklistServiceTest、持久化测试 |
| TO-5 | 企业列表、更新、软删除、版本冲突、重复删除和跨企业隔离。 | B2、B3 | OnboardingCompanyChecklistServiceTest、OnboardingConcurrencyIntegrationTest |
| TO-6 | STUDENT/COMPANY/ADMIN/匿名权限矩阵和白名单响应。 | B2、B3 | OnboardingAuthorizationIntegrationTest、OnboardingPrivacyTest |
| TO-7 | 公司知识无记录回退、企业读取、首次创建、更新和长度校验。 | B2 | mvn -Dtest=CompanyKnowledgeServiceTest,CompanyKnowledgeControllerTest test |
| TO-8 | 评价只取公开记录;0、1、2、3 条边界;评分分布、标签和八维摘要。 | B1、B2 | 聚合 Repository 测试、CompanyKnowledgeServiceTest |
| TO-9 | 知识版本冲突返回 9706,不覆盖新内容。 | B2、B3 | OnboardingConcurrencyIntegrationTest |
| TO-10 | 9 个接口的状态码、请求/响应 DTO、错误码和 OpenAPI 一致性。 | B3 | OnboardingEndToEndIntegrationTest、python docs/verify_openapi.py |
| TO-11 | 迁移、种子、实体、Repository、Service、Controller 和权限集成场景全部可重复。 | B1、B2、B3 | mvn -Dtest=Onboarding*Test test |
| TO-12 | 既有模块回归、完整打包、静态契约和无敏感字段泄露。 | B3 | mvn clean verify、python docs/verify_openapi.py |
Build Rules
- 每个批次按 TDD 先写失败测试,再实现最小行为,不得跳过测试。
- 只修改允许范围内文件;发现需要修改已验收接口、历史迁移或既有响应语义时立即停止并触发 Rewind。
- 迁移和种子数据必须可在 H2(
MODE=MySQL)与真实 MySQL 执行,不依赖外部文件路径。 - 所有清单排序、完成率、评价汇总和标签排序必须确定性;禁止随机数、当前时间或请求顺序影响结果。
- 新增日志不得包含个人完成明细、Token、手机号、邮箱、IP、User-Agent、评价哈希或审核原因。
- OpenAPI 注解、示例和实际响应必须一致,不能只改文档或只改运行时。
- 企业内容按纯文本处理,不拼接 HTML;前端展示安全由 JSON 字符串和前端转义共同保证。
- 不启动或停止 Docker;若需要真实 MySQL/Docker 黑盒验证,必须先取得用户单独授权。
Review Gates
- DP-3:本执行契约必须由用户明确批准并记录
dp_3_result、dp_3_timestamp后,才能开始任何实现。 - Batch Review:B1、B2、B3 每批完成后由
code-reviewer按规范符合性和代码质量评审,记录pass或fail。 - DP-4:批准契约后由
build-executor给出执行模式和 wave 计划,用户确认后开始执行。 - Verification Gate:实现完成后执行专项测试、全量测试、OpenAPI 校验和必要的 MySQL/Docker 黑盒验证。
- DP-7:由
release-archivist完成最终验证与关闭,不在本契约内自动完成。
Rewind Conditions
出现以下任一情况必须停止执行并回到规划阶段刷新工件和本契约:
- 需要新增、删除或改变用户可见接口、请求字段、响应字段、权限或错误语义。
- 需要改变数据表结构、唯一键、外键、通用/企业项来源模型或迁移编号。
- 需要改变完成状态幂等、乐观锁、完成率公式或软删除语义。
- 需要改变公开评价审核状态、3 条小样本阈值、八维维度或热门标签排序。
- 需要引入 ADMIN 模板治理、内容审核、版本回滚、通知、推荐、Offer 资格门槛或 AI。
- 需要修改 V1-V37、既有企业/岗位/评价接口或既有表结构。
- V38/V39 被其他变更占用。
- 发现任一已批准
MUST/SHALL无法映射到测试义务或执行批次。
DP-3 Approval Gate
执行者确认:本契约完整覆盖已批准的 12 条 Requirement,无未映射需求;B1→B2→B3 依赖清晰;不同批次之间的实体、Repository、DTO 和错误码接口已在 Architecture and Interface Constraints 中固定;所有测试义务均有证据命令。
批准方式:用户明确回复批准本执行契约后,记录 dp_3_result、dp_3_timestamp,再执行 specifying → bridging → approved-for-build 状态转换。DP-3 记录前禁止进入 build-executor。