package main import ( "encoding/csv" "fmt" "os" "strconv" "strings" "time" "github.com/lib/pq" "github.com/topfans/backend/pkg/jwt" ) type TestUser struct { UserID int64 Mobile string AssetIDs pq.Int64Array ExhibitionIDs pq.Int64Array } func GenerateTokensForLoadtest(cfg *Config) error { jwt.SetSecret(cfg.JWTSecret) db, err := openDB(cfg) if err != nil { return err } defer db.Close() rows, err := db.Query(` SELECT u.id, u.mobile, COALESCE(array_agg(DISTINCT a.id) FILTER (WHERE a.id IS NOT NULL), '{}'::int8[]), COALESCE(array_agg(DISTINCT e.id) FILTER (WHERE e.id IS NOT NULL), '{}'::int8[]) FROM users u LEFT JOIN assets a ON a.owner_uid = u.id AND a.star_id = $1 LEFT JOIN fan_profiles fp ON fp.user_id = u.id AND fp.star_id = $1 LEFT JOIN booth_slots bs ON bs.host_profile_id = fp.id AND bs.slot_index IN (1, 2) LEFT JOIN exhibitions e ON e.slot_id = bs.slot_id AND e.occupier_star_id = $1 WHERE u.id BETWEEN $2 AND $3 GROUP BY u.id, u.mobile ORDER BY u.id `, LoadtestStarID, LoadtestUserMin, LoadtestUserMax) if err != nil { return err } defer rows.Close() var users []TestUser for rows.Next() { var u TestUser if err := rows.Scan(&u.UserID, &u.Mobile, &u.AssetIDs, &u.ExhibitionIDs); err != nil { return err } users = append(users, u) } if err := rows.Err(); err != nil { return err } f, err := os.Create("users.csv") if err != nil { return err } defer f.Close() w := csv.NewWriter(f) defer w.Flush() if err := w.Write([]string{"phone", "password", "user_id", "star_id", "jwt_token", "asset_ids", "exhibition_ids"}); err != nil { return err } now := time.Now().UnixMilli() for _, u := range users { token, err := jwt.GenerateToken(u.UserID, LoadtestStarID, now) if err != nil { return err } if err := w.Write([]string{ u.Mobile, "Test@123", strconv.FormatInt(u.UserID, 10), "999900", token, joinInt64([]int64(u.AssetIDs)), joinInt64([]int64(u.ExhibitionIDs)), }); err != nil { return err } } fmt.Printf("✅ users.csv written: %d rows\n", len(users)) return nil } func joinInt64(s []int64) string { parts := make([]string, len(s)) for i, v := range s { parts[i] = strconv.FormatInt(v, 10) } return strings.Join(parts, ";") }