Forráskód Böngészése

docs(绩效): 添加 360 环评产品需求文档

明确邀请审核、评价门禁、隐私边界和成功指标。\n\n记录独立 Peer Review 模块、周期快照权限与测试策略。
wangkangyjy 4 napja
szülő
commit
39ed999854
1 módosított fájl, 416 hozzáadás és 0 törlés
  1. 416 0
      docs/superpowers/specs/2026-07-16-360-peer-review-design.md

+ 416 - 0
docs/superpowers/specs/2026-07-16-360-peer-review-design.md

@@ -0,0 +1,416 @@
+# OKR 绩效系统 360 环评产品需求文档
+
+## 1. Executive Summary
+
+### Problem Statement
+
+现有绩效终评主要依赖员工自评与直属 Leader 判断,缺少日常协作同事的结构化反馈,容易形成单一观察视角。公司人数较少,评价人身份也容易被间接识别,因此环评内容必须严格限制在周期直属 Leader 范围内。
+
+### Proposed Solution
+
+在 `ASSESSING` 阶段嵌入 360 环评:员工自评后邀请 3~5 名合格同事,经周期直属 Leader 审核后完成三维度评分和简评。至少收到 2 份有效评价后,Leader 才能进入终评;环评不直接计入绩效总分,仅作为 Leader 判断和绩效沟通的参考。
+
+### Success Criteria
+
+1. 首个上线周期中,至少 90% 的非豁免参评员工在名单截止前完成合规邀请并通过 Leader 审核。
+2. 至少 85% 的有效受邀评价在评价截止前提交;分母不包含已拒绝或因参与资格变化而失效的邀请。
+3. 任何员工端、评价人端或管理员端接口均不得返回其权限之外的原始环评分数、简评或评价人提交状态。
+4. 少于 2 份有效评价时,系统必须阻止 Leader 提交终评;达到门禁后不得改变现有正式绩效计分公式。
+5. MVP 在下一个绩效考核周期开始前具备生产可用条件,并沿用现有 Vue 3、Spring Boot 与 SQLite 架构。
+
+## 2. User Experience & Functionality
+
+### User Personas
+
+- **被评价人**:本周期 `ACTIVE` 参与人,有周期快照直属考评人;提交自评后选择并邀请评价同事。
+- **评价同事**:本周期 `ACTIVE` 参与人,与被评价人不存在被排除的上下级关系;查看限定材料并提交评价。
+- **周期直属 Leader**:取周期发布时冻结的 `evaluatorId`;审核邀请名单、查看实名环评原文并完成终评。
+- **超级管理员**:配置环评截止时间、查看流程统计和阻塞情况;不能通过产品接口或后台页面查看原始评价内容。
+
+### Primary User Flow
+
+```text
+周期进入 ASSESSING
+→ 员工提交绩效自评
+→ 员工提交 3~5 人邀请名单
+→ 周期直属 Leader 批准或驳回名单
+→ 系统向获批评价人发送邀请
+→ 评价人接受并提交,或拒绝并说明原因
+→ 被评价人在累计邀请上限内补邀
+→ 系统累计有效提交数
+→ 至少 2 份且满足开放条件
+→ Leader 查看环评参考信息并提交正式终评
+→ Leader 在绩效沟通中综合转述反馈
+→ 周期归档后全部环评数据只读
+```
+
+### User Stories and Acceptance Criteria
+
+#### Story 1:管理员配置环评时间
+
+As a 超级管理员, I want to configure invitation and review deadlines for a period, so that the 360 review can finish before Leader final scoring.
+
+Acceptance Criteria:
+
+- 周期提供“邀请名单截止时间”和“评价提交截止时间”两个配置项。
+- 两个时间必须位于该周期允许考评的时间范围内,且名单截止时间早于评价截止时间。
+- 时间配置在环评流程启动后不得缩短至早于当前时间;允许向后延长以处理阻塞。
+- 管理员可以查看应参与人数、已完成邀请人数、有效邀请数、已提交评价数和终评阻塞人数。
+- 管理员统计接口不返回评价人身份、单份评分或简评。
+
+#### Story 2:员工选择评价同事
+
+As a 被评价人, I want to invite qualified colleagues after self-evaluation, so that my Leader receives perspectives beyond my self-assessment.
+
+Acceptance Criteria:
+
+- 只有已提交自评的非豁免 `ACTIVE` 参与人可以创建邀请名单。
+- 每人每周期累计邀请 3~5 名不同同事;被拒绝或后续失效的邀请仍计入累计邀请人数。
+- 邀请名单至少包含 1 名本部门同事和 1 名跨部门同事。
+- 候选人必须是同一周期的 `ACTIVE` 参与人。
+- 候选人不得是被评价人本人、周期直属 Leader 或周期快照中的直属下属。
+- 部门内外、直属 Leader 和直属下属关系全部基于周期参与人快照判定,不使用实时组织关系。
+- 重复人员、人数不合法、缺少内外部门覆盖或包含排除对象时,系统拒绝提交并指出具体原因。
+- 名单提交后进入待审核状态,在 Leader 驳回前不可重复提交。
+
+#### Story 3:Leader 审核邀请名单
+
+As a 周期直属 Leader, I want to approve or reject a proposed reviewer list, so that feedback is not limited to selectively chosen friendly colleagues.
+
+Acceptance Criteria:
+
+- 只有周期快照中的 `evaluatorId` 可以审核该员工名单。
+- Leader 可以批准整份名单,或驳回整份名单并填写原因;MVP 不支持逐人审批、替换或由 Leader 补充评价人。
+- 驳回后,被评价人可以在名单截止前修改并重新提交。
+- 审核时后端重新校验人数、部门覆盖、参与资格和排除关系,避免名单提交后状态变化导致越权。
+- 名单批准后,系统为名单中每位评价人创建唯一邀请并发送通知。
+
+#### Story 4:评价人接受或拒绝邀请
+
+As an 评价同事, I want to accept or decline an invitation, so that I can respond honestly when I lack sufficient collaboration context.
+
+Acceptance Criteria:
+
+- 评价人可以接受邀请,也可以拒绝并填写简短原因。
+- 拒绝后不可恢复该邀请,被评价人收到补邀通知并能看到拒绝人及拒绝原因。
+- 被评价人可以在名单截止前补邀其他合格同事,但整个周期累计邀请人数不得超过 5 人。
+- 人员离职、停用或被移出周期后,未提交邀请自动标记失效;在累计上限内允许补邀。
+- 评价人只能处理发给自己的邀请,重复操作必须保持幂等。
+
+#### Story 5:评价人查看限定材料
+
+As an 评价同事, I want to review relevant performance evidence, so that my feedback is grounded in observable work.
+
+Acceptance Criteria:
+
+- 评价人可以只读查看被评价人的 OKR、KR 完成情况和工作成果说明。
+- 评价人不能查看被评价人的自评分数、专项加扣分、其他评价人身份与内容、Leader 评分或最终结果。
+- 页面明确提示:被评价人不能直接查看环评内容,周期直属 Leader 可以实名查看原始反馈。
+- 评价材料从本周期绩效数据读取,不允许评价人修改任何被评价人数据。
+
+#### Story 6:评价人填写并提交评价
+
+As an 评价同事, I want to score clear dimensions and provide brief comments, so that the Leader receives comparable and actionable feedback.
+
+Acceptance Criteria:
+
+- 评价表包含三个整数评分,取值均为 1~5:
+  - 目标贡献:结合 OKR/KR 完成情况,评价实际产出与目标贡献。
+  - 协作表现:评价沟通响应、信息共享和跨团队配合。
+  - 责任担当:评价承诺兑现、问题跟进和困难情况下的担当。
+- 每个维度显示统一锚点:1 分明显不足、3 分符合预期、5 分显著超出预期;维度文案提供相应行为解释。
+- “突出表现”和“改进建议”均必填,每项 10~300 字。
+- 评价人可以保存草稿;草稿不计入有效提交数,也不对 Leader 展示。
+- 正式提交时重新校验权限、截止时间、分数和文字长度。
+- 正式提交后不可修改;重复提交不会创建第二份响应。
+- 三维度平均值仅用于 Leader 参考展示,不换算为 100 分,不写入正式绩效分数。
+
+#### Story 7:员工查看流程进度
+
+As a 被评价人, I want to know whether the process is progressing, so that I can handle rejections without seeing confidential feedback.
+
+Acceptance Criteria:
+
+- 员工可以看到自己的邀请名单、Leader 审核状态、拒绝人及拒绝原因。
+- 员工只能看到“已收到 N 份”的汇总提交进度,不显示哪位评价人已提交或未提交。
+- 员工不能查看任何环评分数、平均值、简评、原始内容或提交时间。
+- 周期结束、终评发布和绩效沟通后,员工仍不能通过产品页面或接口查看环评内容。
+
+#### Story 8:Leader 查看环评并完成终评
+
+As a 周期直属 Leader, I want to review identified peer feedback before final scoring, so that my decision considers multiple work perspectives.
+
+Acceptance Criteria:
+
+- Leader 可以查看评价人实名信息、每份三维度评分、原始简评和三维度平均值。
+- 环评区域嵌入现有终评页面,不增加独立侧边栏模块。
+- Leader 页面明确提示环评仅作参考,不直接计入正式绩效总分。
+- 在评价截止前,只有当所有未拒绝且未失效的已批准邀请均已提交、并且有效提交数不少于 2 时,才可提前开放终评。
+- 到达评价截止时间后,只要有效提交数不少于 2,即使仍有未提交邀请,也允许终评。
+- 有效提交少于 2 时,Leader 终评接口和按钮均被阻止;管理员只能延长截止时间,不能绕过最低份数。
+- Leader 对评价内容的访问权取周期快照 `evaluatorId`,不随实时汇报关系变化。
+
+#### Story 9:Leader 在绩效沟通中反馈
+
+As a 周期直属 Leader, I want to synthesize peer feedback during the performance conversation, so that the employee receives useful guidance without exposing reviewers.
+
+Acceptance Criteria:
+
+- 系统不自动把环评原文复制给员工,也不向员工生成环评结果页面。
+- Leader 在现有绩效沟通流程中自行综合转述观察结论。
+- 面向员工的通知、反馈页面和历史绩效页面不得包含环评分数、原始简评或评价人信息。
+
+#### Story 10:系统发送流程通知
+
+As a participant, I want timely task notifications, so that the review finishes before its deadlines.
+
+Acceptance Criteria:
+
+- 即时通知覆盖:名单待审核、审核通过、审核驳回、收到评价邀请、邀请被拒绝、达到终评门禁。
+- 名单截止前 24 小时提醒尚未完成邀请的员工和待审核 Leader。
+- 评价截止前 24 小时提醒尚未提交的评价人,并向仍被阻塞的 Leader 展示状态。
+- 同一业务事件只生成一次通知。
+- 员工通知不包含谁已提交评价;任何通知均不包含评分或简评正文。
+
+#### Story 11:周期归档
+
+As a 超级管理员, I want peer-review data frozen with the archived period, so that historical evidence remains consistent.
+
+Acceptance Criteria:
+
+- 360 环评通过 Leader 终评门禁间接参与现有归档准备度:少于 2 份时无法产生终评,进而阻止归档。
+- 周期进入 `ARCHIVED` 后,邀请、草稿、已提交评价和流程状态全部只读。
+- 历史 Leader 访问仍按周期快照判定;管理员仍只能查看统计数据。
+
+### Notification and Error States
+
+- 名单逾期未提交:员工操作入口锁定,管理员统计显示阻塞;管理员可延长名单截止时间。
+- 名单已提交但未审核:Leader 收到待办,评价邀请尚不发送。
+- 评价截止后不足 2 份:终评保持阻塞,管理员可延长评价截止时间。
+- 邀请人在提交过程中失去参与资格:事务内校验失败,该邀请转为失效。
+- 并发提交或重复点击:唯一约束与事务校验保证每个邀请最多一份正式评价。
+- 非授权读取:返回无权访问,不通过“空数据”暗示记录是否存在。
+
+### Non-Goals
+
+- 环评分数直接加权或换算进正式绩效总分。
+- 被评价人查看环评平均分、原始简评、评价人身份或匿名评价结果。
+- 超级管理员查看或导出原始评价内容。
+- Leader 指定、补充或逐人审批评价人。
+- 邀请直属 Leader、直属下属、非本周期参与人或外部人员。
+- 独立 360 环评菜单、公司级环评人才盘点、团队排名或跨周期趋势分析。
+- AI 自动总结、情绪分析、措辞改写或评价质量判断。
+- 匿名消息往返、评价申诉或被评价人针对单条反馈回复。
+- 邮件、短信、企业微信、飞书等外部通知渠道;MVP 复用站内通知。
+
+## 3. AI System Requirements (If Applicable)
+
+本功能 MVP 不包含 AI 能力,不调用外部模型或 AI API,也不对评价文本进行自动总结、分类或评分。AI 相关工具、评测集和输出质量指标不适用。
+
+## 4. Technical Specifications
+
+### Architecture Overview
+
+新增独立的 Peer Review 深模块,负责邀请、审核、评价、资格判定、期限、隐私 DTO 和聚合结果。现有绩效模块只通过单一高层接缝查询是否允许终评:
+
+```text
+现有绩效页面
+    ↓
+Peer Review API / Service
+    ├── 周期参与人和考评人快照
+    ├── OKR/KR 与工作成果只读查询
+    ├── 邀请、响应与聚合数据
+    └── NotificationEvent
+              ↓
+PerformanceService → canFinalize(periodId, userId) → 提交 Leader 终评
+```
+
+该边界使 Peer Review 内部状态可以独立演进,现有正式计分公式和评分记录结构无需感知环评分数。
+
+### Module Responsibilities
+
+- **Peer Review Controller**:提供被评价人、评价人、Leader 和管理员各自的最小 API 表面。
+- **Peer Review Service**:执行周期状态、快照权限、候选资格、人数、部门覆盖、期限、状态转换和终评门禁校验。
+- **Peer Review Query/DTO**:按角色分别组装响应,禁止复用包含完整字段的实体作为 API 返回值。
+- **Performance Service 集成点**:在 Leader 终评事务内调用 `canFinalize(periodId, userId)`,服务端强制门禁。
+- **Notification Event**:复用现有异步站内通知机制发送流程事件。
+
+### State Model
+
+`peer_review_request` 建议状态:
+
+```text
+DRAFT
+→ PENDING_APPROVAL
+→ REJECTED → PENDING_APPROVAL
+→ IN_PROGRESS
+→ READY_FOR_FINAL
+→ ARCHIVED
+```
+
+- `READY_FOR_FINAL` 是派生业务状态,最终是否允许终评仍在提交事务中实时计算。
+- 在评价截止前,满足“至少 2 份 + 所有有效邀请已提交”才派生为可终评。
+- 到达评价截止后,满足“至少 2 份”即可派生为可终评。
+
+`peer_review_invitation` 建议状态:
+
+```text
+PENDING → ACCEPTED → SUBMITTED
+        ↘ DECLINED
+        ↘ INVALIDATED
+```
+
+`peer_review_response` 状态:`DRAFT` 或 `SUBMITTED`。
+
+### Data Model
+
+#### assessment_period
+
+新增:
+
+- `peer_invitation_deadline`
+- `peer_review_deadline`
+
+#### peer_review_request
+
+核心字段:
+
+- `id`
+- `period_id`
+- `subject_user_id`
+- `leader_id`,取周期考评人快照
+- `status`
+- `submitted_at`
+- `approved_at`
+- `created_at`
+- `updated_at`
+- `deleted`
+
+唯一约束:`period_id + subject_user_id`。
+
+#### peer_review_invitation
+
+核心字段:
+
+- `id`
+- `request_id`
+- `reviewer_id`
+- `reviewer_department_id_snapshot`
+- `relation_type_snapshot`,`SAME_DEPARTMENT` 或 `CROSS_DEPARTMENT`
+- `status`
+- `decline_reason`
+- `responded_at`
+- `created_at`
+- `updated_at`
+- `deleted`
+
+唯一约束:`request_id + reviewer_id`,包括已拒绝和已失效记录,以落实累计邀请上限。
+
+#### peer_review_response
+
+核心字段:
+
+- `id`
+- `invitation_id`
+- `goal_contribution_score`
+- `collaboration_score`
+- `accountability_score`
+- `strengths`
+- `improvement_suggestion`
+- `status`
+- `submitted_at`
+- `created_at`
+- `updated_at`
+- `deleted`
+
+唯一约束:`invitation_id`。
+
+### Integration Points
+
+建议 API 分组如下,具体 DTO 名称在实现计划中确定:
+
+- `/api/peer-reviews/my/**`:员工邀请名单、审核状态、拒绝信息和汇总进度。
+- `/api/peer-reviews/invitations/**`:评价人待办、限定材料、接受、拒绝、草稿和提交。
+- `/api/peer-reviews/leader/**`:名单审核、直属员工环评状态、实名详情与聚合结果。
+- `/api/peer-reviews/admin/**`:周期统计和阻塞情况,不返回原始内容。
+- `/api/periods/**`:扩展两个环评截止时间的创建、更新和校验。
+- `/api/scores/**`:Leader 终评提交前增加 Peer Review 门禁,不修改正式评分请求和计分公式。
+
+### Security & Privacy
+
+- 所有授权在后端执行,前端隐藏不作为权限控制。
+- 被评价人、评价人、周期直属 Leader 和管理员分别使用最小 DTO;禁止返回后再由前端删字段。
+- Leader 读取权限仅匹配请求保存的周期快照 `leader_id`。
+- 超级管理员的全局管理能力不扩展为原始环评内容读取权限;产品不提供相关 Controller 路由。
+- 员工端不返回单个评价人的提交状态或提交时间,避免在小团队中通过时间关联识别反馈来源。
+- 日志和通知不得记录评分、简评正文或完整评价 DTO。
+- 正式提交、审批和终评门禁在事务内重新读取当前状态,避免并发绕过。
+- 归档后所有写接口拒绝修改。
+
+### Testing Strategy
+
+主测试接缝采用 API 生命周期集成测试,与现有 `PerformanceLifecycleApiIntegrationTest` 模式保持一致。核心场景覆盖:
+
+1. 员工提交自评。
+2. 提交合规邀请名单。
+3. Leader 审核通过。
+4. 一人拒绝并触发补邀。
+5. 两名评价人分别保存草稿并正式提交。
+6. 少于 2 份时终评失败,达到 2 份并满足开放条件后终评成功。
+7. 周期归档后所有环评写入失败。
+
+必须增加以下安全与边界断言:
+
+- 同一记录分别以员工、无关员工、评价人、周期 Leader、实时新 Leader 和超级管理员身份读取,验证字段级权限。
+- 2、3、5、6 人名单边界;同部门/跨部门覆盖;重复邀请;本人、Leader、直属下属和非参与人排除。
+- 名单与评价截止时间前后边界。
+- 草稿不计数、重复提交幂等、并发提交唯一性。
+- 拒绝与失效仍占累计邀请名额。
+- 环评均分不改变 `performance_score` 的任何正式得分字段。
+- 现有自评、Leader 评分、通知、申诉、绩效沟通和归档测试继续通过。
+
+## 5. Risks & Roadmap
+
+### Phased Rollout
+
+#### MVP:下一个绩效周期
+
+- 周期双截止时间配置。
+- 员工邀请、Leader 整单审核、评价人接受/拒绝与补邀。
+- 三维度五分制、两项必填简评和草稿/提交。
+- 两份有效评价门禁。
+- Leader 实名参考面板、管理员匿名统计、站内通知。
+- 周期快照权限和归档只读。
+
+#### v1.1:基于首期数据决定
+
+- 仅在成功指标未达标且用户研究证明确有需要时,优化提醒频率、候选人筛选和管理统计。
+- 不默认加入被评价人结果查看或评分加权。
+
+#### v2.0:明确提出新业务目标后另立 PRD
+
+- 独立年度/专项 360 环评。
+- 团队能力趋势或人才盘点。
+- AI 辅助总结或反馈质量检测。
+
+### Product and Technical Risks
+
+| 风险 | 影响 | MVP 应对 |
+|---|---|---|
+| 小公司中通过措辞或时间猜测评价人 | 降低真实反馈意愿 | 员工不看原文或单人状态;Leader 综合转述;通知不含内容 |
+| 员工选择关系较好的同事 | 样本偏差 | Leader 审核整份名单;强制部门内外覆盖;禁止上下级 |
+| 邀请或评价延迟阻塞终评 | 影响周期归档 | 两个截止时间、提前 24 小时提醒、拒绝补邀、管理员阻塞统计 |
+| 仅 2 份评价代表性有限 | Leader 过度解读 | 明确“参考、不加权”;展示每份原始反馈而非伪装成精确绩效分 |
+| 实时组织关系变化造成越权 | 历史权限错误 | 所有角色与部门关系使用周期参与人快照 |
+| 管理员全局权限泄露敏感内容 | 破坏反馈信任 | 不提供管理员原始内容 API/页面;日志不写评价正文 |
+| 累计 5 人上限后仍不足 2 份 | 员工无法继续补邀,终评阻塞 | 页面提前提示剩余名额;Leader 审核时提示风险;必要时管理员延长评价期限,但不绕过最低份数 |
+
+### Launch Readiness
+
+上线前必须满足:
+
+- 全生命周期、权限矩阵、截止时间和终评门禁集成测试通过。
+- 现有绩效生命周期回归测试通过。
+- 使用至少 5 个测试账号完成员工、评价人、Leader、管理员四视角人工验收。
+- 确认员工端网络响应中不存在环评分数、简评、单人提交状态或提交时间。
+- 管理员确认下一个周期的两个截止时间并完成一次测试通知演练。