@@ -1,70 +0,0 @@
|
||||
---
|
||||
schema: "hl-changelog/v2"
|
||||
ticket: "5319"
|
||||
title: "团期配车就绪门禁与清零释放内部契约"
|
||||
consumer: "internal"
|
||||
change_type: "修改接口"
|
||||
backend_status: "deployed"
|
||||
gateway_status: "not_required"
|
||||
frontend_status: "not_required"
|
||||
frontend_owner: ""
|
||||
frontend_ref: ""
|
||||
target_release: ""
|
||||
verified_at: ""
|
||||
status_note: "PR #5432 已合并 dev-v3(c3c78ea8f);fleet 4b1ab397 / order-v3 5bc5d247 已部署测试环境并经服务直连验证。internal 契约仅供服务间 Feign 消费,前端不涉及。"
|
||||
updated_at: "2026-08-03"
|
||||
base: "dev-v3"
|
||||
---
|
||||
|
||||
|
||||
# 团期配车就绪门禁与清零释放内部契约(#5319)
|
||||
|
||||
> **服务**: hl-fleet-service(8087)/ hl-order-service-v3(8086)
|
||||
> **PR**: #5432
|
||||
> **Issue**: #5319
|
||||
> **日期**: 2026-08-03
|
||||
> **影响范围**: 团期配车重配就绪校验、整团清零/释放、vehicle_ready 双向回填(服务间 internal Feign)
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ 关键变化
|
||||
|
||||
- Fleet `POST /internal/fleet/dispatch/group-batch/reconfigure` 重配前新增 order-v3 权威基线校验:
|
||||
- 服务日必须完整覆盖团期 departDate..endDate(缺首日/末日/中间日、越界、空洞原子失败)
|
||||
- 仅 `RESOURCE_PREPARING`(成团后资源配置阶段)可配,已流团/终态及出行后状态拒绝
|
||||
- 新增 `clearAll=true` 显式整团清零语义(软删全部活跃配车 + vehicle_ready=false)
|
||||
- `GROUP_READY` 意图按团期级 planVersion 去重(新表 fleet_group_dispatch_plan),相同计划重复提交不新增意图
|
||||
|
||||
## 变更接口
|
||||
|
||||
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|
||||
|---|------|------|------|----------|------|
|
||||
| 1 | 团期配车重配 | POST | `/internal/fleet/dispatch/group-batch/reconfigure`(Fleet,Feign 入向) | 修改接口 | 新增权威基线校验 + clearAll 清零;请求体新增 `clearAll` 字段(可空) |
|
||||
| 2 | 团期配车占用释放 | POST | `/internal/fleet/dispatch/group-batch/:groupBatchId/release`(Fleet,Feign 入向) | 新增接口 | 幂等软删全部活跃配车 + vehicle_ready=false |
|
||||
| 3 | 团期配车权威基线 | GET | `/v3/internal/group-batch/:groupBatchId/dispatch-baseline`(order-v3,Feign 出向) | 新增接口 | 返回服务日集合 + 生命周期可配判定;团期不存在返 589500 |
|
||||
| 4 | 重置配车就绪 | POST | `/v3/internal/group-batch/:groupBatchId/vehicle-ready-reset`(order-v3,Feign 出向) | 新增接口 | vehicle_ready=false 幂等重置 |
|
||||
| 5 | 回填配车就绪 | POST | `/v3/internal/group-batch/:groupBatchId/vehicle-ready`(order-v3,Feign 出向) | 修改接口 | 语义不变(置 true 幂等),配合清零/释放双向闭环 |
|
||||
|
||||
## 调用方动作(internal)
|
||||
|
||||
- order-v3 团期配车编排方:重配请求按权威服务日提交完整计划;需清零时置 `clearAll=true`(demands 可空)
|
||||
- 共享 DTO:`GroupBatchDispatchBaselineDTO`(hl-common-core)新增
|
||||
- 前端不消费任何 internal 端点,无前端动作
|
||||
|
||||
## 验证证据
|
||||
|
||||
- 定向测试:Fleet `GroupDispatchServiceTest`(29 用例)+ writer/effect/listener;order-v3 `GroupBatchServiceTest`/Outbox processor/service/listener/controller 契约
|
||||
- reactor verify:Fleet 2870 用例(仅 Testcontainers MySQL 无 Docker 环境失败,基线同样失败);order-v3 全量 verify 通过;fleet spotless:check 通过
|
||||
- 网关验证:internal 路径经网关 403 为设计行为(JwtAuthFilter 全局阻断);经服务直连验证 release=200、dispatch-baseline=589500(失败关闭)、vehicle-ready-reset=200、vehicle-ready=200(证据 `tmp/5319-gateway-evidence.md`)
|
||||
- 兼容性结论:既有 `vehicle-ready`(置 true)契约不变;重配请求在完整覆盖校验下语义收紧(此前不完整计划可提交),调用方须按权威服务日提交
|
||||
|
||||
## 关联 / 联系人
|
||||
|
||||
### 链接
|
||||
|
||||
- **Issue**: [#5319](https://git.1814.love:8443/wx/HL/issues/5319)
|
||||
- **PR**: [#5432](https://git.1814.love:8443/wx/HL/pulls/5432)
|
||||
- **Merge commit**: [c3c78ea8f4](https://git.1814.love:8443/wx/HL/commit/c3c78ea8f4)
|
||||
### 联系人
|
||||
|
||||
- **后端负责人**: @wx
|
||||
@@ -1,70 +0,0 @@
|
||||
---
|
||||
schema: "hl-changelog/v2"
|
||||
ticket: "5470"
|
||||
title: "DAILY_V3 配车快照回调 hmac-secret 缺失降级 SHA-256"
|
||||
consumer: "internal"
|
||||
change_type: "修改接口"
|
||||
backend_status: "deployed"
|
||||
gateway_status: "not_required"
|
||||
frontend_status: "not_required"
|
||||
frontend_owner: ""
|
||||
frontend_ref: ""
|
||||
target_release: ""
|
||||
verified_at: "2026-08-04"
|
||||
status_note: "Fleet→order DAILY_V3 配车快照回调在 order.assignment.snapshot.hmac-secret 未配置时不再 500,降级无密钥 SHA-256 指纹;fleet outbox 投递 SUCCESS、order_vehicle_assignment 正常落库。"
|
||||
updated_at: "2026-08-04"
|
||||
base: "dev-v3"
|
||||
---
|
||||
|
||||
# 【修改接口·内部服务】DAILY_V3 配车快照回调 hmac-secret 缺失降级 (#5470)
|
||||
|
||||
> **PR**: #5474 | **服务**: order-v3 | **更新时间**: 2026-08-04
|
||||
|
||||
## 1. 接口背景
|
||||
|
||||
fleet 派单(holdMode=0 创建成功)后通过 DAILY_V3 快照 outbox 回调 order-v3 同步配车投影。order 侧对回调请求计算拓扑指纹(`topology_fingerprint`,幂等/计数校验共用)需要 `order.assignment.snapshot.hmac-secret` 配置;该配置缺失时原实现 fail-fast 抛 `IllegalStateException` → 回调 HTTP 500 → 快照不落库、fleet outbox 无限重试。本次改为配置缺失时降级为无密钥 SHA-256 指纹并记 warn 日志。
|
||||
|
||||
## 变更接口清单
|
||||
|
||||
| # | 接口名 | 方法 | 路径 | 变更类型 | 说明 |
|
||||
|---|--------|------|------|----------|------|
|
||||
| 1 | DAILY_V3 配车快照回写 | POST | `/v3/internal/order/vehicle-assignment/callback` | 修改 | hmac-secret 未配置时不再 500,降级 SHA-256 指纹继续落库 |
|
||||
|
||||
## 2. 行为变化
|
||||
|
||||
| 场景 | 原来 | 现在 |
|
||||
|------|------|------|
|
||||
| `order.assignment.snapshot.hmac-secret` 未配置 | HTTP 500 `Fleet snapshot HMAC secret is not configured`,快照不落库,fleet outbox 无限重试 | 200 正常处理;拓扑指纹改用无密钥 SHA-256(64 位 hex),后端 warn 日志提示降级 |
|
||||
| hmac-secret 已配置 | HMAC-SHA256 指纹 | 不变 |
|
||||
| 同 payload 重复投递(同 revision+eventId+digest) | IDEMPOTENT | 不变(降级指纹同样幂等) |
|
||||
| stale revision | STALE_IGNORED | 不变 |
|
||||
|
||||
## 3. 接口详情
|
||||
|
||||
- **方法/路径**:`POST /v3/internal/order/vehicle-assignment/callback`
|
||||
- **认证**:internal token(`X-Internal-Token`)+ `VehicleAssignmentSnapshotInternalTokenFilter` fail-closed;网关不暴露至公网
|
||||
- **请求体**:`VehicleAssignmentSnapshotCallbackReqVO`(contractVersion=DAILY_V3、eventId、orderId、requirementId、snapshotRevision、planServiceDates/planFleetItemIndexes/planTopologySize、dailyAssignments[])
|
||||
- **响应**:`{eventId, orderId, requirementId, result(APPLIED/IDEMPOTENT/STALE_IGNORED/ORDER_CANCELLED_IGNORED), acceptedSnapshotRevision, activeDailyCellCount, usedVehicleDayCount, feeReadyVehicleDayCount, snapshotActive, processedAt}`
|
||||
- **错误码**:契约不支持/快照非法/需求不存在/订单不匹配/revision 冲突/结算已冻结等业务码不变;不再出现未捕获 500
|
||||
|
||||
## 4. 前端需要做什么
|
||||
|
||||
无(internal 接口,无前端消费)。
|
||||
|
||||
## 5. 后端测试、部署与验证
|
||||
|
||||
- 单元测试:`VehicleAssignmentSnapshotDigestTest` 3 用例(空 secret 降级 SHA-256 确定性 + 字段敏感、HMAC 确定性、全字段覆盖);`DailyVehicleAssignmentSnapshotServiceTest` 12 用例(含 IDEMPOTENT/STALE/revision 冲突)。
|
||||
- 模块验证:`mvn -pl hl-order-service-v3 -am verify` 7427 测试 0 失败。
|
||||
- 部署:TEST hl-order-service-v3 rolling 部署完成(dev-v3 @ 97ad827da,双实例 UP)。
|
||||
- 验证(TEST 2026-08-04):对隔离事件 `342887996946780160`(orderId=2084274056961331202)requeue 重放 → fleet outbox `SUCCESS`(processed_at 14:04:00,retry_count 归零);`order_vehicle_assignment` 3 行落库(8-03~8-05,used=3/feeReady=3,driver_phone_ciphertext 加密列正常);`order_vehicle_requirement` 回写 `assignment_contract_version=DAILY_V3`、`assignment_snapshot_revision=1`、`assignment_event_id=342887996946780160`、`assignment_snapshot_active=1`、status=DONE;error_logs 无修复后新增 500(仅 7 条修复前历史记录)。
|
||||
|
||||
## 关联 / 联系人
|
||||
|
||||
### 链接
|
||||
|
||||
- **Issue**: [#5470](https://git.1814.love:8443/wx/HL/issues/5470)
|
||||
- **PR**: [#5474](https://git.1814.love:8443/wx/HL/pulls/5474)
|
||||
- **Merge commit**: [97ad827da5](https://git.1814.love:8443/wx/HL/commit/97ad827da5)
|
||||
### 联系人
|
||||
|
||||
- **后端负责人**: @wx
|
||||
@@ -1,125 +0,0 @@
|
||||
---
|
||||
schema: "hl-changelog/v2"
|
||||
ticket: "5446"
|
||||
title: "HOLD 通知管理端状态查询与受控重试"
|
||||
consumer: "admin"
|
||||
author: "wx(GIT)"
|
||||
change_type: "新增接口"
|
||||
backend_status: "deployed"
|
||||
gateway_status: "not_required"
|
||||
frontend_status: "verified"
|
||||
frontend_owner: "Pi"
|
||||
frontend_ref: "hl-admin@6e4c6b224b204cd792e02f29a6e61689b0d9a588"
|
||||
target_release: "v2.1"
|
||||
verified_at: "2026-08-04"
|
||||
status_note: "后端 PR #5447 已合并 dev-v3(merge 15d79a8d4);测试部署 task ba1b84af 成功;网关验证 5 项通过(参数校验/missing/stale 拒绝);管理后台已由 Pi 领取并开始适配。"
|
||||
updated_at: "2026-08-04"
|
||||
base: "dev-v3"
|
||||
generated: "2026-08-03T23:19:24+08:00"
|
||||
---
|
||||
|
||||
|
||||
# HOLD 通知管理端状态查询与受控重试
|
||||
|
||||
## 关联
|
||||
|
||||
- Issue: [#5446](https://git.1814.love:8443/wx/HL/issues/5446)
|
||||
- Backend tracking: [#5366 B10](https://git.1814.love:8443/wx/HL/issues/5366)
|
||||
- PR: [#5447](https://git.1814.love:8443/wx/HL/pulls/5447)(merge commit 15d79a8d4)
|
||||
|
||||
|
||||
### 链接
|
||||
|
||||
- **Issue**: [#5446](https://git.1814.love:8443/wx/HL/issues/5446)
|
||||
- **PR**: [#5447](https://git.1814.love:8443/wx/HL/pulls/5447)
|
||||
- **Merge commit**: [15d79a8d4b](https://git.1814.love:8443/wx/HL/commit/15d79a8d4b)
|
||||
### 联系人
|
||||
|
||||
- **后端负责人**: @wx
|
||||
## 变更接口
|
||||
|
||||
| 方法 | 路径 | 来源 |
|
||||
|---|---|---|
|
||||
| `GET` | `/admin/fleet/assignments/hold-notification/status` | `hl-fleet-service/src/main/java/com/hulalv/fleet/messagetemplate/controller/AssignmentHoldNotificationAdminController.java` |
|
||||
| `POST` | `/admin/fleet/assignments/hold-notification/retry` | 同上 |
|
||||
|
||||
路径前缀 `/admin/fleet/**` 已由网关登录/角色校验与 `FleetAdminRoleGuardInterceptor`(VEHICLE_MANAGER / SUPER_ADMIN)收口,无需新增网关规则。
|
||||
|
||||
## 1. 状态查询 `GET /admin/fleet/assignments/hold-notification/status`
|
||||
|
||||
请求参数(query):
|
||||
|
||||
| 参数 | 类型 | 必填 | 说明 |
|
||||
|---|---|---|---|
|
||||
| `assignmentGroupId` | `String(Long)` | 是 | 派车组 ID |
|
||||
| `notificationGeneration` | `String(Long)` | 是 | HOLD 通知代际 |
|
||||
| `attemptId` | `String` | 否 | 调用方生成的 attempt 标识(幂等/审计定位),≤64 字符 |
|
||||
|
||||
响应 `data`:
|
||||
|
||||
| 字段 | JSON 类型 | 可空 | 说明 |
|
||||
|---|---|---|---|
|
||||
| `assignmentGroupId` | `String(Long)` | 否 | 回显 |
|
||||
| `notificationGeneration` | `String(Long)` | 否 | 回显 |
|
||||
| `assignmentStatus` | `String` | 是 | 派车状态;HOLDING=仍在待确认,其余=已离开 holding |
|
||||
| `deliveryStatus` | `String` | 否 | `NOT_FOUND/PENDING/SENT/FAILED/AMBIGUOUS/INVALIDATED`;`SENT` 只表示系统发送成功,不表示通道送达回执 |
|
||||
| `messageLogId` | `String(Long)` | 是 | 本地通知日志 ID |
|
||||
| `outboxEventId` | `String(Long)` | 是 | 可靠通知 Outbox 事件 ID |
|
||||
| `outboxStatus` | `String` | 是 | `PENDING/PROCESSING/QUARANTINED/SUCCESS` |
|
||||
| `retryCount` | `Integer` | 是 | Outbox 累计处理重试次数 |
|
||||
| `sentAt` | `String(date-time)` | 是 | 有可信发送成功事实时返回 |
|
||||
| `dispatchAttemptedAt` | `String(date-time)` | 是 | 最近一次向通知中心发起分发的时间 |
|
||||
| `lastError` | `String` | 是 | 最近失败/对账留痕(脱敏) |
|
||||
| `canRetry` | `Boolean` | 否 | 是否允许管理端重试:仅明确失败且未发送成功且未取消时为 `true` |
|
||||
| `lastReplayAttemptId` | `String` | 是 | 上次管理端重试 attemptId |
|
||||
| `lastReplayReason` | `String` | 是 | 上次管理端重试原因 |
|
||||
| `lastReplayedBy` | `String(Long)` | 是 | 上次重试操作人 |
|
||||
| `lastReplayedAt` | `String(date-time)` | 是 | 上次重试时间 |
|
||||
| `attemptStatus` | `String` | 是 | 本次请求 attempt 处理状态:`ACCEPTED/SUCCEEDED/REJECTED/AMBIGUOUS`(持久幂等:同一 attemptId 重复提交直接返回已记录结果) |
|
||||
| `attemptResultNote` | `String` | 是 | 本次 attempt 处理结果摘要(脱敏) |
|
||||
|
||||
错误码:400 参数校验 / `100001` 派车组不存在 / `100003` 通知代际已过期 / 401 未登录。
|
||||
|
||||
## 2. 受控重试 `POST /admin/fleet/assignments/hold-notification/retry`
|
||||
|
||||
请求体:
|
||||
|
||||
| 字段 | 类型 | 必填 | 说明 |
|
||||
|---|---|---|---|
|
||||
| `assignmentGroupId` | `String(Long)` | 是 | 派车组 ID |
|
||||
| `notificationGeneration` | `String(Long)` | 是 | HOLD 通知代际 |
|
||||
| `attemptId` | `String` | 是 | 本次重试 attempt 标识(幂等键组成部分 + 审计),≤64 字符 |
|
||||
| `reason` | `String` | 是 | 核查失败原因后的重试说明,≤200 字 |
|
||||
|
||||
行为约束:
|
||||
|
||||
- 幂等键 = `assignmentGroupId:notificationGeneration:attemptId`,持久化于 `fleet_hold_notification_retry_attempt` 唯一索引,重复提交(含 Redis 防重窗口过期后)幂等返回已记录结果,不重复发送、不重复写 Outbox;
|
||||
- 仅允许明确失败(`FAILED`,Outbox `QUARANTINED` 或 `PENDING`+错误)的 HOLD 通知重试;`QUARANTINED` 重置失败预算,`PENDING`+错误立即重试;
|
||||
- `UNKNOWN/AMBIGUOUS`(dispatching)先按通知中心供应商发送日志对账:存在真实外部成功则补记发送事实并返回 `SENT`,仍无法判定则拒绝重试(fail closed);
|
||||
- stale(代际过期)/missing(派车组或日志不存在)/wrong identity 一律拒绝;
|
||||
- 重试复用原 Outbox 事件与供应商幂等键,不新建事件、不直接外呼,不改变派车状态;
|
||||
- 操作人、原因、attemptId 记入 Outbox 审计列(`last_replay_*`)。
|
||||
|
||||
响应:同状态查询 `data`(重试后最新事实)。
|
||||
|
||||
错误码:400 参数校验 / `100001` 派车组或通知日志不存在 / `100003` 通知代际已过期或已取消 / `100503` 资源竞争(并发重试)/ 401 未登录。
|
||||
|
||||
## 契约影响文件
|
||||
|
||||
- `hl-fleet-service/src/main/java/com/hulalv/fleet/messagetemplate/controller/AssignmentHoldNotificationAdminController.java`
|
||||
- `hl-fleet-service/src/main/java/com/hulalv/fleet/messagetemplate/service/AssignmentHoldNotificationAdminService.java`
|
||||
- `hl-fleet-service/src/main/java/com/hulalv/fleet/messagetemplate/vo/AssignmentHoldNotificationStatusReqVO.java`
|
||||
- `hl-fleet-service/src/main/java/com/hulalv/fleet/messagetemplate/vo/AssignmentHoldNotificationStatusRespVO.java`
|
||||
- `hl-fleet-service/src/main/java/com/hulalv/fleet/messagetemplate/vo/AssignmentHoldNotificationRetryReqVO.java`
|
||||
- `hl-fleet-service/src/main/java/db/migration/V20260803_008__add_outbox_hold_replay_attempt_id.java`
|
||||
|
||||
## 前端/调用方动作
|
||||
|
||||
管理后台新增适配:派车详情/司机通知维度展示 `deliveryStatus` 与 `canRetry`;`canRetry=true` 时提供重试按钮,重试需携带调用方生成的 `attemptId` 与原因;`AMBIGUOUS` 不提供重试入口(等待自动对账)。所有 Long ID 按 String 消费。
|
||||
|
||||
## 验证证据
|
||||
|
||||
- 定向测试:`AssignmentHoldNotificationAdminServiceTest` 24 项 / `AssignmentHoldNotificationAdminControllerTest` 5 项 / `HoldNotificationRetryAttemptMapperTest` 2 / `WechatMessageLogMapperTest` 2 / `AssignmentInsuranceOutboxMapperTest` 18 / 迁移可重入测试 2(Fleet reactor verify 3047 项 0 failures,1 项 Docker 环境型 error 与本任务无关)
|
||||
- Spotless: check 通过
|
||||
- 网关验证:经 api.test.1814.love:9443 实测 5 项(status 缺参 400 / 组不存在 100001 / 过期代际 100003 / retry 缺 attemptId 400 / retry 过期代际 100003),证据 sha256 c8759216
|
||||
- 兼容性结论:纯新增端点,无既有字段或行为变更
|
||||
@@ -1,92 +0,0 @@
|
||||
---
|
||||
schema: "hl-changelog/v2"
|
||||
ticket: "5444"
|
||||
title: "Step2 canonical full snapshot 与稳定槽位"
|
||||
consumer: "admin"
|
||||
author: "wx(GIT)"
|
||||
change_type: "修改接口"
|
||||
backend_status: "released"
|
||||
gateway_status: "verified"
|
||||
frontend_status: "verified"
|
||||
frontend_owner: "Pi"
|
||||
frontend_ref: "hl-admin@6e4c6b224b204cd792e02f29a6e61689b0d9a588"
|
||||
target_release: "v2.1"
|
||||
verified_at: "2026-08-04"
|
||||
status_note: "后端 canonicalSnapshot 契约已发布并完成网关验证;管理后台已由 Pi 领取并开始适配。"
|
||||
updated_at: "2026-08-04"
|
||||
base: "dev-v3"
|
||||
generated: "2026-08-03T23:34:18+08:00"
|
||||
---
|
||||
|
||||
|
||||
# Step2 canonical full snapshot 与稳定槽位
|
||||
|
||||
> #5444(#5366 B08/B09 后端):派车弹窗 Step2 canonical full snapshot 与稳定槽位。
|
||||
> 后端实现已合入 PR #5448(merge 8ceb8c5);测试部署 task 80234589;网关验证通过。
|
||||
|
||||
## 关联
|
||||
|
||||
- Issue: #5444
|
||||
- PR: [#5448](https://git.1814.love:8443/wx/HL/pulls/5448)
|
||||
|
||||
|
||||
### 链接
|
||||
|
||||
- **Issue**: [#5444](https://git.1814.love:8443/wx/HL/issues/5444)
|
||||
- **PR**: [#5448](https://git.1814.love:8443/wx/HL/pulls/5448)
|
||||
- **Merge commit**: [8ceb8c5cf2](https://git.1814.love:8443/wx/HL/commit/8ceb8c5cf2)
|
||||
### 联系人
|
||||
|
||||
- **后端负责人**: @wx
|
||||
## 变更接口
|
||||
|
||||
| 方法 | 路径 | 来源 |
|
||||
|---|---|---|
|
||||
| `POST` | `/admin/fleet/assignments/candidates` | 响应新增 `canonicalSnapshot` 区块;请求新增可选同代校验参数(additive,向后兼容) |
|
||||
|
||||
## 契约影响文件
|
||||
|
||||
- `hl-fleet-service/src/main/java/com/hulalv/fleet/assignment/vo/AssignmentCandidateReqVO.java`
|
||||
- `hl-fleet-service/src/main/java/com/hulalv/fleet/assignment/vo/AssignmentCandidateRespVO.java`
|
||||
- `hl-fleet-service/src/test/java/com/hulalv/fleet/assignment/controller/AssignmentControllerTest.java`
|
||||
|
||||
## 请求新增(均可选)
|
||||
|
||||
- `expectedPlanGeneration`(Long·String):Step2 幂等重试/同代校验期望计划代际;携带且与当前 canonical 快照不符时以 `605061` 拒绝(generation 漂移 fail-closed)。
|
||||
- `expectedSnapshotVersion`(Long·String):同上,期望快照版本。
|
||||
|
||||
## 响应新增 `canonicalSnapshot` 区块(additive)
|
||||
|
||||
- `planGeneration`(Long·String):当前计划代际(不透明令牌);与 `snapshotVersion` 共同标识同一份 canonical 快照。
|
||||
- `snapshotVersion`(Long·String):当前快照版本;同代内容修订递增。
|
||||
- `retainedSlotIds`(Long·String[]):有序 RetainedSlotSet(稳定槽位集合);不重编号、不丢 protected/active slot、至少 1 个。
|
||||
- `editableServiceDates`(LocalDate[]):完整有序可编辑服务日。
|
||||
- `cells`:每个 `RetainedSlotSet × editableServiceDates` 笛卡尔积位置唯一 cell:
|
||||
- `slotId`(Long·String)
|
||||
- `serviceDate`(LocalDate)
|
||||
- `used`:`USED` / `UNUSED` / `null`(无切片行=未编辑)
|
||||
- `readOnly`(Boolean):只读 cell 不可被批量操作改写
|
||||
- `readOnlyReason`(String):只读原因;可编辑为 null(派单已完结 / 派单已取消 / 服务日期已过去 / 对账期已关账)
|
||||
- `vehicleId` / `driverId`(Long·String,未派或不用车为 null)
|
||||
- `selectedVehicle`(对象,未选或资源失效为 null):`vehicleId` / `plate` / `modelName` / `seats`
|
||||
- `selectedDriver`(对象,未选或资源失效为 null):`driverId` / `name` / `maskedPhone`(司机域脱敏)/ `driverStatus` / `season`
|
||||
|
||||
## 行为说明(B08/B09)
|
||||
|
||||
- 首次进入 Step2 且不存在稳定槽位时,后端在 requirement 锁 + 独立新事务内原子生成至少 1 个稳定 `slotId` 并落 `fleet_assignment` unassigned 每日切片;同一 `planGeneration + snapshotVersion` 下重复读取/幂等重试不重复建槽、不重编号。
|
||||
- `selectedVehicle`/`selectedDriver` 为与 `snapshotVersion` 同代的已选资源展示快照,独立于候选分页/筛选;null/失效资源 fail-closed 不编造。
|
||||
- 未传 `requirementId` 或需求上下文不可用时 `canonicalSnapshot` 为 `null`,候选查询本身不受影响。
|
||||
|
||||
## 前端/调用方动作
|
||||
|
||||
- Step2 前端可消费 `canonicalSnapshot` 区块组织稳定槽位 UI;重复读取/幂等重试时回传 `expectedPlanGeneration`/`expectedSnapshotVersion` 做同代校验。
|
||||
- 不新增前端建槽 API 与二次批量查询 API;`selectedVehicle`/`selectedDriver` 直接取自现有 `selectedVehicleId`/`selectedDriverId` 入参。
|
||||
- 未消费新字段的既有调用保持兼容(additive)。
|
||||
|
||||
## 验证证据
|
||||
|
||||
- 定向测试:`Step2CanonicalSnapshotServiceTest`(11 用例:首次原子建槽/同代幂等不重编号/并发/漂移 fail-closed/脱敏/跨页过滤/null 失效/readOnly cell)、`AssignmentCandidateServiceTest`、`AssignmentControllerTest`(canonicalSnapshot 挂载 + 透传),全部通过。
|
||||
- Fleet 全量测试:3022/3023 通过;唯一失败 `FleetInsuranceTaskTeamNoMysqlTest` 为 Testcontainers 无 Docker 环境型失败(基线上同样失败)。
|
||||
- Spotless `spotless:check` 通过。
|
||||
- 网关验证:`https://api.test.1814.love:9443` POST /admin/fleet/assignments/candidates 真实订单 3 槽×3 天 9 cell;同代 expected 重试 snapshotVersion 不变;漂移 605061 fail-closed;无 requirement/未知需求快照 null。证据 `D:/evidence/5444-gateway-step2-snapshot.json`。
|
||||
- 兼容性结论:请求/响应均为 additive 扩展,向后兼容。
|
||||
在新工单中引用
屏蔽一个用户