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_chart_url)
+ } else {
+ String::new()
+ };
- let charts_email_html = format!(
- r#"{}{}
- "#,
- if !singles_chart_url.is_empty() { format!(r#"
"#, singles_chart_url) } else { String::new() },
- if !doubles_chart_url.is_empty() { format!(r#"
"#, 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!("
Win rate when partnered together (all-time doubles)
@@ -2964,7 +2922,7 @@ async fn send_daily_summary(