6.8 KiB
6.8 KiB
Phase 3: 设备体系完善 - Context
Gathered: 2026-03-28 Status: Ready for planning
## Phase Boundary扩展设备数据模型(D-0)、对接 Gateway sync-info 同步接口(D-1)、建立"当前使用卡"标识(D-2)、将刷新接口接入 sync-info 完成端到端数据更新(D-3)。
全部为修复性/完善性变更,无新业务模块。仅影响设备相关模型、Gateway 客户端、资产刷新服务。
## Implementation DecisionsPlan 分组策略
- D-01: 拆分为 2 个 Plan:
- Plan 1(基础层):D-0(迁移+模型+DTO)+ D-1(Gateway SyncDeviceInfo 方法)+ D-2(is_current 字段)
- Plan 2(功能层):D-3(Refresh 接入 sync-info + updateDeviceFromSyncInfo)
- D-02: Plan 1 内部执行顺序:D-0 先行(DB 迁移、Device Model、DeviceSimBinding Model、DTO 全部到位)→ D-1 + D-2 并行(都依赖 D-0,互不依赖)
- D-03: 每个子任务独立一个 commit(延续 Phase 1/2 粒度规范)
DB 迁移
- D-04: 迁移编号从
000090起,拆为 2 个迁移文件:000090_device_fields_extension:tb_device 新增 5 个字段000091_device_sim_binding_is_current:tb_device_sim_binding 新增 is_current 字段
- D-05: 使用
.up.sql/.down.sql双文件形式(与现有迁移规范一致)
Gateway 类型定义位置
- D-06:
SyncDeviceInfoReq/SyncDeviceInfoResp放在internal/gateway/models.go(与现有 DeviceInfoReq / SlotInfoResp 等结构保持风格一致) - D-07:
SyncDeviceInfo()方法放在internal/gateway/device.go(与现有 GetDeviceInfo / GetSlotInfo 等方法一起) - 修正文档中将类型嵌入 device.go 代码片段属于示意,不代表最终位置
实时字段暴露范围
- D-08: Refresh 响应中不暴露非存储实时字段(rssi / battery_level / ssid / wifi_enabled 等)
- D-09: 实时字段仅在调用 sync-info 时写入 DB 存储字段(online_status / last_online_time / software_version / switch_mode / last_gateway_sync_at)
- D-10: 这满足所有成功标准(标准 2、4 只要求存储字段同步)
is_current 字段的 DTO 同步范围
- D-11:
is_current同步到两处 DTO:BoundCardInfo(internal/model/dto/asset_dto.go)—— 资产实时状态 Refresh 响应中的绑定卡列表DeviceCardBindingResponse(internal/model/dto/device_dto.go)—— 设备管理页 ListDeviceCards 接口
- D-12: 两处同步,保持前端两个场景下的数据一致
updateDeviceFromSyncInfo 实现细节
- D-13:
updateDeviceFromSyncInfo为私有函数,位于internal/service/asset/service.go - D-14: is_current 更新使用事务:先全部设为 false,再把 current_iccid 对应行设为 true(原子操作,防止中间状态)
- D-15: sync-info 调用失败时不阻断刷新流程,仅记录 Warn 日志(
sync-info 调用失败)
Agent's Discretion
last_online_time/last_gateway_sync_at字段 parsing(sync-info 返回字符串,需转换为 time.Time)的具体格式,agent 参考 Gateway 文档中的last_update_time示例格式DeviceRealtimeInfo独立 DTO 结构不创建(不暴露实时字段,无需此结构)updateDeviceFromSyncInfo的 DB 更新使用 GORMUpdates(map[string]any{...}),不用Save()(避免全字段覆写)
<canonical_refs>
Canonical References
Downstream agents MUST read these before planning or implementing.
修复规格(核心参考)
.sisyphus/plans/修正业务-完整方案.md— 完整修复规格书,含每个需求的代码片段和人工验收清单:- 方案 D(DEVICE-01~04):约第 955-1130 行(D-0 字段策略 + D-1 Gateway 接口 + D-2 is_current + D-3 Refresh 接入)
Gateway 接口文档
docs/第三方文档/gateway设备详情同步接口.md— sync-info 接口完整字段说明(data 字段映射表、cardNo 规则、认证方式)
需要修改的核心文件
internal/model/device.go— D-0:新增 5 个 DB 字段internal/model/device_sim_binding.go— D-2:新增 is_current 字段internal/model/dto/asset_dto.go— D-2:BoundCardInfo 新增 is_currentinternal/model/dto/device_dto.go— D-0:DeviceResponse 新增 5 个字段;D-2:DeviceCardBindingResponse 新增 is_currentinternal/gateway/models.go— D-1:新增 SyncDeviceInfoReq / SyncDeviceInfoRespinternal/gateway/device.go— D-1:新增 SyncDeviceInfo() 方法internal/service/asset/service.go— D-3:Refresh device 分支追加 sync-info 调用;新增 updateDeviceFromSyncInfo()migrations/— D-0:000090_device_fields_extension;D-2:000091_device_sim_binding_is_current
现有参考实现
internal/service/asset/service.go:Refresh()— 约第 295 行,现有 device 刷新分支(追加 sync-info 调用入口)
</canonical_refs>
<code_context>
Existing Code Insights
Reusable Assets
internal/gateway/client.go:doRequestWithResponse[T]()— 泛型请求方法,SyncDeviceInfo 直接复用(与 GetDeviceInfo 相同调用模式)internal/service/asset/service.go:Refresh()— 已有 device 冷却 Key + 绑定卡遍历框架,D-3 在此追加 sync-info 调用internal/service/asset/service.go:deviceSimBindingStore— 已注入,D-3 的 updateDeviceFromSyncInfo 可直接使用
Established Patterns
- Gateway 类型分离:结构体在
models.go,方法在对应领域文件(device.go / flow_card.go 等) - DB 更新:使用
Updates(map[string]any{...})+Model(&T{})+Where,不用Save() - 错误处理:非关键步骤失败用
logger.Warn,关键步骤用errors.Wrap
Integration Points
internal/gateway/device.go— 新增 SyncDeviceInfo 方法internal/service/asset/service.go:Refresh()device 分支 —— sync-info 调用入口(冷却 Key 设置之前,已遍历完绑定卡之后)BoundCardInfo在asset_dto.go(被 AssetRealtimeStatusResponse 引用,多个 C 端和 B 端接口共用)
</code_context>
## Specific Ideas- 修正文档中 D-3 的代码片段提供了
updateDeviceFromSyncInfo的函数骨架,agent 应直接参考(文件:.sisyphus/plans/修正业务-完整方案.md方案 D-3 段落) SyncDeviceInfoResp.LastOnlineTime字段类型用string(Gateway 返回字符串),在 updateDeviceFromSyncInfo 内按需 Parse
- 设备实时字段(rssi / battery_level / ssid 等)暴露到 Refresh 响应 —— 超出当前成功标准,考虑 Phase 4+ 或按需补充
- DeviceRealtimeInfo 独立 DTO 结构 —— 若未来暴露实时字段时再创建
Phase: 03-device-system Context gathered: 2026-03-28