forked from baskbuddy/zhangshun
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.
3.9 KiB
3.9 KiB
评分治理 API(Candidate Scoring Governance)
规则版本
candidate-scoring-v0.1· 基础路径/api/v1为求职者评分提供申诉、审核、回滚、审计基础能力;不改已验收评分接口与引擎规则。
回滚语义
回滚 = ① 记录回滚前快照(candidate_scoring_snapshot_history);② 按当前数据确定性重算(复用 CandidateScoringCalculator);③ 写入 candidate_dimension_scores 新版本;④ 记录回滚后快照;⑤ 申诉状态置 ROLLED_BACK;⑥ 写申诉历史与审计。不恢复旧分数——是"批准申诉后的确定性重新计算"。
接口(9 个接口落在 8 个路径,OpenAPI 87 → 95)
| # | 接口 | 方法 | 角色 |
|---|---|---|---|
| 1 | /profile/me/candidate-scoring/appeals |
POST | STUDENT 本人(提交申诉) |
| 2 | /profile/me/candidate-scoring/appeals |
GET | STUDENT 本人(我的列表) |
| 3 | /profile/me/candidate-scoring/appeals/{appealId} |
GET | 本人 / ADMIN |
| 4 | /profile/me/candidate-scoring/appeals/{appealId}/cancel |
POST | STUDENT 本人(撤销,仅 PENDING) |
| 5 | /admin/candidate-scoring/appeals |
GET | ADMIN |
| 6 | /admin/candidate-scoring/appeals/{appealId}/decision |
POST | ADMIN |
| 7 | /admin/candidate-scoring/appeals/{appealId}/rollback |
POST | ADMIN |
| 8 | /admin/candidate-scoring/appeals/{appealId}/history |
GET | 本人(脱敏)/ ADMIN(全量) |
| 9 | /admin/candidate-scoring/snapshots/{candidateUserId}/{dimension}/{period}/history |
GET | ADMIN |
请求/响应
CreateAppealRequest:dimension(8 枚举)、period(yyyy-MM)、reason(必填,缺 → 8604)、idempotencyKey(可选)。AppealDecisionRequest:decision(APPROVE/REJECT)、reason(REJECT 必填 → 8604)。AppealResponse:appealId、candidateId、dimension、period、status、reason、decision、decisionReason、reviewerId(学生端不返回)、reviewedAt、rollbackAt、scoreAtAppeal、snapshotVersionAtAppeal、rulesVersion、createdAt、updatedAt。- 历史项:
actorRole(STUDENT/ADMIN,学生端可见);actorUserId(仅 ADMIN)。 - 快照审计项:回滚前后
score/version/rulesVersion完整变化(仅 ADMIN)。
权限矩阵
| 接口 | 未登录 | STUDENT | COMPANY | ADMIN |
|---|---|---|---|---|
| 申诉 1–4 | 401 | ✅ 本人 | 403 | 403 |
| 历史(8) | 401 | ✅ 本人(脱敏) | 403 | ✅ 全量 |
| admin 5/6/7/9 | 401 | 403 | 403 | ✅ |
身份一律取自 JWT;学生仅能访问自己的申诉;COMPANY 全 403/2002;ADMIN 的 candidateUserId 路径参数仅 ADMIN 可用。
状态机
PENDING ──> APPROVED ──> ROLLED_BACK(终态)
│ └────────────> REJECTED(终态)
└────────────> CANCELLED(终态)
并发与幂等
active_key = {candidate}:{dimension}:{period}唯一约束保护 PENDING/APPROVED;终态清空 active_key 允许重新提交。- 同 idempotencyKey 同请求体 → 200 幂等;不同请求体 → 409/8607;并发创建唯一冲突 → 409/8602。
- 审核
@Version乐观锁,并发冲突 → 409/8606。 - 回滚限流
candidate_scoring_rollback_limits+SELECT ... FOR UPDATE悲观锁;每学生每自然年 ≤3 次,第 4 次 409/8605;重复回滚幂等 200。
错误码(新增 86xx)
| code | HTTP | 含义 |
|---|---|---|
| 8601 | 404 | 申诉不存在 |
| 8602 | 409 | 同维度+周期已有活跃申诉 |
| 8603 | 409 | 申诉已决定 |
| 8604 | 400 | 缺少理由 |
| 8605 | 409 | 年度回滚次数超限(3) |
| 8606 | 409 | 非法状态流转 / 并发冲突 |
| 8607 | 409 | 幂等键冲突(请求体不同) |
脱敏
学生端响应不返回:reviewerId、actorUserId、phone、email、passwordHash、resumeUrl、内部评分日志。ADMIN 可见 reviewerId 与 actorUserId。