package main import ( "fmt" "log" "time" "bindbox-game/configs" "bindbox-game/internal/pkg/logger" "bindbox-game/internal/repository/mysql" "bindbox-game/internal/repository/mysql/dao" usersvc "bindbox-game/internal/service/user" "context" "flag" ) func main() { flag.Parse() // 1. Initialize Configs (Requires being in the project root or having CONFIG_FILE env) configs.Init() // 2. Initialize Real MySQL Repo dbRepo, err := mysql.New() if err != nil { log.Fatalf("MySQL init failed: %v", err) } // 3. Initialize Logger d := dao.Use(dbRepo.GetDbW()) l, err := logger.NewCustomLogger(d, logger.WithOutputInConsole()) if err != nil { log.Fatalf("Logger creation failed: %v", err) } // 4. Initialize User Service us := usersvc.New(l, dbRepo) userID := int64(9090) orderID := int64(4695) // The order that already had double deduction ctx := context.Background() fmt.Printf("--- Verifying Idempotency for Order %d ---\n", orderID) // Using raw DB for checking counts db := dbRepo.GetDbR() // Count existing ledger records var beforeCount int64 db.Table("user_coupon_ledger").Where("order_id = ? AND action = 'apply'", orderID).Count(&beforeCount) fmt.Printf("Before call: %d ledger records\n", beforeCount) // Call DeductCouponsForPaidOrder fmt.Println("Calling DeductCouponsForPaidOrder...") // Pass nil as tx, the service will use dbRepo.GetDbW() err = us.DeductCouponsForPaidOrder(ctx, nil, userID, orderID, time.Now()) if err != nil { fmt.Printf("Error during DeductCouponsForPaidOrder: %v\n", err) } // Count after ledger records var afterCount int64 db.Table("user_coupon_ledger").Where("order_id = ? AND action = 'apply'", orderID).Count(&afterCount) fmt.Printf("After call: %d ledger records\n", afterCount) if beforeCount == afterCount { fmt.Println("\nSUCCESS: Fix is idempotent! No new records added.") } else { fmt.Println("\nFAILURE: Still adding duplicate records.") } }