# 隐私设置(Privacy Settings)API 联调说明 > 模块:学生隐私设置。用于控制**简历可见性**与**联系方式可见性**,仅 STUDENT 角色可用。 ## 1. 接口概览 | 方法 | 路径 | 角色 | 说明 | |------|------|------|------| | GET | `/profile/me/privacy` | STUDENT | 查询当前学生隐私设置;无记录返回默认对象,不写库 | | PUT | `/profile/me/privacy` | STUDENT | 更新当前学生隐私设置;upsert 确保同一学生至多一行 | 其余角色:COMPANY / ADMIN → `403 / 2002`;未登录 → `HTTP 401`。 身份一律从 JWT / SecurityContext 获取,**不接受** `userId`、`studentUserId`、`candidateId` 等请求参数。 ## 2. 枚举 `ResumeVisibility` | 值 | 含义 | |----|------| | `PRIVATE`(默认) | 企业不可见 | | `APPLIED_COMPANIES` | 仅当学生在该企业存在**有效投递**时企业可见(WITHDRAWN / REJECTED 不算有效投递) | | `VERIFIED_COMPANIES` | 仅 `verified=true` 的企业可见 | ## 3. GET /profile/me/privacy 无 Path / Query / Body 参数。 无历史记录时返回**默认对象**(不会向数据库写入任何记录): ```json { "code": 200, "message": "ok", "data": { "studentUserId": 2, "resumeVisibility": "PRIVATE", "contactVisible": false, "version": 0 }, "timestamp": "2026-08-25T10:00:00Z" } ``` 有历史记录时额外包含 `id`、`createdAt`、`updatedAt`。 | 状态码 | 业务码 | 说明 | |--------|--------|------| | 200 | 200 | 成功 | | 401 | 401 | 未登录 | | 403 | 2002 | 非 STUDENT 角色 | ## 4. PUT /profile/me/privacy 请求体(`ContactVisible`、`resumeVisibility` 必填,`version` 可选): ```json { "resumeVisibility": "APPLIED_COMPANIES", "contactVisible": true, "version": 0 } ``` - 首次调用创建记录,之后更新,始终保证同一学生只有一行。 - `version` 不传或传 `0` 表示非严格校验;传了且与当前版本不一致 → `409 / 9201`。 响应: ```json { "code": 200, "message": "ok", "data": { "id": 1, "studentUserId": 2, "resumeVisibility": "APPLIED_COMPANIES", "contactVisible": true, "version": 0, "createdAt": "2026-08-25T10:00:00", "updatedAt": "2026-08-25T10:00:00" }, "timestamp": "2026-08-25T10:00:00Z" } ``` | 状态码 | 业务码 | 说明 | |--------|--------|------| | 200 | 200 | 成功 | | 400 | 1001 | 缺少必填字段 / 非法枚举 | | 401 | 401 | 未登录 | | 403 | 2002 | 非 STUDENT 角色 | | 409 | 9201 | 乐观锁版本冲突 | ## 5. 隐私脱敏接入说明 现有企业候选人详情 `/company/candidates/{applicationId}` 与候选人列表 `/company/candidates` 已在响应中排除 `resumeUrl` 与联系方式字段,保持原路径、原权限、原白名单不变,且本轮不新增联系方式字段。 隐私策略方法 `canCompanyViewResume(studentUserId, companyId, applicationId)` 已随本模块提供,供企业侧按 `ResumeVisibility` 判定简历可见性。 ## 6. 审计 更新隐私设置会写入审计日志 `UPDATE_PRIVACY_SETTINGS`。审计中**不得**写入 `phone / email / password / jwt / resumeUrl` 等敏感值。 ## S03-B:`resumeVisibility` 的企业侧执行边界 此前 `resumeVisibility` 只有存储与读写接口,**没有任何企业侧代码路径读取它**,等同于空转开关。 S03 起该设置在企业读取简历文件的唯一入口 `GET /company/candidates/{applicationId}/resume` 上真正生效,判定全部由失败关闭的 `CompanyResumeAccessPolicy` 完成。 ### 可见性决策表 | 设置 | 企业条件 | 投递条件 | 结果 | |---|---|---|---| | 无设置记录 / `null` | 任意 | 任意 | 403(按 PRIVATE 处理) | | `PRIVATE` | 任意 | 包括已投递、面试、录用 | 403 | | `APPLIED_COMPANIES` | 岗位属于当前企业 | `SUBMITTED`/`VIEWED`/`INTERVIEW`/`HIRED` | 200 | | `APPLIED_COMPANIES` | 岗位属于当前企业 | `WITHDRAWN`/`REJECTED` | 403 | | `APPLIED_COMPANIES` | 其他企业 | 任意 | 403 | | `VERIFIED_COMPANIES` | 当前企业 `verified=true` 且拥有该投递岗位 | 任意合法投递状态 | 200 | | `VERIFIED_COMPANIES` | 未认证企业或其他企业 | 任意 | 403 | ### 重要变更 - **`APPLIED_COMPANIES` 与 `VERIFIED_COMPANIES` 现在都强制校验「投递所属岗位属于当前企业」。** 此前 `canCompanyViewResume` 不校验公司归属:`APPLIED_COMPANIES` 完全不使用 `companyId`, `VERIFIED_COMPANIES` 只校验企业 `verified` —— 任何已认证企业都可凭任意 `applicationId` 查看简历。 - `VERIFIED_COMPANIES` **不是**「知道学生 ID 即可查看」:仍需合法的候选业务上下文。 - 隐私拒绝统一返回 `FORBIDDEN(2002)`;跨企业同样 403,不通过差异响应泄露归属。 - `PrivacySettingsService.canCompanyViewResume` 保留为委托方法,判定逻辑已收束到策略类, 不再保留可被误用的宽松实现。