use serde::Deserialize; #[derive(Debug, Clone, Deserialize)] pub struct Config { #[serde(default = "default_database_url")] pub database_url: String, #[serde(default = "default_port")] pub server_port: u16, #[serde(default)] pub session_secure: bool, #[serde(default = "default_admin_username")] pub admin_username: String, #[serde(default = "default_admin_email")] pub admin_email: String, #[serde(default = "default_admin_password")] pub admin_password: String, #[serde(default = "default_mfa_enabled")] pub mfa_enabled: bool, #[serde(default = "default_mfa_service_name")] pub mfa_service_name: String, #[serde(default = "default_sync_interval")] pub sync_interval_secs: u64, #[serde(default = "default_sync_direction")] pub default_sync_direction: String, #[serde(default = "default_conflict_resolution")] pub conflict_resolution: String, #[serde(default = "default_max_workers")] pub max_workers: usize, #[serde(default = "default_smtp_host")] pub smtp_host: String, #[serde(default = "default_smtp_port")] pub smtp_port: u16, #[serde(default)] pub smtp_username: String, #[serde(default)] pub smtp_password: String, #[serde(default = "default_smtp_from")] pub smtp_from: String, } fn default_database_url() -> String { "postgresql://sap_user:papsync123@localhost:5432/sap_sync".to_string() } fn default_port() -> u16 { 3001 } fn default_admin_username() -> String { "admin".to_string() } fn default_admin_email() -> String { "admin@sap-sync.local".to_string() } fn default_admin_password() -> String { "Admin123!".to_string() } fn default_mfa_enabled() -> bool { true } fn default_mfa_service_name() -> String { "SAP Sync".to_string() } fn default_sync_interval() -> u64 { 3600 } fn default_sync_direction() -> String { "sap_to_plesk".to_string() } fn default_conflict_resolution() -> String { "timestamp_based".to_string() } fn default_max_workers() -> usize { 4 } fn default_smtp_host() -> String { "localhost".to_string() } fn default_smtp_port() -> u16 { 1025 } fn default_smtp_from() -> String { "noreply@sap-sync.local".to_string() } impl Config { pub fn from_env() -> Self { dotenvy::dotenv().ok(); Config { database_url: std::env::var("DATABASE_URL").unwrap_or_else(|_| default_database_url()), server_port: std::env::var("APP__SERVER__PORT") .or_else(|_| std::env::var("PORT")) .unwrap_or_else(|_| "3001".to_string()) .parse() .unwrap_or(default_port()), session_secure: std::env::var("APP__SESSION__SECURE") .map(|v| v == "1" || v == "true") .unwrap_or(false), admin_username: std::env::var("ADMIN_USERNAME") .unwrap_or_else(|_| default_admin_username()), admin_email: std::env::var("ADMIN_EMAIL").unwrap_or_else(|_| default_admin_email()), admin_password: std::env::var("ADMIN_PASSWORD") .unwrap_or_else(|_| default_admin_password()), mfa_enabled: std::env::var("APP__MFA__ENABLED") .map(|v| v == "1" || v == "true") .unwrap_or(default_mfa_enabled()), mfa_service_name: std::env::var("APP__MFA__QR_CODE_SERVICE_NAME") .unwrap_or_else(|_| default_mfa_service_name()), sync_interval_secs: std::env::var("APP__SYNC__DEFAULT_INTERVAL_SECONDS") .unwrap_or_else(|_| "3600".to_string()) .parse() .unwrap_or(default_sync_interval()), default_sync_direction: std::env::var("APP__SYNC__DEFAULT_DIRECTION") .unwrap_or_else(|_| default_sync_direction()), conflict_resolution: std::env::var("APP__SYNC__CONFLICT_RESOLUTION") .unwrap_or_else(|_| default_conflict_resolution()), max_workers: std::env::var("APP__SYNC__MAX_WORKERS") .unwrap_or_else(|_| "4".to_string()) .parse() .unwrap_or(default_max_workers()), smtp_host: std::env::var("SMTP_HOST").unwrap_or_else(|_| default_smtp_host()), smtp_port: std::env::var("SMTP_PORT") .unwrap_or_else(|_| "1025".to_string()) .parse() .unwrap_or(default_smtp_port()), smtp_username: std::env::var("SMTP_USERNAME").unwrap_or_default(), smtp_password: std::env::var("SMTP_PASSWORD").unwrap_or_default(), smtp_from: std::env::var("SMTP_FROM").unwrap_or_else(|_| default_smtp_from()), } } }