Compare commits
No commits in common. "60b397b529cb287818236ebedab5f8692ea6fab1" and "6d2b11a797be981ca820b45e73fa2e4762007ec8" have entirely different histories.
60b397b529
...
6d2b11a797
47
rust/Cargo.lock
generated
47
rust/Cargo.lock
generated
@ -270,15 +270,6 @@ version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5"
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-queue"
|
||||
version = "0.3.12"
|
||||
@ -1380,15 +1371,6 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "matchers"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9"
|
||||
dependencies = [
|
||||
"regex-automata",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "md-5"
|
||||
version = "0.10.6"
|
||||
@ -2239,7 +2221,6 @@ dependencies = [
|
||||
"tokio",
|
||||
"toml",
|
||||
"tracing",
|
||||
"tracing-appender",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
@ -2922,14 +2903,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c"
|
||||
dependencies = [
|
||||
"deranged",
|
||||
"itoa",
|
||||
"libc",
|
||||
"num-conv",
|
||||
"num_threads",
|
||||
"powerfmt",
|
||||
"serde_core",
|
||||
"time-core",
|
||||
"time-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2938,16 +2917,6 @@ version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca"
|
||||
|
||||
[[package]]
|
||||
name = "time-macros"
|
||||
version = "0.2.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215"
|
||||
dependencies = [
|
||||
"num-conv",
|
||||
"time-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinystr"
|
||||
version = "0.8.2"
|
||||
@ -3143,18 +3112,6 @@ dependencies = [
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-appender"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "786d480bce6247ab75f005b14ae1624ad978d3029d9113f0a22fa1ac773faeaf"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"thiserror 2.0.18",
|
||||
"time",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-attributes"
|
||||
version = "0.1.31"
|
||||
@ -3193,14 +3150,10 @@ version = "0.3.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e"
|
||||
dependencies = [
|
||||
"matchers",
|
||||
"nu-ansi-term",
|
||||
"once_cell",
|
||||
"regex-automata",
|
||||
"sharded-slab",
|
||||
"smallvec",
|
||||
"thread_local",
|
||||
"tracing",
|
||||
"tracing-core",
|
||||
"tracing-log",
|
||||
]
|
||||
|
||||
@ -31,8 +31,7 @@ thiserror = "2"
|
||||
|
||||
# Logging
|
||||
tracing = "0.1"
|
||||
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
||||
tracing-appender = "0.2"
|
||||
tracing-subscriber = "0.3"
|
||||
|
||||
# Date/time
|
||||
chrono = { version = "0.4", features = ["serde"] }
|
||||
|
||||
@ -22,8 +22,8 @@ pub async fn sync_teams(pool: &SqlitePool, season: i64, client: &LeagueApiClient
|
||||
for data in response.teams {
|
||||
let manager1_name = data.manager1.and_then(|m| m.name);
|
||||
let manager2_name = data.manager2.and_then(|m| m.name);
|
||||
let gm_discord_id = data.gm_discord_id;
|
||||
let gm2_discord_id = data.gm2_discord_id;
|
||||
let gm_discord_id = data.gm_discord_id.map(|id| id.to_string());
|
||||
let gm2_discord_id = data.gm2_discord_id.map(|id| id.to_string());
|
||||
let division_id = data.division.as_ref().map(|d| d.id).flatten();
|
||||
let division_name = data.division.as_ref().and_then(|d| d.division_name.clone());
|
||||
let league_abbrev = data.division.as_ref().and_then(|d| d.league_abbrev.clone());
|
||||
@ -185,6 +185,7 @@ pub async fn sync_transactions(
|
||||
continue;
|
||||
};
|
||||
|
||||
let move_id_str = move_id.to_string();
|
||||
let player_id = player.id;
|
||||
// Schema has from_team_id/to_team_id as NOT NULL; use 0 as sentinel for missing teams
|
||||
let from_team_id = data.oldteam.map(|t| t.id).unwrap_or(0);
|
||||
@ -205,7 +206,7 @@ pub async fn sync_transactions(
|
||||
)
|
||||
.bind(season)
|
||||
.bind(week)
|
||||
.bind(&move_id)
|
||||
.bind(move_id_str)
|
||||
.bind(player_id)
|
||||
.bind(from_team_id)
|
||||
.bind(to_team_id)
|
||||
|
||||
@ -59,12 +59,12 @@ pub struct TeamData {
|
||||
pub stadium: Option<String>,
|
||||
#[serde(default)]
|
||||
pub salary_cap: Option<f64>,
|
||||
/// Discord user ID of the primary GM (API sends as string).
|
||||
/// Discord user ID of the primary GM (API sends integer, DB stores as String).
|
||||
#[serde(rename = "gmid", default)]
|
||||
pub gm_discord_id: Option<String>,
|
||||
/// Discord user ID of the secondary GM (API sends as string).
|
||||
pub gm_discord_id: Option<i64>,
|
||||
/// Discord user ID of the secondary GM (API sends integer, DB stores as String).
|
||||
#[serde(rename = "gmid2", default)]
|
||||
pub gm2_discord_id: Option<String>,
|
||||
pub gm2_discord_id: Option<i64>,
|
||||
#[serde(default)]
|
||||
pub manager1: Option<Manager>,
|
||||
#[serde(default)]
|
||||
@ -147,9 +147,9 @@ pub struct TransactionsResponse {
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct TransactionData {
|
||||
/// Transaction move ID — API field is "moveid" (string like "Season-013-Week-11-1772073335").
|
||||
/// Transaction move ID — API field is "moveid".
|
||||
#[serde(rename = "moveid", default)]
|
||||
pub move_id: Option<String>,
|
||||
pub move_id: Option<i64>,
|
||||
#[serde(default)]
|
||||
pub week: Option<i64>,
|
||||
#[serde(default)]
|
||||
|
||||
@ -7,8 +7,7 @@ pub async fn init_pool(db_path: &Path) -> Result<SqlitePool> {
|
||||
let db_url = format!("sqlite://{}?mode=rwc", db_path.display());
|
||||
let options = SqliteConnectOptions::from_str(&db_url)?
|
||||
.create_if_missing(true)
|
||||
.journal_mode(sqlx::sqlite::SqliteJournalMode::Wal)
|
||||
.foreign_keys(false);
|
||||
.journal_mode(sqlx::sqlite::SqliteJournalMode::Wal);
|
||||
|
||||
let pool = SqlitePoolOptions::new()
|
||||
.max_connections(5)
|
||||
@ -19,6 +18,10 @@ pub async fn init_pool(db_path: &Path) -> Result<SqlitePool> {
|
||||
}
|
||||
|
||||
pub async fn create_tables(pool: &SqlitePool) -> Result<()> {
|
||||
sqlx::query("PRAGMA foreign_keys = ON")
|
||||
.execute(pool)
|
||||
.await?;
|
||||
|
||||
// 1. teams — API-provided PKs (no autoincrement)
|
||||
sqlx::query(
|
||||
"CREATE TABLE IF NOT EXISTS teams (
|
||||
@ -172,9 +175,9 @@ pub async fn create_tables(pool: &SqlitePool) -> Result<()> {
|
||||
season INTEGER NOT NULL,
|
||||
week INTEGER NOT NULL,
|
||||
move_id TEXT NOT NULL,
|
||||
player_id INTEGER NOT NULL,
|
||||
from_team_id INTEGER NOT NULL,
|
||||
to_team_id INTEGER NOT NULL,
|
||||
player_id INTEGER NOT NULL REFERENCES players(id),
|
||||
from_team_id INTEGER NOT NULL REFERENCES teams(id),
|
||||
to_team_id INTEGER NOT NULL REFERENCES teams(id),
|
||||
cancelled INTEGER DEFAULT 0,
|
||||
frozen INTEGER DEFAULT 0,
|
||||
synced_at TEXT,
|
||||
|
||||
@ -5,27 +5,11 @@ use ratatui::DefaultTerminal;
|
||||
use sqlx::sqlite::SqlitePool;
|
||||
use tokio::sync::mpsc;
|
||||
use tokio::time::{interval, Duration};
|
||||
use tracing_appender::non_blocking::WorkerGuard;
|
||||
use tracing_subscriber::EnvFilter;
|
||||
|
||||
use sba_scout::app::{App, AppMessage};
|
||||
use sba_scout::config;
|
||||
use sba_scout::db;
|
||||
|
||||
fn init_logging(log_dir: &std::path::Path) -> WorkerGuard {
|
||||
std::fs::create_dir_all(log_dir).ok();
|
||||
let file_appender = tracing_appender::rolling::never(log_dir, "sba-scout.log");
|
||||
let (non_blocking, guard) = tracing_appender::non_blocking(file_appender);
|
||||
tracing_subscriber::fmt()
|
||||
.with_writer(non_blocking)
|
||||
.with_env_filter(
|
||||
EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info")),
|
||||
)
|
||||
.with_ansi(false)
|
||||
.init();
|
||||
guard
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
let settings = match config::load_settings() {
|
||||
@ -36,9 +20,6 @@ async fn main() -> Result<()> {
|
||||
}
|
||||
};
|
||||
|
||||
let log_dir = settings.db_path.parent().unwrap_or(std::path::Path::new("data"));
|
||||
let _log_guard = init_logging(log_dir);
|
||||
|
||||
if let Some(parent) = settings.db_path.parent() {
|
||||
std::fs::create_dir_all(parent)?;
|
||||
}
|
||||
|
||||
@ -56,7 +56,6 @@ impl DashboardState {
|
||||
let _ = tx.send(AppMessage::RosterLoaded(roster));
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::error!("Failed to load roster: {e}");
|
||||
let _ = tx.send(AppMessage::Notify(
|
||||
format!("Failed to load roster: {e}"),
|
||||
NotifyLevel::Error,
|
||||
@ -120,7 +119,6 @@ impl DashboardState {
|
||||
);
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::error!("Sync failed: {e}");
|
||||
self.sync_state = SyncState::Error;
|
||||
self.sync_message = format!("Sync failed: {e}");
|
||||
}
|
||||
|
||||
@ -157,7 +157,6 @@ impl GamedayState {
|
||||
let _ = tx_c.send(AppMessage::TeamsLoaded(teams));
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::error!("Failed to load teams: {e}");
|
||||
let _ = tx_c.send(AppMessage::Notify(
|
||||
format!("Failed to load teams: {e}"),
|
||||
NotifyLevel::Error,
|
||||
@ -621,7 +620,6 @@ impl GamedayState {
|
||||
let _ = tx.send(AppMessage::PitchersLoaded(pitchers));
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::error!("Failed to load pitchers: {e}");
|
||||
let _ = tx.send(AppMessage::Notify(
|
||||
format!("Failed to load pitchers: {e}"),
|
||||
NotifyLevel::Error,
|
||||
@ -663,7 +661,6 @@ impl GamedayState {
|
||||
let _ = tx.send(AppMessage::MatchupsCalculated(results));
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::error!("Matchup calculation failed: {e}");
|
||||
let _ = tx.send(AppMessage::Notify(
|
||||
format!("Matchup calculation failed: {e}"),
|
||||
NotifyLevel::Error,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user