7.2 KiB
phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, must_haves
| phase | plan | type | wave | depends_on | files_modified | autonomous | requirements | must_haves | |||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 01-p0 | 02 | execute | 2 |
|
|
true |
|
|
Purpose: 首次实名后自动激活"囤货套餐"的完整链路当前完全断裂——task 被 _ = task 丢弃,实际走 Redis RPush 降级,但无消费者消费这个列表。修复后套餐激活任务正常进入 Asynq 队列被消费。
Output:
- polling_handler.go: 新增 asynqClient 字段,triggerFirstRealnameActivation 改为 EnqueueContext
- pkg/queue/handler.go: registerPollingHandlers 传入 h.asynqClient
<execution_context> @$HOME/.config/opencode/get-shit-done/workflows/execute-plan.md @$HOME/.config/opencode/get-shit-done/templates/summary.md </execution_context>
@.planning/phases/01-p0/01-01-SUMMARY.md @.planning/phases/01-p0/01-CONTEXT.md修复规格书(方案 A-3,第 165-299 行)
@.sisyphus/plans/修正业务-完整方案.md
```go // pkg/queue/handler.go Handler struct(已存在) type Handler struct { db *gorm.DB redis *redis.Client asynqClient *asynq.Client // ← 已有此字段,直接传给 NewPollingHandler // ... }// registerPollingHandlers 当前调用(需修改) pollingHandler := task.NewPollingHandler( h.db, h.redis, // h.asynqClient ← 缺少此行 h.gatewayClient, h.workerResult.Services.UsageService, h.logger, )
<!-- polling_handler.go 当前错误代码(triggerFirstRealnameActivation 第 1100 行) -->
```go
// 当前降级代码(需删除 RPush 部分,直接用 EnqueueContext)
task := asynq.NewTask(constants.TaskTypePackageFirstActivation, payloadBytes, ...)
activationKey := constants.RedisPollingManualQueueKey(constants.TaskTypePackageFirstActivation)
h.redis.RPush(ctx, activationKey, string(payloadBytes)) // ← 删掉
_ = task // ← 删掉
在 PollingHandler struct(第 31-42 行附近)新增字段:
type PollingHandler struct {
db *gorm.DB
redis *redis.Client
asynqClient *asynq.Client // 新增
gatewayClient *gateway.Client
// ... 其余字段不变
}
步骤 2:修改 NewPollingHandler 构造函数签名(第 44 行附近)
新增 asynqClient *asynq.Client 参数(位置:redis 之后,gatewayClient 之前):
func NewPollingHandler(
db *gorm.DB,
redis *redis.Client,
asynqClient *asynq.Client, // 新增
gatewayClient *gateway.Client,
usageService *packagepkg.UsageService,
logger *zap.Logger,
) *PollingHandler {
return &PollingHandler{
db: db,
redis: redis,
asynqClient: asynqClient, // 新增
gatewayClient: gatewayClient,
// ... 其余字段不变
}
}
步骤 3:修改 triggerFirstRealnameActivation(第 1100 行附近)
删除 RPush 降级代码,改为 EnqueueContext:
// 删除这两行:
// activationKey := constants.RedisPollingManualQueueKey(constants.TaskTypePackageFirstActivation)
// h.redis.RPush(ctx, activationKey, string(payloadBytes))
// _ = task
// 替换为:
if _, err := h.asynqClient.EnqueueContext(ctx, task); err != nil {
h.logger.Warn("提交首次实名激活任务失败",
zap.Uint("package_usage_id", pkg.ID),
zap.Error(err))
continue
}
注意:task 变量已在上方声明,不需要重新创建。
步骤 4:修改 pkg/queue/handler.go:registerPollingHandlers(第 151 行附近)
在 NewPollingHandler 调用中补充 h.asynqClient 参数:
pollingHandler := task.NewPollingHandler(
h.db,
h.redis,
h.asynqClient, // 新增,Handler 结构体已有此字段
h.gatewayClient,
h.workerResult.Services.UsageService,
h.logger,
)
修改完成后执行 go build ./...,确认编译通过,提交独立 commit(per D-05)。
go build ./... && rg "_ = task" internal/task/polling_handler.go && echo "FAIL: _ = task 仍存在" || echo "PASS: _ = task 已删除"
- PollingHandler struct 含 asynqClient 字段
- NewPollingHandler 接受 asynqClient 参数
- triggerFirstRealnameActivation 使用 asynqClient.EnqueueContext,不再 RPush
- _ = task 这行已被删除
- pkg/queue/handler.go 传入 h.asynqClient
- go build ./... 编译通过
# 1. 编译验证
go build ./...
# 2. 确认降级代码已删除
rg "_ = task" internal/task/polling_handler.go
rg "RPush.*TaskTypePackageFirstActivation\|RedisPollingManualQueueKey" internal/task/polling_handler.go
# 3. 确认正确入队代码存在
rg "asynqClient.EnqueueContext" internal/task/polling_handler.go
# 4. 确认 registerPollingHandlers 传了 asynqClient
rg "NewPollingHandler" pkg/queue/handler.go
人工验收(参见修正业务-完整方案.md A-3 验收清单):
- Worker 日志:首次实名触发时应出现实名激活任务入队日志
- DBHub:
SELECT id, status, pending_realname_activation, activated_at FROM tb_package_usage WHERE pending_realname_activation=true ORDER BY id DESC LIMIT 20;
<success_criteria>
go build ./...编译通过- PollingHandler 有 asynqClient 字段且被正确初始化
- triggerFirstRealnameActivation 使用 EnqueueContext,不再 RPush
_ = task行不存在- 独立 commit 已提交 </success_criteria>