Files
junhong_cmp_fiber/.planning/phases/03-device-system/03-CONTEXT.md
2026-03-28 11:16:02 +08:00

6.8 KiB
Raw Blame History

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 Decisions

Plan 分组策略

  • D-01: 拆分为 2 个 Plan
    • Plan 1基础层D-0迁移+模型+DTO+ D-1Gateway SyncDeviceInfo 方法)+ D-2is_current 字段)
    • Plan 2功能层D-3Refresh 接入 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_extensiontb_device 新增 5 个字段
    • 000091_device_sim_binding_is_currenttb_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
    • BoundCardInfointernal/model/dto/asset_dto.go)—— 资产实时状态 Refresh 响应中的绑定卡列表
    • DeviceCardBindingResponseinternal/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 字段 parsingsync-info 返回字符串,需转换为 time.Time的具体格式agent 参考 Gateway 文档中的 last_update_time 示例格式
  • DeviceRealtimeInfo 独立 DTO 结构不创建(不暴露实时字段,无需此结构)
  • updateDeviceFromSyncInfo 的 DB 更新使用 GORM Updates(map[string]any{...}),不用 Save()(避免全字段覆写)

<canonical_refs>

Canonical References

Downstream agents MUST read these before planning or implementing.

修复规格(核心参考)

  • .sisyphus/plans/修正业务-完整方案.md — 完整修复规格书,含每个需求的代码片段和人工验收清单:
    • 方案 DDEVICE-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-2BoundCardInfo 新增 is_current
  • internal/model/dto/device_dto.go — D-0DeviceResponse 新增 5 个字段D-2DeviceCardBindingResponse 新增 is_current
  • internal/gateway/models.go — D-1新增 SyncDeviceInfoReq / SyncDeviceInfoResp
  • internal/gateway/device.go — D-1新增 SyncDeviceInfo() 方法
  • internal/service/asset/service.go — D-3Refresh device 分支追加 sync-info 调用;新增 updateDeviceFromSyncInfo()
  • migrations/ — D-0000090_device_fields_extensionD-2000091_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 设置之前,已遍历完绑定卡之后)
  • BoundCardInfoasset_dto.go(被 AssetRealtimeStatusResponse 引用,多个 C 端和 B 端接口共用)

</code_context>

## Specific Ideas
  • 修正文档中 D-3 的代码片段提供了 updateDeviceFromSyncInfo 的函数骨架agent 应直接参考(文件:.sisyphus/plans/修正业务-完整方案.md 方案 D-3 段落)
  • SyncDeviceInfoResp.LastOnlineTime 字段类型用 stringGateway 返回字符串),在 updateDeviceFromSyncInfo 内按需 Parse
## Deferred Ideas
  • 设备实时字段rssi / battery_level / ssid 等)暴露到 Refresh 响应 —— 超出当前成功标准,考虑 Phase 4+ 或按需补充
  • DeviceRealtimeInfo 独立 DTO 结构 —— 若未来暴露实时字段时再创建

Phase: 03-device-system Context gathered: 2026-03-28