diff --git a/logs/pickleball-error.log b/logs/pickleball-error.log index ac7feee..ceb6c2d 100644 --- a/logs/pickleball-error.log +++ b/logs/pickleball-error.log @@ -719,3 +719,4 @@ thread 'main' (234988) panicked at src/main.rs:52:10: called `Result::unwrap()` on an `Err` value: Os { code: 48, kind: AddrInUse, message: "Address already in use" } note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace Migration error: error returned from database: (code: 1) no such column: rating +Migration error: error returned from database: (code: 1) no such column: rating diff --git a/logs/pickleball.log b/logs/pickleball.log index df71231..22ee3bb 100644 --- a/logs/pickleball.log +++ b/logs/pickleball.log @@ -1068,3 +1068,16 @@ Starting Pickleball ELO Tracker Server on port 3000... ➕ Add Player: http://localhost:3000/players/new 🎾 Record Match: http://localhost:3000/matches/new +🏓 Pickleball ELO Tracker v3.0 +============================== + +Starting Pickleball ELO Tracker Server on port 3000... + +✅ Server running at http://localhost:3000 +📊 Leaderboard: http://localhost:3000/leaderboard +📜 Match History: http://localhost:3000/matches +👥 Players: http://localhost:3000/players +⚖️ Team Balancer: http://localhost:3000/balance +➕ Add Player: http://localhost:3000/players/new +🎾 Record Match: http://localhost:3000/matches/new + diff --git a/pickleball-elo b/pickleball-elo index 579fff9..31c52a2 100755 Binary files a/pickleball-elo and b/pickleball-elo differ diff --git a/src/main.rs b/src/main.rs index 588cbb3..628fa1b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2766,14 +2766,14 @@ async fn send_daily_summary( format!("https://quickchart.io/chart?c={}&w=500&h=250&bkg=white", encoded) } - // Get singles/doubles history for email charts - let singles_email_history: Vec<(i64, String, String, f64)> = sqlx::query_as( + // Get unified ELO history for email chart (all match types) + let elo_email_history: Vec<(i64, String, String, f64)> = sqlx::query_as( r#"SELECT m.id, strftime('%H:%M', datetime(m.timestamp, '-5 hours')) as time_str, p.name, mp.rating_after FROM matches m JOIN match_participants mp ON m.id = mp.match_id JOIN players p ON mp.player_id = p.id - WHERE date(m.timestamp) = ? AND m.match_type = 'singles' + WHERE date(m.timestamp) = ? ORDER BY m.timestamp, p.name"# ) .bind(&target_date) @@ -2781,32 +2781,16 @@ async fn send_daily_summary( .await .unwrap_or_default(); - let doubles_email_history: Vec<(i64, String, String, f64)> = sqlx::query_as( - r#"SELECT m.id, strftime('%H:%M', datetime(m.timestamp, '-5 hours')) as time_str, - p.name, mp.rating_after - FROM matches m - JOIN match_participants mp ON m.id = mp.match_id - JOIN players p ON mp.player_id = p.id - WHERE date(m.timestamp) = ? AND m.match_type = 'doubles' - ORDER BY m.timestamp, p.name"# - ) - .bind(&target_date) - .fetch_all(&state.pool) - .await - .unwrap_or_default(); + let elo_chart_url = build_email_chart(&elo_email_history, &colors_email, "Unified ELO Rating"); - let singles_chart_url = build_email_chart(&singles_email_history, &colors_email, "Singles Rating"); - let doubles_chart_url = build_email_chart(&doubles_email_history, &colors_email, "Doubles Rating"); + let charts_email_html = if !elo_chart_url.is_empty() { + format!(r#"ELO Rating Chart"#, elo_chart_url) + } else { + String::new() + }; - let charts_email_html = format!( - r#"{}{} - "#, - if !singles_chart_url.is_empty() { format!(r#"Singles Rating Chart"#, singles_chart_url) } else { String::new() }, - if !doubles_chart_url.is_empty() { format!(r#"Doubles Rating Chart"#, doubles_chart_url) } else { String::new() } - ); - - // Get leaderboard data - let top_singles: Vec<(String, f64)> = sqlx::query_as( + // Get unified leaderboard data + let top_players: Vec<(String, f64)> = sqlx::query_as( r#"SELECT DISTINCT p.name, p.singles_rating FROM players p JOIN match_participants mp ON p.id = mp.player_id @@ -2816,24 +2800,7 @@ async fn send_daily_summary( .await .unwrap_or_default(); - let top_doubles: Vec<(String, f64)> = sqlx::query_as( - r#"SELECT DISTINCT p.name, p.singles_rating - FROM players p - JOIN match_participants mp ON p.id = mp.player_id - ORDER BY p.singles_rating DESC LIMIT 5"# - ) - .fetch_all(&state.pool) - .await - .unwrap_or_default(); - - let singles_html: String = top_singles.iter().enumerate() - .map(|(i, (name, rating))| { - let medal = match i { 0 => "🥇", 1 => "🥈", 2 => "🥉", _ => "" }; - format!("{} {}. {}{:.0}", medal, i+1, name, rating) - }) - .collect(); - - let doubles_html: String = top_doubles.iter().enumerate() + let leaderboard_html: String = top_players.iter().enumerate() .map(|(i, (name, rating))| { let medal = match i { 0 => "🥇", 1 => "🥈", 2 => "🥉", _ => "" }; format!("{} {}. {}{:.0}", medal, i+1, name, rating) @@ -2942,17 +2909,8 @@ async fn send_daily_summary( {} -

📊 Leaderboard

-
-
-

Singles

- {}
-
-
-

Doubles

- {}
-
-
+

📊 Leaderboard (Unified ELO)

+ {}

🤝 Partner Synergy

Win rate when partnered together (all-time doubles)

@@ -2964,7 +2922,7 @@ async fn send_daily_summary( - "#, target_date, matches_email_html, charts_email_html, players_email_html, singles_html, doubles_html, heatmap_email); + "#, target_date, matches_email_html, charts_email_html, players_email_html, leaderboard_html, heatmap_email); // Send emails use lettre::{Message, SmtpTransport, Transport};