feat: backend servis iskeletini ve yönetim uçlarını ekle
This commit is contained in:
133
backend/app/db.py
Normal file
133
backend/app/db.py
Normal file
@@ -0,0 +1,133 @@
|
||||
from collections.abc import Iterator
|
||||
from contextlib import contextmanager
|
||||
from datetime import datetime
|
||||
|
||||
from sqlalchemy import Boolean, DateTime, Integer, String, Text, create_engine, select
|
||||
from sqlalchemy.orm import DeclarativeBase, Mapped, Session, mapped_column, sessionmaker
|
||||
|
||||
from app.config import get_settings
|
||||
|
||||
|
||||
DEFAULT_SETTINGS = {
|
||||
"terminal_mode": "3",
|
||||
"search_provider": "brave",
|
||||
"ollama_base_url": "http://127.0.0.1:11434",
|
||||
"default_model": "qwen3.5:4b",
|
||||
}
|
||||
|
||||
DEFAULT_TOOLS = {
|
||||
"brave_search": True,
|
||||
"searxng_search": False,
|
||||
"web_fetch": True,
|
||||
"apple_notes": True,
|
||||
"files": True,
|
||||
"terminal": True,
|
||||
}
|
||||
|
||||
|
||||
class Base(DeclarativeBase):
|
||||
pass
|
||||
|
||||
|
||||
class SettingORM(Base):
|
||||
__tablename__ = "settings"
|
||||
|
||||
key: Mapped[str] = mapped_column(String(100), primary_key=True)
|
||||
value: Mapped[str] = mapped_column(Text, nullable=False)
|
||||
updated_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, nullable=False)
|
||||
|
||||
|
||||
class ToolStateORM(Base):
|
||||
__tablename__ = "tool_states"
|
||||
|
||||
name: Mapped[str] = mapped_column(String(100), primary_key=True)
|
||||
enabled: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True)
|
||||
updated_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, nullable=False)
|
||||
|
||||
|
||||
class AuthorizedUserORM(Base):
|
||||
__tablename__ = "authorized_users"
|
||||
|
||||
telegram_user_id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
username: Mapped[str | None] = mapped_column(String(255))
|
||||
display_name: Mapped[str | None] = mapped_column(String(255))
|
||||
is_active: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, nullable=False)
|
||||
updated_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, nullable=False)
|
||||
|
||||
|
||||
class MemoryItemORM(Base):
|
||||
__tablename__ = "memory_items"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
|
||||
content: Mapped[str] = mapped_column(Text, nullable=False)
|
||||
kind: Mapped[str] = mapped_column(String(50), nullable=False, default="message")
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, nullable=False)
|
||||
|
||||
|
||||
class AuditLogORM(Base):
|
||||
__tablename__ = "audit_logs"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
|
||||
category: Mapped[str] = mapped_column(String(50), nullable=False)
|
||||
message: Mapped[str] = mapped_column(Text, nullable=False)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, nullable=False)
|
||||
|
||||
|
||||
class SecretORM(Base):
|
||||
__tablename__ = "secrets"
|
||||
|
||||
key: Mapped[str] = mapped_column(String(100), primary_key=True)
|
||||
value: Mapped[str] = mapped_column(Text, nullable=False)
|
||||
updated_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, nullable=False)
|
||||
|
||||
|
||||
settings = get_settings()
|
||||
engine = create_engine(
|
||||
settings.db_url,
|
||||
connect_args={"check_same_thread": False} if settings.db_url.startswith("sqlite") else {},
|
||||
)
|
||||
SessionLocal = sessionmaker(bind=engine, autoflush=False, autocommit=False)
|
||||
|
||||
|
||||
def init_db() -> None:
|
||||
Base.metadata.create_all(bind=engine)
|
||||
with session_scope() as session:
|
||||
_seed_defaults(session)
|
||||
|
||||
|
||||
def _seed_defaults(session: Session) -> None:
|
||||
for key, value in DEFAULT_SETTINGS.items():
|
||||
if session.get(SettingORM, key) is None:
|
||||
session.add(SettingORM(key=key, value=value))
|
||||
|
||||
for name, enabled in DEFAULT_TOOLS.items():
|
||||
if session.get(ToolStateORM, name) is None:
|
||||
session.add(ToolStateORM(name=name, enabled=enabled))
|
||||
|
||||
|
||||
def get_session() -> Iterator[Session]:
|
||||
session = SessionLocal()
|
||||
try:
|
||||
yield session
|
||||
finally:
|
||||
session.close()
|
||||
|
||||
|
||||
@contextmanager
|
||||
def session_scope() -> Iterator[Session]:
|
||||
session = SessionLocal()
|
||||
try:
|
||||
yield session
|
||||
session.commit()
|
||||
except Exception:
|
||||
session.rollback()
|
||||
raise
|
||||
finally:
|
||||
session.close()
|
||||
|
||||
|
||||
def list_recent_logs(session: Session, limit: int = 10) -> list[str]:
|
||||
stmt = select(AuditLogORM).order_by(AuditLogORM.created_at.desc(), AuditLogORM.id.desc()).limit(limit)
|
||||
return [row.message for row in session.scalars(stmt)]
|
||||
|
||||
Reference in New Issue
Block a user