All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m21s
主要变更: - 新增 AssetIdentifier 模型及 Store,统一管理资产标识符(ICCID/IMEI/SN 等) - 新增迁移:asset_identifier 表、order 表新增 asset_identifier 字段、iot_card.virtual_no NOT NULL 约束 - 资产 Handler/Service/Route 全面重构,支持标识符路由查询与解析 - 新增资产历史订单查询接口,支持跨设备/卡/钱包维度的订单聚合 - 设备与物联卡导入任务强制校验虚拟号,缺失时直接拒绝 - Excel 工具函数优化,前端导入指引文档同步更新 - 归档三个 OpenSpec 提案:asset-identifier-standardization、asset-historical-orders、import-mandatory-virtual-no - 更新 OpenAPI 文档及相关 DTO Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
54 lines
3.7 KiB
Markdown
54 lines
3.7 KiB
Markdown
## Why
|
||
|
||
当前系统的 B 端资产操作接口大量使用数据库主键 ID(`/assets/:asset_type/:id/`、`/devices/:id/`)作为路径参数,导致接口语义模糊、前端被迫持有无业务含义的 ID、换货后旧 ID 失效等问题。与此同时,IoT 卡和设备的虚拟号(VirtualNo)没有跨表全局唯一约束,ICCID/VirtualNo 在多个子系统中的使用也不一致。现阶段系统尚处于开发测试期,是建立资产标识符规范的最佳窗口。
|
||
|
||
## What Changes
|
||
|
||
- **[BREAKING]** B 端资产操作接口路径参数统一改为资产标识符(ICCID 或 VirtualNo),废弃基于数据库主键 ID 的路由
|
||
- **[BREAKING]** 订单创建接口(B 端 + C 端)从传入 `iot_card_id`/`device_id` 主键改为传入 `identifier` 标识符
|
||
- **[NEW]** 新增全局资产标识符注册表 `tb_asset_identifier`,在数据库层保证 ICCID/VirtualNo 跨 `tb_iot_card` 和 `tb_device` 两表全局唯一,防止并发写入冲突
|
||
- **[NEW]** 资产解析服务(Resolve)主路径改走注册表,单次查询即可定位资产,替代原有的跨表 OR 查询
|
||
- **[FIX]** 修复:已绑定设备的 IoT 卡(`is_standalone=false`)可被单独购买套餐的 Bug,改为直接报错并引导用户至设备页面购买
|
||
- 订单查询列表新增按资产标识符过滤条件
|
||
- 订单响应新增资产标识符字段,前端无需二次查询
|
||
- 所有 B 端 `:id` 路由同步更新,前端需切换调用方式
|
||
|
||
## Capabilities
|
||
|
||
### New Capabilities
|
||
|
||
- `asset-identifier-registry`:全局资产标识符注册表(`tb_asset_identifier`)的模型定义、写入/查询接口,以及 Resolve 服务的注册表主路径改造
|
||
- `asset-identifier-routes`:B 端统一标识符路由规范——将 `/assets/:asset_type/:id/*`、`/devices/:id/*`、`/iot-cards/:id/*` 全线迁移为 `/assets/:identifier/*`、`/devices/:virtual_no/*`
|
||
|
||
### Modified Capabilities
|
||
|
||
- `asset-resolve`:主查询路径改走 `tb_asset_identifier`;IMEI/SN/MSISDN 降级为 fallback 模糊查询
|
||
- `order-management`:CreateAdminOrderRequest 改用 `identifier`;OrderResponse 新增 `asset_identifier` 字段;OrderListRequest 新增 `identifier` 过滤条件
|
||
- `client-order-purchase`:CreateOrderRequest 改用 `identifier`,系统内部解析资产类型
|
||
- `package-purchase-validation`:新增 `is_standalone` 校验——若卡已绑定设备则拒绝单卡购买套餐
|
||
|
||
## Impact
|
||
|
||
**受影响的代码**:
|
||
- `internal/model/`:新增 `AssetIdentifier` 模型;`Order` 模型新增 `asset_identifier` 快照字段
|
||
- `internal/store/postgres/`:新增 `asset_identifier_store.go`;`order_store.go` 新增标识符过滤
|
||
- `internal/service/asset/`:`Resolve` 方法改走注册表
|
||
- `internal/service/purchase_validation/`:新增 `is_standalone` 校验
|
||
- `internal/handler/admin/`:`asset.go`、`device.go`、`iot_card.go`、`order.go` 全面更新路径参数和请求/响应 DTO
|
||
- `internal/handler/app/`:`client_order.go` 更新请求 DTO
|
||
- `internal/routes/`:`asset.go`、`device.go`、`iot_card.go`、`order.go` 路由重注册
|
||
- `internal/model/dto/`:`asset_dto.go`、`order_dto.go`、`client_order_dto.go` 字段变更
|
||
- `migrations/`:新增迁移文件创建 `tb_asset_identifier` 表
|
||
|
||
**受影响的 API(BREAKING)**:
|
||
- `GET /api/admin/assets/:asset_type/:id/*`(7 个端点)
|
||
- `POST /api/admin/assets/device/:device_id/stop|start`
|
||
- `DELETE /api/admin/devices/:id`
|
||
- `GET|POST|DELETE /api/admin/devices/:id/cards*`
|
||
- `PATCH /api/admin/devices/:id/deactivate`
|
||
- `PATCH /api/admin/iot-cards/:id/deactivate`
|
||
- `POST /api/admin/orders`(请求体变更)
|
||
- `POST /api/c/v1/orders/create`(请求体变更)
|
||
|
||
**前端影响**:所有使用 `asset_id` 做路径参数的页面必须切换为使用 `identifier`(ICCID 或 VirtualNo)
|