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

58 lines
5.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## 1. 数据库迁移
- [ ] 1.1 创建迁移文件 `000120_add_polling_card_status.up.sql``tb_polling_config` 新增 `card_status_check_interval INT NULL``tb_iot_card` 新增 `last_card_status_check_at TIMESTAMPTZ NULL`
- [ ] 1.2 创建对应回滚文件 `000120_add_polling_card_status.down.sql`DROP 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.go``pkg/config/config.go` 无报错
## 3. 数据模型更新
- [ ] 3.1 `internal/model/polling.go``PollingConfig` 结构体新增 `CardStatusCheckInterval *int`GORM column: `card_status_check_interval`
- [ ] 3.2 `internal/model/iot_card.go``IotCard` 结构体新增 `LastCardStatusCheckAt *time.Time`GORM column: `last_card_status_check_at`
- [ ] 3.3 验证:`LspDiagnostics` 检查两个 model 文件无报错
## 4. PollingBase 新增 verboseLog 支持
- [ ] 4.1 `internal/task/polling_base.go``PollingBase` 结构体新增 `verboseLog bool` 字段;`NewPollingBase` 函数签名新增 `verboseLog bool` 参数并赋值
- [ ] 4.2 `cmd/worker/main.go``task.NewPollingBase(...)` 调用新增 `cfg.Polling.VerboseLog` 参数
- [ ] 4.3 验证:`LspDiagnostics` 检查 `polling_base.go``main.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 判断 → 比较状态是否变化 → 写 DB`last_card_status_check_at` + 可选 `network_status`)→ 状态变化时更新缓存并调用 `EvaluateAndAct` → 更新统计 → 重入队
- [ ] 6.3 验证:`LspDiagnostics` 检查新文件无报错
## 7. 轮询系统基础设施集成
- [ ] 7.1 `internal/task/polling_utils.go``getIntervalByTaskType` 新增 `case constants.TaskTypePollingCardStatus`,返回 `cfg.CardStatusCheckInterval`
- [ ] 7.2 `internal/polling/queue_manager.go``allTaskTypes` slice 追加 `constants.TaskTypePollingCardStatus`
- [ ] 7.3 `internal/polling/lifecycle_service.go``getEnabledTaskTypes` 新增 card_status 条件(`CardStatusCheckInterval != nil && *CardStatusCheckInterval > 0``calcInitialDelay` 新增对应 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` 回滚和重新迁移均成功