This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: 查询资产跨代历史订单(含前代)
|
||||
|
||||
当 `include_previous=true` 时,系统 SHALL 通过换货链追溯前代资产,返回前代订单,并在响应中区分世代来源。
|
||||
|
||||
**追溯逻辑**:
|
||||
1. 通过 `ExchangeOrder.new_asset_id` 逆向查找当前资产的换货来源
|
||||
2. 得到前代的 `old_asset_identifier`,查询该标识符的订单
|
||||
3. 递归追溯,最多向前 10 代(安全上限)
|
||||
4. 追溯范围 MUST 同时覆盖 `flow_type=shipping` 与 `flow_type=direct` 的已完成换货单
|
||||
5. 追溯 MUST 仅使用 `status=4` 的已完成换货单,禁止把发货中、取消或半成品记录纳入链路
|
||||
6. 历史记录若 `flow_type` 为空或缺失,系统 MUST 按 `shipping` 兼容处理
|
||||
|
||||
**响应结构(AssetOrdersResponse)**:
|
||||
```json
|
||||
{
|
||||
"current_generation": {
|
||||
"generation": 2,
|
||||
"identifier": "DEV-001",
|
||||
"asset_type": "device",
|
||||
"total": 5,
|
||||
"page": 1,
|
||||
"page_size": 20,
|
||||
"items": [ ...订单列表... ]
|
||||
},
|
||||
"previous_generations": [
|
||||
{
|
||||
"generation": 1,
|
||||
"identifier": "DEV-OLD-001",
|
||||
"asset_type": "device",
|
||||
"exchange_no": "EXC20260101XXXXXX",
|
||||
"exchanged_at": "2026-01-01T00:00:00Z",
|
||||
"total": 3,
|
||||
"items": [ ...前代订单列表(最近20条)... ]
|
||||
}
|
||||
],
|
||||
"truncated": false
|
||||
}
|
||||
```
|
||||
|
||||
`previous_generations[].exchanged_at` MUST 优先取换货单 `completed_at`,不得在 `completed_at` 存在时直接将 `updated_at` 视为真实换货完成时间。
|
||||
|
||||
若历史单据尚无 `completed_at`,系统 MUST 采用 `updated_at` 兼容回退策略;新完成单据 MUST 优先使用 `completed_at`。
|
||||
|
||||
#### Scenario: 查询 direct 换货后的全代际订单
|
||||
- **WHEN** 管理员请求 `GET /api/admin/assets/DEV-NEW-001/orders?include_previous=true`,且当前资产来自一次 `flow_type=direct` 的已完成换货
|
||||
- **THEN** `previous_generations` MUST 返回来源旧资产的订单链
|
||||
- **AND** `exchanged_at` MUST 返回该换货单的 `completed_at`
|
||||
|
||||
#### Scenario: 查询 shipping 换货后的全代际订单
|
||||
- **WHEN** 管理员请求 `GET /api/admin/assets/DEV-001/orders?include_previous=true`,DEV-001 来自一次 `flow_type=shipping` 的已完成换货
|
||||
- **THEN** `current_generation` 包含 DEV-001 本代的订单
|
||||
- **AND** `previous_generations[0]` 包含来源旧资产的订单,并附带换货单号和真实完成时间
|
||||
|
||||
#### Scenario: 未完成换货单不进入追溯链
|
||||
- **WHEN** 当前资产只存在 `status=3` 的发货待确认换货单来源记录
|
||||
- **THEN** `include_previous=true` MUST NOT 将该换货单作为前代来源
|
||||
|
||||
#### Scenario: 历史完成单据回退完成时间
|
||||
- **WHEN** 前代来源换货单 `status=4` 但 `completed_at` 为空
|
||||
- **THEN** `previous_generations[].exchanged_at` MUST 使用该换货单 `updated_at` 兼容回退
|
||||
|
||||
#### Scenario: 资产本身就是第一代(无前代)
|
||||
- **WHEN** 管理员请求带 `include_previous=true`,但该资产从未经过换货
|
||||
- **THEN** `previous_generations` 为空数组 `[]`
|
||||
- **AND** `current_generation` 正常返回本代订单
|
||||
|
||||
#### Scenario: 换货链超过追溯上限
|
||||
- **WHEN** 换货链深度超过 10 代
|
||||
- **THEN** 追溯在第 10 代截断,`truncated=true`
|
||||
- **AND** 已追溯到的前代数据正常返回
|
||||
|
||||
#### Scenario: 前代订单分页
|
||||
- **WHEN** 请求带 `include_previous=true`
|
||||
- **THEN** 分页参数(page/page_size)只对 `current_generation` 的订单生效
|
||||
- **AND** 前代订单每代最多返回 20 条(不支持前代内分页)
|
||||
|
||||
#### Scenario: 无 include_previous 时响应不含前代字段
|
||||
- **WHEN** 管理员请求不带 `include_previous=true`(或传 false)
|
||||
- **THEN** 响应结构中 `previous_generations` 字段为 null 或不返回,节省带宽
|
||||
Reference in New Issue
Block a user