refactor: reorganize models into subpackages

Move models into domain subpackages (max 4 files each):
- models/tool/ — tool_type, tool_instance, tool_definition_manifest
- models/config/ — config_profile
- models/user/ — user, user_config, ssh_key
- models/project/ — project, git_repository, workspace
- models/system/ — health_check, notification, instance_event, terminal_session

models/__init__.py continues to re-export all symbols, so consumers
using 'from src.models import X' are unaffected. Updated direct file
imports across the backend to use the new paths.

Quality gates: py_compile passed, ruff passed.
This commit is contained in:
2026-06-04 10:00:10 +02:00
parent 0127d283a6
commit 0591b00ded
62 changed files with 136 additions and 87 deletions
+1
View File
@@ -0,0 +1 @@
"""Config module."""
+4 -4
View File
@@ -14,10 +14,10 @@ from sqlalchemy.orm import selectinload
from src.api.shared_validators import validate_env_vars as _validate_env_vars from src.api.shared_validators import validate_env_vars as _validate_env_vars
from src.auth.dependencies import get_current_user_id, get_db_session from src.auth.dependencies import get_current_user_id, get_db_session
from src.models.config_profile import ConfigProfile, ConfigProfileInclude from src.models import ConfigProfile, ConfigProfileInclude
from src.models.project import Project from src.models.project import Project
from src.models.tool_type import ToolType from src.models import ToolType
from src.models.user_config import UserConfig from src.models import UserConfig
from src.services.config_profile_resolver import ( from src.services.config_profile_resolver import (
ConfigProfileCycleError, ConfigProfileCycleError,
check_include_cycle, check_include_cycle,
@@ -991,7 +991,7 @@ async def validate_git_url(
env = None env = None
key_path = None key_path = None
if data.ssh_key_id: if data.ssh_key_id:
from src.models.ssh_key import SSHKey from src.models import SSHKey
from src.services.ssh_keys import _get_fernet from src.services.ssh_keys import _get_fernet
try: try:
+2 -2
View File
@@ -5,9 +5,9 @@ from sqlalchemy import func, select
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from src.auth.dependencies import get_current_user_id, get_db_session from src.auth.dependencies import get_current_user_id, get_db_session
from src.models.git_repository import GitRepository from src.models import GitRepository
from src.models.project import Project from src.models.project import Project
from src.models.ssh_key import SSHKey from src.models import SSHKey
router = APIRouter(prefix="/dashboard", tags=["dashboard"]) router = APIRouter(prefix="/dashboard", tags=["dashboard"])
+2 -2
View File
@@ -17,8 +17,8 @@ from src.auth.dependencies import (
get_db_session, get_db_session,
) )
from src.config import Settings from src.config import Settings
from src.models.git_repository import GitRepository from src.models import GitRepository
from src.models.ssh_key import SSHKey from src.models import SSHKey
from src.utils.git_files import ( from src.utils.git_files import (
commit_file, commit_file,
get_file_content, get_file_content,
+2 -2
View File
@@ -8,8 +8,8 @@ from fastapi import APIRouter, Depends, HTTPException, Request, Response, status
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from src.auth.dependencies import get_current_user_id, get_db_session from src.auth.dependencies import get_current_user_id, get_db_session
from src.models.tool_instance import ToolInstance from src.models import ToolInstance
from src.models.tool_type import ToolType from src.models import ToolType
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
+1 -1
View File
@@ -9,7 +9,7 @@ from sqlalchemy.ext.asyncio import AsyncSession
from src.auth.dependencies import get_current_user, get_db_session from src.auth.dependencies import get_current_user, get_db_session
from src.models.user import User from src.models.user import User
from src.models.user_config import UserConfig from src.models import UserConfig
from src.services.notification_service import notification_service from src.services.notification_service import notification_service
router = APIRouter(prefix="/notifications", tags=["notifications"]) router = APIRouter(prefix="/notifications", tags=["notifications"])
+1
View File
@@ -0,0 +1 @@
"""Project module."""
+4 -4
View File
@@ -13,10 +13,10 @@ from src.auth.dependencies import (
get_current_user_id, get_current_user_id,
get_db_session, get_db_session,
) )
from src.models.git_repository import GitRepository from src.models import GitRepository
from src.models.project import Project from src.models.project import Project
from src.models.ssh_key import SSHKey from src.models import SSHKey
from src.models.tool_instance import ToolInstance from src.models import ToolInstance
router = APIRouter(prefix="/projects", tags=["projects"]) router = APIRouter(prefix="/projects", tags=["projects"])
@@ -101,7 +101,7 @@ async def list_projects(
) )
projects = result.scalars().all() projects = result.scalars().all()
from src.models.workspace import Workspace from src.models import Workspace
enriched = [] enriched = []
for project in projects: for project in projects:
+1 -1
View File
@@ -12,7 +12,7 @@ from sqlalchemy.ext.asyncio import AsyncSession
from src.auth.dependencies import _get_user, get_current_user_id, get_db_session from src.auth.dependencies import _get_user, get_current_user_id, get_db_session
from src.config import Settings from src.config import Settings
from src.models.ssh_key import SSHKey from src.models import SSHKey
router = APIRouter(prefix="/ssh-keys", tags=["ssh-keys"]) router = APIRouter(prefix="/ssh-keys", tags=["ssh-keys"])
+1
View File
@@ -0,0 +1 @@
"""System module."""
+3 -3
View File
@@ -12,9 +12,9 @@ from sqlalchemy.ext.asyncio import AsyncSession
from starlette.websockets import WebSocketDisconnect from starlette.websockets import WebSocketDisconnect
from src.auth.dependencies import get_current_user_id, get_db_session from src.auth.dependencies import get_current_user_id, get_db_session
from src.models.terminal_session import TerminalSessionModel from src.models import TerminalSessionModel
from src.models.tool_instance import ToolInstance from src.models import ToolInstance
from src.models.tool_type import ToolType from src.models import ToolType
from src.services.terminal_manager import MaxSessionsExceededError, terminal_manager from src.services.terminal_manager import MaxSessionsExceededError, terminal_manager
router = APIRouter() router = APIRouter()
+1
View File
@@ -0,0 +1 @@
"""Tool module."""
+2 -2
View File
@@ -9,8 +9,8 @@ from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from src.auth.dependencies import get_current_user_id, get_db_session from src.auth.dependencies import get_current_user_id, get_db_session
from src.models.tool_definition_manifest import ToolDefinitionManifest from src.models import ToolDefinitionManifest
from src.models.tool_type import ToolType from src.models import ToolType
from src.services.manifest_compiler import ( from src.services.manifest_compiler import (
compile_compose, compile_compose,
compile_dockerfile, compile_dockerfile,
+11 -11
View File
@@ -30,12 +30,12 @@ from src.auth.dependencies import (
) )
from src.services.event_bus import InstanceEventBus from src.services.event_bus import InstanceEventBus
from src.services.lifecycle_hooks import publish_lifecycle_event from src.services.lifecycle_hooks import publish_lifecycle_event
from src.models.config_profile import ConfigProfile from src.models import ConfigProfile
from src.models.git_repository import GitRepository from src.models import GitRepository
from src.models.project import Project from src.models.project import Project
from src.models.ssh_key import SSHKey from src.models import SSHKey
from src.models.tool_instance import ToolInstance from src.models import ToolInstance
from src.models.tool_type import ToolType from src.models import ToolType
from src.services.clone import check_dirty_state, clone_repository from src.services.clone import check_dirty_state, clone_repository
from src.services.config_profile_resolver import ( from src.services.config_profile_resolver import (
ConfigProfileCycleError, ConfigProfileCycleError,
@@ -856,7 +856,7 @@ async def create_instance(
workspace = None workspace = None
workspace_id = None workspace_id = None
if data.workspace_id: if data.workspace_id:
from src.models.workspace import Workspace as WorkspaceModel from src.models import Workspace as WorkspaceModel
try: try:
workspace_id = uuid.UUID(data.workspace_id) workspace_id = uuid.UUID(data.workspace_id)
@@ -1056,7 +1056,7 @@ services:
elif tool_type.definition_type == "manifest": elif tool_type.definition_type == "manifest":
# Manifest-based: generate compose only; image built lazily on start # Manifest-based: generate compose only; image built lazily on start
from src.models.tool_definition_manifest import ToolDefinitionManifest from src.models import ToolDefinitionManifest
manifest_def = await session.get( manifest_def = await session.get(
ToolDefinitionManifest, tool_type.manifest_id ToolDefinitionManifest, tool_type.manifest_id
@@ -1341,7 +1341,7 @@ async def _prepare_manifest_instance(
Returns: Returns:
Tuple of (image_tag, compose_content, resolved_manifest, home_dir) Tuple of (image_tag, compose_content, resolved_manifest, home_dir)
""" """
from src.models.tool_definition_manifest import ToolDefinitionManifest from src.models import ToolDefinitionManifest
tool_type = await session.get(ToolType, instance.tool_type_id) tool_type = await session.get(ToolType, instance.tool_type_id)
manifest_def = await session.get(ToolDefinitionManifest, tool_type.manifest_id) manifest_def = await session.get(ToolDefinitionManifest, tool_type.manifest_id)
@@ -1537,7 +1537,7 @@ async def start_instance(
container_uid = 0 container_uid = 0
container_gid = 0 container_gid = 0
if tool_type and tool_type.definition_type == "manifest" and tool_type.manifest_id: if tool_type and tool_type.definition_type == "manifest" and tool_type.manifest_id:
from src.models.tool_definition_manifest import ToolDefinitionManifest from src.models import ToolDefinitionManifest
manifest_def = await session.get(ToolDefinitionManifest, tool_type.manifest_id) manifest_def = await session.get(ToolDefinitionManifest, tool_type.manifest_id)
if manifest_def: if manifest_def:
@@ -1724,7 +1724,7 @@ async def start_instance(
# Determine repo path (workspace takes precedence) # Determine repo path (workspace takes precedence)
repo_path = "" repo_path = ""
if instance.workspace_id: if instance.workspace_id:
from src.models.workspace import Workspace as WorkspaceModel from src.models import Workspace as WorkspaceModel
workspace = await session.get(WorkspaceModel, instance.workspace_id) workspace = await session.get(WorkspaceModel, instance.workspace_id)
if workspace: if workspace:
@@ -2767,7 +2767,7 @@ async def get_instance_events(
List of event dictionaries. List of event dictionaries.
""" """
from sqlalchemy import select from sqlalchemy import select
from src.models.instance_event import InstanceEvent from src.models import InstanceEvent
_user = await _get_user(session, user_id) _user = await _get_user(session, user_id)
_project = await _get_owned_project(project_id, user_id, session) _project = await _get_owned_project(project_id, user_id, session)
+1 -1
View File
@@ -12,7 +12,7 @@ from src.api.tool_types_validation import (
validate_required_variables, validate_required_variables,
) )
from src.auth.dependencies import _get_user, get_current_user_id, get_db_session from src.auth.dependencies import _get_user, get_current_user_id, get_db_session
from src.models.tool_type import ToolType from src.models import ToolType
from src.models.user import User from src.models.user import User
router = APIRouter(prefix="/tool-types", tags=["tool-types"]) router = APIRouter(prefix="/tool-types", tags=["tool-types"])
+1
View File
@@ -0,0 +1 @@
"""User module."""
+1 -1
View File
@@ -7,7 +7,7 @@ from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from src.auth.dependencies import _get_user, get_current_user_id, get_db_session from src.auth.dependencies import _get_user, get_current_user_id, get_db_session
from src.models.user_config import UserConfig from src.models import UserConfig
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
+1
View File
@@ -0,0 +1 @@
"""Workspace module."""
+1 -1
View File
@@ -6,7 +6,7 @@ from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from src.auth.dependencies import get_current_user_id, get_db_session from src.auth.dependencies import get_current_user_id, get_db_session
from src.models.workspace import Workspace from src.models import Workspace
from src.services.file_service import FileService from src.services.file_service import FileService
router = APIRouter(prefix="/workspaces/{workspace_id}/files") router = APIRouter(prefix="/workspaces/{workspace_id}/files")
+1 -1
View File
@@ -6,7 +6,7 @@ from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from src.auth.dependencies import get_current_user_id, get_db_session from src.auth.dependencies import get_current_user_id, get_db_session
from src.models.workspace import Workspace from src.models import Workspace
from src.services.git_operations import GitOperations from src.services.git_operations import GitOperations
router = APIRouter(prefix="/workspaces/{workspace_id}/git") router = APIRouter(prefix="/workspaces/{workspace_id}/git")
+2 -2
View File
@@ -7,8 +7,8 @@ from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from src.auth.dependencies import get_current_user_id, get_db_session from src.auth.dependencies import get_current_user_id, get_db_session
from src.models.tool_instance import ToolInstance from src.models import ToolInstance
from src.models.workspace import Workspace from src.models import Workspace
router = APIRouter(prefix="/workspaces/{workspace_id}/instances") router = APIRouter(prefix="/workspaces/{workspace_id}/instances")
+3 -3
View File
@@ -9,9 +9,9 @@ from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import selectinload from sqlalchemy.orm import selectinload
from src.auth.dependencies import get_current_user_id, get_db_session from src.auth.dependencies import get_current_user_id, get_db_session
from src.models.git_repository import GitRepository from src.models import GitRepository
from src.models.tool_instance import ToolInstance from src.models import ToolInstance
from src.models.workspace import Workspace from src.models import Workspace
from src.services.workspace_manager import WorkspaceHasInstancesError, WorkspaceManager from src.services.workspace_manager import WorkspaceHasInstancesError, WorkspaceManager
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
+2 -2
View File
@@ -29,8 +29,8 @@ from src.api.workspace_git import router as workspace_git_router
from src.api.workspace_instances import router as workspace_instances_router from src.api.workspace_instances import router as workspace_instances_router
from src.api.workspaces import all_workspaces_router, router as workspaces_router from src.api.workspaces import all_workspaces_router, router as workspaces_router
from src.config import Settings from src.config import Settings
from src.models.notification import Notification # noqa: F401 Alembic model discovery from src.models import Notification # noqa: F401 Alembic model discovery
from src.models.terminal_session import TerminalSessionModel # noqa: F401 Alembic model discovery from src.models import TerminalSessionModel # noqa: F401 Alembic model discovery
from src.database import init_database from src.database import init_database
from src.logging_config import ( from src.logging_config import (
ExceptionLoggingMiddleware, ExceptionLoggingMiddleware,
+14 -14
View File
@@ -1,18 +1,18 @@
from src.models.base import Base from src.models.base import Base
from src.models.config_profile import ConfigProfile, ConfigProfileInclude from src.models.config.config_profile import ConfigProfile, ConfigProfileInclude
from src.models.git_repository import GitRepository from src.models.project.git_repository import GitRepository
from src.models.health_check import HealthCheck from src.models.project.project import Project
from src.models.instance_event import InstanceEvent from src.models.project.workspace import Workspace
from src.models.notification import Notification from src.models.system.health_check import HealthCheck
from src.models.project import Project from src.models.system.instance_event import InstanceEvent
from src.models.ssh_key import SSHKey from src.models.system.notification import Notification
from src.models.terminal_session import TerminalSessionModel from src.models.system.terminal_session import TerminalSessionModel
from src.models.tool_definition_manifest import ToolDefinitionManifest from src.models.tool.tool_definition_manifest import ToolDefinitionManifest
from src.models.tool_instance import ToolInstance from src.models.tool.tool_instance import ToolInstance
from src.models.tool_type import ToolType from src.models.tool.tool_type import ToolType
from src.models.user import User from src.models.user.ssh_key import SSHKey
from src.models.user_config import UserConfig from src.models.user.user import User
from src.models.workspace import Workspace from src.models.user.user_config import UserConfig
__all__ = [ __all__ = [
"Base", "Base",
+5
View File
@@ -0,0 +1,5 @@
"""Config models module."""
from src.models.config.config_profile import ConfigProfile, ConfigProfileInclude
__all__ = ["ConfigProfile", "ConfigProfileInclude"]
@@ -17,7 +17,7 @@ from src.models.base import Base, TimestampMixin, UUIDPrimaryKeyMixin
if TYPE_CHECKING: if TYPE_CHECKING:
from src.models.project import Project from src.models.project import Project
from src.models.tool_type import ToolType from src.models import ToolType
from src.models.user import User from src.models.user import User
+7
View File
@@ -0,0 +1,7 @@
"""Project models module."""
from src.models.project.git_repository import GitRepository
from src.models.project.project import Project
from src.models.project.workspace import Workspace
__all__ = ["GitRepository", "Project", "Workspace"]
@@ -10,7 +10,7 @@ from src.models.base import Base, TimestampMixin, UUIDPrimaryKeyMixin
if TYPE_CHECKING: if TYPE_CHECKING:
from src.models.project import Project from src.models.project import Project
from src.models.ssh_key import SSHKey from src.models import SSHKey
from src.models.user import User from src.models.user import User
@@ -8,8 +8,8 @@ from sqlalchemy.orm import Mapped, mapped_column, relationship
from src.models.base import Base, TimestampMixin, UUIDPrimaryKeyMixin from src.models.base import Base, TimestampMixin, UUIDPrimaryKeyMixin
if TYPE_CHECKING: if TYPE_CHECKING:
from src.models.git_repository import GitRepository from src.models import GitRepository
from src.models.ssh_key import SSHKey from src.models import SSHKey
from src.models.user import User from src.models.user import User
@@ -12,7 +12,7 @@ from sqlalchemy.orm import Mapped, mapped_column, relationship
from src.models.base import Base, TimestampMixin from src.models.base import Base, TimestampMixin
if TYPE_CHECKING: if TYPE_CHECKING:
from src.models.git_repository import GitRepository from src.models import GitRepository
from src.models.user import User from src.models.user import User
+8
View File
@@ -0,0 +1,8 @@
"""System models module."""
from src.models.system.health_check import HealthCheck
from src.models.system.instance_event import InstanceEvent
from src.models.system.notification import Notification
from src.models.system.terminal_session import TerminalSessionModel
__all__ = ["HealthCheck", "InstanceEvent", "Notification", "TerminalSessionModel"]
+7
View File
@@ -0,0 +1,7 @@
"""Tool models module."""
from src.models.tool.tool_definition_manifest import ToolDefinitionManifest
from src.models.tool.tool_instance import ToolInstance
from src.models.tool.tool_type import ToolType
__all__ = ["ToolDefinitionManifest", "ToolInstance", "ToolType"]
@@ -9,12 +9,12 @@ from sqlalchemy.orm import Mapped, mapped_column, relationship
from src.models.base import Base, TimestampMixin, UUIDPrimaryKeyMixin from src.models.base import Base, TimestampMixin, UUIDPrimaryKeyMixin
if TYPE_CHECKING: if TYPE_CHECKING:
from src.models.config_profile import ConfigProfile from src.models import ConfigProfile
from src.models.git_repository import GitRepository from src.models import GitRepository
from src.models.project import Project from src.models.project import Project
from src.models.tool_type import ToolType from src.models import ToolType
from src.models.user import User from src.models.user import User
from src.models.workspace import Workspace from src.models import Workspace
class ToolInstance(UUIDPrimaryKeyMixin, TimestampMixin, Base): class ToolInstance(UUIDPrimaryKeyMixin, TimestampMixin, Base):
@@ -6,8 +6,7 @@ from sqlalchemy import Uuid as UUID
from sqlalchemy.orm import Mapped, mapped_column, relationship from sqlalchemy.orm import Mapped, mapped_column, relationship
from src.models.base import Base, TimestampMixin, UUIDPrimaryKeyMixin from src.models.base import Base, TimestampMixin, UUIDPrimaryKeyMixin
from src.models.tool.tool_definition_manifest import ToolDefinitionManifest
from src.models.tool_definition_manifest import ToolDefinitionManifest
if TYPE_CHECKING: if TYPE_CHECKING:
from src.models.user import User from src.models.user import User
+7
View File
@@ -0,0 +1,7 @@
"""User models module."""
from src.models.user.ssh_key import SSHKey
from src.models.user.user import User
from src.models.user.user_config import UserConfig
__all__ = ["SSHKey", "User", "UserConfig"]
@@ -7,8 +7,8 @@ from src.models.base import Base, TimestampMixin, UUIDPrimaryKeyMixin
if TYPE_CHECKING: if TYPE_CHECKING:
from src.models.project import Project from src.models.project import Project
from src.models.ssh_key import SSHKey from src.models import SSHKey
from src.models.user_config import UserConfig from src.models import UserConfig
class User(UUIDPrimaryKeyMixin, TimestampMixin, Base): class User(UUIDPrimaryKeyMixin, TimestampMixin, Base):
+1
View File
@@ -0,0 +1 @@
"""Config module."""
+1
View File
@@ -0,0 +1 @@
"""Project module."""
+1
View File
@@ -0,0 +1 @@
"""System module."""
+1
View File
@@ -0,0 +1 @@
"""Tool module."""
+1
View File
@@ -0,0 +1 @@
"""User module."""
+1 -1
View File
@@ -5,7 +5,7 @@ import logging
from sqlalchemy import select, text from sqlalchemy import select, text
from src.database import SessionLocal from src.database import SessionLocal
from src.models.tool_type import ToolType from src.models import ToolType
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
+1
View File
@@ -0,0 +1 @@
"""Config module."""
@@ -13,7 +13,7 @@ from typing import Any
from sqlalchemy import select from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from src.models.config_profile import ConfigProfile, ConfigProfileInclude from src.models import ConfigProfile, ConfigProfileInclude
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
+1 -1
View File
@@ -4,7 +4,7 @@ import logging
import os import os
from dataclasses import dataclass from dataclasses import dataclass
from src.models.workspace import Workspace from src.models import Workspace
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
+1
View File
@@ -0,0 +1 @@
"""Git module."""
+1 -1
View File
@@ -4,7 +4,7 @@ import asyncio
import logging import logging
from dataclasses import dataclass from dataclasses import dataclass
from src.models.workspace import Workspace from src.models import Workspace
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
+2 -2
View File
@@ -10,8 +10,8 @@ from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from src.database import SessionLocal from src.database import SessionLocal
from src.models.health_check import HealthCheck from src.models import HealthCheck
from src.models.tool_instance import ToolInstance from src.models import ToolInstance
from src.services.correlation import get_correlation_id from src.services.correlation import get_correlation_id
from src.services.docker import get_container_status from src.services.docker import get_container_status
from src.services.tunnel import check_tunnel_health from src.services.tunnel import check_tunnel_health
@@ -0,0 +1 @@
"""Instance module."""
+2 -2
View File
@@ -6,8 +6,8 @@ from datetime import datetime, timezone
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from src.models.instance_event import InstanceEvent from src.models import InstanceEvent
from src.models.tool_instance import ToolInstance from src.models import ToolInstance
from src.services.correlation import get_correlation_id from src.services.correlation import get_correlation_id
from src.services.event_bus import InstanceEventBus, InstanceEventPayload from src.services.event_bus import InstanceEventBus, InstanceEventPayload
from src.services.notification_service import notification_service from src.services.notification_service import notification_service
@@ -8,7 +8,7 @@ from sqlalchemy import func, select, update
from sqlalchemy.engine import CursorResult from sqlalchemy.engine import CursorResult
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from src.models.notification import Notification from src.models import Notification
class NotificationService: class NotificationService:
+1
View File
@@ -0,0 +1 @@
"""Shared module."""
@@ -0,0 +1 @@
"""Terminal module."""
+1 -1
View File
@@ -9,7 +9,7 @@ from fastapi import WebSocket
from sqlalchemy.dialects.postgresql import insert as pg_insert from sqlalchemy.dialects.postgresql import insert as pg_insert
from src.database import SessionLocal from src.database import SessionLocal
from src.models.terminal_session import TerminalSessionModel from src.models import TerminalSessionModel
from src.services.terminal_session import TerminalSession from src.services.terminal_session import TerminalSession
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
+7 -7
View File
@@ -14,15 +14,15 @@ from typing import TYPE_CHECKING
from sqlalchemy import select from sqlalchemy import select
from src.models.workspace import Workspace from src.models import Workspace
from src.services.git_service import GitService from src.services.git_service import GitService
from src.services.ssh_keys import _get_fernet from src.services.ssh_keys import _get_fernet
if TYPE_CHECKING: if TYPE_CHECKING:
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from src.models.git_repository import GitRepository from src.models import GitRepository
from src.models.tool_instance import ToolInstance from src.models import ToolInstance
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -96,7 +96,7 @@ class WorkspaceManager:
# Load SSH key if repo has one # Load SSH key if repo has one
ssh_key = None ssh_key = None
if getattr(repo, "ssh_key_id", None) and session is not None: if getattr(repo, "ssh_key_id", None) and session is not None:
from src.models.ssh_key import SSHKey from src.models import SSHKey
result = await session.execute( result = await session.execute(
select(SSHKey).where(SSHKey.id == repo.ssh_key_id) select(SSHKey).where(SSHKey.id == repo.ssh_key_id)
@@ -181,8 +181,8 @@ class WorkspaceManager:
# Load SSH key if repo has one # Load SSH key if repo has one
ssh_key = None ssh_key = None
if session is not None: if session is not None:
from src.models.git_repository import GitRepository from src.models import GitRepository
from src.models.ssh_key import SSHKey from src.models import SSHKey
repo = await session.get(GitRepository, workspace.repo_id) repo = await session.get(GitRepository, workspace.repo_id)
if repo and getattr(repo, "ssh_key_id", None): if repo and getattr(repo, "ssh_key_id", None):
@@ -241,7 +241,7 @@ class WorkspaceManager:
session: AsyncSession, session: AsyncSession,
) -> list[ToolInstance]: ) -> list[ToolInstance]:
"""Get all tool instances associated with this workspace.""" """Get all tool instances associated with this workspace."""
from src.models.tool_instance import ToolInstance from src.models import ToolInstance
result = await session.execute( result = await session.execute(
select(ToolInstance).where(ToolInstance.workspace_id == workspace.id) select(ToolInstance).where(ToolInstance.workspace_id == workspace.id)