feat add connections management and health summary improvements

This commit is contained in:
2026-03-15 16:40:43 +03:00
parent eba0fab091
commit 027d17f193
17 changed files with 8521 additions and 10819 deletions

View File

@@ -14,6 +14,7 @@
from sqlalchemy import create_engine, inspect, text
from sqlalchemy.orm import sessionmaker
from ..models.mapping import Base
from ..models.connection import ConnectionConfig
# Import models to ensure they're registered with Base
from ..models import task as _task_models # noqa: F401
from ..models import auth as _auth_models # noqa: F401
@@ -22,6 +23,7 @@ from ..models import llm as _llm_models # noqa: F401
from ..models import assistant as _assistant_models # noqa: F401
from ..models import profile as _profile_models # noqa: F401
from ..models import clean_release as _clean_release_models # noqa: F401
from ..models import connection as _connection_models # noqa: F401
from .logger import belief_scope, logger
from .auth.config import auth_config
import os
@@ -281,6 +283,23 @@ def _ensure_git_server_configs_columns(bind_engine):
# [/DEF:_ensure_git_server_configs_columns:Function]
# [DEF:ensure_connection_configs_table:Function]
# @PURPOSE: Ensures the external connection registry table exists in the main database.
# @PRE: bind_engine points to the application database.
# @POST: connection_configs table exists without dropping existing data.
def ensure_connection_configs_table(bind_engine):
with belief_scope("ensure_connection_configs_table"):
try:
ConnectionConfig.__table__.create(bind=bind_engine, checkfirst=True)
except Exception as migration_error:
logger.warning(
"[database][EXPLORE] ConnectionConfig table ensure failed: %s",
migration_error,
)
raise
# [/DEF:ensure_connection_configs_table:Function]
# [DEF:init_db:Function]
# @PURPOSE: Initializes the database by creating all tables.
# @PRE: engine, tasks_engine and auth_engine are initialized.
@@ -295,6 +314,7 @@ def init_db():
_ensure_llm_validation_results_columns(engine)
_ensure_user_dashboard_preferences_health_columns(engine)
_ensure_git_server_configs_columns(engine)
ensure_connection_configs_table(engine)
# [/DEF:init_db:Function]
# [DEF:get_db:Function]

View File

@@ -0,0 +1,56 @@
# [DEF:backend.src.core.encryption_key:Module]
# @TIER: CRITICAL
# @SEMANTICS: encryption, key, bootstrap, environment, startup
# @PURPOSE: Resolve and persist the Fernet encryption key required by runtime services.
# @LAYER: Infra
# @RELATION: DEPENDS_ON -> backend.src.core.logger
# @INVARIANT: Runtime key resolution never falls back to an ephemeral secret.
from __future__ import annotations
import os
from pathlib import Path
from cryptography.fernet import Fernet
from .logger import logger, belief_scope
DEFAULT_ENV_FILE_PATH = Path(__file__).resolve().parents[2] / ".env"
# [DEF:ensure_encryption_key:Function]
# @PURPOSE: Ensure backend runtime has a persistent valid Fernet key.
# @PRE: env_file_path points to a writable backend .env file or ENCRYPTION_KEY exists in process environment.
# @POST: Returns a valid Fernet key and guarantees it is present in process environment.
# @SIDE_EFFECT: May create or append backend/.env when key is missing.
def ensure_encryption_key(env_file_path: Path = DEFAULT_ENV_FILE_PATH) -> str:
with belief_scope("ensure_encryption_key", f"env_file_path={env_file_path}"):
existing_key = os.getenv("ENCRYPTION_KEY", "").strip()
if existing_key:
Fernet(existing_key.encode())
logger.reason("Using ENCRYPTION_KEY from process environment.")
return existing_key
if env_file_path.exists():
for raw_line in env_file_path.read_text(encoding="utf-8").splitlines():
if raw_line.startswith("ENCRYPTION_KEY="):
persisted_key = raw_line.partition("=")[2].strip()
if persisted_key:
Fernet(persisted_key.encode())
os.environ["ENCRYPTION_KEY"] = persisted_key
logger.reason(f"Loaded ENCRYPTION_KEY from {env_file_path}.")
return persisted_key
generated_key = Fernet.generate_key().decode()
with env_file_path.open("a", encoding="utf-8") as env_file:
if env_file.tell() > 0:
env_file.write("\n")
env_file.write(f"ENCRYPTION_KEY={generated_key}\n")
os.environ["ENCRYPTION_KEY"] = generated_key
logger.reason(f"Generated ENCRYPTION_KEY and persisted it to {env_file_path}.")
logger.reflect("Encryption key is available for runtime services.")
return generated_key
# [/DEF:ensure_encryption_key:Function]
# [/DEF:backend.src.core.encryption_key:Module]