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)
}
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<String, ServerConfigRow> = 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<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(
&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<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;
for line in content.lines().skip(1) {
let parts: Vec<&str> = line.split(',').collect();
@ -513,8 +469,8 @@ 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()")
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::<diesel::sql_types::Uuid, _>(new_id)
.bind::<diesel::sql_types::Uuid, _>(bot_id)
.bind::<diesel::sql_types::Text, _>(key)
@ -526,13 +482,6 @@ diesel::sql_query("INSERT INTO bot_configuration (id, bot_id, config_key, config
}
}
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!(
"Synced {} config values for bot {} from {}",
updated, bot_id, config_path

View file

@ -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);