# R01-A 请求身份与 requestId 收束实施指令 ## 一、任务性质 本轮只完成 R01-A 第一批,不进入异常映射、评分规则、百分位、消息未读、PersonalDataCollector 或推荐权重重构。 允许修改公共请求上下文组件、最多 8 个 Controller 及其测试和文档;禁止新增接口、ErrorCode、Flyway、表、索引或依赖。 ## 二、开始前核查 在 `C:\Users\15642\Desktop\zhilai` 执行并记录: ```powershell git branch --show-current git status --short git diff --cached --name-only git log -5 --oneline git diff --check ``` 分支必须为 `refactor/r01-structure-performance`,HEAD 必须包含 Q01 检查点 `77dc624`,暂存区必须为空。完整搜索适用的 AGENTS.md;保护全部历史未跟踪文件。 ## 三、先写基线清单 列出所有私有 `resolveUserId/userId/requireAdmin` 与 `requestId/getRequestId` 方法,记录:文件、公开端点、当前异常、角色检查位置、资源归属检查位置、requestId 来源。 第一批只迁移以下 8 个 Controller: 1. `AssessmentController` 2. `AbilityController` 3. `ProfileController` 4. `ResumeVersionController` 5. `PreferenceController` 6. `CompetitionRankingController` 7. `PersonalDataExportController` 8. `PrivacySettingsController` 若其中存在与未提交修改重叠,停止并报告,不得改换到其它文件凑数。 ## 四、身份组件 复用现有 `CurrentUserAccessor`,不要创建第二个身份解析器。Controller 通过构造器注入并调用 `requireUserId()`。 必须保持: - null Authentication、AnonymousAuthenticationToken、`anonymousUser`、未认证、空白主体、Unicode 数字、带正负号、Long 溢出和 userId<=0 全部 401; - 不回显主体内容、异常类或堆栈; - 不接受请求参数中的 userId; - 角色与资源归属仍由原 Service/Controller 的既有位置判断; - 不将原 403 或 404 改成 401。 删除迁移 Controller 内的私有身份解析代码和不再使用的 SecurityContext 依赖。 ## 五、requestId 组件 先完整阅读 `common/logging/RequestIdFilter`、`RequestLoggingFilter`、`AuditContext` 和 `GlobalExceptionHandler`。 新增 `common/logging/RequestIdAccessor`,提供 `String get(HttpServletRequest request)`。它必须复用过滤器产出的规范化 requestId;禁止重新生成第二个值,禁止直接信任超长/非法客户端头。 若 RequestIdFilter 当前没有 request attribute,允许增加一个常量属性并写入规范化后的值。响应头、MDC、Controller body、AuditContext 与异常响应必须保持同源。过滤器结束后仍清理 MDC。 只替换上述 8 个 Controller 的私有 requestId 方法。GlobalExceptionHandler 本轮只允许改为调用 accessor,不得重构 HTTP 状态映射。 ## 六、必须先新增的测试 新增或加强: - `RequestIdAccessorTest` - `RequestContextMigrationIntegrationTest` - 8 个 Controller 的既有权限回归 至少覆盖: 1. 合法客户端 requestId 原样使用; 2. 缺失、空白、超长、非法字符时使用过滤器规范化值; 3. 响应头、响应 body、MDC 日志与 AuditContext 同一值; 4. 并发请求不串 requestId; 5. 过滤器完成后 MDC 清理; 6. 八类非法 principal 均 401 而非 500; 7. 错误响应不包含 principal; 8. STUDENT/COMPANY/ADMIN 权限矩阵与改动前一致; 9. 拒绝请求无业务写入; 10. 反证:绕过 filter 直接传超长请求头时 accessor 不得返回原值。 禁止只 Mock 新组件后断言 Controller 返回 mock 值;至少一组测试必须使用真实 SecurityFilterChain、RequestIdFilter 和 MVC。 ## 七、量化验收 整改前后分别统计: ```powershell rg -l "private (Long|long) resolveUserId|private .*userId\(\)" mydreamjob-server/src/main/java rg -l "private String (getRequestId|requestId)\(" mydreamjob-server/src/main/java ``` 第一批必须精确减少对应 8 个 Controller 的重复方法,不得声称全仓已完成。报告剩余数量和文件清单。 ## 八、验证 依次运行定向测试、八个模块关联测试、`mvn test`、`mvn clean verify`、`python ..\docs\verify_openapi.py`、`git diff --check`。 预期 OpenAPI 保持 176/214;测试数量以实际为准,Failures=0、Errors=0、Skipped=0。 ## 九、停止条件 完成 R01-A 第一批代码、测试和报告后停止。暂存区保持空;不得 commit/push;不得进入 R01-B/C/D/E。 最终状态只能写: `R01-A 第一批请求上下文收束完成,待独立代码复验。`