feat(server): codes.GrantPaidSubscriptionTx 提炼订阅叠加语义供 pay 复用
CreateSubscription/applySubscription 加 source 参数(兑换路径传 "code" 零行为变化);新导出 GrantPaidSubscriptionTx(ctx, tx, ...) 供 pay 侧在 调用方事务内以 source='pay' 复用同一段叠加语义(同 plan 活跃订阅原地 延长,否则新建行),写 pay_grant 审计。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
This commit is contained in:
@@ -156,7 +156,7 @@ func (svc *Service) grantSubscription(userID int64) libcodes.GrantFunc[grantOutc
|
||||
if err != nil {
|
||||
return grantOutcome{}, err
|
||||
}
|
||||
subID, expiresAt, err := svc.applySubscription(ctx, tx, userID, planID, dur.Days)
|
||||
subID, expiresAt, err := svc.applySubscription(ctx, tx, userID, planID, dur.Days, "code")
|
||||
if err != nil {
|
||||
return grantOutcome{}, err
|
||||
}
|
||||
@@ -177,10 +177,13 @@ func (svc *Service) grantSubscription(userID int64) libcodes.GrantFunc[grantOutc
|
||||
}
|
||||
|
||||
// applySubscription:同 plan 有活跃订阅 → 取最晚到期那条 max(expires,now)+days
|
||||
// 原地延长;否则新建一行 max(now, latestSamePlan)+days。算法体与迁移前完全一致,
|
||||
// 仅签名从 (*CodeRow, *apierr.Error) 改为 (planID, days, error)。
|
||||
// 原地延长;否则新建一行 max(now, latestSamePlan)+days,source 记录新建行的
|
||||
// 创建者("code"=兑换码,"pay"=支付)。算法体与迁移前完全一致,仅签名从
|
||||
// (*CodeRow, *apierr.Error) 改为 (planID, days, source, error)。
|
||||
// ExtendSubscription 路径不看 source:延长的是既有行,行上的 source 仍是
|
||||
// 该行最初创建者,不因后续延长(不论来源)而改写——台账/审计保留完整出处。
|
||||
func (svc *Service) applySubscription(
|
||||
ctx context.Context, tx *sql.Tx, userID, planID int64, durationDays int,
|
||||
ctx context.Context, tx *sql.Tx, userID, planID int64, durationDays int, source string,
|
||||
) (int64, time.Time, error) {
|
||||
subs, err := svc.store.GetActiveSubscriptions(ctx, tx, userID)
|
||||
if err != nil {
|
||||
@@ -209,7 +212,7 @@ func (svc *Service) applySubscription(
|
||||
}
|
||||
return samePlanSub.ID, base.AddDate(0, 0, durationDays), nil
|
||||
}
|
||||
newSubID, err := svc.store.CreateSubscription(ctx, tx, userID, planID, durationDays, latestSamePlan)
|
||||
newSubID, err := svc.store.CreateSubscription(ctx, tx, userID, planID, durationDays, latestSamePlan, source)
|
||||
if err != nil {
|
||||
return 0, time.Time{}, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user