semantic update

This commit is contained in:
2026-03-10 21:33:09 +03:00
parent 542835e0ff
commit b77fa45e4e
10 changed files with 2084 additions and 1499 deletions

View File

@@ -36,18 +36,23 @@ class ConfigManager:
# @SIDE_EFFECT: Reads config sources and updates logging configuration.
# @DATA_CONTRACT: Input(str config_path) -> Output(None; self.config: AppConfig)
def __init__(self, config_path: str = "config.json"):
with belief_scope("__init__"):
assert isinstance(config_path, str) and config_path, "config_path must be a non-empty string"
with belief_scope("ConfigManager.__init__"):
if not isinstance(config_path, str) or not config_path:
logger.explore("Invalid config_path provided", extra={"path": config_path})
raise ValueError("config_path must be a non-empty string")
logger.info(f"[ConfigManager][Entry] Initializing with legacy path {config_path}")
logger.reason(f"Initializing ConfigManager with legacy path: {config_path}")
self.config_path = Path(config_path)
self.config: AppConfig = self._load_config()
configure_logger(self.config.settings.logging)
assert isinstance(self.config, AppConfig), "self.config must be an instance of AppConfig"
if not isinstance(self.config, AppConfig):
logger.explore("Config loading resulted in invalid type", extra={"type": type(self.config)})
raise TypeError("self.config must be an instance of AppConfig")
logger.info("[ConfigManager][Exit] Initialized")
logger.reflect("ConfigManager initialization complete")
# [/DEF:__init__:Function]
# [DEF:_default_config:Function]
@@ -104,20 +109,23 @@ class ConfigManager:
# @SIDE_EFFECT: Database read/write, possible migration write, logging.
# @DATA_CONTRACT: Input(None) -> Output(AppConfig)
def _load_config(self) -> AppConfig:
with belief_scope("_load_config"):
with belief_scope("ConfigManager._load_config"):
session: Session = SessionLocal()
try:
record = self._get_record(session)
if record and record.payload:
logger.info("[_load_config][Coherence:OK] Configuration loaded from database")
return AppConfig(**record.payload)
logger.reason("Configuration found in database")
config = AppConfig(**record.payload)
logger.reflect("Database configuration validated")
return config
logger.info("[_load_config][Action] No database config found, migrating legacy config")
logger.reason("No database config found, initiating legacy migration")
config = self._load_from_legacy_file()
self._save_config_to_db(config, session=session)
logger.reflect("Legacy configuration migrated to database")
return config
except Exception as e:
logger.error(f"[_load_config][Coherence:Failed] Error loading config from DB: {e}")
logger.explore(f"Error loading config from DB: {e}")
return self._default_config()
finally:
session.close()
@@ -130,8 +138,9 @@ class ConfigManager:
# @SIDE_EFFECT: Database insert/update, commit/rollback, logging.
# @DATA_CONTRACT: Input(AppConfig, Optional[Session]) -> Output(None)
def _save_config_to_db(self, config: AppConfig, session: Optional[Session] = None):
with belief_scope("_save_config_to_db"):
assert isinstance(config, AppConfig), "config must be an instance of AppConfig"
with belief_scope("ConfigManager._save_config_to_db"):
if not isinstance(config, AppConfig):
raise TypeError("config must be an instance of AppConfig")
owns_session = session is None
db = session or SessionLocal()
@@ -139,15 +148,17 @@ class ConfigManager:
record = self._get_record(db)
payload = config.model_dump()
if record is None:
logger.reason("Creating new global configuration record")
record = AppConfigRecord(id="global", payload=payload)
db.add(record)
else:
logger.reason("Updating existing global configuration record")
record.payload = payload
db.commit()
logger.info("[_save_config_to_db][Action] Configuration saved to database")
logger.reflect("Configuration successfully committed to database")
except Exception as e:
db.rollback()
logger.error(f"[_save_config_to_db][Coherence:Failed] Failed to save: {e}")
logger.explore(f"Failed to save configuration: {e}")
raise
finally:
if owns_session:
@@ -183,14 +194,15 @@ class ConfigManager:
# @SIDE_EFFECT: Mutates self.config, DB write, logger reconfiguration, logging.
# @DATA_CONTRACT: Input(GlobalSettings) -> Output(None)
def update_global_settings(self, settings: GlobalSettings):
with belief_scope("update_global_settings"):
logger.info("[update_global_settings][Entry] Updating settings")
assert isinstance(settings, GlobalSettings), "settings must be an instance of GlobalSettings"
with belief_scope("ConfigManager.update_global_settings"):
if not isinstance(settings, GlobalSettings):
raise TypeError("settings must be an instance of GlobalSettings")
logger.reason("Updating global settings and persisting")
self.config.settings = settings
self.save()
configure_logger(settings.logging)
logger.info("[update_global_settings][Exit] Settings updated")
logger.reflect("Global settings updated and logger reconfigured")
# [/DEF:update_global_settings:Function]
# [DEF:validate_path:Function]
@@ -257,14 +269,15 @@ class ConfigManager:
# @SIDE_EFFECT: Mutates environment list, DB write, logging.
# @DATA_CONTRACT: Input(Environment) -> Output(None)
def add_environment(self, env: Environment):
with belief_scope("add_environment"):
logger.info(f"[add_environment][Entry] Adding environment {env.id}")
assert isinstance(env, Environment), "env must be an instance of Environment"
with belief_scope("ConfigManager.add_environment"):
if not isinstance(env, Environment):
raise TypeError("env must be an instance of Environment")
logger.reason(f"Adding/Updating environment: {env.id}")
self.config.environments = [e for e in self.config.environments if e.id != env.id]
self.config.environments.append(env)
self.save()
logger.info("[add_environment][Exit] Environment added")
logger.reflect(f"Environment {env.id} persisted")
# [/DEF:add_environment:Function]
# [DEF:update_environment:Function]
@@ -274,22 +287,25 @@ class ConfigManager:
# @SIDE_EFFECT: May mutate environment list, DB write, logging.
# @DATA_CONTRACT: Input(str env_id, Environment updated_env) -> Output(bool)
def update_environment(self, env_id: str, updated_env: Environment) -> bool:
with belief_scope("update_environment"):
logger.info(f"[update_environment][Entry] Updating {env_id}")
assert env_id and isinstance(env_id, str), "env_id must be a non-empty string"
assert isinstance(updated_env, Environment), "updated_env must be an instance of Environment"
with belief_scope("ConfigManager.update_environment"):
if not env_id or not isinstance(env_id, str):
raise ValueError("env_id must be a non-empty string")
if not isinstance(updated_env, Environment):
raise TypeError("updated_env must be an instance of Environment")
logger.reason(f"Attempting to update environment: {env_id}")
for i, env in enumerate(self.config.environments):
if env.id == env_id:
if updated_env.password == "********":
logger.reason("Preserving existing password for masked update")
updated_env.password = env.password
self.config.environments[i] = updated_env
self.save()
logger.info(f"[update_environment][Coherence:OK] Updated {env_id}")
logger.reflect(f"Environment {env_id} updated and saved")
return True
logger.warning(f"[update_environment][Coherence:Failed] Environment {env_id} not found")
logger.explore(f"Environment {env_id} not found for update")
return False
# [/DEF:update_environment:Function]
@@ -300,18 +316,19 @@ class ConfigManager:
# @SIDE_EFFECT: May mutate environment list, conditional DB write, logging.
# @DATA_CONTRACT: Input(str env_id) -> Output(None)
def delete_environment(self, env_id: str):
with belief_scope("delete_environment"):
logger.info(f"[delete_environment][Entry] Deleting {env_id}")
assert env_id and isinstance(env_id, str), "env_id must be a non-empty string"
with belief_scope("ConfigManager.delete_environment"):
if not env_id or not isinstance(env_id, str):
raise ValueError("env_id must be a non-empty string")
logger.reason(f"Attempting to delete environment: {env_id}")
original_count = len(self.config.environments)
self.config.environments = [e for e in self.config.environments if e.id != env_id]
if len(self.config.environments) < original_count:
self.save()
logger.info(f"[delete_environment][Action] Deleted {env_id}")
logger.reflect(f"Environment {env_id} deleted and configuration saved")
else:
logger.warning(f"[delete_environment][Coherence:Failed] Environment {env_id} not found")
logger.explore(f"Environment {env_id} not found for deletion")
# [/DEF:delete_environment:Function]