use std::{net::SocketAddr, process::ExitCode}; use kakeibo::{config::Config, db, routes, state::AppState}; use tracing_subscriber::EnvFilter; #[tokio::main] async fn main() -> ExitCode { // .env dosyasını yükle (proje kökünde; üst klasörler de aranır). Yoksa sorun değil. dotenvy::dotenv().ok(); tracing_subscriber::fmt() .with_env_filter( EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("kakeibo=info")), ) .init(); let config = match Config::from_env() { Ok(c) => c, Err(e) => { tracing::error!("Ayar hatası: {e}"); return ExitCode::FAILURE; } }; let db = match db::connect(&config.mongodb_uri).await { Ok(db) => { tracing::info!("MongoDB bağlantısı kuruldu (veritabanı: {})", db.name()); db } Err(e) => { tracing::error!( "MongoDB'ye bağlanılamadı. MONGODB_URI doğru mu, veritabanı çalışıyor mu? \ (yerelde: npm run db:up)\nDetay: {e}" ); return ExitCode::FAILURE; } }; if let Err(e) = db::prepare(&db).await { tracing::error!("Veritabanı hazırlanamadı (migration/indeks): {e}"); return ExitCode::FAILURE; } let port = config.port; let state = AppState::new(db, config); let app = routes::router(state); let addr = SocketAddr::from(([0, 0, 0, 0], port)); let listener = match tokio::net::TcpListener::bind(addr).await { Ok(l) => l, Err(e) => { tracing::error!( "{port} portu dinlenemedi (başka bir uygulama kullanıyor olabilir): {e}" ); return ExitCode::FAILURE; } }; tracing::info!("Kakeibo API çalışıyor: http://localhost:{port}"); if let Err(e) = axum::serve(listener, app).await { tracing::error!("Sunucu hatası: {e}"); return ExitCode::FAILURE; } ExitCode::SUCCESS }