feat: backend servis iskeletini ve yönetim uçlarını ekle
This commit is contained in:
142
backend/app/admin/services.py
Normal file
142
backend/app/admin/services.py
Normal file
@@ -0,0 +1,142 @@
|
||||
from datetime import datetime
|
||||
|
||||
from sqlalchemy import func, select
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.db import (
|
||||
AuditLogORM,
|
||||
AuthorizedUserORM,
|
||||
MemoryItemORM,
|
||||
SecretORM,
|
||||
SettingORM,
|
||||
ToolStateORM,
|
||||
list_recent_logs,
|
||||
)
|
||||
from app.config import get_settings
|
||||
from app.models import DashboardSnapshot, MemoryRecord, RuntimeSettings, TelegramStatus, ToolToggle, UserRecord
|
||||
|
||||
|
||||
class AdminService:
|
||||
def __init__(self, session: Session) -> None:
|
||||
self.session = session
|
||||
|
||||
def get_runtime_settings(self) -> RuntimeSettings:
|
||||
settings = {
|
||||
item.key: item.value for item in self.session.scalars(select(SettingORM))
|
||||
}
|
||||
tools = list(self.session.scalars(select(ToolStateORM).order_by(ToolStateORM.name.asc())))
|
||||
return RuntimeSettings(
|
||||
terminal_mode=int(settings["terminal_mode"]),
|
||||
search_provider=settings["search_provider"],
|
||||
ollama_base_url=settings["ollama_base_url"],
|
||||
default_model=settings["default_model"],
|
||||
tools=[ToolToggle(name=tool.name, enabled=tool.enabled) for tool in tools],
|
||||
)
|
||||
|
||||
def update_runtime_settings(self, payload: RuntimeSettings) -> RuntimeSettings:
|
||||
self._save_setting("terminal_mode", str(payload.terminal_mode))
|
||||
self._save_setting("search_provider", payload.search_provider)
|
||||
self._save_setting("ollama_base_url", payload.ollama_base_url)
|
||||
self._save_setting("default_model", payload.default_model)
|
||||
|
||||
for tool in payload.tools:
|
||||
record = self.session.get(ToolStateORM, tool.name)
|
||||
if record is None:
|
||||
self.session.add(ToolStateORM(name=tool.name, enabled=tool.enabled, updated_at=datetime.utcnow()))
|
||||
else:
|
||||
record.enabled = tool.enabled
|
||||
record.updated_at = datetime.utcnow()
|
||||
|
||||
self.session.add(AuditLogORM(category="settings", message="settings:runtime-updated"))
|
||||
self.session.commit()
|
||||
return self.get_runtime_settings()
|
||||
|
||||
def dashboard(self) -> DashboardSnapshot:
|
||||
return DashboardSnapshot(
|
||||
settings=self.get_runtime_settings(),
|
||||
whitelist_count=self.session.scalar(select(func.count()).select_from(AuthorizedUserORM)) or 0,
|
||||
memory_items=self.session.scalar(select(func.count()).select_from(MemoryItemORM)) or 0,
|
||||
recent_logs=list_recent_logs(self.session, limit=10),
|
||||
)
|
||||
|
||||
def list_users(self) -> list[UserRecord]:
|
||||
stmt = select(AuthorizedUserORM).order_by(AuthorizedUserORM.created_at.desc())
|
||||
return [
|
||||
UserRecord(
|
||||
telegram_user_id=user.telegram_user_id,
|
||||
username=user.username,
|
||||
display_name=user.display_name,
|
||||
is_active=user.is_active,
|
||||
)
|
||||
for user in self.session.scalars(stmt)
|
||||
]
|
||||
|
||||
def save_user(self, user: UserRecord) -> UserRecord:
|
||||
record = self.session.get(AuthorizedUserORM, user.telegram_user_id)
|
||||
if record is None:
|
||||
record = AuthorizedUserORM(
|
||||
telegram_user_id=user.telegram_user_id,
|
||||
username=user.username,
|
||||
display_name=user.display_name,
|
||||
is_active=user.is_active,
|
||||
created_at=datetime.utcnow(),
|
||||
updated_at=datetime.utcnow(),
|
||||
)
|
||||
self.session.add(record)
|
||||
else:
|
||||
record.username = user.username
|
||||
record.display_name = user.display_name
|
||||
record.is_active = user.is_active
|
||||
record.updated_at = datetime.utcnow()
|
||||
self.session.add(AuditLogORM(category="users", message=f"users:upsert:{user.telegram_user_id}"))
|
||||
self.session.commit()
|
||||
return user
|
||||
|
||||
def list_memory(self) -> list[MemoryRecord]:
|
||||
stmt = select(MemoryItemORM).order_by(MemoryItemORM.created_at.desc(), MemoryItemORM.id.desc()).limit(50)
|
||||
return [
|
||||
MemoryRecord(id=item.id, content=item.content, kind=item.kind, created_at=item.created_at)
|
||||
for item in self.session.scalars(stmt)
|
||||
]
|
||||
|
||||
def clear_memory(self) -> None:
|
||||
for item in self.session.scalars(select(MemoryItemORM)):
|
||||
self.session.delete(item)
|
||||
self.session.add(AuditLogORM(category="memory", message="memory:cleared"))
|
||||
self.session.commit()
|
||||
|
||||
def get_secret_mask(self, key: str) -> str:
|
||||
record = self.session.get(SecretORM, key)
|
||||
value = record.value if record else ""
|
||||
if len(value) < 4:
|
||||
return ""
|
||||
return f"{value[:2]}***{value[-2:]}"
|
||||
|
||||
def save_secret(self, key: str, value: str) -> None:
|
||||
record = self.session.get(SecretORM, key)
|
||||
if record is None:
|
||||
self.session.add(SecretORM(key=key, value=value, updated_at=datetime.utcnow()))
|
||||
else:
|
||||
record.value = value
|
||||
record.updated_at = datetime.utcnow()
|
||||
self.session.add(AuditLogORM(category="secrets", message=f"secrets:updated:{key}"))
|
||||
self.session.commit()
|
||||
|
||||
def _save_setting(self, key: str, value: str) -> None:
|
||||
record = self.session.get(SettingORM, key)
|
||||
if record is None:
|
||||
self.session.add(SettingORM(key=key, value=value, updated_at=datetime.utcnow()))
|
||||
else:
|
||||
record.value = value
|
||||
record.updated_at = datetime.utcnow()
|
||||
|
||||
def telegram_status(self) -> TelegramStatus:
|
||||
settings = get_settings()
|
||||
configured = bool(settings.telegram_bot_token)
|
||||
return TelegramStatus(
|
||||
configured=configured,
|
||||
polling_active=False,
|
||||
message="Telegram token is configured. Polling starts when the backend boots."
|
||||
if configured
|
||||
else "Telegram token is not configured.",
|
||||
)
|
||||
Reference in New Issue
Block a user