diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index 4e915ee..644be13 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -50,7 +50,7 @@ - [x] **DEVICE-01**: 设备模型字段扩展 — DB 迁移新增 `online_status / last_online_time / software_version / switch_mode / last_gateway_sync_at` - [x] **DEVICE-02**: Gateway sync-info 同步接口对接 — `internal/gateway/device.go` 新增 `SyncDeviceInfo()` 方法 - [x] **DEVICE-03**: `tb_device_sim_binding` 新增 `is_current` 字段 — DB 迁移 + Model + 更新逻辑 -- [ ] **DEVICE-04**: 设备 Refresh + 详情接入 sync-info — `RefreshDevice()` 在刷新卡数据后调用 `SyncDeviceInfo()`,更新设备在线状态/固件版本/当前卡标识 +- [x] **DEVICE-04**: 设备 Refresh + 详情接入 sync-info — `RefreshDevice()` 在刷新卡数据后调用 `SyncDeviceInfo()`,更新设备在线状态/固件版本/当前卡标识 ### REFUND — 退款完整功能(方案 I) @@ -145,7 +145,7 @@ | DEVICE-01 | Phase 3 | Complete | | DEVICE-02 | Phase 3 | Complete | | DEVICE-03 | Phase 3 | Complete | -| DEVICE-04 | Phase 3 | Pending | +| DEVICE-04 | Phase 3 | Complete | | REFUND-01 | Phase 4 | Pending | | REFUND-02 | Phase 4 | Pending | | REFUND-03 | Phase 4 | Pending | diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index b11e1d6..4ab9d52 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -12,7 +12,7 @@ - [x] **Phase 1: P0 紧急修复** — 修复所有阻塞主链路的 P0 Bug,使充值→购包→佣金→实名激活全链路可跑通 (completed 2026-03-27) - [x] **Phase 2: 权限/财务/实名/轮询修复** — 补全企业权限、提现财务流程、实名激活架构重构、轮询系统小修 (completed 2026-03-28) -- [ ] **Phase 3: 设备体系完善** — 扩展设备模型字段、对接 Gateway sync-info、完善绑卡标识 +- [x] **Phase 3: 设备体系完善** — 扩展设备模型字段、对接 Gateway sync-info、完善绑卡标识 (completed 2026-03-28) - [ ] **Phase 4: 退款 + 支付 + 运营修复** — 实现退款完整流程、补全富友支付接口、修复运营逻辑 - [ ] **Phase 5: 代码质量清理** — 消除技术债务:佣金断链可观测、删废弃代码、修复权限不一致、迁移分层 - [ ] **Phase 6: 流量体系改革(低峰期)** — 破坏性变更:日粒度流量表 + Redis 增量缓存 + 每日落盘任务 @@ -74,7 +74,7 @@ Plans: Plans: - [x] 03-01-PLAN.md — DEVICE-01/02/03:DB 迁移 + 模型扩展 + Gateway SyncDeviceInfo + DTO 字段(Wave 1) -- [ ] 03-02-PLAN.md — DEVICE-04:Asset Service 接入 sync-info,Refresh 追加设备状态同步(Wave 2) +- [x] 03-02-PLAN.md — DEVICE-04:Asset Service 接入 sync-info,Refresh 追加设备状态同步(Wave 2) --- @@ -128,7 +128,7 @@ Plans: |-------|----------------|--------|-----------| | 1. P0 紧急修复 | 5/5 | Complete | 2026-03-27 | | 2. 权限/财务/实名/轮询修复 | 2/2 | Complete | 2026-03-28 | -| 3. 设备体系完善 | 1/2 | In Progress| | +| 3. 设备体系完善 | 2/2 | Complete | 2026-03-28 | | 4. 退款 + 支付 + 运营修复 | 0/TBD | Not started | - | | 5. 代码质量清理 | 0/TBD | Not started | - | | 6. 流量体系改革(低峰期)| 0/TBD | Not started | - | diff --git a/.planning/STATE.md b/.planning/STATE.md index 1b23ca1..54e3e89 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -3,12 +3,12 @@ gsd_state_version: 1.0 milestone: v1.0 milestone_name: milestone status: unknown -last_updated: "2026-03-28T03:33:58.201Z" +last_updated: "2026-03-28T03:39:07.174Z" progress: total_phases: 6 - completed_phases: 2 + completed_phases: 3 total_plans: 9 - completed_plans: 8 + completed_plans: 9 --- # Project State — 君鸿卡管系统 @@ -52,7 +52,7 @@ Progress: [ 1 ]──[ 2 ]──[ 3 ]──[ 4 ]──[ 5 ]──[ 6 ] |-------|------|--------------|--------| | 1 | P0 紧急修复 | CRITICAL-01~08(8项) | ✓ Complete (2026-03-28) | | 2 | 权限/财务/实名/轮询修复 | PERM-01~02, FIN-01~03, REALNAME-01~05, POLL-01~04(14项) | ✓ Complete (2026-03-28) | -| 3 | 设备体系完善 | DEVICE-01~04(4项) | ○ Not started | +| 3 | 设备体系完善 | DEVICE-01~04(4项) | ✓ Complete (2026-03-28) | | 4 | 退款 + 支付 + 运营修复 | REFUND-01~03, PAY-01~04, OPS-01~02(9项) | ○ Not started | | 5 | 代码质量清理 | CLEAN-01~06(6项) | ○ Not started | | 6 | 流量体系改革(低峰期)| TRAFFIC-01~05(5项) | ○ Not started | @@ -72,6 +72,7 @@ Progress: [ 1 ]──[ 2 ]──[ 3 ]──[ 4 ]──[ 5 ]──[ 6 ] --- | Phase 03-device-system P01 | 8min | 2 tasks | 10 files | +| Phase 03-device-system P02 | 10min | 2 tasks | 3 files | ## Execution Log @@ -95,8 +96,10 @@ Progress: [ 1 ]──[ 2 ]──[ 3 ]──[ 4 ]──[ 5 ]──[ 6 ] - REALNAME-01~05 是原子重构,必须在一个 plan 内完整执行,不可拆分 - REFUND 退款佣金回扣(REFUND-03)必须使用整数算术,禁用 float64 - CRITICAL-02 依赖 CRITICAL-01,CRITICAL-05 依赖 CRITICAL-04 -- DEVICE-02/03/04 依赖 DEVICE-01(字段扩展先行) +- DEVICE-02/03/04 依赖 DEVICE-01(字段扩展先行)✓ Phase 03 完成 - REFUND-02/03 依赖 REFUND-01(数据模型先行) +- DEVICE-04: gatewayClient nil guard 可选注入,sync-info 失败仅记 Warn 不阻断 Refresh 主流程 +- UpdateIsCurrentByDeviceID 事务两步原子更新 is_current,保证同一设备唯一 is_current=true ### Architecture Notes @@ -117,7 +120,7 @@ Progress: [ 1 ]──[ 2 ]──[ 3 ]──[ 4 ]──[ 5 ]──[ 6 ] ## Session Continuity -**Next Action:** Run `/gsd-plan-phase 3` to create detailed plan for Phase 3 (设备体系完善) +**Next Action:** Run `/gsd-plan-phase 4` to create detailed plan for Phase 4 (退款 + 支付 + 运营修复) **Context Files:** @@ -128,4 +131,4 @@ Progress: [ 1 ]──[ 2 ]──[ 3 ]──[ 4 ]──[ 5 ]──[ 6 ] - `.sisyphus/plans/修正业务-完整方案.md` — 每个 Bug 的完整修复规格(含代码片段) --- -*State initialized: 2026-03-27 | Last phase completed: Phase 2 (2026-03-28)* +*State initialized: 2026-03-27 | Last phase completed: Phase 3 (2026-03-28)* diff --git a/.planning/phases/03-device-system/03-02-SUMMARY.md b/.planning/phases/03-device-system/03-02-SUMMARY.md new file mode 100644 index 0000000..9e3d544 --- /dev/null +++ b/.planning/phases/03-device-system/03-02-SUMMARY.md @@ -0,0 +1,83 @@ +--- +phase: 03-device-system +plan: "02" +subsystem: device +tags: [service, gateway, sync-info, store, bootstrap] +dependency_graph: + requires: + - Plan 03-01(tb_device 5字段 + tb_device_sim_binding.is_current + Gateway SyncDeviceInfo 方法) + provides: + - DeviceSimBindingStore.UpdateIsCurrentByDeviceID(事务原子更新 is_current) + - asset.Service.updateDeviceFromSyncInfo(私有函数,同步 5 个设备字段 + is_current) + - asset.Service.Refresh device 分支接入 SyncDeviceInfo(nil guard + Warn 日志) + - asset.Service 注入 gatewayClient + affects: + - DEVICE-04 需求(设备 Refresh + 详情接入 sync-info) +tech_stack: + added: [] + patterns: + - GORM Transaction 两步原子更新模式 + - Service nil guard 可选依赖注入模式 + - ISO 8601 字符串 → time.Time(time.RFC3339) +key_files: + created: [] + modified: + - internal/store/postgres/device_sim_binding_store.go + - internal/service/asset/service.go + - internal/bootstrap/services.go +decisions: + - "gatewayClient 使用 nil guard(而非断言非 nil),允许 bootstrap 传入 nil 依然安全运行" + - "sync-info 失败只记 Warn 日志,不阻断 Refresh 主流程(非关键步骤,D-15 决策)" + - "UpdateIsCurrentByDeviceID 事务两步:先全清 false,再按 ICCID 设 true(原子保证唯一 is_current)" +metrics: + duration: "10min" + completed_date: "2026-03-28" + tasks: 2 + files: 3 +--- + +# Phase 03 Plan 02: Gateway sync-info 接入 Refresh 流程 Summary + +**一句话总结:** 在设备 Refresh 流程末尾接入 Gateway SyncDeviceInfo,通过 updateDeviceFromSyncInfo 原子更新在线状态、固件版本等 5 个设备字段及 is_current 当前卡标识(DEVICE-04)。 + +## Tasks Completed + +| Task | Name | Commit | Files | +|------|------|--------|-------| +| 1 | DeviceSimBindingStore 新增 UpdateIsCurrentByDeviceID 方法 | `ba1886c` | device_sim_binding_store.go | +| 2 | Asset Service 注入 gatewayClient + 实现 updateDeviceFromSyncInfo + Refresh 接入 sync-info | `15dbf8d` | service.go, services.go | + +## Artifacts Delivered + +### Store 层 + +- **UpdateIsCurrentByDeviceID**:事务两步原子更新。第一步将设备所有活跃绑定的 `is_current` 清为 false;第二步通过子查询定位 `current_iccid` 对应的 `iot_card_id`,将该绑定设为 `is_current = true`。`currentIccid` 为空时仅清空。 + +### Service 层 + +- **Service 结构体**:新增 `gatewayClient *gateway.Client` 字段(允许 nil) +- **New() 构造函数**:新增 `gatewayClient *gateway.Client` 参数 +- **Refresh device 分支**:在设置冷却 Key 之后、`GetRealtimeStatus` 返回之前,增加 sync-info 调用逻辑(nil guard 保护,失败只记 Warn 日志) +- **updateDeviceFromSyncInfo 私有函数**: + 1. 解析 `last_online_time`(ISO 8601 → `*time.Time`,`time.RFC3339`) + 2. GORM Updates 更新 5 个字段:`online_status`、`software_version`、`switch_mode`、`last_gateway_sync_at`、`last_online_time`(非空时) + 3. 调用 `UpdateIsCurrentByDeviceID` 原子更新 `is_current` + +### Bootstrap 层 + +- **services.go**:`asset.New()` 调用末尾追加 `deps.GatewayClient` 参数 + +## Deviations from Plan + +None — 计划完全按预期执行。 + +## Verification + +- ✅ `go build ./...` 零新增编译错误 +- ✅ `updateDeviceFromSyncInfo` 方法存在于 `internal/service/asset/service.go` +- ✅ `Refresh` device 分支含 `gatewayClient.SyncDeviceInfo()` 调用(nil guard + Warn 日志) +- ✅ `UpdateIsCurrentByDeviceID` 存在于 `internal/store/postgres/device_sim_binding_store.go` +- ✅ `internal/bootstrap/services.go` asset.New() 传入了 `deps.GatewayClient` +- ✅ sync-info 失败时只记录 Warn,不影响 Refresh 主流程 + +## Self-Check: PASSED