新功能(#4): 抽奖 Stage 2 人工奖领奖工单(crypto / physical / manual_other)
Closes HIF-4 Stage 2 交付:人工奖领奖工单完整闭环。crypto / physical / manual_other 三类奖品从抽中到 mark-paid 的全流程可用。 - 迁移 02159_lottery_claim:UNIQUE(draw_id) + 3 支持索引,状态机 pending_claim→reviewing→paying→paid,rejected 可复活,超时 expired - 3 个 PrizeHandler:Dispatch→ErrDispatchNotSupported 兜底、ClaimSchema 各自形态、ValidateClaim 表驱动 - BuildCryptoClaimSchema:抽中时按奖品 config.networks 注入 enum,前端下拉直接可用 - Draw service dispatchOrEnqueueClaim:人工奖同 tx 插 pending_claim(回滚双清),nonce 重放回读 ExpiresAt + ClaimFormSchema - POST /claim 实装:ownership 校验 → prize 类型校验 → handler.ValidateClaim → crypto network 白名单二次校验 → tx CAS status IN (pending_claim, rejected) AND expires_at > now - Admin CRUD 5 接口:list(IN 批拉 snap + user,无 N+1)、summary(GROUP BY 一次拿计数 + overdue 单查)、approve/reject/mark-paid 全走 CAS + audit - Scheduler @every 1h 扫过期,级联 lottery_draw.dispatch_state → expired - 新增错误码 100005-100011(already_submitted / invalid_claim_data / draw_not_found / not_your_draw / claim_expired / claim_state_invalid) - Rebase 后 Stage 2 测试主动 reuse PR E 的 unmetReasonsNotEmpty + evaluatedAtNotZero matcher,人工奖分支若绕过守卫会立即挂 - Stage 1 全部 4 处 guardrail 后端 rebase 时自检过:UnmetReasons、EvaluatedAt、GrantLedger.Payload、AdminMetaMiddleware 全保留 CI 全绿;28 files, +2442/-126;覆盖率 handler 78.9% / model.lottery 74.3% / draw 68.7% / queue/lottery 76.9%
This commit is contained in:
+22
-12
@@ -152,18 +152,28 @@ const (
|
||||
)
|
||||
|
||||
// Lottery error (100xxx range; 3-digit business = 100)
|
||||
// codes align with HIF-3 spec (Stage 1 issue description):
|
||||
// 4001 not_eligible / 4002 no_chances / 4003 activity_ended
|
||||
// 4004 rate_limited / 4010 not_claimable / 5001 internal_error
|
||||
// codes align with HIF-3 spec (Stage 1 issue description) + HIF-4 (Stage 2):
|
||||
//
|
||||
// 4001 not_eligible / 4002 no_chances / 4003 activity_ended
|
||||
// 4004 rate_limited / 4005 already_submitted / 4006 invalid_claim_data
|
||||
// 4007 draw_not_found / 4008 not_your_draw / 4009 claim_expired
|
||||
// 4010 not_claimable / 5001 internal_error
|
||||
//
|
||||
// wire-level ints stay unique across the whole codebase.
|
||||
const (
|
||||
LotteryNotEligible uint32 = 100001 // 用户未通过门槛
|
||||
LotteryNoChances uint32 = 100002 // 用户已无剩余次数
|
||||
LotteryActivityEnded uint32 = 100003 // 活动未开始 / 已结束 / 或 feature flag 关闭
|
||||
LotteryRateLimited uint32 = 100004 // 触发每秒 1 次限流
|
||||
LotteryNotClaimable uint32 = 100010 // Stage 2 领奖入口占位
|
||||
LotteryInternalError uint32 = 100500 // 内部错误
|
||||
LotteryRuleTooDeep uint32 = 100020 // rules JSON 深度超限
|
||||
LotteryRuleTooMany uint32 = 100021 // rules JSON 节点数超限
|
||||
LotteryRuleTooLarge uint32 = 100022 // rules JSON 体积超限
|
||||
LotteryNotEligible uint32 = 100001 // 用户未通过门槛
|
||||
LotteryNoChances uint32 = 100002 // 用户已无剩余次数
|
||||
LotteryActivityEnded uint32 = 100003 // 活动未开始 / 已结束 / 或 feature flag 关闭
|
||||
LotteryRateLimited uint32 = 100004 // 触发每秒 1 次限流
|
||||
LotteryAlreadySubmitted uint32 = 100005 // Stage 2: 该 draw 已经处于不可再提交的状态
|
||||
LotteryInvalidClaimData uint32 = 100006 // Stage 2: 领奖表单校验失败
|
||||
LotteryDrawNotFound uint32 = 100007 // Stage 2: draw_id 不存在
|
||||
LotteryNotYourDraw uint32 = 100008 // Stage 2: draw 不属于当前登录用户
|
||||
LotteryClaimExpired uint32 = 100009 // Stage 2: 领奖窗口已过期
|
||||
LotteryNotClaimable uint32 = 100010 // Stage 2: 该 draw 不需要 / 不允许领奖(自动奖 / 未中奖)
|
||||
LotteryInternalError uint32 = 100500 // 内部错误
|
||||
LotteryRuleTooDeep uint32 = 100020 // rules JSON 深度超限
|
||||
LotteryRuleTooMany uint32 = 100021 // rules JSON 节点数超限
|
||||
LotteryRuleTooLarge uint32 = 100022 // rules JSON 体积超限
|
||||
LotteryClaimStateInvalid uint32 = 100011 // Stage 2: 运营操作时状态机不允许(如非 reviewing 却 approve)
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user