diff --git a/src/config/mod.rs b/src/config/mod.rs index d2e32362c..1bed62d4a 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -119,24 +119,15 @@ impl AppConfig { self.stack_path.join("logs").join(component) } - pub fn from_database(conn: &mut PgConnection) -> Self { + pub fn from_database(_conn: &mut PgConnection) -> Self { info!("Loading configuration from database"); - - let config_map = match Self::load_config_from_db(conn) { - Ok(map) => { - info!("Loaded {} config values from database", map.len()); - map - } - Err(e) => { - warn!("Failed to load config from database: {}. Using defaults", e); - HashMap::new() - } - }; + // Config is now loaded from bot_configuration table via drive_monitor + let config_map: HashMap = HashMap::new(); let get_str = |key: &str, default: &str| -> String { config_map .get(key) - .map(|v| v.config_value.clone()) + .map(|v: &ServerConfigRow| v.config_value.clone()) .unwrap_or_else(|| default.to_string()) }; @@ -163,8 +154,6 @@ impl AppConfig { let stack_path = PathBuf::from(get_str("STACK_PATH", "./botserver-stack")); - // For database credentials, prioritize environment variables over database values - // because we need the correct credentials to connect to the database in the first place let database = DatabaseConfig { username: std::env::var("TABLES_USERNAME") .unwrap_or_else(|_| get_str("TABLES_USERNAME", "gbuser")), @@ -333,19 +322,6 @@ impl AppConfig { } } - fn load_config_from_db( - conn: &mut PgConnection, - ) -> Result, diesel::result::Error> { - let results = diesel::sql_query("SELECT id, config_key, config_value, config_type, is_encrypted FROM server_configuration").load::(conn)?; - - let mut map = HashMap::new(); - for row in results { - map.insert(row.config_key.clone(), row); - } - - Ok(map) - } - pub fn set_config( &self, conn: &mut PgConnection, @@ -480,32 +456,12 @@ impl ConfigManager { let mut hasher = Sha256::new(); hasher.update(content.as_bytes()); - let file_hash = format!("{:x}", hasher.finalize()); let mut conn = self .conn .lock() .map_err(|e| format!("Failed to acquire lock: {}", e))?; - #[derive(QueryableByName)] - struct SyncHash { - #[diesel(sql_type = Text)] - file_hash: String, - } - - let last_hash: Option = - diesel::sql_query("SELECT file_hash FROM gbot_config_sync WHERE bot_id = $1") - .bind::(bot_id) - .get_result::(&mut *conn) - .optional() - .map_err(|e| format!("Database error: {}", e))? - .map(|row| row.file_hash); - - if last_hash.as_ref() == Some(&file_hash) { - info!("Config file unchanged for bot {}", bot_id); - return Ok(0); - } - let mut updated = 0; for line in content.lines().skip(1) { let parts: Vec<&str> = line.split(',').collect(); @@ -513,26 +469,19 @@ impl ConfigManager { let key = parts[0].trim(); let value = parts[1].trim(); -let new_id: uuid::Uuid = uuid::Uuid::new_v4(); -diesel::sql_query("INSERT INTO bot_configuration (id, bot_id, config_key, config_value, config_type) VALUES ($1, $2, $3, $4, 'string') ON CONFLICT (bot_id, config_key) DO UPDATE SET config_value = EXCLUDED.config_value, updated_at = NOW()") - .bind::(new_id) - .bind::(bot_id) - .bind::(key) - .bind::(value) - .execute(&mut *conn) - .map_err(|e| format!("Failed to update config: {}", e))?; + let new_id: uuid::Uuid = uuid::Uuid::new_v4(); + diesel::sql_query("INSERT INTO bot_configuration (id, bot_id, config_key, config_value, config_type) VALUES ($1, $2, $3, $4, 'string') ON CONFLICT (bot_id, config_key) DO UPDATE SET config_value = EXCLUDED.config_value, updated_at = NOW()") + .bind::(new_id) + .bind::(bot_id) + .bind::(key) + .bind::(value) + .execute(&mut *conn) + .map_err(|e| format!("Failed to update config: {}", e))?; updated += 1; } } - diesel::sql_query("INSERT INTO gbot_config_sync (id, bot_id, config_file_path, file_hash, sync_count) VALUES (gen_random_uuid()::text, $1, $2, $3, 1) ON CONFLICT (bot_id) DO UPDATE SET last_sync_at = NOW(), file_hash = EXCLUDED.file_hash, sync_count = gbot_config_sync.sync_count + 1") - .bind::(bot_id) - .bind::(config_path) - .bind::(&file_hash) - .execute(&mut *conn) - .map_err(|e| format!("Failed to update sync record: {}", e))?; - info!( "Synced {} config values for bot {} from {}", updated, bot_id, config_path diff --git a/src/drive_monitor/mod.rs b/src/drive_monitor/mod.rs index bf61fbbbd..3b4ab605d 100644 --- a/src/drive_monitor/mod.rs +++ b/src/drive_monitor/mod.rs @@ -1,4 +1,5 @@ use crate::basic::compiler::BasicCompiler; +use crate::config::ConfigManager; use crate::kb::embeddings; use crate::kb::qdrant_client; use crate::shared::state::AppState; @@ -241,7 +242,6 @@ impl DriveMonitor { let list_objects = client .list_objects_v2() .bucket(&self.bucket_name.to_lowercase()) - .prefix(prefix) .set_continuation_token(continuation_token) .send() .await?; @@ -281,6 +281,22 @@ impl DriveMonitor { let csv_content = String::from_utf8(bytes.to_vec()) .map_err(|e| format!("UTF-8 error in {}: {}", path, e))?; debug!("Found {}: {} bytes", path, csv_content.len()); + + // Parse config.csv and update bot configuration + let bot_id = path.split('/') + .nth(1) + .and_then(|s| s.strip_suffix(".gbot")) + .and_then(|s| uuid::Uuid::parse_str(s).ok()) + .unwrap_or(uuid::Uuid::nil()); + + if bot_id != uuid::Uuid::nil() { + let config_manager = ConfigManager::new(Arc::clone(&self.state.conn)); + if let Err(e) = config_manager.sync_gbot_config(&bot_id, &csv_content) { + error!("Failed to sync config for bot {} {}: {}", path, bot_id, e); + } else { + info!("Successfully synced config for bot {}", bot_id); + } + } } Err(e) => { debug!("Config file {} not found or inaccessible: {}", path, e);