Commit Graph

101 Commits

Author SHA1 Message Date
shanshanzhong147 fc6f193479 Clean repository development artifacts 2026-06-02 20:56:05 -07:00
shanshanzhong147 5b9f384f81 修复(#132): 退款幂等校验 + 已退款订单防重新激活
Build docker and publish / build (20.15.1) (push) Failing after 21m4s
Build docker and publish / build (20.15.1) (pull_request) Failing after 21m47s
P01:refundOrderLogic.RefundOrder 在事务内 FOR UPDATE 后、lockCommissionSource 前新增
333 退款日志扫描,命中即返回 OrderAlreadyRefunded(61006),不再写日志/扣 commission/
改 order.status。

P02:堵住已退款订单状态被回退入口
- queue/logic/order/stuckOrderRecoveryLogic.go:批扫 status=6 时新增 333 日志守卫,
  已退款订单不再被重置为 5 + 重新入队 activate(HIF-131 trace 中订单 53647 被刷回 5
  的真凶)
- queue/logic/order/activateOrderLogic.go:releaseClaim 同步加守卫做防御性兜底

新增 internal/model/log/refund.go 共享 helper HasRefundCommissionLog:
type=33 + content LIKE 走索引粗筛,再 JSON 反序列化确认 content.type==333 AND
content.order_no==orderNo,防 LIKE 子串误判。

测试:单元测试覆盖正常退款 / 已有 333 日志拒绝 / 子串误判防御 / 脏 JSON 容错;
sqlmock 严格断言命中后事务序列只含 BEGIN/SELECT order FOR UPDATE/SELECT
system_logs/ROLLBACK,无任何 commission 写入。

不做:calculateCommission、status 枚举拆分、表结构变更、支付通道 notify、用户余额回补。

Co-authored-by: multica-agent <github@multica.ai>
2026-05-31 20:19:35 -07:00
shanshanzhong147 02b41e7a2c 修复(#85): 促销系统 quantity 设计修正补丁(跨任务统一修复)
Build docker and publish / build (20.15.1) (push) Failing after 8m50s
Build docker and publish / build (20.15.1) (pull_request) Successful in 8m19s
- subscribe_promo 表加 quantity 字段,BIGINT NOT NULL DEFAULT 1
- EvaluatePromo 加 quantity 参数,按 subscribeID + quantity 精确匹配
- Promo 从 Subscribe 顶层移到 SubscribeDiscount
- 查询加 quantity,返回 map[subscribeID][quantity] 二级映射
- recordPromoUsage 错误向上传播,不再静默吞掉
- preCreate 和 purchase 的 allowPromo 判定统一为 orderType==1
- 迁移脚本增加幂等处理(guarded DROP/ADD/MODIFY)

Co-authored-by: multica-agent <github@multica.ai>
2026-05-27 05:57:21 -07:00
shanshanzhong147 d2f9289338 新功能(#76): 促销系统下单流程集成
Build docker and publish / build (20.15.1) (push) Has been cancelled
Build docker and publish / build (20.15.1) (pull_request) Successful in 8m28s
- 新增促销规则/规格促销价/使用记录模型与幂等迁移
- EvaluatePromo 支持 new_user/inactive_user/campaign 规则判定
- purchase/preCreate 接入促销判定:命中促销时跳过百分比折扣
- activate 激活后按 order_no 幂等写入 promo_usage
- 订单模型和响应结构新增 promo_rule_id、promo_discount 字段

Co-authored-by: multica-agent <github@multica.ai>
2026-05-26 22:18:44 -07:00
shanshanzhong147 0bd7560b64 fix: P1 activation path hardening - Bug 4-9
Bug 4: resolveRenewalActivationSubscription - add fallback by user_id+subscribe_id
  with SELECT FOR UPDATE when token lookup fails

Bug 5: appleIAPNotifyLogic - return error on product ID mapping failure instead of
  silently dropping the notification

Bug 6: NewPurchase fallback query - wrap in transaction with SELECT FOR UPDATE to
  prevent concurrent duplicate subscription creation

Bug 7: appleIAPNotifyLogic - fix UserId=0 by reverse-lookup from original purchase
  order; create renewal audit order record for DID_RENEW/SUBSCRIBED notifications

Bug 8: UpdateOrderStatus - pre-delete cache before DB write (double-delete) to
  close TOCTOU window between DB update and cache invalidation

Bug 9: validateNewUserOnlyEligibilityAtActivation - add Redis distributed lock on
  user_id to serialise concurrent new-user-only order activations

Co-authored-by: multica-agent <github@multica.ai>
2026-05-25 02:18:19 -07:00
shanshanzhong147 a0f2d8a7b8 fix: persist guest/redemption activation context to DB to survive Redis TTL expiry (Bug 1 + Bug 10)
- Add `activation_context` TEXT column to `order` table (migration 02150)
- purchaseLogic: write TemporaryOrderInfo JSON to order.ActivationContext in the same
  insert transaction; Redis write is now best-effort (non-fatal)
- redeemCodeLogic: write redemption {type, redemption_code_id, unit_time, quantity} JSON
  to order.ActivationContext at order creation; Redis write is now best-effort (non-fatal)
- getTempOrderInfo: on Redis miss, fall back to order.ActivationContext from DB;
  logs CRITICAL and returns error if both are missing (old orders with no DB record)
- RedemptionActivate: on Redis miss, fall back to order.ActivationContext from DB;
  same CRITICAL log path for legacy orders

Co-authored-by: multica-agent <github@multica.ai>
2026-05-25 02:18:19 -07:00
shanshanzhong147 30221232c9 fix: 修复订单状态机 claim 机制的三个 Bug 并增加 stuck 订单恢复
- 将 OrderStatusClaimed 从 4 改为 6,消除与 OrderStatusFailed 的值冲突
- finalizeCouponAndOrder 改用直接 DB 更新(WHERE status=6→SET status=5),
  绕过 UpdateOrderStatus 的 status<target 守卫,同时用 model.Update 刷新缓存
- releaseClaim 返回 error,调用处检查并记录日志;releaseClaim 失败由 stuck
  recovery 定时任务兜底
- claimAndGetOrder 对 status=claimed 返回可重试错误而非静默跳过;
  ProcessTask 区分 "stuck in claimed" 与 "非 paid 跳过" 两种场景
- 新增 StuckOrderRecoveryLogic:每 10 分钟扫描超时 claimed 订单,
  重置 status=paid 并重新入队 ForthwithActivateOrder,确保不依赖
  asynq 原始重试(可能已超 maxRetry)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-05-25 02:18:19 -07:00
shanshanzhong147 f6911965dc chore: snapshot current aws standby and backup tooling work 2026-05-13 10:59:03 -07:00
shanshanzhong147 cf70838142 fix(order): restore expired subscribe for invite gifts
Build docker and publish / build (20.15.1) (push) Has been cancelled
2026-04-30 13:16:45 -07:00
shanshanzhong147 280437be91 fix(order): guard renewal activation owner
Build docker and publish / build (20.15.1) (push) Has been cancelled
2026-04-30 12:54:02 -07:00
shanshanzhong147 32e3dc3c73 fix(order): cover invite gifts and inactive renewals
Build docker and publish / build (20.15.1) (push) Successful in 5m36s
2026-04-29 21:52:28 -07:00
shanshanzhong147 47696b9e68 fix(order): reconcile subscriptions and grant device trials
Build docker and publish / build (20.15.1) (push) Has been cancelled
2026-04-29 21:00:46 -07:00
shanshanzhong147 bcefb274ab perf(server): cache speed limit calculations
Build docker and publish / build (20.15.1) (push) Successful in 5m37s
2026-04-29 01:37:59 -07:00
shanshanzhong147 ac57272018 x
Build docker and publish / build (20.15.1) (push) Successful in 6m26s
2026-04-28 06:19:10 -07:00
shanshanzhong147 0ec0e2b9d2 fix(order): align invite gift ownership
Build docker and publish / build (20.15.1) (push) Has been cancelled
2026-04-28 05:19:57 -07:00
shanshanzhong147 ab38cd4943 x
Build docker and publish / build (20.15.1) (push) Failing after 4m44s
2026-04-26 21:12:22 -07:00
shanshanzhong147 9db4762904 fix(order): prevent duplicate subscriptions and repair invite gifts
Build docker and publish / build (20.15.1) (push) Successful in 5m6s
2026-04-24 21:16:21 -07:00
shanshanzhong147 2c9833df58 fix: 有返佣路径首单漏发被邀请用户赠天
Build docker and publish / build (20.15.1) (push) Successful in 5m37s
邀请人有返佣比例时,handleCommission 走佣金路径,
之前完全未调用 grantGiftDays,导致设备首单付费后
被邀请用户拿不到 N 天赠送。

修复:佣金处理完成后,若 IsNew(首单),
额外给被邀请用户调用 grantGiftDays(邀请人不重复赠天,
已通过佣金受益)。

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-04-21 01:57:22 -07:00
shanshanzhong147 9a8ae8b6fd fix: 修复非单订阅模式下过期用户重复购买产生双订阅的问题
Build docker and publish / build (20.15.1) (push) Successful in 4m45s
1. purchaseLogic: 非单订阅模式下购买前查询已有订阅,路由为续费(type=2)
2. activateOrderLogic: 续费激活时触发节点分组重算,确保过期续费后权限生效

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-04-20 20:58:01 -07:00
shanshanzhong147 c0d839deb9 fix: 修复仪表盘时区统计偏移、重复订阅、新增map_apple字段
Build docker and publish / build (20.15.1) (push) Successful in 5m23s
- fix(order/model): QueryDateOrders/QueryDailyOrdersList 使用 time.Date 替代 Truncate 修复 UTC+8 时区偏移
- fix(user/model): QueryResisterUserTotalByDate 同样修复时区截断
- fix(traffic/model): QueryServerTrafficByDay 同样修复时区截断
- fix(activateOrder): 兜底查询防止过期用户重购产生重复订阅
- feat(api): SubscribeDiscount 新增 map_apple 字段
2026-04-20 02:34:23 -07:00
shanshanzhong147 954b19c332 feat: 邮箱规范化(NormalizeEmail)与域名白名单检查(IsEmailDomainWhitelisted)
Build docker and publish / build (20.15.1) (push) Has been cancelled
2026-04-12 18:43:47 -07:00
shanshanzhong147 0b1e6ce3c3 fix: 单订阅模式激活时赠送订阅也用受益者 ID 查找
Build docker and publish / build (20.15.1) (push) Successful in 7m21s
findGiftSubscription 同步改用 singleModeUserId
(家庭组场景为家庭主 ID),与锚点订阅查找保持一致。

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-03-31 06:10:58 -07:00
shanshanzhong147 8838fc51f8 fix: 单订阅模式家庭组购买时用 SubscriptionUserId 查锚点
Build docker and publish / build (20.15.1) (push) Successful in 7m28s
NewPurchase 中查 FindSingleModeAnchorSubscribe 时,家庭组
场景下应使用实际受益者 SubscriptionUserId(成员/主),
而非付款人 UserId,否则找不到已有订阅,会为成员创建新订阅。

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-03-31 05:56:09 -07:00
shanshanzhong147 abc9864d46 fix: 单订阅模式下避免重复创建订阅
Build docker and publish / build (20.15.1) (push) Successful in 7m31s
1. FindSingleModeAnchorSubscribe 补充 status=4(流量耗完)到查询范围,
   避免流量耗尽的订阅被忽略导致续费时新建订阅

2. activateOrderLogic NewPurchase 路径去掉套餐ID匹配检查,
   单订阅模式下无论购买何种套餐都更新现有订阅而非新建

3. singleModeHelper fallback 查询同步补充 status=4

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-03-31 05:13:00 -07:00
shanshanzhong147 202c1c18d7 fix: 修复同 quantity 存在新用户和普通折扣档时老用户无法下单的问题
Build docker and publish / build (20.15.1) (push) Successful in 7m34s
isNewUserOnlyForQuantity 原逻辑取第一条匹配记录即返回,
当同一 quantity 同时配置了 new_user_only=true 和 false 两档时,
结果依赖数组顺序,导致老用户/超24h用户触发 SubscribeNewUserOnly 错误。

修复:扫描所有同 quantity 档位,仅当存在 true 且无 false 兜底时才返回 true;
有 false 兜底则返回 false,老用户可正常购买并命中普通折扣档。

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-03-30 22:30:12 -07:00
shanshanzhong147 e0b2be2058 x
Build docker and publish / build (20.15.1) (push) Successful in 7m36s
2026-03-30 21:05:21 -07:00
shanshanzhong147 d072217e85 x 2026-03-30 07:40:42 -07:00
shanshanzhong147 2a9c01ff8b x
Build docker and publish / build (20.15.1) (push) Successful in 7m28s
2026-03-30 04:49:55 -07:00
shanshanzhong147 1a08949c80 fix: 流量触发限速后主动清除节点用户缓存
节点用户列表缓存(server:user:{id})永不过期,用户流量超限触发按量限速后
缓存中仍是旧的速度值,节点不会感知限速状态。

修复:每次写入 traffic_log 后,检查该订阅是否触发按量限速规则,
若 IsThrottled=true 则立即删除对应节点的用户列表缓存,
节点下次拉取时重新计算并应用降速后的 speed_limit。

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-03-28 18:36:13 -07:00
shanshanzhong147 507ee16a30 x
Build docker and publish / build (20.15.1) (push) Successful in 8m20s
2026-03-28 09:06:24 -07:00
shanshanzhong147 4a2501a3d1 fix: 折扣匹配改为精确匹配 quantity,不再取全局最小值
Build docker and publish / build (20.15.1) (push) Successful in 7m55s
将 getDiscount 和 isNewUserOnlyForQuantity 的匹配逻辑从
inputMonths >= discount.Quantity 改为 inputMonths == discount.Quantity,
买多少天就用多少天对应的折扣,避免错误配置导致折扣泄漏。
同时增加 discount 值合法性校验(>0 且 <100)。

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-03-26 01:28:50 -07:00
shanshanzhong147 e5e9f93f68 Merge remote-tracking branch 'origin/master' into internal 2026-03-19 01:55:01 -07:00
shanshanzhong147 dcdbabdb13 注销
Build docker and publish / build (20.15.1) (push) Successful in 7m34s
2026-03-17 07:12:42 -07:00
EUForest 06a2425474 feat(subscribe): add traffic limit rules and user traffic stats
- Add subscribe traffic_limit schema and migration\n- Support traffic_limit in admin create/update and list/details\n- Apply traffic_limit when building server user list speed limits\n- Add public user traffic stats API
2026-03-14 12:41:52 +08:00
shanshanzhong147 d78ec194af feat: IAP 对账逻辑在激活订单前显式更新订单状态为已支付。
Build docker and publish / build (20.15.1) (push) Successful in 7m16s
2026-03-10 21:53:14 -07:00
shanshanzhong147 4095552252 feat: 为订单表添加 IAP 相关字段并调整 IAP 对账逻辑参数。
Build docker and publish / build (20.15.1) (push) Successful in 7m34s
2026-03-10 21:12:39 -07:00
shanshanzhong147 7c2eddf9c3 feat: 为订单表添加 app_account_token 字段并增强 Apple IAP 对账逻辑,支持通过交易历史记录查找。
Build docker and publish / build (20.15.1) (push) Successful in 7m25s
2026-03-10 20:47:24 -07:00
shanshanzhong147 26f6400e74 feat: 苹果支付uuid 及设备逻辑
Build docker and publish / build (20.15.1) (push) Successful in 8m3s
2026-03-10 19:53:19 -07:00
shanshanzhong147 130fb702ab fix: IAP 支付流程优化与关键 bug 修复
Build docker and publish / build (20.15.1) (push) Successful in 7m42s
- getStatusLogic 类型断言修复(*user.User)
- restoreLogic 事务拆分为单条处理 + appAccountToken 解析
- attachTransactionLogic 提取 ParseProductIdDuration 共享函数
- 新增 config_helper.go 统一 Apple API 配置加载
- reconcileLogic 补充 BundleID 配置读取
- activateOrderLogic 邀请赠送天数逻辑完善

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-03-09 00:27:16 -07:00
shanshanzhong147 79a97ec569 限制套餐具体到 档位
Build docker and publish / build (20.15.1) (push) Successful in 7m45s
2026-03-08 21:25:07 -07:00
EUForest 39310d5b9a Features:
- Node group CRUD operations with traffic-based filtering
  - Three grouping modes: average distribution, subscription-based, and traffic-based
  - Automatic and manual group recalculation with history tracking
  - Group assignment preview before applying changes
  - User subscription group locking to prevent automatic reassignment
  - Subscribe-to-group mapping configuration
  - Group calculation history and detailed reports
  - System configuration for group management (enabled/mode/auto_create)

  Database:
  - Add node_group table for group definitions
  - Add group_history and group_history_detail tables for tracking
  - Add node_group_ids (JSON) to nodes and subscribe tables
  - Add node_group_id and group_locked fields to user_subscribe table
  - Add migration files for schema changes
2026-03-08 23:22:38 +08:00
shanshanzhong147 7a3a53f1a9 ipa
Build docker and publish / build (20.15.1) (push) Successful in 7m47s
2026-03-08 05:12:28 -07:00
shanshanzhong147 1e14e2dbd9 map对齐
Build docker and publish / build (20.15.1) (push) Successful in 7m7s
2026-03-07 07:16:01 -08:00
shanshanzhong147 03573d2e65 双倍时间bug
Build docker and publish / build (20.15.1) (push) Successful in 8m33s
2026-03-07 02:05:48 -08:00
shanshanzhong147 4d913c1728 修复缓存
Build docker and publish / build (20.15.1) (push) Successful in 7m26s
2026-03-06 21:58:29 -08:00
shanshanzhong147 a01570b59d fix gitea workflow path and runner label
Build docker and publish / build (20.15.1) (push) Failing after 8m21s
2026-03-04 06:33:14 -08:00
shanshanzhong147 b0eb6595ac add: 新增ci diamanté 2026-03-03 17:29:45 -08:00
shanshanzhong147 4d8516b2e1 同步历史版本代码 2026-03-03 09:32:22 -08:00
EUForest 34372fe0b3 fix(redemption): enhance redemption code flow with transaction safety and idempotency
This commit addresses critical issues in the redemption code activation flow
to ensure data consistency, prevent duplicate redemptions, and improve user
experience.

Key improvements:

1. Transaction Safety (P0)
   - Wrap subscription creation, used count update, and record insertion in
     a single database transaction
   - Ensure atomicity: all operations succeed or all rollback
   - Prevent orphaned records and data inconsistencies

2. Idempotency Protection (P0)
   - Add redemption record check before processing to prevent duplicate
     operations on queue task retries
   - Maintain idempotency at multiple layers: interface, order, and record

3. Distributed Lock (P1)
   - Implement Redis-based distributed lock (10s timeout) to prevent
     concurrent duplicate redemptions
   - Lock key format: redemption_lock:{user_id}:{code}

4. IsNew Field Correction (P2)
   - Fix IsNew field to correctly determine first-time purchases using
     IsUserEligibleForNewOrder method
   - Ensure accurate statistics and future commission calculations

5. Quota Pre-check (P2)
   - Add quota validation at interface layer for immediate user feedback
   - Prevent "processing" status followed by eventual failure

6. Extended Cache TTL (P2)
   - Increase Redis cache expiration from 30 minutes to 2 hours
   - Ensure queue tasks can retrieve redemption data even with delays

7. Error Handling (P2)
   - Clean up Order records when Redis cache or queue enqueue fails
   - Prevent orphaned Order records in the database

8. Cache Clearing Optimization
   - Add user subscription cache clearing after activation
   - Ensure both node-side and user-side display latest subscription info

Technical details:
- Modified: internal/logic/public/redemption/redeemCodeLogic.go
- Modified: queue/logic/order/activateOrderLogic.go
- Modified: internal/model/redemption/default.go (transaction support)

Testing:
- All changes compiled successfully
- Comprehensive flow verification completed
- Ready for production deployment

BREAKING CHANGE: None
2026-02-09 01:07:39 +08:00
EUForest 5f55b1242e fix: resolve order queue loss issue with retry mechanism and idempotency
- Fix task error handling: return actual errors instead of nil to enable retry
- Add idempotency check: skip processing for already finished orders
- Extend temp order cache: increase from 15 minutes to 24 hours
- Configure retry policy: add MaxRetry(5) for all payment callbacks (Epay, Alipay, Stripe)

This fixes the critical issue where paid orders were being lost due to:
1. Failed tasks being marked as successful and deleted from queue
2. Temporary order info expiring before queue processing
3. No retry mechanism for transient failures

Changes:
- queue/logic/order/activateOrderLogic.go: Fix error returns and add idempotency
- internal/logic/public/portal/purchaseLogic.go: Extend cache to 24 hours
- internal/logic/notify/*NotifyLogic.go: Add retry configuration
2026-01-12 18:30:42 +08:00