use crate::error::{AppError, AppResult}; use std::env; #[derive(Clone, Debug)] pub struct Config { pub database_url: String, pub port: u16, pub zen_api_key: Option, pub tavily_api_key: Option, pub authentik_issuer: String, pub authentik_client_id: String, pub authentik_client_secret: String, pub cors_allowed_origins: Option, pub cookie_secure: bool, pub agent_max_turns: u32, pub agent_max_duration_secs: u64, pub vapid_private_key: String, pub vapid_public_key: String, } impl Config { pub fn from_env() -> AppResult { dotenvy::dotenv().ok(); let database_url = env::var("DATABASE_URL") .map_err(|_| AppError::Config("DATABASE_URL must be set".into()))?; let port = env::var("PORT") .ok() .and_then(|s| s.parse().ok()) .unwrap_or(3000); let zen_api_key = env::var("ZEN_API_KEY").ok(); let tavily_api_key = env::var("TAVILY_API_KEY").ok(); let authentik_issuer = env::var("AUTHENTIK_ISSUER") .map_err(|_| AppError::Config("AUTHENTIK_ISSUER must be set".into()))?; let authentik_client_id = env::var("AUTHENTIK_CLIENT_ID") .map_err(|_| AppError::Config("AUTHENTIK_CLIENT_ID must be set".into()))?; let authentik_client_secret = env::var("AUTHENTIK_CLIENT_SECRET") .map_err(|_| AppError::Config("AUTHENTIK_CLIENT_SECRET must be set".into()))?; let cors_allowed_origins = env::var("CORS_ALLOWED_ORIGINS").ok(); let cookie_secure = env::var("COOKIE_SECURE") .map(|v| v == "true") .unwrap_or(false); let agent_max_turns = env::var("AGENT_MAX_TURNS") .ok() .and_then(|s| s.parse().ok()) .unwrap_or(20); let agent_max_duration_secs = env::var("AGENT_MAX_DURATION_SECS") .ok() .and_then(|s| s.parse().ok()) .unwrap_or(120); let vapid_private_key = env::var("VAPID_PRIVATE_KEY") .map_err(|_| AppError::Config("VAPID_PRIVATE_KEY must be set".into()))?; let vapid_public_key = env::var("VAPID_PUBLIC_KEY") .map_err(|_| AppError::Config("VAPID_PUBLIC_KEY must be set".into()))?; Ok(Config { database_url, port, zen_api_key, tavily_api_key, authentik_issuer, authentik_client_id, authentik_client_secret, cors_allowed_origins, cookie_secure, agent_max_turns, agent_max_duration_secs, vapid_private_key, vapid_public_key, }) } }