7 changed files with 322 additions and 10 deletions
@ -0,0 +1,20 @@ |
|||
# N04 Spec Merge Report |
|||
|
|||
同步时间:2026-09-17T02:48:23Z |
|||
|
|||
| Capability | ADDED | MODIFIED | REMOVED | RENAMED | Status | |
|||
| --- | ---: | ---: | ---: | ---: | --- | |
|||
| onboarding-checklist | 6 | 0 | 0 | 0 | published | |
|||
| company-knowledge | 6 | 0 | 0 | 0 | published | |
|||
|
|||
- Total requirements published: 12 |
|||
- Conflicts: none |
|||
- Delta files retained for traceability. |
|||
- Manual fallback used because ssf sync is unavailable in this environment. |
|||
|
|||
## Hashes |
|||
|
|||
- specs/onboarding-checklist/spec.md: 16dfd71160065d7df6dbd5457557de14ea82177f9b6fe2c128182f8414b74cf6 |
|||
- changes/n04-onboard/specs/onboarding-checklist/spec.md: 22a458ea81e3081d0f427089712269f3481a91cb74f5b46295d16f369ee1a50b |
|||
- specs/company-knowledge/spec.md: fdbba93e72477c4616c8fa35682e3603921000e75a537c4327fbcd81ea966887 |
|||
- changes/n04-onboard/specs/company-knowledge/spec.md: 254cc5df3b9d758d0f26321d6554b634b75672d61331fde74c317ec8d1da4e6e |
|||
@ -0,0 +1,129 @@ |
|||
# Company Knowledge Specification |
|||
|
|||
## Purpose |
|||
|
|||
定义公司知识配置、学生公司知识聚合和公开评价小样本保护行为。 |
|||
|
|||
## Requirements |
|||
|
|||
### Requirement: 学生读取公司知识介绍 |
|||
|
|||
系统 SHALL 允许已登录 STUDENT 通过 `GET /onboarding/companies/{companyId}/knowledge` 读取公司知识介绍。响应 MUST 聚合企业基础资料、企业维护的知识内容以及公开评价摘要,并使用白名单 DTO 排除 `ownerUserId` 等内部字段。 |
|||
|
|||
#### Scenario: 企业已维护知识内容 |
|||
|
|||
- **WHEN** STUDENT 请求存在企业且该企业已有知识内容 |
|||
- **THEN** 系统返回企业基础资料、文化、工作制度、入职指南和更新时间 |
|||
- **AND** `knowledgeState` 为 `CONFIGURED` |
|||
- **AND** 不返回企业 `ownerUserId`、员工用户 ID、评价哈希或审核原因 |
|||
|
|||
#### Scenario: 企业未维护知识内容 |
|||
|
|||
- **WHEN** STUDENT 请求存在企业且该企业没有知识内容记录 |
|||
- **THEN** 系统仍返回企业基础资料 |
|||
- **AND** `knowledgeState` 为 `BASIC_ONLY` |
|||
- **AND** 知识内容字段为 `null` 或空集合,不返回 404 |
|||
|
|||
#### Scenario: 企业不存在 |
|||
|
|||
- **WHEN** STUDENT 请求不存在的 `companyId` |
|||
- **THEN** 系统返回 404 `COMPANY_NOT_FOUND` |
|||
|
|||
### Requirement: 公司知识评价摘要使用公开数据和小样本保护 |
|||
|
|||
系统 SHALL 聚合该企业全部岗位中状态为 `PUBLISHED` 且审核状态为 `AUTO_APPROVED` 或 `APPROVED` 的评价。公开评价少于 3 条时 MUST 返回 `INSUFFICIENT` 或 `EMPTY`,且不得返回平均分或维度均值。达到 3 条时 MAY 返回平均评分、评分分布、热门标签和八维均值。 |
|||
|
|||
#### Scenario: 无公开评价 |
|||
|
|||
- **WHEN** 企业没有任何符合条件的公开评价 |
|||
- **THEN** `reviewSummary.state` 为 `EMPTY` |
|||
- **AND** `totalReviews` 为 0 |
|||
- **AND** `averageRating` 与 `dimensionSummary` 为空 |
|||
|
|||
#### Scenario: 公开评价少于 3 条 |
|||
|
|||
- **WHEN** 企业只有 1 或 2 条符合条件的公开评价 |
|||
- **THEN** `reviewSummary.state` 为 `INSUFFICIENT` |
|||
- **AND** 系统返回真实 `totalReviews` |
|||
- **AND** 不返回平均分、评分分布或维度均值 |
|||
|
|||
#### Scenario: 公开评价达到 3 条 |
|||
|
|||
- **WHEN** 企业有至少 3 条符合条件的公开评价 |
|||
- **THEN** `reviewSummary.state` 为 `SUFFICIENT` |
|||
- **AND** 系统返回平均评分、评分分布、热门标签和维度汇总 |
|||
- **AND** 每个维度返回样本数及是否达到小样本阈值 |
|||
|
|||
### Requirement: 企业读取本企业知识配置 |
|||
|
|||
系统 SHALL 允许 COMPANY 通过 `GET /onboarding/company/knowledge` 读取本企业知识配置。无记录时 MUST 返回 `configured=false` 和空内容,而不是 404;有记录时 MUST 返回内容和当前版本。 |
|||
|
|||
#### Scenario: 尚未配置 |
|||
|
|||
- **WHEN** COMPANY 请求本企业知识配置且尚未创建记录 |
|||
- **THEN** 系统返回 `configured=false` |
|||
- **AND** 内容字段为空,版本为 `0` |
|||
|
|||
#### Scenario: 已配置 |
|||
|
|||
- **WHEN** COMPANY 请求本企业已有知识配置 |
|||
- **THEN** 系统返回文化、工作制度、入职指南、更新时间和当前版本 |
|||
- **AND** `configured=true` |
|||
|
|||
### Requirement: 企业 Upsert 公司知识内容 |
|||
|
|||
系统 SHALL 允许 COMPANY 通过 `PUT /onboarding/company/knowledge` 创建或更新本企业知识内容。字段 MUST 使用纯文本并受长度限制,不允许 HTML 富文本。更新已有记录时 MUST 使用乐观锁版本;版本冲突返回 409 `ONBOARDING_KNOWLEDGE_CONCURRENT_UPDATE`。 |
|||
|
|||
#### Scenario: 首次创建 |
|||
|
|||
- **WHEN** COMPANY 首次提交合法的知识内容 |
|||
- **THEN** 系统创建绑定该企业的知识记录 |
|||
- **AND** 返回 `configured=true` 和版本 `0` |
|||
|
|||
#### Scenario: 使用当前版本更新 |
|||
|
|||
- **WHEN** COMPANY 使用当前版本提交新的文化、制度或入职指南 |
|||
- **THEN** 系统更新记录并递增版本 |
|||
- **AND** 返回最新内容 |
|||
|
|||
#### Scenario: 使用过期版本更新 |
|||
|
|||
- **WHEN** COMPANY 使用过期版本提交知识内容 |
|||
- **THEN** 系统返回 409 `ONBOARDING_KNOWLEDGE_CONCURRENT_UPDATE` |
|||
- **AND** 不覆盖数据库中的新内容 |
|||
|
|||
#### Scenario: 非法内容 |
|||
|
|||
- **WHEN** 请求字段超出最大长度或包含不受支持的格式 |
|||
- **THEN** 系统返回 400 `BAD_REQUEST` |
|||
- **AND** 不写入知识记录 |
|||
|
|||
### Requirement: 公司知识权限与所有权隔离 |
|||
|
|||
学生读取接口 MUST 仅允许 STUDENT;企业配置接口 MUST 仅允许 COMPANY 且只操作当前用户拥有的企业。任何跨企业读取配置或修改操作 MUST 被拒绝。 |
|||
|
|||
#### Scenario: 企业访问本企业配置 |
|||
|
|||
- **WHEN** COMPANY 读取或更新自己的知识记录 |
|||
- **THEN** 系统允许操作 |
|||
|
|||
#### Scenario: 非企业访问企业配置 |
|||
|
|||
- **WHEN** STUDENT、ADMIN 或未登录用户访问企业知识配置接口 |
|||
- **THEN** 系统返回 401 或 403 |
|||
- **AND** 不读取或修改企业配置 |
|||
|
|||
#### Scenario: 不存在的企业 |
|||
|
|||
- **WHEN** STUDENT 请求不存在的公司知识 |
|||
- **THEN** 系统返回 404 `COMPANY_NOT_FOUND` |
|||
|
|||
### Requirement: 不改变既有评价与企业接口语义 |
|||
|
|||
本变更 MUST 只读复用既有企业、岗位、评价和维度评分数据,不得修改既有表结构、响应字段或权限语义。 |
|||
|
|||
#### Scenario: 既有评价接口回归 |
|||
|
|||
- **WHEN** 执行已有评价与企业模块测试 |
|||
- **THEN** 所有既有测试保持通过 |
|||
- **AND** OpenAPI 中既有路径的请求与响应语义不变 |
|||
@ -0,0 +1,155 @@ |
|||
# Onboarding Checklist Specification |
|||
|
|||
## Purpose |
|||
|
|||
定义学生入职清单读取、个人完成状态、企业自定义项管理和通用清单回退行为。 |
|||
|
|||
## Requirements |
|||
|
|||
### Requirement: 学生读取有效入职清单 |
|||
|
|||
系统 SHALL 允许已登录 STUDENT 按 `companyId` 读取由通用清单与企业活动自定义项组成的有效入职清单。响应 MUST 包含企业、当前学生完成状态、完成数量、总数量、完成率、是否是企业自定义配置,以及按 `sortOrder`、`id` 稳定排序的条目。 |
|||
|
|||
#### Scenario: 企业未配置自定义项 |
|||
|
|||
- **WHEN** STUDENT 请求存在企业的清单,且该企业没有活动自定义项 |
|||
- **THEN** 系统返回全部活动通用清单项 |
|||
- **AND** `customized` 为 `false` |
|||
- **AND** 每个条目返回标准来源、分类、标题、说明、必填标记和当前学生的完成状态 |
|||
|
|||
#### Scenario: 企业已配置自定义项 |
|||
|
|||
- **WHEN** STUDENT 请求存在企业的清单,且该企业存在活动自定义项 |
|||
- **THEN** 系统返回活动通用项与企业自定义项 |
|||
- **AND** 通用项与企业项使用稳定排序,响应 `customized` 为 `true` |
|||
- **AND** 每个条目的 `itemId` 和 `source` 足以用于后续完成状态更新 |
|||
|
|||
#### Scenario: 企业不存在 |
|||
|
|||
- **WHEN** STUDENT 请求不存在的 `companyId` |
|||
- **THEN** 系统返回 404 与既有 `COMPANY_NOT_FOUND` 错误码 |
|||
- **AND** 不创建完成状态行 |
|||
|
|||
### Requirement: 学生更新个人清单完成状态 |
|||
|
|||
系统 SHALL 允许 STUDENT 通过 `PUT /onboarding/companies/{companyId}/checklist/items/{itemId}/completion` 将本人对指定有效条目的状态设置为完成或未完成。请求 MUST 使用绝对状态语义,重复提交同一状态 MUST 不创建重复记录。响应 MUST 返回条目状态、版本和更新后的完成率。 |
|||
|
|||
#### Scenario: 首次标记完成 |
|||
|
|||
- **WHEN** STUDENT 对本人可访问的条目提交 `completed=true` |
|||
- **THEN** 系统创建该学生与该条目的完成记录 |
|||
- **AND** 设置 `completedAt` |
|||
- **AND** 返回更新后的完成数量、总数量和完成率 |
|||
|
|||
#### Scenario: 重复设置相同状态 |
|||
|
|||
- **WHEN** STUDENT 对同一条目重复提交相同 `completed` 值 |
|||
- **THEN** 系统返回幂等成功结果 |
|||
- **AND** 数据库仍只有一条学生与条目完成记录 |
|||
- **AND** 不改变首次完成后的业务结果 |
|||
|
|||
#### Scenario: 取消完成 |
|||
|
|||
- **WHEN** STUDENT 对已完成条目的提交 `completed=false` |
|||
- **THEN** 系统将记录置为未完成 |
|||
- **AND** 清除 `completedAt` |
|||
- **AND** 返回更新后的完成率 |
|||
|
|||
#### Scenario: 条目不属于该企业 |
|||
|
|||
- **WHEN** STUDENT 使用属于另一企业自定义项的 `itemId` 调用更新接口 |
|||
- **THEN** 系统返回 404 `ONBOARDING_CHECKLIST_ITEM_NOT_FOUND` |
|||
- **AND** 不允许创建或修改完成记录 |
|||
|
|||
### Requirement: 企业创建自定义清单项 |
|||
|
|||
系统 SHALL 允许 COMPANY 为本企业创建自定义清单项。请求 MUST 校验标题、说明、分类、排序值和必填标记。请求携带 `idempotencyKey` 时,同一企业、同一 key 且请求体相同 MUST 返回原条目;请求体不同 MUST 返回 409 `ONBOARDING_IDEMPOTENCY_CONFLICT`。 |
|||
|
|||
#### Scenario: 创建成功 |
|||
|
|||
- **WHEN** COMPANY 提交合法的标题、分类和可选说明 |
|||
- **THEN** 系统创建仅属于该企业的活动条目 |
|||
- **AND** 返回条目 ID、来源 `COMPANY`、版本、排序值和必填标记 |
|||
|
|||
#### Scenario: 幂等重放 |
|||
|
|||
- **WHEN** COMPANY 使用相同 `idempotencyKey` 和相同请求体重复创建 |
|||
- **THEN** 系统返回第一次创建的条目 |
|||
- **AND** 数据库不产生第二条记录 |
|||
|
|||
#### Scenario: 幂等键内容冲突 |
|||
|
|||
- **WHEN** COMPANY 重复使用同一 `idempotencyKey`,但标题、分类、说明、排序或必填标记不同 |
|||
- **THEN** 系统返回 409 `ONBOARDING_IDEMPOTENCY_CONFLICT` |
|||
|
|||
#### Scenario: 超出企业条目上限 |
|||
|
|||
- **WHEN** COMPANY 已拥有 50 条活动自定义项并继续创建 |
|||
- **THEN** 系统返回 409 `ONBOARDING_ITEM_LIMIT_EXCEEDED` |
|||
- **AND** 不写入第 51 条活动条目 |
|||
|
|||
### Requirement: 企业查询和更新自定义清单项 |
|||
|
|||
系统 SHALL 允许 COMPANY 查询本企业全部自定义项,并通过带版本号的更新请求修改标题、说明、分类、排序、必填标记和活动状态。版本冲突 MUST 返回 409 `ONBOARDING_CHECKLIST_ITEM_CONCURRENT_UPDATE`,不得静默覆盖。 |
|||
|
|||
#### Scenario: 查询本企业条目 |
|||
|
|||
- **WHEN** COMPANY 请求本企业自定义条目列表 |
|||
- **THEN** 系统返回该企业条目,包括活动与软删除条目及当前版本 |
|||
- **AND** 不返回其他企业的条目 |
|||
|
|||
#### Scenario: 正常更新 |
|||
|
|||
- **WHEN** COMPANY 使用当前 `version` 更新本企业条目 |
|||
- **THEN** 系统保存修改并递增版本 |
|||
- **AND** 返回更新后的条目 |
|||
|
|||
#### Scenario: 版本过期 |
|||
|
|||
- **WHEN** COMPANY 使用过期 `version` 更新条目 |
|||
- **THEN** 系统返回 409 `ONBOARDING_CHECKLIST_ITEM_CONCURRENT_UPDATE` |
|||
- **AND** 不覆盖数据库中较新的值 |
|||
|
|||
### Requirement: 企业软删除自定义清单项 |
|||
|
|||
系统 SHALL 允许 COMPANY 通过带当前 `version` 的删除请求软删除本企业条目。软删除 MUST 只将条目标记为非活动,不物理删除条目或学生历史完成记录。重复删除已非活动条目 MUST 返回幂等成功结果。 |
|||
|
|||
#### Scenario: 首次删除 |
|||
|
|||
- **WHEN** COMPANY 使用当前版本删除本企业活动条目 |
|||
- **THEN** 系统将条目 `active` 置为 `false` |
|||
- **AND** 该条目不再出现在学生有效清单中 |
|||
- **AND** 既有完成记录保留 |
|||
|
|||
#### Scenario: 重复删除 |
|||
|
|||
- **WHEN** COMPANY 再次删除已软删除条目 |
|||
- **THEN** 系统返回成功 |
|||
- **AND** 不产生第二次数据变更 |
|||
|
|||
#### Scenario: 删除其他企业条目 |
|||
|
|||
- **WHEN** COMPANY 删除不属于本企业的条目 |
|||
- **THEN** 系统返回 404 `ONBOARDING_CHECKLIST_ITEM_NOT_FOUND` |
|||
- **AND** 目标条目保持原状态 |
|||
|
|||
### Requirement: 清单权限和数据最小化 |
|||
|
|||
学生接口 MUST 仅允许 STUDENT;企业配置接口 MUST 仅允许 COMPANY 且操作绑定当前用户拥有的企业。所有响应 MUST 使用白名单 DTO,不返回用户密码、Token、IP、User-Agent、评价审核原因或其他企业内部的非必要字段。 |
|||
|
|||
#### Scenario: 非学生访问学生清单 |
|||
|
|||
- **WHEN** COMPANY、ADMIN 或未登录用户访问学生清单接口 |
|||
- **THEN** 系统返回 401 或 403 |
|||
- **AND** 不返回清单或完成状态 |
|||
|
|||
#### Scenario: 非企业访问企业配置 |
|||
|
|||
- **WHEN** STUDENT、ADMIN 或未登录用户访问企业配置接口 |
|||
- **THEN** 系统返回 401 或 403 |
|||
- **AND** 不创建或修改企业条目 |
|||
|
|||
#### Scenario: 企业无绑定资料 |
|||
|
|||
- **WHEN** COMPANY 用户尚未创建企业资料却调用企业配置接口 |
|||
- **THEN** 系统返回 404 `COMPANY_NOT_FOUND` |
|||
Loading…
Reference in new issue