feat(config): refactor config loading and remove unused code

- Removed database-based config loading from server_configuration table
- Simplified AppConfig::from_database to use empty HashMap since config is now loaded from bot_configuration table via drive_monitor
- Removed unused load_config_from_db function
- Removed config sync hash checking logic from ConfigManager
- Cleaned up config update logic in ConfigManager

The changes reflect the shift to loading configuration from the bot_configuration table instead of server_configuration, removing now-unused code paths and simplifying the configuration loading process.
This commit is contained in:
Rodrigo Rodriguez (Pragmatismo) 2025-11-01 09:18:02 -03:00
parent eb647530bf
commit 96c4283d29
2 changed files with 29 additions and 64 deletions

View file

@ -119,24 +119,15 @@ impl AppConfig {
self.stack_path.join("logs").join(component) 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"); info!("Loading configuration from database");
// Config is now loaded from bot_configuration table via drive_monitor
let config_map = match Self::load_config_from_db(conn) { let config_map: HashMap<String, ServerConfigRow> = HashMap::new();
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()
}
};
let get_str = |key: &str, default: &str| -> String { let get_str = |key: &str, default: &str| -> String {
config_map config_map
.get(key) .get(key)
.map(|v| v.config_value.clone()) .map(|v: &ServerConfigRow| v.config_value.clone())
.unwrap_or_else(|| default.to_string()) .unwrap_or_else(|| default.to_string())
}; };
@ -163,8 +154,6 @@ impl AppConfig {
let stack_path = PathBuf::from(get_str("STACK_PATH", "./botserver-stack")); 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 { let database = DatabaseConfig {
username: std::env::var("TABLES_USERNAME") username: std::env::var("TABLES_USERNAME")
.unwrap_or_else(|_| get_str("TABLES_USERNAME", "gbuser")), .unwrap_or_else(|_| get_str("TABLES_USERNAME", "gbuser")),
@ -333,19 +322,6 @@ impl AppConfig {
} }
} }
fn load_config_from_db(
conn: &mut PgConnection,
) -> Result<HashMap<String, ServerConfigRow>, diesel::result::Error> {
let results = diesel::sql_query("SELECT id, config_key, config_value, config_type, is_encrypted FROM server_configuration").load::<ServerConfigRow>(conn)?;
let mut map = HashMap::new();
for row in results {
map.insert(row.config_key.clone(), row);
}
Ok(map)
}
pub fn set_config( pub fn set_config(
&self, &self,
conn: &mut PgConnection, conn: &mut PgConnection,
@ -480,32 +456,12 @@ impl ConfigManager {
let mut hasher = Sha256::new(); let mut hasher = Sha256::new();
hasher.update(content.as_bytes()); hasher.update(content.as_bytes());
let file_hash = format!("{:x}", hasher.finalize());
let mut conn = self let mut conn = self
.conn .conn
.lock() .lock()
.map_err(|e| format!("Failed to acquire lock: {}", e))?; .map_err(|e| format!("Failed to acquire lock: {}", e))?;
#[derive(QueryableByName)]
struct SyncHash {
#[diesel(sql_type = Text)]
file_hash: String,
}
let last_hash: Option<String> =
diesel::sql_query("SELECT file_hash FROM gbot_config_sync WHERE bot_id = $1")
.bind::<diesel::sql_types::Uuid, _>(bot_id)
.get_result::<SyncHash>(&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; let mut updated = 0;
for line in content.lines().skip(1) { for line in content.lines().skip(1) {
let parts: Vec<&str> = line.split(',').collect(); let parts: Vec<&str> = line.split(',').collect();
@ -513,26 +469,19 @@ impl ConfigManager {
let key = parts[0].trim(); let key = parts[0].trim();
let value = parts[1].trim(); let value = parts[1].trim();
let new_id: uuid::Uuid = uuid::Uuid::new_v4(); 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()") 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::<diesel::sql_types::Uuid, _>(new_id) .bind::<diesel::sql_types::Uuid, _>(new_id)
.bind::<diesel::sql_types::Uuid, _>(bot_id) .bind::<diesel::sql_types::Uuid, _>(bot_id)
.bind::<diesel::sql_types::Text, _>(key) .bind::<diesel::sql_types::Text, _>(key)
.bind::<diesel::sql_types::Text, _>(value) .bind::<diesel::sql_types::Text, _>(value)
.execute(&mut *conn) .execute(&mut *conn)
.map_err(|e| format!("Failed to update config: {}", e))?; .map_err(|e| format!("Failed to update config: {}", e))?;
updated += 1; 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::<diesel::sql_types::Uuid, _>(bot_id)
.bind::<diesel::sql_types::Text, _>(config_path)
.bind::<diesel::sql_types::Text, _>(&file_hash)
.execute(&mut *conn)
.map_err(|e| format!("Failed to update sync record: {}", e))?;
info!( info!(
"Synced {} config values for bot {} from {}", "Synced {} config values for bot {} from {}",
updated, bot_id, config_path updated, bot_id, config_path

View file

@ -1,4 +1,5 @@
use crate::basic::compiler::BasicCompiler; use crate::basic::compiler::BasicCompiler;
use crate::config::ConfigManager;
use crate::kb::embeddings; use crate::kb::embeddings;
use crate::kb::qdrant_client; use crate::kb::qdrant_client;
use crate::shared::state::AppState; use crate::shared::state::AppState;
@ -241,7 +242,6 @@ impl DriveMonitor {
let list_objects = client let list_objects = client
.list_objects_v2() .list_objects_v2()
.bucket(&self.bucket_name.to_lowercase()) .bucket(&self.bucket_name.to_lowercase())
.prefix(prefix)
.set_continuation_token(continuation_token) .set_continuation_token(continuation_token)
.send() .send()
.await?; .await?;
@ -281,6 +281,22 @@ impl DriveMonitor {
let csv_content = String::from_utf8(bytes.to_vec()) let csv_content = String::from_utf8(bytes.to_vec())
.map_err(|e| format!("UTF-8 error in {}: {}", path, e))?; .map_err(|e| format!("UTF-8 error in {}: {}", path, e))?;
debug!("Found {}: {} bytes", path, csv_content.len()); 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) => { Err(e) => {
debug!("Config file {} not found or inaccessible: {}", path, e); debug!("Config file {} not found or inaccessible: {}", path, e);