From 23e0fb96a5991c410c036550a6f555ecebc67d76 Mon Sep 17 00:00:00 2001 From: pwklppg <123456@.com> Date: Thu, 17 Sep 2026 10:48:46 +0800 Subject: [PATCH] docs: publish N04 specs and verification waiver --- changes/n04-onboard/.spec-superflow.yaml | 11 +- .../n04-onboard/.superpowers/sdd/progress.md | 2 + changes/n04-onboard/decision-point-audit.md | 9 +- changes/n04-onboard/spec-merge-report.md | 20 +++ changes/n04-onboard/verification-report.md | 6 +- specs/company-knowledge/spec.md | 129 +++++++++++++++ specs/onboarding-checklist/spec.md | 155 ++++++++++++++++++ 7 files changed, 322 insertions(+), 10 deletions(-) create mode 100644 changes/n04-onboard/spec-merge-report.md create mode 100644 specs/company-knowledge/spec.md create mode 100644 specs/onboarding-checklist/spec.md diff --git a/changes/n04-onboard/.spec-superflow.yaml b/changes/n04-onboard/.spec-superflow.yaml index 30761d4..d3a54f1 100644 --- a/changes/n04-onboard/.spec-superflow.yaml +++ b/changes/n04-onboard/.spec-superflow.yaml @@ -38,7 +38,10 @@ resume_from: T7-review resume_mode: manual resumed_at: 2026-09-17T01:17:47Z resume_count: 1 -verification_blocked: true -verification_outcome: conditional-pending-formal-waiver -dp_6_result: conditional: N04 96/96 tests, OpenAPI 135 paths / 9 onboarding operations, package pass; 1492-test full suite has 2 failures and 9 errors in pre-existing non-N04 tests; real MySQL/Docker acceptance pending -dp_6_timestamp: 2026-09-17T01:53:38Z +verification_blocked: false +verification_outcome: conditional-pass-with-formal-waiver +dp_6_result: pass: N04 96/96 tests, OpenAPI 135 paths / 9 onboarding operations, package pass; 1492-test full suite has 2 failures and 9 errors in pre-existing non-N04 tests formally waived; real MySQL/Docker acceptance remains a pre-release gate +dp_6_timestamp: 2026-09-17T02:47:50Z +test_result: pass: scoped verification with formal waiver +spec_sync_result: manual publication passed: 12 requirements across 2 capabilities +spec_sync_timestamp: 2026-09-17T02:48:23Z diff --git a/changes/n04-onboard/.superpowers/sdd/progress.md b/changes/n04-onboard/.superpowers/sdd/progress.md index b2db2c6..0ead64d 100644 --- a/changes/n04-onboard/.superpowers/sdd/progress.md +++ b/changes/n04-onboard/.superpowers/sdd/progress.md @@ -21,3 +21,5 @@ - 2026-09-17T01:41:13Z Task T8: failed attempt 1/3 - review W3-T8 FAIL; OpenAPI knowledge example lacks version and create request schema omits runtime defaults. - 2026-09-17T01:45:47Z Task T8: complete after focused repair (commit 310d931; W3-T8-rereview PASS; OpenAPI 135 paths / 172 operations, 9 onboarding operations / 6 paths; 96 tests pass). - 2026-09-17T01:50:30Z W3 wave review PASS (conditional within N04): 96 tests, RR boundary 1, randomized E2E 7, OpenAPI 135 paths/9 operations; external blockers are existing full-suite failures and pending MySQL/Docker acceptance. +- 2026-09-17T02:47:50Z DP-6 pass with formal waiver: user accepted existing non-N04 full-suite failures; real MySQL/Docker remains a pre-release gate. +- 2026-09-17T02:48:23Z Spec merge completed manually: onboarding-checklist 6 requirements / 20 scenarios, company-knowledge 6 requirements / 16 scenarios; no conflicts. diff --git a/changes/n04-onboard/decision-point-audit.md b/changes/n04-onboard/decision-point-audit.md index 583ef34..45a620b 100644 --- a/changes/n04-onboard/decision-point-audit.md +++ b/changes/n04-onboard/decision-point-audit.md @@ -12,8 +12,8 @@ | DP-3 | approved | execution contract B1-B3 与 12 条 Requirement 映射已批准 | | DP-4 | approved | SDD;W1/W2/W3 串行 wave 和依赖已固化 | | DP-5 | not-triggered | T6/T8 各一次聚焦修复后复评通过,未达到三轮升级条件 | -| DP-6 | conditional-pending-waiver | N04 专项、OpenAPI、打包通过;全量套件有既有非 N04 失败;真实 MySQL/Docker 待验收 | -| DP-7 | pending | 等待用户接受条件验证并批准归档 | +| DP-6 | pass with formal waiver | N04 专项、OpenAPI、打包通过;既有非 N04 全量失败由用户正式豁免;真实 MySQL/Docker 保留为发布前门禁 | +| DP-7 | pending | 等待归档确认 | ## Contract Coverage @@ -45,4 +45,7 @@ - N04 变更集中在 com.mydreamjob.onboarding、V38/V39、SecurityConfig、ErrorCode、GlobalExceptionHandler、OpenAPI、接口文档和 onboarding 测试。 - 未修改 V1-V38 历史迁移,未改变既有企业、岗位、Offer 或评价接口语义。 -- 所有 W3 任务和 wave 复审均 PASS;全量测试外部失败已单独记录。 \ No newline at end of file +- 所有 W3 任务和 wave 复审均 PASS;全量测试外部失败已单独记录。 +## Formal Waiver + +用户于 2026-09-17T02:47:50Z 明确批准:将与 N04 无关的既有全量测试失败作为正式豁免,并将真实 MySQL 8.4 / Docker 黑盒验收保留为发布前门禁。 diff --git a/changes/n04-onboard/spec-merge-report.md b/changes/n04-onboard/spec-merge-report.md new file mode 100644 index 0000000..383279b --- /dev/null +++ b/changes/n04-onboard/spec-merge-report.md @@ -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 \ No newline at end of file diff --git a/changes/n04-onboard/verification-report.md b/changes/n04-onboard/verification-report.md index e4297a1..6e3a802 100644 --- a/changes/n04-onboard/verification-report.md +++ b/changes/n04-onboard/verification-report.md @@ -4,7 +4,7 @@ ## Outcome -条件通过,待用户正式接受豁免。N04 范围内验证通过,但仓库全量测试和真实 MySQL/Docker 验收尚未完成。 +通过并带正式豁免。N04 范围内验证通过;仓库全量测试中的既有非 N04 失败已由用户正式豁免;真实 MySQL/Docker 验收保留为发布前门禁。 ## Passed @@ -18,8 +18,8 @@ - mvn clean verify:1492 tests,2 failures,9 errors;失败均在 N04 范围外。 - 真实 MySQL 8.4 / Docker 黑盒验收:未执行。 -- 正式豁免与归档确认尚未记录。 +- 正式豁免已记录;归档确认仍待 DP-7。 ## Required Approval -用户需要明确确认:接受既有非 N04 全量测试失败作为正式豁免,并将真实 MySQL/Docker 验收保留为发布前门禁;确认后方可记录 DP-6 并进入 delta spec 合并和 DP-7。 \ No newline at end of file +用户已批准正式豁免。允许进入 delta spec 合并和 DP-7;真实 MySQL/Docker 验收仍需在发布前完成。 \ No newline at end of file diff --git a/specs/company-knowledge/spec.md b/specs/company-knowledge/spec.md new file mode 100644 index 0000000..08fff64 --- /dev/null +++ b/specs/company-knowledge/spec.md @@ -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 中既有路径的请求与响应语义不变 \ No newline at end of file diff --git a/specs/onboarding-checklist/spec.md b/specs/onboarding-checklist/spec.md new file mode 100644 index 0000000..8b140db --- /dev/null +++ b/specs/onboarding-checklist/spec.md @@ -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` \ No newline at end of file