37ccaa4fdc
Service organization (19 files moved into 6 subpackages): - services/instance/ — event_bus, health_monitor, lifecycle_hooks - services/config/ — config_profile_resolver - services/git/ — clone, git_operations, git_service - services/build/ — docker_build, manifest_compiler - services/terminal/ — terminal_manager, terminal_session - services/shared/ — correlation, file_service, notification_service, permission_fixer, readiness_probe, ssh_keys, tunnel, workspace_manager API router organization (16 files moved into 6 subpackages): - api/tool/ — tool_instances, tool_types, tool_definitions, tool_types_validation, sessions (extracted from tool_instances) - api/config/ — config_profiles, user_config - api/workspace/ — workspaces, workspace_files, workspace_git, workspace_instances - api/user/ — users, auth, ssh_keys - api/project/ — projects, git_repositories - api/system/ — health, events, notifications, dashboard, terminal, instance_proxy Updated main.py imports and all __init__.py re-exports. Sessions router extracted from tool_instances.py into api/tool/sessions.py. Quality gates: py_compile passed, ruff passed.
99 lines
2.9 KiB
Python
99 lines
2.9 KiB
Python
import logging
|
|
import uuid
|
|
|
|
from fastapi import APIRouter, Depends
|
|
from sqlalchemy import select
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from src.auth.dependencies import _get_user, get_current_user_id, get_db_session
|
|
from src.models import UserConfig
|
|
from src.schemas.user import UserConfigResponse, UserConfigUpdate
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
router = APIRouter(prefix="/users/me", tags=["user-config"])
|
|
|
|
|
|
async def _get_or_create_config(
|
|
session: AsyncSession, user_id: uuid.UUID
|
|
) -> UserConfig:
|
|
"""Get or create user config record.
|
|
|
|
Args:
|
|
session: Database session.
|
|
user_id: UUID of the user.
|
|
|
|
Returns:
|
|
The user's config, creating a new one if it doesn't exist.
|
|
"""
|
|
result = await session.execute(
|
|
select(UserConfig).where(UserConfig.user_id == user_id)
|
|
)
|
|
config = result.scalar_one_or_none()
|
|
if config is None:
|
|
config = UserConfig(user_id=user_id, config={})
|
|
session.add(config)
|
|
await session.commit()
|
|
await session.refresh(config)
|
|
return config
|
|
|
|
|
|
@router.get(
|
|
"/config",
|
|
response_model=UserConfigResponse,
|
|
summary="Get user config",
|
|
description="Get the current user's configuration settings.",
|
|
)
|
|
async def get_user_config(
|
|
user_id: uuid.UUID = Depends(get_current_user_id),
|
|
session: AsyncSession = Depends(get_db_session),
|
|
) -> UserConfigResponse:
|
|
"""Get the current user's configuration.
|
|
|
|
Args:
|
|
user_id: ID of the authenticated user.
|
|
session: Database session.
|
|
|
|
Returns:
|
|
The user's configuration settings.
|
|
"""
|
|
_user = await _get_user(session, user_id)
|
|
config = await _get_or_create_config(session, user_id)
|
|
return UserConfigResponse.model_validate(config.config)
|
|
|
|
|
|
@router.patch(
|
|
"/config",
|
|
response_model=UserConfigResponse,
|
|
summary="Update user config",
|
|
description="Update the current user's configuration settings.",
|
|
)
|
|
async def update_user_config(
|
|
data: UserConfigUpdate,
|
|
user_id: uuid.UUID = Depends(get_current_user_id),
|
|
session: AsyncSession = Depends(get_db_session),
|
|
) -> UserConfigResponse:
|
|
"""Update the current user's configuration.
|
|
|
|
Args:
|
|
data: Configuration update data with optional fields.
|
|
user_id: ID of the authenticated user.
|
|
session: Database session.
|
|
|
|
Returns:
|
|
The updated user configuration.
|
|
"""
|
|
_user = await _get_user(session, user_id)
|
|
config = await _get_or_create_config(session, user_id)
|
|
|
|
# Merge updates
|
|
update_data = data.model_dump(exclude_unset=True)
|
|
logger.debug("Updating user config for user %s: %s", user_id, update_data)
|
|
# SQLAlchemy JSON doesn't track dict mutations, so we replace the whole dict
|
|
config.config = {**config.config, **update_data}
|
|
|
|
await session.commit()
|
|
await session.refresh(config)
|
|
logger.debug("Updated config: %s", config.config)
|
|
return UserConfigResponse.model_validate(config.config)
|