┌─ GO ───────────────────────────────────────────────────────────────────────┐
│ package generator │
│ │
│ import ( │
│ "database/sql" │
│ "fmt" │
│ "ookstats/internal/wow" │
│ "ookstats/internal/writer" │
│ "os" │
│ "path/filepath" │
│ "strings" │
│ "sync" │
│ "sync/atomic" │
│ "time" │
│ ) │
│ │
│ // playerLeaderboardJob represents a single player leaderboard generation task │
│ type playerLeaderboardJob struct { │
│ seasonID int │
│ seasonName string │
│ scope string // "global", "regional", "realm", "class" │
│ region string // for regional/realm/class scopes │
│ realmSlug string // for realm scope │
│ classKey string // for class scope │
│ out string │
│ pageSize int │
│ regions []string // for class scope │
│ } │
│ │
│ // GeneratePlayerLeaderboards generates player ranking JSON files for all scopes p │
│ er season │
│ // Uses a worker pool for parallel generation │
│ func GeneratePlayerLeaderboards(db *sql.DB, out string, pageSize int, regions []st │
│ ring, workers int) error { │
│ if pageSize <= 0 { │
│ pageSize = 25 │
│ } │
│ if workers <= 0 { │
│ workers = 10 │
│ } │
│ │
│ // Default regions │
│ if len(regions) == 0 { │
│ regions = []string{"us", "eu", "kr", "tw"} │
│ } │
│ │
│ // Load seasons │
│ seasons, err := loadSeasons(db) │
│ if err != nil { │
│ return err │
│ } │
│ │
│ if len(seasons) == 0 { │
│ fmt.Println("Warning: No seasons found - skipping player leaderboard generation" │
│ ) │
│ return nil │
│ } │
│ │
│ // Pre-load realm slugs per region (only parent realms) │
│ realmSlugs := make(map[string][]string) │
│ for _, reg := range regions { │
│ slugs, err := loadParentRealmSlugs(db, reg) │
│ if err != nil { │
│ return err │
│ } │
│ realmSlugs[reg] = slugs │
│ } │
│ │
│ classKeys := []string{"death_knight", "druid", "hunter", "mage", "monk", "paladin │
│ ", "priest", "rogue", "shaman", "warlock", "warrior"} │
│ │
│ // Count total jobs │
│ var totalJobs int │
│ for range seasons { │
│ totalJobs += 1 // global │
│ totalJobs += len(regions) // regional │
│ for _, reg := range regions { │
│ totalJobs += len(realmSlugs[reg]) // realm │
│ } │
│ totalJobs += len(classKeys) // class (each handles all scopes internally) │
│ } │
│ │
│ fmt.Printf("Generating player leaderboards with %d workers (%d total jobs)...\n", │
│ workers, totalJobs) │
│ │
│ // Create job channel │
│ jobs := make(chan playerLeaderboardJob, 100) │
│ var firstErr atomic.Value │
│ var completed atomic.Int64 │
│ var wg sync.WaitGroup │
│ │
│ // Start workers │
│ for i := 0; i < workers; i++ { │
│ wg.Add(1) │
│ go func() { │
│ defer wg.Done() │
│ for job := range jobs { │
│ if firstErr.Load() != nil { │
│ continue │
│ } │
│ │
│ var err error │
│ switch job.scope { │
│ case "global": │
│ err = generateGlobalPlayerLeaderboard(db, job.out, job.pageSize, job.seasonID │
│ ) │
│ case "regional": │
│ err = generateRegionalPlayerLeaderboard(db, job.out, job.region, job.pageSize │
│ , job.seasonID) │
│ case "realm": │
│ err = generateSingleRealmPlayerLeaderboard(db, job.out, job.region, job.realm │
│ Slug, job.pageSize, job.seasonID) │
│ case "class": │
│ err = generateClassPlayerLeaderboards(db, job.out, job.classKey, job.pageSize │
│ , job.regions, job.seasonID) │
│ } │
│ │
│ if err != nil { │
│ firstErr.CompareAndSwap(nil, err) │
│ continue │
│ } │
│ │
│ c := completed.Add(1) │
│ if c%50 == 0 { │
│ fmt.Printf(" ... %d/%d player leaderboards generated\n", c, totalJobs) │
│ } │
│ } │
│ }() │
│ } │
│ │
│ // Queue all jobs │
│ for _, season := range seasons { │
│ fmt.Printf("\n=== Queuing Player Leaderboards for Season %d (%s) ===\n", season. │
│ ID, season.Name) │
│ seasonOut := filepath.Join(out, "season", fmt.Sprintf("%d", season.ID)) │
│ │
│ // Global │
│ jobs <- playerLeaderboardJob{ │
│ seasonID: season.ID, │
│ scope: "global", │
│ out: seasonOut, │
│ pageSize: pageSize, │
│ } │
│ │
│ // Regional │
│ for _, reg := range regions { │
│ jobs <- playerLeaderboardJob{ │
│ seasonID: season.ID, │
│ scope: "regional", │
│ region: reg, │
│ out: seasonOut, │
│ pageSize: pageSize, │
│ } │
│ } │
│ │
│ // Realm │
│ for _, reg := range regions { │
│ for _, rslug := range realmSlugs[reg] { │
│ jobs <- playerLeaderboardJob{ │
│ seasonID: season.ID, │
│ scope: "realm", │
│ region: reg, │
│ realmSlug: rslug, │
│ out: seasonOut, │
│ pageSize: pageSize, │
│ } │
│ } │
│ } │
│ │
│ // Class (each handles global/regional/realm internally) │
│ for _, cls := range classKeys { │
│ jobs <- playerLeaderboardJob{ │
│ seasonID: season.ID, │
│ scope: "class", │
│ classKey: cls, │
│ out: seasonOut, │
│ pageSize: pageSize, │
│ regions: regions, │
│ } │
│ } │
│ } │
│ close(jobs) │
│ │
│ wg.Wait() │
│ │
│ if err := firstErr.Load(); err != nil { │
│ return err.(error) │
│ } │
│ │
│ fmt.Printf("\n[OK] Generated %d player leaderboards\n", completed.Load()) │
│ return nil │
│ } │
│ │
│ func generateGlobalPlayerLeaderboard(db *sql.DB, out string, pageSize int, seasonI │
│ D int) error { │
│ dir := filepath.Join(out, "players", "global") │
│ if err := os.MkdirAll(dir, 0o755); err != nil { │
│ return err │
│ } │
│ rows, err := db.Query(` │
│ SELECT p.id, p.name, r.slug, r.name, r.region, │
│ COALESCE(pd.class_name,''), COALESCE(pd.active_spec_name,''), pp.main_spec_i │
│ d, │
│ pp.combined_best_time, pp.dungeons_completed, pp.total_runs, │
│ COALESCE(pp.global_ranking_bracket, '') │
│ FROM players p │
│ JOIN realms r ON p.realm_id = r.id │
│ JOIN player_profiles pp ON p.id = pp.player_id │
│ LEFT JOIN player_details pd ON p.id = pd.player_id │
│ WHERE pp.season_id = ? AND pp.has_complete_coverage = 1 AND pp.combined_best_tim │
│ e IS NOT NULL │
│ ORDER BY pp.combined_best_time ASC, p.name ASC │
│ `, seasonID) │
│ if err != nil { │
│ return fmt.Errorf("players query (global, season %d): %w", seasonID, err) │
│ } │
│ all, err := scanPlayerRows(rows) │
│ if err != nil { │
│ return err │
│ } │
│ return writePlayerLeaderboardPages(dir, all, "Global Player Rankings", pageSize) │
│ } │
│ │
│ func generateRegionalPlayerLeaderboard(db *sql.DB, out, region string, pageSize in │
│ t, seasonID int) error { │
│ dir := filepath.Join(out, "players", "regional", region) │
│ if err := os.MkdirAll(dir, 0o755); err != nil { │
│ return err │
│ } │
│ rows, err := db.Query(` │
│ SELECT p.id, p.name, r.slug, r.name, r.region, │
│ COALESCE(pd.class_name,''), COALESCE(pd.active_spec_name,''), pp.main_spec_i │
│ d, │
│ pp.combined_best_time, pp.dungeons_completed, pp.total_runs, │
│ COALESCE(pp.regional_ranking_bracket, '') │
│ FROM players p │
│ JOIN realms r ON p.realm_id = r.id │
│ JOIN player_profiles pp ON p.id = pp.player_id │
│ LEFT JOIN player_details pd ON p.id = pd.player_id │
│ WHERE pp.season_id = ? AND r.region = ? AND pp.has_complete_coverage = 1 AND pp. │
│ combined_best_time IS NOT NULL │
│ ORDER BY pp.combined_best_time ASC, p.name ASC │
│ `, seasonID, region) │
│ if err != nil { │
│ return fmt.Errorf("players query (regional, season %d): %w", seasonID, err) │
│ } │
│ all, err := scanPlayerRows(rows) │
│ if err != nil { │
│ return err │
│ } │
│ title := strings.ToUpper(region) + " Player Rankings" │
│ return writePlayerLeaderboardPages(dir, all, title, pageSize) │
│ } │
│ │
│ // pool = parent + child realms (matches per-season realm leaderboard) │
│ func generateSingleRealmPlayerLeaderboard(db *sql.DB, out, region, rslug string, p │
│ ageSize int, seasonID int) error { │
│ dir := filepath.Join(out, "players", "realm", region, rslug) │
│ if err := os.MkdirAll(dir, 0o755); err != nil { │
│ return err │
│ } │
│ rows, err := db.Query(` │
│ SELECT p.id, p.name, r.slug, r.name, r.region, │
│ COALESCE(pd.class_name,''), COALESCE(pd.active_spec_name,''), pp.main_spec_i │
│ d, │
│ pp.combined_best_time, pp.dungeons_completed, pp.total_runs, │
│ COALESCE(pp.realm_ranking_bracket, '') │
│ FROM players p │
│ JOIN realms r ON p.realm_id = r.id │
│ JOIN player_profiles pp ON p.id = pp.player_id │
│ LEFT JOIN player_details pd ON p.id = pd.player_id │
│ WHERE pp.season_id = ? AND r.region = ? │
│ AND (r.slug = ? OR r.parent_realm_slug = ?) │
│ AND pp.has_complete_coverage = 1 AND pp.combined_best_time IS NOT NULL │
│ ORDER BY pp.combined_best_time ASC, p.name ASC │
│ `, seasonID, region, rslug, rslug) │
│ if err != nil { │
│ return fmt.Errorf("players query (realm, season %d): %w", seasonID, err) │
│ } │
│ all, err := scanPlayerRows(rows) │
│ if err != nil { │
│ return err │
│ } │
│ title := strings.ToUpper(region) + "/" + rslug + " Player Rankings" │
│ return writePlayerLeaderboardPages(dir, all, title, pageSize) │
│ } │
│ │
│ func writePlayerLeaderboardPages(dir string, all []map[string]any, title string, p │
│ ageSize int) error { │
│ total := len(all) │
│ pages := (total + pageSize - 1) / pageSize │
│ for p := 1; p <= pages; p++ { │
│ start := (p - 1) * pageSize │
│ end := start + pageSize │
│ if end > total { │
│ end = total │
│ } │
│ page := buildPlayerLeaderboardPage(all[start:end], title, total, pages, p, pageS │
│ ize) │
│ if err := writer.WriteJSONFileCompact(filepath.Join(dir, fmt.Sprintf("%d.json", │
│ p)), page); err != nil { │
│ return err │
│ } │
│ } │
│ return nil │
│ } │
│ │
│ // generateClassPlayerLeaderboards generates class-filtered player rankings for a │
│ season │
│ func generateClassPlayerLeaderboards(db *sql.DB, out, classKey string, pageSize in │
│ t, regions []string, seasonID int) error { │
│ // Global class leaderboard │
│ if err := generateClassScope(db, out, "global", "", "", classKey, pageSize, seaso │
│ nID); err != nil { │
│ return err │
│ } │
│ │
│ // Regional class leaderboards │
│ for _, reg := range regions { │
│ if err := generateClassScope(db, out, "regional", reg, "", classKey, pageSize, s │
│ easonID); err != nil { │
│ return err │
│ } │
│ │
│ // Realm class leaderboards - only for parent/independent realms (skip child rea │
│ lms) │
│ slugs, err := loadParentRealmSlugs(db, reg) │
│ if err != nil { │
│ return err │
│ } │
│ │
│ for _, rslug := range slugs { │
│ if err := generateClassScope(db, out, "realm", reg, rslug, classKey, pageSize, │
│ seasonID); err != nil { │
│ return err │
│ } │
│ } │
│ } │
│ return nil │
│ } │
│ │
│ // generateClassScope generates a class-filtered leaderboard for a specific scope │
│ and season │
│ func generateClassScope(db *sql.DB, out, scope, region, realmSlug, classKey string │
│ , pageSize int, seasonID int) error { │
│ var dir string │
│ if scope == "global" { │
│ dir = filepath.Join(out, "players", "class", classKey, "global") │
│ } else if scope == "regional" { │
│ dir = filepath.Join(out, "players", "class", classKey, "regional", region) │
│ } else { │
│ dir = filepath.Join(out, "players", "class", classKey, "realm", region, realmSlu │
│ g) │
│ } │
│ if err := os.MkdirAll(dir, 0o755); err != nil { │
│ return err │
│ } │
│ │
│ // Fetch ALL players for this season, then filter by class in Go (to handle fallb │
│ ack logic) │
│ var rows *sql.Rows │
│ var err error │
│ if scope == "global" { │
│ rows, err = db.Query(` │
│ SELECT p.id, p.name, r.slug, r.name, r.region, │
│ COALESCE(pd.class_name,''), COALESCE(pd.active_spec_name,''), pp.main_spec_ │
│ id, │
│ pp.combined_best_time, pp.dungeons_completed, pp.total_runs, │
│ COALESCE(pp.global_class_bracket, '') │
│ FROM players p │
│ JOIN realms r ON p.realm_id = r.id │
│ JOIN player_profiles pp ON p.id = pp.player_id │
│ LEFT JOIN player_details pd ON p.id = pd.player_id │
│ WHERE pp.season_id = ? AND pp.has_complete_coverage = 1 AND pp.combined_best_ti │
│ me IS NOT NULL │
│ AND pp.class_name IS NOT NULL │
│ ORDER BY pp.combined_best_time ASC, p.name ASC │
│ `, seasonID) │
│ } else if scope == "regional" { │
│ rows, err = db.Query(` │
│ SELECT p.id, p.name, r.slug, r.name, r.region, │
│ COALESCE(pd.class_name,''), COALESCE(pd.active_spec_name,''), pp.main_spec_ │
│ id, │
│ pp.combined_best_time, pp.dungeons_completed, pp.total_runs, │
│ COALESCE(pp.region_class_bracket, '') │
│ FROM players p │
│ JOIN realms r ON p.realm_id = r.id │
│ JOIN player_profiles pp ON p.id = pp.player_id │
│ LEFT JOIN player_details pd ON p.id = pd.player_id │
│ WHERE pp.season_id = ? AND r.region = ? AND pp.has_complete_coverage = 1 AND pp │
│ .combined_best_time IS NOT NULL │
│ AND pp.class_name IS NOT NULL │
│ ORDER BY pp.combined_best_time ASC, p.name ASC │
│ `, seasonID, region) │
│ } else { │
│ // Realm scope - include entire pool (parent + all children) │
│ rows, err = db.Query(` │
│ SELECT p.id, p.name, r.slug, r.name, r.region, │
│ COALESCE(pd.class_name,''), COALESCE(pd.active_spec_name,''), pp.main_spec_ │
│ id, │
│ pp.combined_best_time, pp.dungeons_completed, pp.total_runs, │
│ COALESCE(pp.realm_class_bracket, '') │
│ FROM players p │
│ JOIN realms r ON p.realm_id = r.id │
│ JOIN player_profiles pp ON p.id = pp.player_id │
│ LEFT JOIN player_details pd ON p.id = pd.player_id │
│ WHERE pp.season_id = ? AND r.region = ? │
│ AND (r.slug = ? OR r.parent_realm_slug = ?) │
│ AND pp.has_complete_coverage = 1 AND pp.combined_best_time IS NOT NULL │
│ AND pp.class_name IS NOT NULL │
│ ORDER BY pp.combined_best_time ASC, p.name ASC │
│ `, seasonID, region, realmSlug, realmSlug) │
│ } │
│ if err != nil { │
│ return err │
│ } │
│ defer rows.Close() │
│ │
│ type PlayerRow struct { │
│ ID int64 │
│ Name, RealmSlug, RealmName, Region, ClassName, ActiveSpecName string │
│ MainSpecID sql.NullInt64 │
│ CombinedBestTime sql.NullInt64 │
│ DungeonsCompleted, TotalRuns int │
│ RankingBracket string │
│ } │
│ │
│ // Collect all matching players (filter by class in Go) │
│ var allMatching []PlayerRow │
│ for rows.Next() { │
│ var r PlayerRow │
│ if err := rows.Scan(&r.ID, &r.Name, &r.RealmSlug, &r.RealmName, &r.Region, &r.Cl │
│ assName, &r.ActiveSpecName, &r.MainSpecID, &r.CombinedBestTime, &r.DungeonsComplet │
│ ed, &r.TotalRuns, &r.RankingBracket); err != nil { │
│ return err │
│ } │
│ │
│ // Derive class from main_spec_id if missing │
│ derivedClass := r.ClassName │
│ derivedSpec := r.ActiveSpecName │
│ if (derivedClass == "" || derivedSpec == "") && r.MainSpecID.Valid { │
│ if cls, spec, ok := wow.GetClassAndSpec(int(r.MainSpecID.Int64)); ok { │
│ if derivedClass == "" { │
│ derivedClass = cls │
│ } │
│ if derivedSpec == "" { │
│ derivedSpec = spec │
│ } │
│ } │
│ } │
│ │
│ // Filter by class (case-insensitive, space -> underscore) │
│ playerClassKey := strings.ReplaceAll(strings.ToLower(derivedClass), " ", "_") │
│ if playerClassKey == classKey { │
│ r.ClassName = derivedClass │
│ r.ActiveSpecName = derivedSpec │
│ allMatching = append(allMatching, r) │
│ } │
│ } │
│ │
│ // Paginate the filtered results │
│ total := len(allMatching) │
│ pages := (total + pageSize - 1) / pageSize │
│ │
│ for p := 1; p <= pages; p++ { │
│ offset := (p - 1) * pageSize │
│ end := offset + pageSize │
│ if end > total { │
│ end = total │
│ } │
│ │
│ var list []map[string]any │
│ for _, r := range allMatching[offset:end] { │
│ obj := map[string]any{ │
│ "player_id": r.ID, │
│ "name": r.Name, │
│ "realm_slug": r.RealmSlug, │
│ "realm_name": r.RealmName, │
│ "region": r.Region, │
│ "class_name": r.ClassName, │
│ "active_spec_name": r.ActiveSpecName, │
│ "dungeons_completed": r.DungeonsCompleted, │
│ "total_runs": r.TotalRuns, │
│ } │
│ if r.RankingBracket != "" { │
│ obj["ranking_percentile"] = r.RankingBracket │
│ } │
│ if r.MainSpecID.Valid { │
│ obj["main_spec_id"] = int(r.MainSpecID.Int64) │
│ } │
│ if r.CombinedBestTime.Valid { │
│ obj["combined_best_time"] = r.CombinedBestTime.Int64 │
│ } │
│ list = append(list, obj) │
│ } │
│ │
│ title := "Global Player Rankings" │
│ if scope == "regional" { │
│ title = strings.ToUpper(region) + " Player Rankings" │
│ } else if scope == "realm" { │
│ title = strings.ToUpper(region) + "/" + realmSlug + " Player Rankings" │
│ } │
│ │
│ page := buildPlayerLeaderboardPage(list, title, total, pages, p, pageSize) │
│ if err := writer.WriteJSONFileCompact(filepath.Join(dir, fmt.Sprintf("%d.json", │
│ p)), page); err != nil { │
│ return err │
│ } │
│ } │
│ return nil │
│ } │
│ │
│ // scanPlayerRows scans player rows and applies class/spec fallback │
│ func scanPlayerRows(rows *sql.Rows) ([]map[string]any, error) { │
│ defer rows.Close() │
│ │
│ type PlayerRow struct { │
│ ID int64 │
│ Name string │
│ RealmSlug string │
│ RealmName string │
│ Region string │
│ ClassName string │
│ ActiveSpecName string │
│ MainSpecID sql.NullInt64 │
│ CombinedBestTime sql.NullInt64 │
│ DungeonsCompleted int │
│ TotalRuns int │
│ RankingBracket string │
│ } │
│ │
│ var list []map[string]any │
│ for rows.Next() { │
│ var r PlayerRow │
│ if err := rows.Scan(&r.ID, &r.Name, &r.RealmSlug, &r.RealmName, &r.Region, &r.Cl │
│ assName, &r.ActiveSpecName, &r.MainSpecID, &r.CombinedBestTime, &r.DungeonsComplet │
│ ed, &r.TotalRuns, &r.RankingBracket); err != nil { │
│ return nil, err │
│ } │
│ │
│ obj := map[string]any{ │
│ "player_id": r.ID, │
│ "name": r.Name, │
│ "realm_slug": r.RealmSlug, │
│ "realm_name": r.RealmName, │
│ "region": r.Region, │
│ "class_name": r.ClassName, │
│ "active_spec_name": r.ActiveSpecName, │
│ "dungeons_completed": r.DungeonsCompleted, │
│ "total_runs": r.TotalRuns, │
│ } │
│ │
│ if r.RankingBracket != "" { │
│ obj["ranking_percentile"] = r.RankingBracket │
│ } │
│ │
│ // Apply class/spec fallback if missing │
│ if r.MainSpecID.Valid { │
│ v := int(r.MainSpecID.Int64) │
│ obj["class_name"], obj["active_spec_name"] = wow.FallbackClassAndSpec(r.ClassNa │
│ me, r.ActiveSpecName, &v) │
│ obj["main_spec_id"] = v │
│ } │
│ │
│ if r.CombinedBestTime.Valid { │
│ obj["combined_best_time"] = r.CombinedBestTime.Int64 │
│ } │
│ list = append(list, obj) │
│ } │
│ return list, nil │
│ } │
│ │
│ // buildPlayerLeaderboardPage builds a player leaderboard page structure │
│ func buildPlayerLeaderboardPage(leaderboard []map[string]any, title string, total, │
│ totalPages, currentPage, pageSize int) map[string]any { │
│ return map[string]any{ │
│ "leaderboard": leaderboard, │
│ "title": title, │
│ "generated_timestamp": time.Now().UnixMilli(), │
│ "pagination": map[string]any{ │
│ "currentPage": currentPage, │
│ "pageSize": pageSize, │
│ "totalPlayers": total, │
│ "totalPages": totalPages, │
│ "hasNextPage": currentPage < totalPages, │
│ "hasPrevPage": currentPage > 1, │
│ "totalRuns": total, // keep compatibility with frontend │
│ }, │
│ } │
│ } │
└────────────────────────────────────────────────────────────────────────────────────┘
┌─ GO ─────────────────────────────────┐
│ package generator │
│ │
│ import ( │
│ "database/sql" │
│ "fmt" │
│ "ookstats/internal/wow" │
│ "ookstats/internal/writer" │
│ "os" │
│ "path/filepath" │
│ "strings" │
│ "sync" │
│ "sync/atomic" │
│ "time" │
│ ) │
│ │
│ // playerLeaderboardJob represents a single │
│ player leaderboard generation task │
│ type playerLeaderboardJob struct { │
│ seasonID int │
│ seasonName string │
│ scope string // "global", "regional", │
│ "realm", "class" │
│ region string // for regional/realm/cla │
│ ss scopes │
│ realmSlug string // for realm scope │
│ classKey string // for class scope │
│ out string │
│ pageSize int │
│ regions []string // for class scope │
│ } │
│ │
│ // GeneratePlayerLeaderboards generates play │
│ er ranking JSON files for all scopes per sea │
│ son │
│ // Uses a worker pool for parallel generatio │
│ n │
│ func GeneratePlayerLeaderboards(db *sql.DB, │
│ out string, pageSize int, regions []string, │
│ workers int) error { │
│ if pageSize <= 0 { │
│ pageSize = 25 │
│ } │
│ if workers <= 0 { │
│ workers = 10 │
│ } │
│ │
│ // Default regions │
│ if len(regions) == 0 { │
│ regions = []string{"us", "eu", "kr", "tw"} │
│ } │
│ │
│ // Load seasons │
│ seasons, err := loadSeasons(db) │
│ if err != nil { │
│ return err │
│ } │
│ │
│ if len(seasons) == 0 { │
│ fmt.Println("Warning: No seasons found - s │
│ kipping player leaderboard generation") │
│ return nil │
│ } │
│ │
│ // Pre-load realm slugs per region (only pa │
│ rent realms) │
│ realmSlugs := make(map[string][]string) │
│ for _, reg := range regions { │
│ slugs, err := loadParentRealmSlugs(db, reg │
│ ) │
│ if err != nil { │
│ return err │
│ } │
│ realmSlugs[reg] = slugs │
│ } │
│ │
│ classKeys := []string{"death_knight", "drui │
│ d", "hunter", "mage", "monk", "paladin", "pr │
│ iest", "rogue", "shaman", "warlock", "warrio │
│ r"} │
│ │
│ // Count total jobs │
│ var totalJobs int │
│ for range seasons { │
│ totalJobs += 1 // global │
│ totalJobs += len(regions) // regional │
│ for _, reg := range regions { │
│ totalJobs += len(realmSlugs[reg]) // real │
│ m │
│ } │
│ totalJobs += len(classKeys) // class (each │
│ handles all scopes internally) │
│ } │
│ │
│ fmt.Printf("Generating player leaderboards │
│ with %d workers (%d total jobs)...\n", worke │
│ rs, totalJobs) │
│ │
│ // Create job channel │
│ jobs := make(chan playerLeaderboardJob, 100 │
│ ) │
│ var firstErr atomic.Value │
│ var completed atomic.Int64 │
│ var wg sync.WaitGroup │
│ │
│ // Start workers │
│ for i := 0; i < workers; i++ { │
│ wg.Add(1) │
│ go func() { │
│ defer wg.Done() │
│ for job := range jobs { │
│ if firstErr.Load() != nil { │
│ continue │
│ } │
│ │
│ var err error │
│ switch job.scope { │
│ case "global": │
│ err = generateGlobalPlayerLeaderboard(d │
│ b, job.out, job.pageSize, job.seasonID) │
│ case "regional": │
│ err = generateRegionalPlayerLeaderboard │
│ (db, job.out, job.region, job.pageSize, job. │
│ seasonID) │
│ case "realm": │
│ err = generateSingleRealmPlayerLeaderbo │
│ ard(db, job.out, job.region, job.realmSlug, │
│ job.pageSize, job.seasonID) │
│ case "class": │
│ err = generateClassPlayerLeaderboards(d │
│ b, job.out, job.classKey, job.pageSize, job. │
│ regions, job.seasonID) │
│ } │
│ │
│ if err != nil { │
│ firstErr.CompareAndSwap(nil, err) │
│ continue │
│ } │
│ │
│ c := completed.Add(1) │
│ if c%50 == 0 { │
│ fmt.Printf(" ... %d/%d player leaderbo │
│ ards generated\n", c, totalJobs) │
│ } │
│ } │
│ }() │
│ } │
│ │
│ // Queue all jobs │
│ for _, season := range seasons { │
│ fmt.Printf("\n=== Queuing Player Leaderboa │
│ rds for Season %d (%s) ===\n", season.ID, se │
│ ason.Name) │
│ seasonOut := filepath.Join(out, "season", │
│ fmt.Sprintf("%d", season.ID)) │
│ │
│ // Global │
│ jobs <- playerLeaderboardJob{ │
│ seasonID: season.ID, │
│ scope: "global", │
│ out: seasonOut, │
│ pageSize: pageSize, │
│ } │
│ │
│ // Regional │
│ for _, reg := range regions { │
│ jobs <- playerLeaderboardJob{ │
│ seasonID: season.ID, │
│ scope: "regional", │
│ region: reg, │
│ out: seasonOut, │
│ pageSize: pageSize, │
│ } │
│ } │
│ │
│ // Realm │
│ for _, reg := range regions { │
│ for _, rslug := range realmSlugs[reg] { │
│ jobs <- playerLeaderboardJob{ │
│ seasonID: season.ID, │
│ scope: "realm", │
│ region: reg, │
│ realmSlug: rslug, │
│ out: seasonOut, │
│ pageSize: pageSize, │
│ } │
│ } │
│ } │
│ │
│ // Class (each handles global/regional/rea │
│ lm internally) │
│ for _, cls := range classKeys { │
│ jobs <- playerLeaderboardJob{ │
│ seasonID: season.ID, │
│ scope: "class", │
│ classKey: cls, │
│ out: seasonOut, │
│ pageSize: pageSize, │
│ regions: regions, │
│ } │
│ } │
│ } │
│ close(jobs) │
│ │
│ wg.Wait() │
│ │
│ if err := firstErr.Load(); err != nil { │
│ return err.(error) │
│ } │
│ │
│ fmt.Printf("\n[OK] Generated %d player lead │
│ erboards\n", completed.Load()) │
│ return nil │
│ } │
│ │
│ func generateGlobalPlayerLeaderboard(db *sql │
│ .DB, out string, pageSize int, seasonID int) │
│ error { │
│ dir := filepath.Join(out, "players", "globa │
│ l") │
│ if err := os.MkdirAll(dir, 0o755); err != n │
│ il { │
│ return err │
│ } │
│ rows, err := db.Query(` │
│ SELECT p.id, p.name, r.slug, r.name, r.reg │
│ ion, │
│ COALESCE(pd.class_name,''), COALESCE(p │
│ d.active_spec_name,''), pp.main_spec_id, │
│ pp.combined_best_time, pp.dungeons_com │
│ pleted, pp.total_runs, │
│ COALESCE(pp.global_ranking_bracket, '' │
│ ) │
│ FROM players p │
│ JOIN realms r ON p.realm_id = r.id │
│ JOIN player_profiles pp ON p.id = pp.playe │
│ r_id │
│ LEFT JOIN player_details pd ON p.id = pd.p │
│ layer_id │
│ WHERE pp.season_id = ? AND pp.has_complete │
│ _coverage = 1 AND pp.combined_best_time IS N │
│ OT NULL │
│ ORDER BY pp.combined_best_time ASC, p.name │
│ ASC │
│ `, seasonID) │
│ if err != nil { │
│ return fmt.Errorf("players query (global, │
│ season %d): %w", seasonID, err) │
│ } │
│ all, err := scanPlayerRows(rows) │
│ if err != nil { │
│ return err │
│ } │
│ return writePlayerLeaderboardPages(dir, all │
│ , "Global Player Rankings", pageSize) │
│ } │
│ │
│ func generateRegionalPlayerLeaderboard(db *s │
│ ql.DB, out, region string, pageSize int, sea │
│ sonID int) error { │
│ dir := filepath.Join(out, "players", "regio │
│ nal", region) │
│ if err := os.MkdirAll(dir, 0o755); err != n │
│ il { │
│ return err │
│ } │
│ rows, err := db.Query(` │
│ SELECT p.id, p.name, r.slug, r.name, r.reg │
│ ion, │
│ COALESCE(pd.class_name,''), COALESCE(p │
│ d.active_spec_name,''), pp.main_spec_id, │
│ pp.combined_best_time, pp.dungeons_com │
│ pleted, pp.total_runs, │
│ COALESCE(pp.regional_ranking_bracket, │
│ '') │
│ FROM players p │
│ JOIN realms r ON p.realm_id = r.id │
│ JOIN player_profiles pp ON p.id = pp.playe │
│ r_id │
│ LEFT JOIN player_details pd ON p.id = pd.p │
│ layer_id │
│ WHERE pp.season_id = ? AND r.region = ? AN │
│ D pp.has_complete_coverage = 1 AND pp.combin │
│ ed_best_time IS NOT NULL │
│ ORDER BY pp.combined_best_time ASC, p.name │
│ ASC │
│ `, seasonID, region) │
│ if err != nil { │
│ return fmt.Errorf("players query (regional │
│ , season %d): %w", seasonID, err) │
│ } │
│ all, err := scanPlayerRows(rows) │
│ if err != nil { │
│ return err │
│ } │
│ title := strings.ToUpper(region) + " Player │
│ Rankings" │
│ return writePlayerLeaderboardPages(dir, all │
│ , title, pageSize) │
│ } │
│ │
│ // pool = parent + child realms (matches per │
│ -season realm leaderboard) │
│ func generateSingleRealmPlayerLeaderboard(db │
│ *sql.DB, out, region, rslug string, pageSiz │
│ e int, seasonID int) error { │
│ dir := filepath.Join(out, "players", "realm │
│ ", region, rslug) │
│ if err := os.MkdirAll(dir, 0o755); err != n │
│ il { │
│ return err │
│ } │
│ rows, err := db.Query(` │
│ SELECT p.id, p.name, r.slug, r.name, r.reg │
│ ion, │
│ COALESCE(pd.class_name,''), COALESCE(p │
│ d.active_spec_name,''), pp.main_spec_id, │
│ pp.combined_best_time, pp.dungeons_com │
│ pleted, pp.total_runs, │
│ COALESCE(pp.realm_ranking_bracket, '') │
│ FROM players p │
│ JOIN realms r ON p.realm_id = r.id │
│ JOIN player_profiles pp ON p.id = pp.playe │
│ r_id │
│ LEFT JOIN player_details pd ON p.id = pd.p │
│ layer_id │
│ WHERE pp.season_id = ? AND r.region = ? │
│ AND (r.slug = ? OR r.parent_realm_slug = │
│ ?) │
│ AND pp.has_complete_coverage = 1 AND pp.c │
│ ombined_best_time IS NOT NULL │
│ ORDER BY pp.combined_best_time ASC, p.name │
│ ASC │
│ `, seasonID, region, rslug, rslug) │
│ if err != nil { │
│ return fmt.Errorf("players query (realm, s │
│ eason %d): %w", seasonID, err) │
│ } │
│ all, err := scanPlayerRows(rows) │
│ if err != nil { │
│ return err │
│ } │
│ title := strings.ToUpper(region) + "/" + rs │
│ lug + " Player Rankings" │
│ return writePlayerLeaderboardPages(dir, all │
│ , title, pageSize) │
│ } │
│ │
│ func writePlayerLeaderboardPages(dir string, │
│ all []map[string]any, title string, pageSiz │
│ e int) error { │
│ total := len(all) │
│ pages := (total + pageSize - 1) / pageSize │
│ for p := 1; p <= pages; p++ { │
│ start := (p - 1) * pageSize │
│ end := start + pageSize │
│ if end > total { │
│ end = total │
│ } │
│ page := buildPlayerLeaderboardPage(all[sta │
│ rt:end], title, total, pages, p, pageSize) │
│ if err := writer.WriteJSONFileCompact(file │
│ path.Join(dir, fmt.Sprintf("%d.json", p)), p │
│ age); err != nil { │
│ return err │
│ } │
│ } │
│ return nil │
│ } │
│ │
│ // generateClassPlayerLeaderboards generates │
│ class-filtered player rankings for a season │
│ func generateClassPlayerLeaderboards(db *sql │
│ .DB, out, classKey string, pageSize int, reg │
│ ions []string, seasonID int) error { │
│ // Global class leaderboard │
│ if err := generateClassScope(db, out, "glob │
│ al", "", "", classKey, pageSize, seasonID); │
│ err != nil { │
│ return err │
│ } │
│ │
│ // Regional class leaderboards │
│ for _, reg := range regions { │
│ if err := generateClassScope(db, out, "reg │
│ ional", reg, "", classKey, pageSize, seasonI │
│ D); err != nil { │
│ return err │
│ } │
│ │
│ // Realm class leaderboards - only for par │
│ ent/independent realms (skip child realms) │
│ slugs, err := loadParentRealmSlugs(db, reg │
│ ) │
│ if err != nil { │
│ return err │
│ } │
│ │
│ for _, rslug := range slugs { │
│ if err := generateClassScope(db, out, "re │
│ alm", reg, rslug, classKey, pageSize, season │
│ ID); err != nil { │
│ return err │
│ } │
│ } │
│ } │
│ return nil │
│ } │
│ │
│ // generateClassScope generates a class-filt │
│ ered leaderboard for a specific scope and se │
│ ason │
│ func generateClassScope(db *sql.DB, out, sco │
│ pe, region, realmSlug, classKey string, page │
│ Size int, seasonID int) error { │
│ var dir string │
│ if scope == "global" { │
│ dir = filepath.Join(out, "players", "class │
│ ", classKey, "global") │
│ } else if scope == "regional" { │
│ dir = filepath.Join(out, "players", "class │
│ ", classKey, "regional", region) │
│ } else { │
│ dir = filepath.Join(out, "players", "class │
│ ", classKey, "realm", region, realmSlug) │
│ } │
│ if err := os.MkdirAll(dir, 0o755); err != n │
│ il { │
│ return err │
│ } │
│ │
│ // Fetch ALL players for this season, then │
│ filter by class in Go (to handle fallback lo │
│ gic) │
│ var rows *sql.Rows │
│ var err error │
│ if scope == "global" { │
│ rows, err = db.Query(` │
│ SELECT p.id, p.name, r.slug, r.name, r.re │
│ gion, │
│ COALESCE(pd.class_name,''), COALESCE( │
│ pd.active_spec_name,''), pp.main_spec_id, │
│ pp.combined_best_time, pp.dungeons_co │
│ mpleted, pp.total_runs, │
│ COALESCE(pp.global_class_bracket, '') │
│ FROM players p │
│ JOIN realms r ON p.realm_id = r.id │
│ JOIN player_profiles pp ON p.id = pp.play │
│ er_id │
│ LEFT JOIN player_details pd ON p.id = pd. │
│ player_id │
│ WHERE pp.season_id = ? AND pp.has_complet │
│ e_coverage = 1 AND pp.combined_best_time IS │
│ NOT NULL │
│ AND pp.class_name IS NOT NULL │
│ ORDER BY pp.combined_best_time ASC, p.nam │
│ e ASC │
│ `, seasonID) │
│ } else if scope == "regional" { │
│ rows, err = db.Query(` │
│ SELECT p.id, p.name, r.slug, r.name, r.re │
│ gion, │
│ COALESCE(pd.class_name,''), COALESCE( │
│ pd.active_spec_name,''), pp.main_spec_id, │
│ pp.combined_best_time, pp.dungeons_co │
│ mpleted, pp.total_runs, │
│ COALESCE(pp.region_class_bracket, '') │
│ FROM players p │
│ JOIN realms r ON p.realm_id = r.id │
│ JOIN player_profiles pp ON p.id = pp.play │
│ er_id │
│ LEFT JOIN player_details pd ON p.id = pd. │
│ player_id │
│ WHERE pp.season_id = ? AND r.region = ? A │
│ ND pp.has_complete_coverage = 1 AND pp.combi │
│ ned_best_time IS NOT NULL │
│ AND pp.class_name IS NOT NULL │
│ ORDER BY pp.combined_best_time ASC, p.nam │
│ e ASC │
│ `, seasonID, region) │
│ } else { │
│ // Realm scope - include entire pool (pare │
│ nt + all children) │
│ rows, err = db.Query(` │
│ SELECT p.id, p.name, r.slug, r.name, r.re │
│ gion, │
│ COALESCE(pd.class_name,''), COALESCE( │
│ pd.active_spec_name,''), pp.main_spec_id, │
│ pp.combined_best_time, pp.dungeons_co │
│ mpleted, pp.total_runs, │
│ COALESCE(pp.realm_class_bracket, '') │
│ FROM players p │
│ JOIN realms r ON p.realm_id = r.id │
│ JOIN player_profiles pp ON p.id = pp.play │
│ er_id │
│ LEFT JOIN player_details pd ON p.id = pd. │
│ player_id │
│ WHERE pp.season_id = ? AND r.region = ? │
│ AND (r.slug = ? OR r.parent_realm_slug = │
│ ?) │
│ AND pp.has_complete_coverage = 1 AND pp. │
│ combined_best_time IS NOT NULL │
│ AND pp.class_name IS NOT NULL │
│ ORDER BY pp.combined_best_time ASC, p.nam │
│ e ASC │
│ `, seasonID, region, realmSlug, realmSlug) │
│ } │
│ if err != nil { │
│ return err │
│ } │
│ defer rows.Close() │
│ │
│ type PlayerRow struct { │
│ ID │
│ int64 │
│ Name, RealmSlug, RealmName, Region, ClassN │
│ ame, ActiveSpecName string │
│ MainSpecID │
│ sql.NullInt64 │
│ CombinedBestTime │
│ sql.NullInt64 │
│ DungeonsCompleted, TotalRuns │
│ int │
│ RankingBracket │
│ string │
│ } │
│ │
│ // Collect all matching players (filter by │
│ class in Go) │
│ var allMatching []PlayerRow │
│ for rows.Next() { │
│ var r PlayerRow │
│ if err := rows.Scan(&r.ID, &r.Name, &r.Rea │
│ lmSlug, &r.RealmName, &r.Region, &r.ClassNam │
│ e, &r.ActiveSpecName, &r.MainSpecID, &r.Comb │
│ inedBestTime, &r.DungeonsCompleted, &r.Total │
│ Runs, &r.RankingBracket); err != nil { │
│ return err │
│ } │
│ │
│ // Derive class from main_spec_id if missi │
│ ng │
│ derivedClass := r.ClassName │
│ derivedSpec := r.ActiveSpecName │
│ if (derivedClass == "" || derivedSpec == " │
│ ") && r.MainSpecID.Valid { │
│ if cls, spec, ok := wow.GetClassAndSpec(i │
│ nt(r.MainSpecID.Int64)); ok { │
│ if derivedClass == "" { │
│ derivedClass = cls │
│ } │
│ if derivedSpec == "" { │
│ derivedSpec = spec │
│ } │
│ } │
│ } │
│ │
│ // Filter by class (case-insensitive, spac │
│ e -> underscore) │
│ playerClassKey := strings.ReplaceAll(strin │
│ gs.ToLower(derivedClass), " ", "_") │
│ if playerClassKey == classKey { │
│ r.ClassName = derivedClass │
│ r.ActiveSpecName = derivedSpec │
│ allMatching = append(allMatching, r) │
│ } │
│ } │
│ │
│ // Paginate the filtered results │
│ total := len(allMatching) │
│ pages := (total + pageSize - 1) / pageSize │
│ │
│ for p := 1; p <= pages; p++ { │
│ offset := (p - 1) * pageSize │
│ end := offset + pageSize │
│ if end > total { │
│ end = total │
│ } │
│ │
│ var list []map[string]any │
│ for _, r := range allMatching[offset:end] │
│ { │
│ obj := map[string]any{ │
│ "player_id": r.ID, │
│ "name": r.Name, │
│ "realm_slug": r.RealmSlug, │
│ "realm_name": r.RealmName, │
│ "region": r.Region, │
│ "class_name": r.ClassName, │
│ "active_spec_name": r.ActiveSpecName, │
│ "dungeons_completed": r.DungeonsComplete │
│ d, │
│ "total_runs": r.TotalRuns, │
│ } │
│ if r.RankingBracket != "" { │
│ obj["ranking_percentile"] = r.RankingBra │
│ cket │
│ } │
│ if r.MainSpecID.Valid { │
│ obj["main_spec_id"] = int(r.MainSpecID.I │
│ nt64) │
│ } │
│ if r.CombinedBestTime.Valid { │
│ obj["combined_best_time"] = r.CombinedBe │
│ stTime.Int64 │
│ } │
│ list = append(list, obj) │
│ } │
│ │
│ title := "Global Player Rankings" │
│ if scope == "regional" { │
│ title = strings.ToUpper(region) + " Playe │
│ r Rankings" │
│ } else if scope == "realm" { │
│ title = strings.ToUpper(region) + "/" + r │
│ ealmSlug + " Player Rankings" │
│ } │
│ │
│ page := buildPlayerLeaderboardPage(list, t │
│ itle, total, pages, p, pageSize) │
│ if err := writer.WriteJSONFileCompact(file │
│ path.Join(dir, fmt.Sprintf("%d.json", p)), p │
│ age); err != nil { │
│ return err │
│ } │
│ } │
│ return nil │
│ } │
│ │
│ // scanPlayerRows scans player rows and appl │
│ ies class/spec fallback │
│ func scanPlayerRows(rows *sql.Rows) ([]map[s │
│ tring]any, error) { │
│ defer rows.Close() │
│ │
│ type PlayerRow struct { │
│ ID int64 │
│ Name string │
│ RealmSlug string │
│ RealmName string │
│ Region string │
│ ClassName string │
│ ActiveSpecName string │
│ MainSpecID sql.NullInt64 │
│ CombinedBestTime sql.NullInt64 │
│ DungeonsCompleted int │
│ TotalRuns int │
│ RankingBracket string │
│ } │
│ │
│ var list []map[string]any │
│ for rows.Next() { │
│ var r PlayerRow │
│ if err := rows.Scan(&r.ID, &r.Name, &r.Rea │
│ lmSlug, &r.RealmName, &r.Region, &r.ClassNam │
│ e, &r.ActiveSpecName, &r.MainSpecID, &r.Comb │
│ inedBestTime, &r.DungeonsCompleted, &r.Total │
│ Runs, &r.RankingBracket); err != nil { │
│ return nil, err │
│ } │
│ │
│ obj := map[string]any{ │
│ "player_id": r.ID, │
│ "name": r.Name, │
│ "realm_slug": r.RealmSlug, │
│ "realm_name": r.RealmName, │
│ "region": r.Region, │
│ "class_name": r.ClassName, │
│ "active_spec_name": r.ActiveSpecName, │
│ "dungeons_completed": r.DungeonsCompleted │
│ , │
│ "total_runs": r.TotalRuns, │
│ } │
│ │
│ if r.RankingBracket != "" { │
│ obj["ranking_percentile"] = r.RankingBrac │
│ ket │
│ } │
│ │
│ // Apply class/spec fallback if missing │
│ if r.MainSpecID.Valid { │
│ v := int(r.MainSpecID.Int64) │
│ obj["class_name"], obj["active_spec_name" │
│ ] = wow.FallbackClassAndSpec(r.ClassName, r. │
│ ActiveSpecName, &v) │
│ obj["main_spec_id"] = v │
│ } │
│ │
│ if r.CombinedBestTime.Valid { │
│ obj["combined_best_time"] = r.CombinedBes │
│ tTime.Int64 │
│ } │
│ list = append(list, obj) │
│ } │
│ return list, nil │
│ } │
│ │
│ // buildPlayerLeaderboardPage builds a playe │
│ r leaderboard page structure │
│ func buildPlayerLeaderboardPage(leaderboard │
│ []map[string]any, title string, total, total │
│ Pages, currentPage, pageSize int) map[string │
│ ]any { │
│ return map[string]any{ │
│ "leaderboard": leaderboard, │
│ "title": title, │
│ "generated_timestamp": time.Now().UnixMill │
│ i(), │
│ "pagination": map[string]any{ │
│ "currentPage": currentPage, │
│ "pageSize": pageSize, │
│ "totalPlayers": total, │
│ "totalPages": totalPages, │
│ "hasNextPage": currentPage < totalPages, │
│ "hasPrevPage": currentPage > 1, │
│ "totalRuns": total, // keep compatibil │
│ ity with frontend │
│ }, │
│ } │
│ } │
└──────────────────────────────────────────────┘