## Why

功能 ID：`feature-direct-exchange-flow`

现有换货系统只支持“后台建单 → 客户填写收货地址 → 后台发货 → 后台确认完成”的单一路径，无法覆盖“直接换到新卡/新设备、无需发货”的业务场景。更关键的是，当前“换货单完成”“旧资产已换货标记”“客户绑定切换”“迁移事务提交”并不在同一事务边界内，已经存在完成语义和资产真实状态不一致的风险。

本次变更需要在保留原 `shipping` 流程的前提下，补充 `direct` 流程，并把换货完成的核心语义收敛为可审计、可追溯、可直接落地实现的单事务闭环。

## What Changes

- 为换货单引入 `flow_type`，区分 `shipping` 与 `direct` 两种流程类型，而不是复用状态字段硬编码不同分支。
- `flow_type` 对旧客户端保持兼容：后台创建接口未传时按 `shipping` 处理；传入非法值必须拒绝。
- 扩展换货单模型与接口契约，补充 `shipped_at`、`completed_at` 等真实业务时间字段，并在创建接口中支持 `direct` 流程所需的 `new_identifier`、`migrate_data`。
- 保留原 `shipping` 状态机：`1 待填写信息 -> 2 待发货 -> 3 已发货待确认 -> 4 已完成`，且 `1/2 -> 5 已取消`。
- 新增 `direct` 流程：后台创建换货单时即可完成，直接进入 `status=4`，不经过客户端填写地址和后台发货。
- `direct` 创建必须是原子动作：任一校验、必做切换或可选迁移失败时，整笔事务回滚且不保留半成品换货单。
- 将“完成换货”拆分为两个层次并统一纳入单事务：
  - 必做切换：写入新资产快照、旧资产 `asset_status -> 3`、新资产 `asset_status -> 2`、客户绑定切到新资产、换货单写完成时间并置为 `4`。
  - 可选迁移：仅在 `migrate_data=true` 时执行钱包余额、流水、套餐、标签、累计充值/首充状态等数据迁移。
- 明确“客户绑定切换到新资产”属于换货完成必做动作，而不是仅在 `migrate_data=true` 时才执行；若旧资产存在客户绑定但新资产无法承接绑定，整个完成动作必须失败并回滚。
- 明确资产准入边界：旧资产必须是 `asset_status=2` 已销售；新资产必须是 `asset_status=1` 在库、同类型、同归属店铺且未被有效客户绑定占用。
- 明确钱包迁移边界：旧资产钱包存在冻结余额时不得迁移，必须拒绝完成并回滚，避免未结业务资金被静默搬迁。
- 修正换货链追溯语义：资产历史订单中的 `exchanged_at` 必须取真实 `completed_at`，且追溯逻辑同时覆盖 `shipping` 与 `direct` 两种已完成单据。
- 历史已完成单据没有 `completed_at` 时，追溯接口按兼容策略回退到 `updated_at`；新完成单据必须写入 `completed_at`。
- 明确旧资产“转新”规则：仅在 `renew` 时执行 `generation + 1` 和重新入库；换货完成本身不改变 `generation`。

## Capabilities

### New Capabilities

- 无

### Modified Capabilities

- `exchange-order-model`：换货单模型新增流程类型与真实业务时间字段，并扩展状态机以同时表达 `shipping` 与 `direct`。
- `exchange-admin-management`：后台发起、发货、确认完成、取消、转新的接口契约与行为规则需要调整，以支持 `direct` 流程和完成换货单事务。
- `exchange-client-notification`：客户端待处理查询与填写收货地址逻辑仅适用于 `shipping` 流程。
- `exchange-data-migration`：将“完成换货必做切换”和“可选迁移”拆分，并统一到单事务边界。
- `personal-customer`：换货完成时的个人客户资产绑定切换规则需要调整，补充绑定无法承接时的失败语义。
- `asset-historical-orders`：换货链追溯的完成时间来源与追溯范围需要调整。
- `asset-lifecycle-status`：补充换货完成与转新对旧资产、新资产生命周期状态的业务流转规范。
- `asset-generation`：补充 `generation` 只在 `renew` 阶段递增、不在换货完成阶段变化的约束。
- `iot-card`：明确 IoT 卡在换货换出、换入、转新场景下的生命周期行为。
- `device`：明确设备在换货换出、换入、转新场景下的生命周期行为。

## Impact

- 受影响模型与 DTO：`internal/model/exchange_order.go`、`internal/model/dto/exchange_dto.go`，以及与 `IotCard`、`Device`、`PersonalCustomerDevice`、`AssetWallet` 相关的换货协作模型。
- 受影响服务与事务边界：`internal/service/exchange/service.go`、`internal/service/exchange/migration.go`、`internal/service/asset/service.go`。
- 受影响存储层：`internal/store/postgres/exchange_order_store.go` 及相关资产查询/绑定/钱包读写逻辑。
- 受影响接口：
  - 后台：`POST /api/admin/exchanges`、`GET /api/admin/exchanges`、`GET /api/admin/exchanges/:id`、`POST /api/admin/exchanges/:id/ship`、`POST /api/admin/exchanges/:id/complete`、`POST /api/admin/exchanges/:id/cancel`、`POST /api/admin/exchanges/:id/renew`
  - 客户端：`GET /api/c/v1/exchange/pending`、`POST /api/c/v1/exchange/:id/shipping-info`
- 受影响常量与状态语义：`pkg/constants/constants.go`、`pkg/constants/asset_status.go` 及状态文字映射。
- 受影响数据库结构：`tb_exchange_order` 需要新增 `flow_type`、`shipped_at`、`completed_at` 等字段，并调整相关索引与查询语义。
- 受影响文档与文档生成器：新增或修改 handler 后，必须同步更新 `cmd/api/docs.go` 与 `cmd/gendocs/main.go`。
