┌─ nix/pkgs/ookstats/src/cmd/generate.go ────────────────────────────────────┐
│ diff --git a/nix/pkgs/ookstats/src/cmd/generate.go b/nix/pkgs/ookstats/src/cmd/gen │
│ erate.go │
│ index 9881fb5..6df34ed 100644 │
│ --- a/nix/pkgs/ookstats/src/cmd/generate.go │
│ +++ b/nix/pkgs/ookstats/src/cmd/generate.go │
│ @@ -784,23 +784,77 @@ func generateSinglePlayerJSON(player PlayerData, bestRunsMap │
│ map[int64][]BestRun │
│ if err := os.MkdirAll(dir, 0o755); err != nil { │
│ return fmt.Errorf("mkdir player dir: %w", err) │
│ } │
│ - fname := filepath.Join(dir, strings.ToLower(pj.Name)+".json") │
│ + fname := filepath.Join(dir, safeSlugName(pj.Name)+".json") │
│ return writeJSONFile(fname, page) │
│ } │
│ │
│ +// safeSlugName converts an arbitrary player name to a safe lowercase filename wi │
│ thout path separators. │
│ +func safeSlugName(s string) string { │
│ + s = strings.ToLower(strings.TrimSpace(s)) │
│ + // replace path separators explicitly │
│ + s = strings.ReplaceAll(s, "/", "-") │
│ + s = strings.ReplaceAll(s, "\\", "-") │
│ + // allow a-z, 0-9, '-', '_' only; replace spaces with '-' │
│ + out := make([]rune, 0, len(s)) │
│ + for _, r := range s { │
│ + switch { │
│ + case r >= 'a' && r <= 'z': │
│ + out = append(out, r) │
│ + case r >= '0' && r <= '9': │
│ + out = append(out, r) │
│ + case r == '-' || r == '_': │
│ + out = append(out, r) │
│ + case r == ' ': │
│ + out = append(out, '-') │
│ + default: │
│ + // drop other runes │
│ + } │
│ + } │
│ + if len(out) == 0 { return "player" } │
│ + return string(out) │
│ +} │
│ + │
│ func writeJSONFile(path string, v any) error { │
│ - tmp := path + ".tmp" │
│ - f, err := os.Create(tmp) │
│ - if err != nil { return fmt.Errorf("create %s: %w", tmp, err) } │
│ - enc := json.NewEncoder(f) │
│ + // Ensure parent directory exists (robust for all callers) │
│ + if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil { │
│ + return fmt.Errorf("mkdir %s: %w", filepath.Dir(path), err) │
│ + } │
│ + │
│ + // Create a temp file in the target directory to avoid cross-filesystem issue │
│ s │
│ + tmpFile, err := os.CreateTemp(filepath.Dir(path), ".tmp-*.json") │
│ + if err != nil { │
│ + return fmt.Errorf("create temp for %s: %w", path, err) │
│ + } │
│ + tmp := tmpFile.Name() │
│ + │
│ + enc := json.NewEncoder(tmpFile) │
│ enc.SetEscapeHTML(false) │
│ enc.SetIndent("", " ") │
│ if err := enc.Encode(v); err != nil { │
│ - f.Close(); os.Remove(tmp) │
│ + tmpFile.Close() │
│ + os.Remove(tmp) │
│ return fmt.Errorf("encode json %s: %w", path, err) │
│ } │
│ - if err := f.Close(); err != nil { os.Remove(tmp); return err } │
│ - if err := os.Rename(tmp, path); err != nil { os.Remove(tmp); return fmt.Error │
│ f("rename %s: %w", path, err) } │
│ + // Flush to disk │
│ + if err := tmpFile.Sync(); err != nil { │
│ + tmpFile.Close() │
│ + os.Remove(tmp) │
│ + return fmt.Errorf("sync temp %s: %w", tmp, err) │
│ + } │
│ + if err := tmpFile.Close(); err != nil { │
│ + os.Remove(tmp) │
│ + return fmt.Errorf("close temp %s: %w", tmp, err) │
│ + } │
│ + │
│ + // Atomic replace; add a short retry in case of transient fs race │
│ + if err := os.Rename(tmp, path); err != nil { │
│ + // Retry once after ensuring parent dir again │
│ + _ = os.MkdirAll(filepath.Dir(path), 0o755) │
│ + if err2 := os.Rename(tmp, path); err2 != nil { │
│ + os.Remove(tmp) │
│ + return fmt.Errorf("rename %s: %w", path, err2) │
│ + } │
│ + } │
│ return nil │
│ } │
│ │
│ @@ -1143,6 +1197,243 @@ func generatePlayerLeaderboards(db *sql.DB, out string, pa │
│ geSize int, regions [] │
│ for _, reg := range regions { │
│ if err := writeScope("regional", reg); err != nil { return err } │
│ } │
│ + // realm scope (per region -> realm) │
│ + for _, reg := range regions { │
│ + rrows, err := db.Query(`SELECT slug FROM realms WHERE region = ? ORDER BY │
│ slug`, reg) │
│ + if err != nil { return fmt.Errorf("players realms list: %w", err) } │
│ + slugs := []string{} │
│ + for rrows.Next() { var s string; if err := rrows.Scan(&s); err != nil { r │
│ rows.Close(); return err }; slugs = append(slugs, s) } │
│ + rrows.Close() │
│ + for _, rslug := range slugs { │
│ + dir := filepath.Join(out, "players", "realm", reg, rslug) │
│ + if err := os.MkdirAll(dir, 0o755); err != nil { return err } │
│ + // count total │
│ + var total int │
│ + if err := db.QueryRow(` │
│ + SELECT COUNT(*) │
│ + 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 r.region = ? AND r.slug = ? AND pp.has_complete_coverage = │
│ 1 AND pp.combined_best_time IS NOT NULL │
│ + `, reg, rslug).Scan(&total); err != nil { return fmt.Errorf("players │
│ total (realm): %w", err) } │
│ + pages := (total + pageSize - 1) / pageSize │
│ + for p := 1; p <= pages; p++ { │
│ + offset := (p-1) * pageSize │
│ + rows, err := db.Query(` │
│ + SELECT p.id, p.name, r.slug, r.name, r.region, │
│ + COALESCE(pd.class_name,''), COALESCE(pd.active_spec_na │
│ me,''), pp.main_spec_id, │
│ + pp.combined_best_time, pp.dungeons_completed, pp.total │
│ _runs │
│ + 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 r.region = ? AND r.slug = ? AND pp.has_complete_coverag │
│ e = 1 AND pp.combined_best_time IS NOT NULL │
│ + ORDER BY pp.combined_best_time ASC, p.name ASC │
│ + LIMIT ? OFFSET ? │
│ + `, reg, rslug, pageSize, offset) │
│ + if err != nil { return err } │
│ + type PlayerRow struct { │
│ + ID int64; Name string; RealmSlug string; RealmName string; Re │
│ gion string; ClassName string; ActiveSpecName string; MainSpecID sql.NullInt64; Co │
│ mbinedBestTime sql.NullInt64; DungeonsCompleted int; TotalRuns int │
│ + } │
│ + list := []map[string]any{} │
│ + for rows.Next() { │
│ + var r PlayerRow │
│ + if err := rows.Scan(&r.ID, &r.Name, &r.RealmSlug, &r.RealmNam │
│ e, &r.Region, &r.ClassName, &r.ActiveSpecName, &r.MainSpecID, &r.CombinedBestTime, │
│ &r.DungeonsCompleted, &r.TotalRuns); err != nil { rows.Close(); return 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.MainSpecID.Valid { obj["main_spec_id"] = int(r.MainSpecI │
│ D.Int64) } │
│ + if r.CombinedBestTime.Valid { obj["combined_best_time"] = r.C │
│ ombinedBestTime.Int64 } │
│ + list = append(list, obj) │
│ + } │
│ + rows.Close() │
│ + page := map[string]any{ │
│ + "leaderboard": list, │
│ + "title": strings.ToUpper(reg) + "/" + rslug + " Player Rankin │
│ gs", │
│ + "generated_timestamp": time.Now().UnixMilli(), │
│ + "pagination": map[string]any{ │
│ + "currentPage": p, │
│ + "pageSize": pageSize, │
│ + "totalPlayers": total, │
│ + "totalPages": pages, │
│ + "hasNextPage": p < pages, │
│ + "hasPrevPage": p > 1, │
│ + "totalRuns": total, │
│ + }, │
│ + } │
│ + if err := writeJSONFile(filepath.Join(dir, fmt.Sprintf("%d.json", │
│ p)), page); err != nil { return err } │
│ + } │
│ + } │
│ + } │
│ + │
│ + // class-filtered variants │
│ + classKeys := []string{"death_knight","druid","hunter","mage","monk","paladin" │
│ ,"priest","rogue","shaman","warlock","warrior"} │
│ + │
│ + // helper to write class-scoped pages │
│ + writeClassScope := func(scope string, region string, realmSlug string, classK │
│ ey string) 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", re │
│ gion) │
│ + } else { │
│ + dir = filepath.Join(out, "players", "class", classKey, "realm", regio │
│ n, realmSlug) │
│ + } │
│ + if err := os.MkdirAll(dir, 0o755); err != nil { return err } │
│ + │
│ + // totals │
│ + var total int │
│ + if scope == "global" { │
│ + if err := db.QueryRow(` │
│ + SELECT COUNT(*) │
│ + FROM players p │
│ + JOIN player_profiles pp ON p.id = pp.player_id │
│ + LEFT JOIN player_details pd ON p.id = pd.player_id │
│ + WHERE pp.has_complete_coverage = 1 AND pp.combined_best_time IS N │
│ OT NULL │
│ + AND REPLACE(LOWER(pd.class_name),' ', '_') = ? │
│ + `, classKey).Scan(&total); err != nil { return fmt.Errorf("players to │
│ tal (class global): %w", err) } │
│ + } else if scope == "regional" { │
│ + if err := db.QueryRow(` │
│ + SELECT COUNT(*) │
│ + 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 r.region = ? AND pp.has_complete_coverage = 1 AND pp.combin │
│ ed_best_time IS NOT NULL │
│ + AND REPLACE(LOWER(pd.class_name),' ', '_') = ? │
│ + `, region, classKey).Scan(&total); err != nil { return fmt.Errorf("pl │
│ ayers total (class regional): %w", err) } │
│ + } else { │
│ + if err := db.QueryRow(` │
│ + SELECT COUNT(*) │
│ + 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 r.region = ? AND r.slug = ? AND pp.has_complete_coverage = │
│ 1 AND pp.combined_best_time IS NOT NULL │
│ + AND REPLACE(LOWER(pd.class_name),' ', '_') = ? │
│ + `, region, realmSlug, classKey).Scan(&total); err != nil { return fmt │
│ .Errorf("players total (class realm): %w", err) } │
│ + } │
│ + pages := (total + pageSize - 1) / pageSize │
│ + │
│ + for p := 1; p <= pages; p++ { │
│ + offset := (p-1) * pageSize │
│ + 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_na │
│ me,''), pp.main_spec_id, │
│ + pp.combined_best_time, pp.dungeons_completed, pp.total │
│ _runs │
│ + 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.has_complete_coverage = 1 AND pp.combined_best_time │
│ IS NOT NULL │
│ + AND REPLACE(LOWER(pd.class_name),' ', '_') = ? │
│ + ORDER BY pp.combined_best_time ASC, p.name ASC │
│ + LIMIT ? OFFSET ? │
│ + `, classKey, pageSize, offset) │
│ + } 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_na │
│ me,''), pp.main_spec_id, │
│ + pp.combined_best_time, pp.dungeons_completed, pp.total │
│ _runs │
│ + 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 r.region = ? AND pp.has_complete_coverage = 1 AND pp.co │
│ mbined_best_time IS NOT NULL │
│ + AND REPLACE(LOWER(pd.class_name),' ', '_') = ? │
│ + ORDER BY pp.combined_best_time ASC, p.name ASC │
│ + LIMIT ? OFFSET ? │
│ + `, region, classKey, pageSize, offset) │
│ + } else { │
│ + rows, err = db.Query(` │
│ + SELECT p.id, p.name, r.slug, r.name, r.region, │
│ + COALESCE(pd.class_name,''), COALESCE(pd.active_spec_na │
│ me,''), pp.main_spec_id, │
│ + pp.combined_best_time, pp.dungeons_completed, pp.total │
│ _runs │
│ + 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 r.region = ? AND r.slug = ? AND pp.has_complete_coverag │
│ e = 1 AND pp.combined_best_time IS NOT NULL │
│ + AND REPLACE(LOWER(pd.class_name),' ', '_') = ? │
│ + ORDER BY pp.combined_best_time ASC, p.name ASC │
│ + LIMIT ? OFFSET ? │
│ + `, region, realmSlug, classKey, pageSize, offset) │
│ + } │
│ + if err != nil { return err } │
│ + type PlayerRow struct { ID int64; Name, RealmSlug, RealmName, Region, │
│ ClassName, ActiveSpecName string; MainSpecID sql.NullInt64; CombinedBestTime sql. │
│ NullInt64; DungeonsCompleted, TotalRuns int } │
│ + 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.ClassName, &r.ActiveSpecName, &r.MainSpecID, &r.CombinedBestTime, &r. │
│ DungeonsCompleted, &r.TotalRuns); err != nil { rows.Close(); return 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.MainSpecID.Valid { obj["main_spec_id"] = int(r.MainSpecID.In │
│ t64) } │
│ + if r.CombinedBestTime.Valid { obj["combined_best_time"] = r.Combi │
│ nedBestTime.Int64 } │
│ + list = append(list, obj) │
│ + } │
│ + rows.Close() │
│ + pageObj := map[string]any{ │
│ + "leaderboard": list, │
│ + "title": func() string { │
│ + if scope == "global" { return "Global Player Rankings" } │
│ + if scope == "regional" { return strings.ToUpper(region) + " P │
│ layer Rankings" } │
│ + return strings.ToUpper(region) + "/" + realmSlug + " Player R │
│ ankings" │
│ + }(), │
│ + "generated_timestamp": time.Now().UnixMilli(), │
│ + "pagination": map[string]any{ │
│ + "currentPage": p, │
│ + "pageSize": pageSize, │
│ + "totalPlayers": total, │
│ + "totalPages": pages, │
│ + "hasNextPage": p < pages, │
│ + "hasPrevPage": p > 1, │
│ + "totalRuns": total, │
│ + }, │
│ + } │
│ + if err := writeJSONFile(filepath.Join(dir, fmt.Sprintf("%d.json", p)) │
│ , pageObj); err != nil { return err } │
│ + } │
│ + return nil │
│ + } │
│ + │
│ + // Generate class pages │
│ + for _, cls := range classKeys { │
│ + // global │
│ + if err := writeClassScope("global", "", "", cls); err != nil { return err │
│ } │
│ + // regional │
│ + for _, reg := range regions { │
│ + if err := writeClassScope("regional", reg, "", cls); err != nil { ret │
│ urn err } │
│ + // realm │
│ + rrows, err := db.Query(`SELECT slug FROM realms WHERE region = ? ORDE │
│ R BY slug`, reg) │
│ + if err != nil { return fmt.Errorf("players class realms list: %w", er │
│ r) } │
│ + slugs := []string{} │
│ + for rrows.Next() { var s string; if err := rrows.Scan(&s); err != nil │
│ { rrows.Close(); return err }; slugs = append(slugs, s) } │
│ + rrows.Close() │
│ + for _, rslug := range slugs { │
│ + if err := writeClassScope("realm", reg, rslug, cls); err != nil { │
│ return err } │
│ + } │
│ + } │
│ + } │
│ fmt.Println("[OK] Player leaderboards generated") │
│ return nil │
│ } │
└────────────────────────────────────────────────────────────────────────────────────┘
┌─ .../ookstats/src/cmd/generate.go ───┐
│ diff --git a/nix/pkgs/ookstats/src/cmd/gener │
│ ate.go b/nix/pkgs/ookstats/src/cmd/generate. │
│ go │
│ index 9881fb5..6df34ed 100644 │
│ --- a/nix/pkgs/ookstats/src/cmd/generate.go │
│ +++ b/nix/pkgs/ookstats/src/cmd/generate.go │
│ @@ -784,23 +784,77 @@ func generateSinglePla │
│ yerJSON(player PlayerData, bestRunsMap map[i │
│ nt64][]BestRun │
│ if err := os.MkdirAll(dir, 0o755); err │
│ != nil { │
│ return fmt.Errorf("mkdir player dir │
│ : %w", err) │
│ } │
│ - fname := filepath.Join(dir, strings.ToL │
│ ower(pj.Name)+".json") │
│ + fname := filepath.Join(dir, safeSlugNam │
│ e(pj.Name)+".json") │
│ return writeJSONFile(fname, page) │
│ } │
│ │
│ +// safeSlugName converts an arbitrary playe │
│ r name to a safe lowercase filename without │
│ path separators. │
│ +func safeSlugName(s string) string { │
│ + s = strings.ToLower(strings.TrimSpace(s │
│ )) │
│ + // replace path separators explicitly │
│ + s = strings.ReplaceAll(s, "/", "-") │
│ + s = strings.ReplaceAll(s, "\\", "-") │
│ + // allow a-z, 0-9, '-', '_' only; repla │
│ ce spaces with '-' │
│ + out := make([]rune, 0, len(s)) │
│ + for _, r := range s { │
│ + switch { │
│ + case r >= 'a' && r <= 'z': │
│ + out = append(out, r) │
│ + case r >= '0' && r <= '9': │
│ + out = append(out, r) │
│ + case r == '-' || r == '_': │
│ + out = append(out, r) │
│ + case r == ' ': │
│ + out = append(out, '-') │
│ + default: │
│ + // drop other runes │
│ + } │
│ + } │
│ + if len(out) == 0 { return "player" } │
│ + return string(out) │
│ +} │
│ + │
│ func writeJSONFile(path string, v any) erro │
│ r { │
│ - tmp := path + ".tmp" │
│ - f, err := os.Create(tmp) │
│ - if err != nil { return fmt.Errorf("crea │
│ te %s: %w", tmp, err) } │
│ - enc := json.NewEncoder(f) │
│ + // Ensure parent directory exists (robu │
│ st for all callers) │
│ + if err := os.MkdirAll(filepath.Dir(path │
│ ), 0o755); err != nil { │
│ + return fmt.Errorf("mkdir %s: %w", f │
│ ilepath.Dir(path), err) │
│ + } │
│ + │
│ + // Create a temp file in the target dir │
│ ectory to avoid cross-filesystem issues │
│ + tmpFile, err := os.CreateTemp(filepath. │
│ Dir(path), ".tmp-*.json") │
│ + if err != nil { │
│ + return fmt.Errorf("create temp for │
│ %s: %w", path, err) │
│ + } │
│ + tmp := tmpFile.Name() │
│ + │
│ + enc := json.NewEncoder(tmpFile) │
│ enc.SetEscapeHTML(false) │
│ enc.SetIndent("", " ") │
│ if err := enc.Encode(v); err != nil { │
│ - f.Close(); os.Remove(tmp) │
│ + tmpFile.Close() │
│ + os.Remove(tmp) │
│ return fmt.Errorf("encode json %s: │
│ %w", path, err) │
│ } │
│ - if err := f.Close(); err != nil { os.Re │
│ move(tmp); return err } │
│ - if err := os.Rename(tmp, path); err != │
│ nil { os.Remove(tmp); return fmt.Errorf("ren │
│ ame %s: %w", path, err) } │
│ + // Flush to disk │
│ + if err := tmpFile.Sync(); err != nil { │
│ + tmpFile.Close() │
│ + os.Remove(tmp) │
│ + return fmt.Errorf("sync temp %s: %w │
│ ", tmp, err) │
│ + } │
│ + if err := tmpFile.Close(); err != nil { │
│ + os.Remove(tmp) │
│ + return fmt.Errorf("close temp %s: % │
│ w", tmp, err) │
│ + } │
│ + │
│ + // Atomic replace; add a short retry in │
│ case of transient fs race │
│ + if err := os.Rename(tmp, path); err != │
│ nil { │
│ + // Retry once after ensuring parent │
│ dir again │
│ + _ = os.MkdirAll(filepath.Dir(path), │
│ 0o755) │
│ + if err2 := os.Rename(tmp, path); er │
│ r2 != nil { │
│ + os.Remove(tmp) │
│ + return fmt.Errorf("rename %s: % │
│ w", path, err2) │
│ + } │
│ + } │
│ return nil │
│ } │
│ │
│ @@ -1143,6 +1197,243 @@ func generatePlayerL │
│ eaderboards(db *sql.DB, out string, pageSize │
│ int, regions [] │
│ for _, reg := range regions { │
│ if err := writeScope("regional", re │
│ g); err != nil { return err } │
│ } │
│ + // realm scope (per region -> realm) │
│ + for _, reg := range regions { │
│ + rrows, err := db.Query(`SELECT slug │
│ FROM realms WHERE region = ? ORDER BY slug` │
│ , reg) │
│ + if err != nil { return fmt.Errorf(" │
│ players realms list: %w", err) } │
│ + slugs := []string{} │
│ + for rrows.Next() { var s string; if │
│ err := rrows.Scan(&s); err != nil { rrows.C │
│ lose(); return err }; slugs = append(slugs, │
│ s) } │
│ + rrows.Close() │
│ + for _, rslug := range slugs { │
│ + dir := filepath.Join(out, "play │
│ ers", "realm", reg, rslug) │
│ + if err := os.MkdirAll(dir, 0o75 │
│ 5); err != nil { return err } │
│ + // count total │
│ + var total int │
│ + if err := db.QueryRow(` │
│ + SELECT COUNT(*) │
│ + 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 r.region = ? AND r.sl │
│ ug = ? AND pp.has_complete_coverage = 1 AND │
│ pp.combined_best_time IS NOT NULL │
│ + `, reg, rslug).Scan(&total); er │
│ r != nil { return fmt.Errorf("players total │
│ (realm): %w", err) } │
│ + pages := (total + pageSize - 1) │
│ / pageSize │
│ + for p := 1; p <= pages; p++ { │
│ + offset := (p-1) * pageSize │
│ + rows, err := db.Query(` │
│ + SELECT p.id, p.name, r. │
│ slug, r.name, r.region, │
│ + COALESCE(pd.clas │
│ s_name,''), COALESCE(pd.active_spec_name,'') │
│ , pp.main_spec_id, │
│ + pp.combined_best │
│ _time, pp.dungeons_completed, pp.total_runs │
│ + FROM players p │
│ + JOIN realms r ON p.real │
│ m_id = r.id │
│ + JOIN player_profiles pp │
│ ON p.id = pp.player_id │
│ + LEFT JOIN player_detail │
│ s pd ON p.id = pd.player_id │
│ + WHERE r.region = ? AND │
│ r.slug = ? AND pp.has_complete_coverage = 1 │
│ AND pp.combined_best_time IS NOT NULL │
│ + ORDER BY pp.combined_be │
│ st_time ASC, p.name ASC │
│ + LIMIT ? OFFSET ? │
│ + `, reg, rslug, pageSize, of │
│ fset) │
│ + if err != nil { return err │
│ } │
│ + type PlayerRow struct { │
│ + ID int64; Name string; │
│ RealmSlug string; RealmName string; Region s │
│ tring; ClassName string; ActiveSpecName stri │
│ ng; MainSpecID sql.NullInt64; CombinedBestTi │
│ me sql.NullInt64; DungeonsCompleted int; Tot │
│ alRuns int │
│ + } │
│ + 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.ClassName, &r.ActiveSpecName, &r. │
│ MainSpecID, &r.CombinedBestTime, &r.Dungeons │
│ Completed, &r.TotalRuns); err != nil { rows. │
│ Close(); return err } │
│ + obj := map[string]any{ │
│ + "player_id": r.ID, │
│ + "name": r.Name, │
│ + "realm_slug": r.Rea │
│ lmSlug, │
│ + "realm_name": r.Rea │
│ lmName, │
│ + "region": r.Region, │
│ + "class_name": r.Cla │
│ ssName, │
│ + "active_spec_name": │
│ r.ActiveSpecName, │
│ + "dungeons_completed │
│ ": r.DungeonsCompleted, │
│ + "total_runs": r.Tot │
│ alRuns, │
│ + } │
│ + if r.MainSpecID.Valid { │
│ obj["main_spec_id"] = int(r.MainSpecID.Int6 │
│ 4) } │
│ + if r.CombinedBestTime.V │
│ alid { obj["combined_best_time"] = r.Combine │
│ dBestTime.Int64 } │
│ + list = append(list, obj │
│ ) │
│ + } │
│ + rows.Close() │
│ + page := map[string]any{ │
│ + "leaderboard": list, │
│ + "title": strings.ToUppe │
│ r(reg) + "/" + rslug + " Player Rankings", │
│ + "generated_timestamp": │
│ time.Now().UnixMilli(), │
│ + "pagination": map[strin │
│ g]any{ │
│ + "currentPage": p, │
│ + "pageSize": pageSiz │
│ e, │
│ + "totalPlayers": tot │
│ al, │
│ + "totalPages": pages │
│ , │
│ + "hasNextPage": p < │
│ pages, │
│ + "hasPrevPage": p > │
│ 1, │
│ + "totalRuns": total, │
│ + }, │
│ + } │
│ + if err := writeJSONFile(fil │
│ epath.Join(dir, fmt.Sprintf("%d.json", p)), │
│ page); err != nil { return err } │
│ + } │
│ + } │
│ + } │
│ + │
│ + // class-filtered variants │
│ + classKeys := []string{"death_knight","d │
│ ruid","hunter","mage","monk","paladin","prie │
│ st","rogue","shaman","warlock","warrior"} │
│ + │
│ + // helper to write class-scoped pages │
│ + writeClassScope := func(scope string, r │
│ egion string, realmSlug string, classKey str │
│ ing) error { │
│ + var dir string │
│ + if scope == "global" { │
│ + dir = filepath.Join(out, "playe │
│ rs", "class", classKey, "global") │
│ + } else if scope == "regional" { │
│ + dir = filepath.Join(out, "playe │
│ rs", "class", classKey, "regional", region) │
│ + } else { │
│ + dir = filepath.Join(out, "playe │
│ rs", "class", classKey, "realm", region, rea │
│ lmSlug) │
│ + } │
│ + if err := os.MkdirAll(dir, 0o755); │
│ err != nil { return err } │
│ + │
│ + // totals │
│ + var total int │
│ + if scope == "global" { │
│ + if err := db.QueryRow(` │
│ + SELECT COUNT(*) │
│ + FROM players p │
│ + JOIN player_profiles pp ON │
│ p.id = pp.player_id │
│ + LEFT JOIN player_details pd │
│ ON p.id = pd.player_id │
│ + WHERE pp.has_complete_cover │
│ age = 1 AND pp.combined_best_time IS NOT NUL │
│ L │
│ + AND REPLACE(LOWER(pd.clas │
│ s_name),' ', '_') = ? │
│ + `, classKey).Scan(&total); err │
│ != nil { return fmt.Errorf("players total (c │
│ lass global): %w", err) } │
│ + } else if scope == "regional" { │
│ + if err := db.QueryRow(` │
│ + SELECT COUNT(*) │
│ + 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 r.region = ? AND pp.h │
│ as_complete_coverage = 1 AND pp.combined_bes │
│ t_time IS NOT NULL │
│ + AND REPLACE(LOWER(pd.clas │
│ s_name),' ', '_') = ? │
│ + `, region, classKey).Scan(&tota │
│ l); err != nil { return fmt.Errorf("players │
│ total (class regional): %w", err) } │
│ + } else { │
│ + if err := db.QueryRow(` │
│ + SELECT COUNT(*) │
│ + 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 r.region = ? AND r.sl │
│ ug = ? AND pp.has_complete_coverage = 1 AND │
│ pp.combined_best_time IS NOT NULL │
│ + AND REPLACE(LOWER(pd.clas │
│ s_name),' ', '_') = ? │
│ + `, region, realmSlug, classKey) │
│ .Scan(&total); err != nil { return fmt.Error │
│ f("players total (class realm): %w", err) } │
│ + } │
│ + pages := (total + pageSize - 1) / p │
│ ageSize │
│ + │
│ + for p := 1; p <= pages; p++ { │
│ + offset := (p-1) * pageSize │
│ + 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.clas │
│ s_name,''), COALESCE(pd.active_spec_name,'') │
│ , pp.main_spec_id, │
│ + pp.combined_best │
│ _time, pp.dungeons_completed, pp.total_runs │
│ + FROM players p │
│ + JOIN realms r ON p.real │
│ m_id = r.id │
│ + JOIN player_profiles pp │
│ ON p.id = pp.player_id │
│ + LEFT JOIN player_detail │
│ s pd ON p.id = pd.player_id │
│ + WHERE pp.has_complete_c │
│ overage = 1 AND pp.combined_best_time IS NOT │
│ NULL │
│ + AND REPLACE(LOWER(pd. │
│ class_name),' ', '_') = ? │
│ + ORDER BY pp.combined_be │
│ st_time ASC, p.name ASC │
│ + LIMIT ? OFFSET ? │
│ + `, classKey, pageSize, offs │
│ et) │
│ + } else if scope == "regional" { │
│ + rows, err = db.Query(` │
│ + SELECT p.id, p.name, r. │
│ slug, r.name, r.region, │
│ + COALESCE(pd.clas │
│ s_name,''), COALESCE(pd.active_spec_name,'') │
│ , pp.main_spec_id, │
│ + pp.combined_best │
│ _time, pp.dungeons_completed, pp.total_runs │
│ + FROM players p │
│ + JOIN realms r ON p.real │
│ m_id = r.id │
│ + JOIN player_profiles pp │
│ ON p.id = pp.player_id │
│ + LEFT JOIN player_detail │
│ s pd ON p.id = pd.player_id │
│ + WHERE r.region = ? AND │
│ pp.has_complete_coverage = 1 AND pp.combined │
│ _best_time IS NOT NULL │
│ + AND REPLACE(LOWER(pd. │
│ class_name),' ', '_') = ? │
│ + ORDER BY pp.combined_be │
│ st_time ASC, p.name ASC │
│ + LIMIT ? OFFSET ? │
│ + `, region, classKey, pageSi │
│ ze, offset) │
│ + } else { │
│ + rows, err = db.Query(` │
│ + SELECT p.id, p.name, r. │
│ slug, r.name, r.region, │
│ + COALESCE(pd.clas │
│ s_name,''), COALESCE(pd.active_spec_name,'') │
│ , pp.main_spec_id, │
│ + pp.combined_best │
│ _time, pp.dungeons_completed, pp.total_runs │
│ + FROM players p │
│ + JOIN realms r ON p.real │
│ m_id = r.id │
│ + JOIN player_profiles pp │
│ ON p.id = pp.player_id │
│ + LEFT JOIN player_detail │
│ s pd ON p.id = pd.player_id │
│ + WHERE r.region = ? AND │
│ r.slug = ? AND pp.has_complete_coverage = 1 │
│ AND pp.combined_best_time IS NOT NULL │
│ + AND REPLACE(LOWER(pd. │
│ class_name),' ', '_') = ? │
│ + ORDER BY pp.combined_be │
│ st_time ASC, p.name ASC │
│ + LIMIT ? OFFSET ? │
│ + `, region, realmSlug, class │
│ Key, pageSize, offset) │
│ + } │
│ + if err != nil { return err } │
│ + type PlayerRow struct { ID int6 │
│ 4; Name, RealmSlug, RealmName, Region, Class │
│ Name, ActiveSpecName string; MainSpecID sql. │
│ NullInt64; CombinedBestTime sql.NullInt64; D │
│ ungeonsCompleted, TotalRuns int } │
│ + list := []map[string]any{} │
│ + for rows.Next() { │
│ + var r PlayerRow │
│ + if err := rows.Scan(&r.ID, │
│ &r.Name, &r.RealmSlug, &r.RealmName, &r.Regi │
│ on, &r.ClassName, &r.ActiveSpecName, &r.Main │
│ SpecID, &r.CombinedBestTime, &r.DungeonsComp │
│ leted, &r.TotalRuns); err != nil { rows.Clos │
│ e(); return err } │
│ + obj := map[string]any{ │
│ + "player_id": r.ID, │
│ + "name": r.Name, │
│ + "realm_slug": r.RealmSl │
│ ug, │
│ + "realm_name": r.RealmNa │
│ me, │
│ + "region": r.Region, │
│ + "class_name": r.ClassNa │
│ me, │
│ + "active_spec_name": r.A │
│ ctiveSpecName, │
│ + "dungeons_completed": r │
│ .DungeonsCompleted, │
│ + "total_runs": r.TotalRu │
│ ns, │
│ + } │
│ + if r.MainSpecID.Valid { obj │
│ ["main_spec_id"] = int(r.MainSpecID.Int64) } │
│ + if r.CombinedBestTime.Valid │
│ { obj["combined_best_time"] = r.CombinedBes │
│ tTime.Int64 } │
│ + list = append(list, obj) │
│ + } │
│ + rows.Close() │
│ + pageObj := map[string]any{ │
│ + "leaderboard": list, │
│ + "title": func() string { │
│ + if scope == "global" { │
│ return "Global Player Rankings" } │
│ + if scope == "regional" │
│ { return strings.ToUpper(region) + " Player │
│ Rankings" } │
│ + return strings.ToUpper( │
│ region) + "/" + realmSlug + " Player Ranking │
│ s" │
│ + }(), │
│ + "generated_timestamp": time │
│ .Now().UnixMilli(), │
│ + "pagination": map[string]an │
│ y{ │
│ + "currentPage": p, │
│ + "pageSize": pageSize, │
│ + "totalPlayers": total, │
│ + "totalPages": pages, │
│ + "hasNextPage": p < page │
│ s, │
│ + "hasPrevPage": p > 1, │
│ + "totalRuns": total, │
│ + }, │
│ + } │
│ + if err := writeJSONFile(filepat │
│ h.Join(dir, fmt.Sprintf("%d.json", p)), page │
│ Obj); err != nil { return err } │
│ + } │
│ + return nil │
│ + } │
│ + │
│ + // Generate class pages │
│ + for _, cls := range classKeys { │
│ + // global │
│ + if err := writeClassScope("global", │
│ "", "", cls); err != nil { return err } │
│ + // regional │
│ + for _, reg := range regions { │
│ + if err := writeClassScope("regi │
│ onal", reg, "", cls); err != nil { return er │
│ r } │
│ + // realm │
│ + rrows, err := db.Query(`SELECT │
│ slug FROM realms WHERE region = ? ORDER BY s │
│ lug`, reg) │
│ + if err != nil { return fmt.Erro │
│ rf("players class realms list: %w", err) } │
│ + slugs := []string{} │
│ + for rrows.Next() { var s string │
│ ; if err := rrows.Scan(&s); err != nil { rro │
│ ws.Close(); return err }; slugs = append(slu │
│ gs, s) } │
│ + rrows.Close() │
│ + for _, rslug := range slugs { │
│ + if err := writeClassScope(" │
│ realm", reg, rslug, cls); err != nil { retur │
│ n err } │
│ + } │
│ + } │
│ + } │
│ fmt.Println("[OK] Player leaderboards g │
│ enerated") │
│ return nil │
│ } │
└──────────────────────────────────────────────┘