Files
junhong_cmp_fiber/openspec/changes/add-polling-card-status-with-verbose-log/tasks.md
huang 4a1e44f9e1
Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Has been cancelled
提案
2026-04-15 11:17:23 +08:00

5.0 KiB
Raw Blame History

1. 数据库迁移

  • 1.1 创建迁移文件 000120_add_polling_card_status.up.sqltb_polling_config 新增 card_status_check_interval INT NULLtb_iot_card 新增 last_card_status_check_at TIMESTAMPTZ NULL
  • 1.2 创建对应回滚文件 000120_add_polling_card_status.down.sqlDROP COLUMN 两列
  • 1.3 执行 make migrate-up 并验证:make migrate-version 确认 dirty=false使用 PostgreSQL MCP 验证两列已创建

2. 常量与配置

  • 2.1 pkg/constants/constants.go:轮询任务类型常量块新增 TaskTypePollingCardStatus = "polling:card_status"
  • 2.2 pkg/config/config.go:新增 PollingConfig struct { VerboseLog bool },在 Config 中加入 Polling PollingConfig 字段
  • 2.3 pkg/config/defaults/config.yaml:在 polling 配置区新增 verbose_log: false
  • 2.4 验证:LspDiagnostics 检查 pkg/constants/constants.gopkg/config/config.go 无报错

3. 数据模型更新

  • 3.1 internal/model/polling.goPollingConfig 结构体新增 CardStatusCheckInterval *intGORM column: card_status_check_interval
  • 3.2 internal/model/iot_card.goIotCard 结构体新增 LastCardStatusCheckAt *time.TimeGORM column: last_card_status_check_at
  • 3.3 验证:LspDiagnostics 检查两个 model 文件无报错

4. PollingBase 新增 verboseLog 支持

  • 4.1 internal/task/polling_base.goPollingBase 结构体新增 verboseLog bool 字段;NewPollingBase 函数签名新增 verboseLog bool 参数并赋值
  • 4.2 cmd/worker/main.gotask.NewPollingBase(...) 调用新增 cfg.Polling.VerboseLog 参数
  • 4.3 验证:LspDiagnostics 检查 polling_base.gomain.go 无报错

5. 现有 Handler 添加 verbose 日志

  • 5.1 internal/task/polling_realname_handler.go:在 QueryRealnameStatus 成功返回后,判断 h.base.verboseLog 为 true 时输出 Info 日志card_id、iccid、real_status、new_status、changed
  • 5.2 internal/task/polling_carddata_handler.go:在 QueryFlow 成功返回后,判断 h.base.verboseLog 为 true 时输出 Info 日志card_id、iccid、gateway_flow_mb、increment_mb、is_cross_month
  • 5.3 internal/task/polling_package_handler.go:在 freshCard 加载成功后、调用 EvaluateAndAct 之前,判断 h.base.verboseLog 为 true 时输出 Info 日志card_id、iccid、network_status、stop_reason
  • 5.4 internal/task/polling_protect_handler.go:在 switch 块执行完毕、UpdateFields(last_protect_check_at) 之前,判断 h.base.verboseLog 为 true 时输出 Info 日志card_id、iccid、stop_protect、start_protect、network_status
  • 5.5 验证:LspDiagnostics 检查上述 4 个 handler 文件无报错

6. 卡状态轮询 Handler 实现

  • 6.1 新建 internal/task/polling_cardstatus_handler.go:实现 PollingCardStatusHandler字段base、gateway、iotCardStore、stopResumeSvc完整实现 Handle 方法
  • 6.2 Handle 方法逻辑:获取并发信号量 → 获取卡信息(带缓存)→ 调用 gateway.QueryCardStatus → 映射状态("停机"→0其他→1→ verbose log 判断 → 比较状态是否变化 → 写 DBlast_card_status_check_at + 可选 network_status)→ 状态变化时更新缓存并调用 EvaluateAndAct → 更新统计 → 重入队
  • 6.3 验证:LspDiagnostics 检查新文件无报错

7. 轮询系统基础设施集成

  • 7.1 internal/task/polling_utils.gogetIntervalByTaskType 新增 case constants.TaskTypePollingCardStatus,返回 cfg.CardStatusCheckInterval
  • 7.2 internal/polling/queue_manager.goallTaskTypes slice 追加 constants.TaskTypePollingCardStatus
  • 7.3 internal/polling/lifecycle_service.gogetEnabledTaskTypes 新增 card_status 条件(CardStatusCheckInterval != nil && *CardStatusCheckInterval > 0calcInitialDelay 新增对应 case
  • 7.4 internal/polling/initializer.go:在 initBatch() 的 if-block 链中新增一段,当 cfg.CardStatusCheckInterval != nil && *cfg.CardStatusCheckInterval > 0 时,以 card.LastCardStatusCheckAt(新增字段)为基准调用 calculateNextCheckTime,向 TaskTypePollingCardStatus 分片队列写入 ZAdd 条目;位置紧跟 ProtectCheckInterval 块之后,格式与其他 4 种类型一致
  • 7.5 验证:LspDiagnostics 检查上述 4 个文件无报错

8. Worker Handler 注册

  • 8.1 pkg/queue/handler.go:在 RegisterHandlers 中创建 cardStatusHandler := task.NewPollingCardStatusHandler(...) 并注册 h.mux.HandleFunc(constants.TaskTypePollingCardStatus, cardStatusHandler.Handle)
  • 8.2 验证:LspDiagnostics 检查 handler.go 无报错;go build ./cmd/worker/... 成功编译

9. 整体验证

  • 9.1 执行 go build ./... 确认整个项目编译通过
  • 9.2 使用 PostgreSQL MCP 验证迁移列已正确创建类型、NULL 约束)
  • 9.3 检查 make migrate-down && make migrate-up 回滚和重新迁移均成功