diff --git a/crates/dtrack-config/src/lib.rs b/crates/dtrack-config/src/lib.rs index f928de1..c16363f 100644 --- a/crates/dtrack-config/src/lib.rs +++ b/crates/dtrack-config/src/lib.rs @@ -4,9 +4,8 @@ use std::path::Path; /// Laufzeit-Konfiguration des DT-MCP. /// -/// Bewusst serde-(de)serialisierbar, damit sie spaeter ueber die Admin-UI -/// (Stage 3) editiert und auf Platte persistiert werden kann. Aufloesung: -/// explizite Datei (`DTRACK_CONFIG`) hat Vorrang, sonst Umgebungsvariablen. +/// Bewusst serde-(de)serialisierbar, damit sie ueber die Admin-UI editiert und +/// auf Platte persistiert werden kann. Aufloesung via [`DtrackConfig::resolve`]. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct DtrackConfig { /// Basis-URL der DT-Instanz, z.B. https://dtrack.firma.intern @@ -36,7 +35,7 @@ impl DtrackConfig { } /// Baut die Config aus Umgebungsvariablen (`DTRACK_URL` / `DTRACK_API_KEY` - /// / `DTRACK_INSECURE`). Das ist der Pfad fuers stdio-Binary auf dem Laptop. + /// / `DTRACK_INSECURE`). pub fn from_env() -> Result { let url = std::env::var("DTRACK_URL").context("DTRACK_URL nicht gesetzt")?; let api_key = std::env::var("DTRACK_API_KEY").context("DTRACK_API_KEY nicht gesetzt")?; @@ -46,10 +45,21 @@ impl DtrackConfig { Ok(Self { url, api_key, insecure }) } - /// Aufloesung mit Vorrang: explizite Datei (`DTRACK_CONFIG`) -> sonst env. + /// Aufloesung der Config: + /// - `DTRACK_CONFIG` gesetzt + Datei existiert -> Datei laden + /// - `DTRACK_CONFIG` gesetzt + Datei fehlt -> aus env bootstrappen und + /// in die Datei schreiben (danach ist die Datei die Quelle der Wahrheit) + /// - `DTRACK_CONFIG` nicht gesetzt -> nur env pub fn resolve() -> Result { match std::env::var("DTRACK_CONFIG") { - Ok(path) => Self::load(path), + Ok(path) if Path::new(&path).exists() => Self::load(path), + Ok(path) => { + let cfg = Self::from_env()?; + if let Err(e) = cfg.save(&path) { + eprintln!("Warnung: Bootstrap-Config nicht schreibbar ({path}): {e}"); + } + Ok(cfg) + } Err(_) => Self::from_env(), } }