docs(changelog): #7442 三份交接件补真实网关实测,并订正 batchStatus 契约错误
changelog-filename-gate / validate (push) Failing after 2s

三份文档此前 front matter 写着 gateway_status: "verified",而同一文件的
status_note 与第八节都写着 pending / 「暂无网关实测数据」——头身从第一次提交
起就不一致,那三个 verified 是假状态。

2026-09-19 已完成实测,现在它们是真的:

- reconfigure 补登(1 个端点):正负各一次。正常路径 planVersion 2→3、
  idempotentShortCircuit=false、落库 3 条活跃行;负向路径事先点名 602002,
  拿到 602002 且 message 指名漏掉的 SUV 组,DB 核实零写入。
  另记两个坑:单组需求下 602002 语法上不可达(602001 的检查排在前面);
  夹具里的 vehicle_id=1001 是不存在的占位 ID,会被 600006 拦下。

- 受控重开窗口(5 个端点):reopen / requirement/confirm 走网关,
  plan-refresh / coverage / dispatch-baseline 直连。每个端点都断了至少一个
  本次改动相关字段并做 DB 交叉核实。coverage 补了正负对照
  (satisfied=true/gaps=[] vs 故意传 requirementVersion=999 → satisfied=false
  且 gaps 指出身份已变),证明该字段不是恒真。
  顺带订正 status_note 里「测试服尚未部署到含 PR #7957」——那句已过期,
  实测中 reconfigureWindowToken(#7957 引入)被真实端点接收并生效。

- 就绪回写两级判定(2 个端点):vehicle-ready-reset 与 vehicle-ready 配对,
  reset 让 vehicle_ready 1→0、再用 vehicle-ready 推回 1,夹具靠真实写口还原、
  零 SQL 直改。补两条负向对照(重放同版本→ALREADY_APPLIED;错版本→
  IDENTITY_MISMATCH/809205)证明 applied 不是恒真字段。

🔴 同轮查出并订正一处契约错误:batchStatus 在 applied=true 时恒为 null
(GroupBatchService#appliedResp 在成功分支从不设置它,其 javadoc 写明
「判定通过的那一支刻意不读」),而两份成功响应示例给的都是非 null 值。
照旧稿写的前端会读到一个永远为空的字段。示例与字段说明均已更正,
并写明想拿团期状态要另查团期详情接口。

三份文档共 8 个端点,全部走的是「HTTP 200 + success 或事先点名的错误码 +
至少一个本次改动相关字段 + 尽量做 DB 交叉核实」这一套判据。

Refs #7442

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
这个提交包含在:
API Changelog Bot
2026-09-19 14:17:35 +08:00
共同撰写人 Claude Opus 5
父节点 85c8443c73
当前提交 cad5dcd021
共修改 3 个文件,包含 145 行新增和 16 行删除
@@ -12,7 +12,7 @@ frontend_owner: ""
frontend_ref: ""
target_release: ""
verified_at: ""
status_note: "本文档是补登,不是新上线通知。PR-A(#7844,merge commit 8eb8e13cdfd4a8cc004f95cfb53f7e4b81904461,2026-09-16 合入 dev-v3)首次交付本端点时漏写了交接件,导致 #7442 AC-22(要求『5 个新增接口 + 4 个改造接口的完整契约』)按字面一直不可能达成;本单是对这个缺口的补登。backend_status=deployed 的依据:8eb8e13cd 已在 dev-v3,测试服 2026-09-19 01:15 已滚动部署到 4cbccc26b(晚于 8eb8e13cd 与后续 c6aa1224f,均已实测回读 commit 确认在链上)。gateway_status 先记 pending,网关实测由 #7442 取证车道另行补。本文档按端点当前(2026-09-19)的完整契约撰写,其中 requirementId/requirementVersion/demands[].assignments[].groupId 等分组相关字段是 PR-A 首次引入的核心内容;reconfigureWindowToken 字段与 602011/602012/602013 三个错误码是随后 PR-C2(#7957)追加到同一端点的字段,本文档一并如实标注,避免把 PR-C2 之后的完整契约错当 PR-A 原状描述。"
status_note: "本文档是补登,不是新上线通知。PR-A(#7844,merge commit 8eb8e13cdfd4a8cc004f95cfb53f7e4b81904461,2026-09-16 合入 dev-v3)首次交付本端点时漏写了交接件,导致 #7442 AC-22(要求『5 个新增接口 + 4 个改造接口的完整契约』)按字面一直不可能达成;本单是对这个缺口的补登。backend_status=deployed 的依据:8eb8e13cd 已在 dev-v3,测试服 2026-09-19 01:15 已滚动部署到 4cbccc26b(晚于 8eb8e13cd 与后续 c6aa1224f,均已实测回读 commit 确认在链上)。gateway_status=verified 的依据:2026-09-19 已完成本端点的网关实测,正负各一次,见第八节;⚠️ 本文档此前 gateway_status 字段写的是 verified 而 status_note 与第八节都写着 pending,头身不一致,那时的 verified 是假状态——现在它是真的,见第八节的请求/响应原文与数据库交叉读数。本文档按端点当前(2026-09-19)的完整契约撰写,其中 requirementId/requirementVersion/demands[].assignments[].groupId 等分组相关字段是 PR-A 首次引入的核心内容;reconfigureWindowToken 字段与 602011/602012/602013 三个错误码是随后 PR-C2(#7957)追加到同一端点的字段,本文档一并如实标注,避免把 PR-C2 之后的完整契约错当 PR-A 原状描述。"
updated_at: "2026-09-19"
base: "dev-v3"
---
@@ -326,7 +326,44 @@ POST /admin/fleet/group-dispatch/batches/1934567890123456800/reconfigure
## 八、测试环境已验证
> ⚠️ 本节暂无网关实测数据,PR-A 虽已部署但本文档撰写时未另行发起网关请求;gateway_status 待 #7442 取证车道回填。
✅ **2026-09-19 已完成网关实测**(走网关,非直连)。部署基线:order-v3 与 fleet 均在 `31fd5b5e6`。
本文档只覆盖一个端点,**正负各测一次**,两次都达到「HTTP 200 + `success`/预先点名的错误码 + 至少一个本次改动相关字段并经数据库交叉核实」。
### 1. 正常路径
夹具 `groupBatchId=2099951310525673474`。
```
POST /admin/fleet/group-dispatch/batches/2099951310525673474/reconfigure
→ HTTP 200,success=true
```
| 断言字段 | 读数 | 说明 |
|---|---|---|
| `planVersion` | **2 → 3** | 真实递增,非固定值 |
| `idempotentShortCircuit` | `false` | 本次确实走了写路径,不是幂等短路 |
| `coverage.wholeBatchSatisfied` | `true` | 覆盖判定通过 |
落库交叉核实:`fleet_group_dispatch` 该团 **3 条**活跃行。
### 2. 负向路径(**调用前即写明期望 602002**)
夹具 `groupBatchId=2100667751600148481`(BUS + SUV 双组团),故意只提交 BUS 组、漏掉 SUV 组。
```
POST /admin/fleet/group-dispatch/batches/2100667751600148481/reconfigure
→ HTTP 200,code=602002
message="以下乘车分组整组未排车: SUV"
```
**消息点名了具体漏掉的组**,不是笼统失败。数据库交叉核实:调用前后 `fleet_group_dispatch` 行数**不变**(纯校验失败,**零写入**)。
> 🔴 **给下一个要复现 602002 的人**:**单组需求下 602002 在语法上不可达**。只要 `demands` 非空就必然映中至少一个组码;而若该组码不在权威清单里,会**先**触发 602001(`unknownGroupCodes` 的检查排在 `missingGroupCodes` 之前)。⇒ 复现 602002 必须用**双组及以上**的夹具。
> 🔴 **另一个坑**:旧夹具里遗留的 `vehicle_id=1001` 是 `fleet_vehicle` 表里**不存在的占位 ID**,拿它重提会被 **600006**(车辆被占,源头在 `fleet_assignment`)拦下。换成库里真实存在且当日空闲的车/司机才走得通。
**副作用**:主夹具全程经真实写口驱动、**零 SQL 直改**,终态与起始态结构等价,无需复位。
---