changelog-filename-gate / validate (push) Failing after 2s
7510/7511/7512 代码早已随供应商关系系列交付(a17a2c2a/4bedc8be),实证后回写 verified 挂 a17a2c2a; 11_7510 为正本 12_7510 的重复副本(canonical_path),标 not_required 消除 pending; 7513/7530/7531/7535 实证前端零改动 not_required。
278 行
13 KiB
Markdown
278 行
13 KiB
Markdown
---
|
||
schema: "hl-changelog/v2"
|
||
ticket: "7531"
|
||
title: "下线 Mock 的行程整体保存端点 POST /v3/admin/order/{orderId}/itinerary/save"
|
||
consumer: "admin"
|
||
author: "jw(GIT)"
|
||
change_type: "删除接口"
|
||
backend_status: "deployed"
|
||
gateway_status: "verified"
|
||
frontend_status: "not_required"
|
||
frontend_owner: "mmg"
|
||
frontend_ref: ""
|
||
target_release: ""
|
||
verified_at: "2026-09-12"
|
||
status_note: "该端点自 2026-05-12 落地至今是 Mock,从未落库一行;下线前已穷举 hl-ui 全部 4 条远端分支确认无人调用,故前端预期无需改动。行程整体保存的真实入口是 POST /v3/admin/order/{id}/adjustment/submit。 前端 2026-09-13 闭环 not_required:前端对 itinerary/save 精确+拼接 grep 零命中,真实行程保存入口 adjustment/submit 在用,saveItinerary 属产品域。零业务代码改动。"
|
||
updated_at: "2026-09-13"
|
||
base: "dev-v3"
|
||
---
|
||
|
||
# order-v3: 下线 Mock 的行程整体保存端点 `POST /v3/admin/order/{orderId}/itinerary/save`
|
||
|
||
**服务**: hl-order-service-v3
|
||
**PR**: #7570
|
||
**Issue**: #7531
|
||
|
||
---
|
||
|
||
## ⚠️ 关键变化
|
||
|
||
🔴 **这个端点从来就没有真的保存过任何东西。** 它自 2026-05-12(`e0fc9de5d`,「6 接口空骨架 + Mock ServiceImpl」)落地起,`ItineraryService#batchSave` 就是 Mock —— **只把请求里的 id 原样回显**,`order_itinerary_day` / `order_itinerary_node` **一行都不写**。也就是说:
|
||
|
||
| 你以为 | 实际 |
|
||
|---|---|
|
||
| 调了它,行程改动保存成功了 | 返回 200,**库里一个字没变**,刷新页面即回到改前 |
|
||
| `updatedNodeIds` 是被更新的节点 | 是**请求里传进来的 id 原样回显**,不代表任何写入 |
|
||
|
||
🔴 **下线不是「功能被砍」,是「假功能被撤掉」。** 行程整体保存**一直**只有一个真实入口:
|
||
**`POST /v3/admin/order/{id}/adjustment/submit`**(订单调整提交)。
|
||
|
||
🔴 **本次下线前已确认无人调用。** 经 Gitea API 枚举 `mmg/hl-ui` 的**远端分支全集 = 4 条**(`v2.1` / `master` / `v1` / `v2`),**4 条全部检索**,`itinerary/save` 与其字符串拼接形态 `itinerary/${` 均 **0 命中**;每条 ref 都带阳性对照(见「八、测试环境已验证」)。因此**前端预期无需任何改动**。
|
||
|
||
---
|
||
|
||
## 一、背景
|
||
|
||
order-v3 的 §5 行程域在 2026-05-12 以「6 接口空骨架 + Mock ServiceImpl」的形式落地,其中 `batchSave`(整体保存)留了 Mock 实现,类 javadoc 里写着「batchSave 仍为 Mock,下期落地。」。
|
||
|
||
此后行程的真实写入能力走的是**订单调整**链路(`adjustment/submit`),`itinerary/save` 这条路再没被真实化过。留着它的代价是:**它长得像一个可用的保存接口,返 200、返 id,但实际是空操作** —— 任何一次误用都会以「保存成功」的外观丢掉用户的全部编辑。
|
||
|
||
本单据此下线该端点,并把「为什么下线 / 替代入口是谁」写进 Controller 类 javadoc 存档。
|
||
|
||
---
|
||
|
||
## 二、变更接口清单
|
||
|
||
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|
||
|---|------|------|------|----------|------|
|
||
| 1 | 行程整体保存(Mock) | POST | `/v3/admin/order/{orderId}/itinerary/save` | 删除 | 端点整体下线;改前是 Mock,从不落库。替代入口 `POST /v3/admin/order/{id}/adjustment/submit` |
|
||
|
||
---
|
||
|
||
## 三、接口详情
|
||
|
||
### 1. 行程整体保存(Mock) `POST /v3/admin/order/{orderId}/itinerary/save`
|
||
|
||
**VO**: `ItinerarySaveReqVO`
|
||
|
||
#### 使用场景
|
||
|
||
**已下线,不再有使用场景。** 改前的设计意图是「订单行程的整体保存」(一次提交多天、多节点的叙事字段改动),但实现始终是 Mock,从未落库。
|
||
|
||
需要改订单行程的,一律走 **`POST /v3/admin/order/{id}/adjustment/submit`**(订单调整提交)—— 它是行程改动**唯一**真实落库的入口,改前改后都是。
|
||
|
||
#### 入参字段表
|
||
|
||
**已下线,不再接受任何入参。** 以下是改前的形态,仅供核对你手上的调用代码是否属于本端点:
|
||
|
||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||
|------|------|------|------|------|------|
|
||
| orderId | Path | Long | ✅ | 订单 ID | **已下线** |
|
||
| days | Body | Array | ✅ | 行程天列表 | **已下线**。改前传什么都不会落库 |
|
||
| days[].id | Body | Long | ✅ | 行程天主键 | **已下线**。改前原样回显在 `updatedNodeIds` 里 |
|
||
|
||
#### 出参字段表
|
||
|
||
**已下线,不再有响应体。** 改前的形态:
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| addedDayIds | Array | **已下线**。改前恒为空数组 |
|
||
| updatedNodeIds | Array | **已下线**。改前是**请求入参的原样回显**,不代表任何写入 |
|
||
| deletedDayIds | Array | **已下线**。改前恒为空数组 |
|
||
|
||
#### 请求示例
|
||
|
||
**端点已下线。** 以下是改前的请求形态,用于识别需要迁移的调用点:
|
||
|
||
```http
|
||
POST /v3/admin/order/{orderId}/itinerary/save
|
||
Authorization: Bearer <admin token>
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"days": [
|
||
{ "id": 7700000000003, "dayNumber": 1, "title": "首日行程" }
|
||
]
|
||
}
|
||
```
|
||
|
||
**迁移到**:`POST /v3/admin/order/{orderId}/adjustment/submit`。
|
||
|
||
#### 响应示例
|
||
|
||
**端点已下线,现在的真实响应是 404:**
|
||
|
||
```json
|
||
{
|
||
"code": 404,
|
||
"message": "接口不存在: POST /v3/admin/order/60001/itinerary/save",
|
||
"data": null,
|
||
"traceId": null,
|
||
"success": false
|
||
}
|
||
```
|
||
|
||
#### 空数据 / 降级响应
|
||
|
||
**不适用** —— 端点已不存在,任何请求(无论 body 是什么、orderId 是否真实存在)都统一返 `code=404`,不存在空数据或降级分支。
|
||
|
||
#### 错误响应
|
||
|
||
改前该端点声明的 5 个错误码 **583030 ~ 583034** 号位**全部保留、一个未删**(号码与符号原样),只在 javadoc 上标注「端点已于 2026-09-12 随 #7531 下线,号位保留待整体保存真实化时启用」。它们**现在不会再被任何路径抛出**。
|
||
|
||
| 码 | 触发(改前) | 现在 |
|
||
|----|------|------|
|
||
| 583030 ~ 583034 | 改前该端点的各校验分支 | **不再可达**;号位保留,未释放给他人 |
|
||
|
||
现在唯一的响应就是路由未命中:
|
||
|
||
```json
|
||
{
|
||
"code": 404,
|
||
"message": "接口不存在: POST /v3/admin/order/2098381549387882497/itinerary/save",
|
||
"data": null,
|
||
"traceId": null,
|
||
"success": false
|
||
}
|
||
```
|
||
|
||
#### 业务边界
|
||
|
||
- **下线是纯删除,不改变任何其它端点的行为。** 同 Controller 的其它行程端点(如 `GET /v3/admin/order/{id}/itinerary`)照常工作。
|
||
- **替代入口 `POST /v3/admin/order/{id}/adjustment/submit` 本单未做任何改动**,其行为、入参、错误码与改前完全一致。
|
||
- **不存在「数据迁移」问题**:被下线的端点从未写过库,所以没有它产生的数据需要清理或订正。
|
||
|
||
---
|
||
|
||
## 四、契约约束与正确调用方式
|
||
|
||
- **不要重试、不要降级兜底**:`POST .../itinerary/save` 现在恒为 `code=404`,重试不会变好。
|
||
- **行程整体保存请调 `POST /v3/admin/order/{orderId}/adjustment/submit`**。
|
||
- **不要把改前的 200 当成保存成功的历史证据**:它是 Mock 返回的 200,与落库无关。若有基于「调过 save 所以行程已改」的假设的页面逻辑或数据判断,那个假设改前就是错的。
|
||
- **错误码 583030-583034 号位不要复用**:它们保留给「整体保存真实化」的后续工单,本单未释放。
|
||
|
||
---
|
||
|
||
## 五、数据库行为
|
||
|
||
**本单零数据库变更**:无新增/修改表、无新增列、无新增索引、**无 Flyway 迁移脚本**、无 Mapper 改动。
|
||
|
||
被下线的端点**改前就不写库**(Mock 实现),因此下线**不产生任何数据影响**:
|
||
- `order_itinerary_day` / `order_itinerary_node` 的既有数据**不受影响**,一行不动;
|
||
- 没有「该端点写出来的数据」需要清理或订正 —— 它从未写出过任何数据。
|
||
|
||
清单里虽是 POST(写方法),但其**改前的实际写库行为为零**,下线后同样为零。
|
||
|
||
---
|
||
|
||
## 六、边界行为
|
||
|
||
| 场景 | 行为 |
|
||
|---|---|
|
||
| 调 `POST .../itinerary/save`,orderId 真实存在 | `code=404`「接口不存在」 |
|
||
| 调 `POST .../itinerary/save`,orderId 不存在 | `code=404`「接口不存在」(与上一行**同样的响应**,不因 id 是否存在而不同) |
|
||
| body 传空 / 传错 / 不传 | 一律 `code=404`(路由层就没命中,不会走到参数校验) |
|
||
| 调同 Controller 的其它行程端点 | **照常 200**,不受影响 |
|
||
| 调替代入口 `adjustment/submit` | **照常工作**,本单未改动 |
|
||
|
||
## 六.6、修改前后对比
|
||
|
||
| 维度 | 改前 | 改后 |
|
||
|---|---|---|
|
||
| `POST /v3/admin/order/{orderId}/itinerary/save` | 路由存在,返 `code=200` | **端点不存在**,返 `code=404` |
|
||
| 该端点的**落库行为** | **零**(Mock,只回显入参 id) | 零(端点已不存在) |
|
||
| `updatedNodeIds` 的含义 | 请求入参的原样回显 | — |
|
||
| `ItinerarySaveReqVO` / `ItinerarySaveRespVO` | 存在 | **已删除** |
|
||
| 错误码 583030-583034 | 声明在该端点上 | **号码与符号原样保留**,仅不再可达 |
|
||
| `POST /v3/admin/order/{id}/adjustment/submit` | 行程改动的真实入口 | **完全不变** |
|
||
| 同 Controller 其它行程端点 | — | **完全不变** |
|
||
| 网关路由配置 | — | **未改动**(`/v3/admin/**` 通配,无需删路由行) |
|
||
|
||
## 六.7、影响评估
|
||
|
||
- **兼容性**:下线前已穷举确认 `mmg/hl-ui` **4 条远端分支全部 0 命中**(含字符串拼接形态),**前端预期无需任何改动**。若某个未纳入这 4 条 ref 的本地分支仍在调用,它会从「200 但什么也没保存」变成「404」—— **后者更诚实**,且迁移目标明确(`adjustment/submit`)。
|
||
- **数据影响**:**零**。该端点从未落库,下线不丢任何数据、不需要任何数据订正。
|
||
- **需要前端动的**:正常情况下无。若发现有调用点,改调 `POST /v3/admin/order/{orderId}/adjustment/submit`。
|
||
- **性能**:无影响(删除的是一段空操作代码路径)。
|
||
- **不影响任何其它服务**:本单只改 order-v3,不动网关、不动 hl-common、不动其它微服务。
|
||
|
||
---
|
||
|
||
## 七、不影响范围
|
||
|
||
- **`POST /v3/admin/order/{id}/adjustment/submit`(订单调整提交)一行未改** —— 行程改动的真实入口,行为与错误码完全不变。
|
||
- **`ItineraryAdminController` 的其它行程端点全部不动**(仅删了 `batchSave` 一个方法,并在类 javadoc 追加下线备注)。
|
||
- **`order_itinerary_day` / `order_itinerary_node` 两张表零变更**,既有数据一行不动。
|
||
- **`ItineraryErrorCode` 的常量号码与符号一个未改**,只加 javadoc 说明。
|
||
- **网关路由零改动**、**Flyway 零新增**、**hl-common / hl-mp-service / hl-fleet-service 零改动**。
|
||
- **小程序端(mp 域)零影响**。
|
||
|
||
---
|
||
|
||
## 八、测试环境已验证
|
||
|
||
**部署**:`hl-order-service-v3` @ `fix/7531-itinerary-save-offline` / `54d9cbe64`(已合并 dev-v3 = `2bd01e6bc`),双实例滚动重启完成。**全部实测经真实网关 `api.test.1814.love:9443` + Bearer 鉴权**。
|
||
|
||
### 端点已下线(两条,覆盖「id 不存在」与「id 真实存在」)
|
||
|
||
```
|
||
POST /v3/admin/order/60001/itinerary/save
|
||
body: {"days":[{"id":7700000000003,"dayNumber":1,"title":"x"}]}
|
||
-> {"code":404,"message":"接口不存在: POST /v3/admin/order/60001/itinerary/save","success":false}
|
||
|
||
POST /v3/admin/order/2098381549387882497/itinerary/save ← 真实存在的订单 id
|
||
-> {"code":404,"message":"接口不存在: POST /v3/admin/order/2098381549387882497/itinerary/save","success":false}
|
||
```
|
||
|
||
### 阳性对照(证明不是整个 Controller 或服务挂了、也不是网关路由整体丢失)
|
||
|
||
```
|
||
GET /v3/admin/order/2098381549387882497/itinerary -> code=200 同 Controller 的其它端点仍在
|
||
POST /v3/admin/order/.../adjustment/submit -> code=587002 替代入口路由仍在,且走到了业务层
|
||
```
|
||
|
||
### 前端调用面调查(AC-1,每条 ref 都带阳性对照)
|
||
|
||
| ref | commit | 日期 | `itinerary/save` | `itinerary/${` | `adjustment/submit`(阳性对照) |
|
||
|---|---|---|---|---|---|
|
||
| `origin/v2.1` | `36c9064a` | 2026-09-12 | **0** | 0 | 6 文件 ✅ |
|
||
| `origin/master` | `68075168` | 2026-08-15 | **0** | 0 | 1 文件 ✅ |
|
||
| `origin/v1` | `fb0abc68` | 2026-08-15 | **0** | 0 | 1 文件 ✅ |
|
||
| `origin/v2` | `157ba864` | 2026-04-30 | **0** | 0 | 0 ⚠️ 见下 |
|
||
|
||
`origin/v2` 的阳性对照为 0,孤立的零结果没有分辨力,故补两条独立判据:① 后端端点诞生于 2026-05-12,比该 ref 冻结的 2026-04-30 **晚 12 天**,不可能被它调用;② 该 ref 上 `/v3/admin/order` **0 个文件**命中(对照 `http.post` 命中 53 个文件,证明 grep 在该 ref 上工作正常)。
|
||
|
||
### 本地全量单测
|
||
|
||
`mvn -o -pl hl-order-service-v3 -am test` → **`Tests run: 9941, Failures: 0, Errors: 13, Skipped: 49`**。
|
||
13 个 Errors 全部是 Testcontainers 找不到 Docker(跑全量前停了本机 colima 腾内存),与本单零交集。
|
||
门禁:`RedLineArchTest` 12/12 绿、`MapperBoundaryArchTest` 26/26 绿。
|
||
|
||
---
|
||
|
||
## 十、相关文档
|
||
|
||
- Issue:https://git.1814.love:8443/wx/HL/issues/7531
|
||
- PR:https://git.1814.love:8443/wx/HL/pulls/7570
|
||
- 端点诞生提交:`e0fc9de5d`(2026-05-12,「6 接口空骨架 + Mock ServiceImpl」#2011)
|
||
- 下线备注存档:`hl-order-service-v3/src/main/java/com/hulalv/order/itinerary/controller/admin/ItineraryAdminController.java` 类 javadoc
|
||
- 替代入口:`POST /v3/admin/order/{id}/adjustment/submit`
|
||
|
||
---
|
||
|
||
## 关联 / 联系人
|
||
|
||
- 后端:jw
|
||
- 前端(hl-ui 管理后台):mmg
|