34 lines
2.5 KiB
Markdown
34 lines
2.5 KiB
Markdown
# 服务端4xx写入可能性核查(阶段3B审查证据)
|
||
|
||
日期:2026-09-22。核查人:主会话(ZCode),应用户2026-09-22裁决第4项执行。方式:**只读源码核查**,无服务端修改、无请求发送、无正式服操作。
|
||
|
||
## 核查对象
|
||
|
||
- 服务端仓库 `C:/projects/N3-Server-CN`,HEAD `858fe7c`(KV 功能提交 `a3d3faa`)。
|
||
- 入口:`LeaderboardAPI/Controllers/PlayerDataApi.cs`(`[Authorize]`,路由 `playerdata/Get|Set|Delete`)。
|
||
- 服务层:`LeaderboardBLL/Services/PlayerKV/PlayerKVService.cs`(EF Core → MySQL `PlayerKV` 表,`SaveChangesAsync` 单点提交)。
|
||
- DTO:`LeaderboardBLL/Models/PlayerKVModel.cs`(`Set.data` / `Delete.keys` 带 `[Required]`)。
|
||
- 管道:`LeaderboardAPI/Program.cs`(Cookie 认证;`OnRedirectToLogin`/`OnRedirectToAccessDenied` 改写为 403;未发现把异常转成 4xx 的中间件)。
|
||
|
||
## 变更请求(Set/Delete)的 4xx 路径清单
|
||
|
||
| 状态码 | 产生点 | 相对写入时机 |
|
||
|---|---|---|
|
||
| 401/403 | Cookie 认证/授权(未认证、会话过期、拒绝) | 动作执行前,未写 |
|
||
| 400 | `[ApiController]` 模型绑定/校验(JSON 不可解析、`data`/`keys` 缺失) | 动作执行前,未写 |
|
||
| 400 | `ResolvePlayerId` 失败(NameIdentifier 缺失/非十进制) | `SetAsync`/`DeleteAsync` 调用前,未写 |
|
||
|
||
控制器在 `SetAsync`/`DeleteAsync` 返回后仅回 200;服务层自身不产生 4xx;数据库/EF 异常未被任何中间件改写状态码,按 ASP.NET Core 默认成为 500。
|
||
|
||
## 结论
|
||
|
||
**当前服务端版本(858fe7c)下,playerdata 变更请求的 4xx(400/401/403)全部产生于服务端写入之前,不存在"已写入后返回 4xx"的代码路径;写入之后的失败表现为 5xx。**
|
||
|
||
## 边界与不改变项
|
||
|
||
1. 本结论为源码级、版本 `858fe7c` 时点结论;服务端后续更新需重新复核。
|
||
2. **客户端本批不改动**:非 200 仍一律保守按 MayHaveCommitted 处理(含 4xx)。若后续要以本证据将 4xx 降级为"确定未提交",须按差异裁决单独评审修改 `PlayerKVClient` 及相关测试,不并入 3B 实施范围。
|
||
3. 500/超时/网络中断的 MayHaveCommitted 语义不受本核查影响(提交确认丢失等场景仍然可能)。
|
||
4. `Set` 空字典 / `Delete` 空列表为 200 no-op;`Set` 批内多键经单次 `SaveChangesAsync`(EF 默认隐式事务)提交,不构成跨请求原子性。
|
||
5. 若部署拓扑插入会改写状态码的反向代理,需在最终包环境复核;当前客户端直连 `http://s101.local:18080/`。
|