a46fb83054
Closes HIF-3 (阶段 PR B) PR B:handler 真实业务对接 + 邀请钩子(迭代含 R1 修复) - 迁移 02157_lottery_grant_ledger:external_ref UNIQUE 作为发奖幂等键 - log.CommissionTypeLottery=339(架构师批准的新常量) - DispatchRequest.IdempotencyKey(架构师 review 建议第 2 条) - GrantLedger + LedgerService.Reserve:INSERT ON CONFLICT DO NOTHING 幂等 upsert - VPNDurationHandler:ResolveEffectiveUser 归位家庭 owner + UpdateSubscribe,ExpireTime 三分支对齐 grantGiftDays - CommissionHandler:UpdateCommission + WriteCommissionLog(339),发给中奖者本人,不做家庭组归位 - Handler 从 model 层迁到 logic 层(避免 model → logic 反向依赖);noop 保留在 model 层 - InviteHook:fire-and-forget 独立 goroutine + 10s timeout,扫 running 活动的 invite_success 源 - ServiceContext 新增 LotteryChance / LotteryLedger / LotteryInviteHook - activateOrderLogic.handleCommission 两条分支通过 invokeInviteHookIfEligible 助手触发,助手内统一 gate IsNew(架构师 R1 打回后的修复) 架构师 R1 打回:branch B 未按"首次付款激活"gate,续费也会给 referer 发抽奖机会 → 已通过助手函数集中收拢,避免 branch A/B 判断漂移。 测试覆盖率:model 76.5% / handler 73.2% / hook 91.7%;补 4 个回归测试覆盖 IsNew 门槛(含关键的 DoesNotFireOnRenewal)。 线上仍零可见变更:无对外路由,钩子仅在活动 status=running 时生效,Stage 1 全流程无活动记录时 loadRunningActivities 返回空。
26 lines
1.8 KiB
SQL
26 lines
1.8 KiB
SQL
-- 02157 抽奖发奖账本(PR B)
|
||
--
|
||
-- 目的:以 external_ref 作为 DB 层唯一键,做每个 draw 的发奖幂等。
|
||
-- 各 PrizeHandler.Dispatch 内先 SELECT/INSERT lottery_grant_ledger,命中即幂等返回,
|
||
-- 未命中再调下游发放(UpdateSubscribe / UpdateCommission + WriteCommissionLog),
|
||
-- 全部在同一 tx 内完成 → 抽奖事务与发奖账本同生共死。
|
||
--
|
||
-- 关键唯一索引:external_ref。惯例值 = "lottery:{activity_id}:{draw_id}"。
|
||
-- handler_type:与 lottery_prize.type 一致(vpn_duration / commission / …),用于统计。
|
||
|
||
CREATE TABLE IF NOT EXISTS `lottery_grant_ledger` (
|
||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
`external_ref` VARCHAR(128) NOT NULL COMMENT '幂等键:lottery:{activity_id}:{draw_id}',
|
||
`handler_type` VARCHAR(32) NOT NULL COMMENT 'handler 类型,与 lottery_prize.type 对齐',
|
||
`user_id` BIGINT UNSIGNED NOT NULL COMMENT '发放对象用户 ID(家庭组已归位到 owner)',
|
||
`activity_id` BIGINT UNSIGNED NOT NULL COMMENT '活动 ID',
|
||
`draw_id` BIGINT UNSIGNED NOT NULL COMMENT '抽奖记录 ID',
|
||
`amount` BIGINT NOT NULL DEFAULT 0 COMMENT '发放数量(天/佣金金额,单位与 handler 一致)',
|
||
`payload` JSON COMMENT '发放后的关键结果快照(订阅 ID、佣金前后余额等)',
|
||
`granted_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '发放完成时间',
|
||
PRIMARY KEY (`id`),
|
||
UNIQUE KEY `uk_external_ref` (`external_ref`),
|
||
KEY `idx_user_activity` (`user_id`, `activity_id`),
|
||
KEY `idx_draw_id` (`draw_id`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='抽奖发奖账本(幂等键 = external_ref)';
|