feat(memory): add protected memory config deletion with end-user safeguards
- Add force parameter to delete_config endpoint for controlled deletion of in-use configs - Implement MemoryConfigService.delete_config with protection against deleting default configs - Add validation to prevent deletion of configs with connected end-users unless force=True - Reorganize controller imports to remove duplicates and improve maintainability - Clean up unused database connection management code from memory_storage_controller - Add detailed docstring to delete_config endpoint explaining protection mechanisms - Update error handling with specific BizCode.RESOURCE_IN_USE for configs in active use - Add comprehensive logging for deletion attempts, warnings, and affected users - Refactor ConfigParamsDelete schema usage to use MemoryConfigService directly - Improve API response structure with affected_users count and force_required flag
This commit is contained in:
@@ -5,32 +5,36 @@ import uuid
|
||||
from os import getenv
|
||||
from typing import List, Optional
|
||||
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.core.config import settings
|
||||
from app.core.error_codes import BizCode
|
||||
from app.core.exceptions import BusinessException, PermissionDeniedException
|
||||
from app.core.logging_config import get_business_logger
|
||||
from app.models.user_model import User
|
||||
|
||||
from app.schemas.workspace_schema import (
|
||||
WorkspaceModelsUpdate,
|
||||
from app.models.workspace_model import (
|
||||
InviteStatus,
|
||||
Workspace,
|
||||
WorkspaceMember,
|
||||
WorkspaceRole,
|
||||
)
|
||||
from sqlalchemy.orm import Session
|
||||
from app.models.workspace_model import Workspace, WorkspaceRole, InviteStatus, WorkspaceMember
|
||||
from app.repositories import workspace_repository
|
||||
from app.repositories.workspace_invite_repository import WorkspaceInviteRepository
|
||||
from app.schemas.workspace_schema import (
|
||||
InviteAcceptRequest,
|
||||
InviteValidateResponse,
|
||||
WorkspaceCreate,
|
||||
WorkspaceUpdate,
|
||||
WorkspaceInviteCreate,
|
||||
WorkspaceInviteResponse,
|
||||
InviteValidateResponse,
|
||||
InviteAcceptRequest,
|
||||
WorkspaceMemberUpdate
|
||||
WorkspaceMemberUpdate,
|
||||
WorkspaceModelsUpdate,
|
||||
WorkspaceUpdate,
|
||||
)
|
||||
|
||||
# 获取业务逻辑专用日志器
|
||||
business_logger = get_business_logger()
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv()
|
||||
def switch_workspace(
|
||||
db: Session,
|
||||
@@ -127,6 +131,27 @@ def create_workspace(
|
||||
db.commit()
|
||||
db.refresh(db_workspace)
|
||||
|
||||
# Create default memory config for the workspace (only for neo4j storage types)
|
||||
if workspace.storage_type == 'neo4j':
|
||||
try:
|
||||
_create_default_memory_config(
|
||||
db=db,
|
||||
workspace_id=db_workspace.id,
|
||||
workspace_name=db_workspace.name,
|
||||
llm_id=llm,
|
||||
embedding_id=embedding,
|
||||
rerank_id=rerank,
|
||||
)
|
||||
business_logger.info(
|
||||
f"为工作空间 {db_workspace.id} 创建默认记忆配置成功"
|
||||
)
|
||||
except Exception as mc_error:
|
||||
business_logger.error(
|
||||
f"为工作空间 {db_workspace.id} 创建默认记忆配置失败: {str(mc_error)}"
|
||||
)
|
||||
# Don't fail workspace creation if memory config creation fails
|
||||
# The workspace can still function without a default memory config
|
||||
|
||||
# 如果 storage_type 是 "rag",自动创建知识库
|
||||
if workspace.storage_type == "rag":
|
||||
business_logger.info(
|
||||
@@ -286,7 +311,7 @@ def _check_workspace_member_permission(db: Session, workspace_id: uuid.UUID, use
|
||||
)
|
||||
|
||||
# 使用统一权限服务检查访问权限
|
||||
from app.core.permissions import permission_service, Subject, Resource, Action
|
||||
from app.core.permissions import Action, Resource, Subject, permission_service
|
||||
|
||||
# 获取用户的工作空间成员关系
|
||||
member = workspace_repository.get_member_in_workspace(
|
||||
@@ -324,7 +349,7 @@ def _check_workspace_admin_permission(db: Session, workspace_id: uuid.UUID, user
|
||||
)
|
||||
|
||||
# 使用统一权限服务检查管理权限
|
||||
from app.core.permissions import permission_service, Subject, Resource, Action
|
||||
from app.core.permissions import Action, Resource, Subject, permission_service
|
||||
|
||||
# 获取用户的工作空间成员关系
|
||||
member = workspace_repository.get_member_in_workspace(
|
||||
@@ -852,3 +877,50 @@ def update_workspace_models_configs(
|
||||
business_logger.error(f"工作空间模型配置更新失败: workspace_id={workspace_id} - {str(e)}")
|
||||
db.rollback()
|
||||
raise BusinessException(f"更新模型配置失败: {str(e)}", BizCode.INTERNAL_ERROR)
|
||||
|
||||
|
||||
def _create_default_memory_config(
|
||||
db: Session,
|
||||
workspace_id: uuid.UUID,
|
||||
workspace_name: str,
|
||||
llm_id: Optional[uuid.UUID] = None,
|
||||
embedding_id: Optional[uuid.UUID] = None,
|
||||
rerank_id: Optional[uuid.UUID] = None,
|
||||
) -> None:
|
||||
"""Create a default memory config for a newly created workspace.
|
||||
|
||||
Args:
|
||||
db: Database session
|
||||
workspace_id: The workspace ID
|
||||
workspace_name: The workspace name (used for config naming)
|
||||
llm_id: Optional LLM model ID
|
||||
embedding_id: Optional embedding model ID
|
||||
rerank_id: Optional rerank model ID
|
||||
"""
|
||||
from app.models.memory_config_model import MemoryConfig
|
||||
|
||||
config_id = uuid.uuid4()
|
||||
|
||||
default_config = MemoryConfig(
|
||||
config_id=config_id,
|
||||
config_name=f"{workspace_name} 默认配置",
|
||||
config_desc="工作空间创建时自动生成的默认记忆配置",
|
||||
workspace_id=workspace_id,
|
||||
llm_id=str(llm_id) if llm_id else None,
|
||||
embedding_id=str(embedding_id) if embedding_id else None,
|
||||
rerank_id=str(rerank_id) if rerank_id else None,
|
||||
state=True, # Active by default
|
||||
is_default=True, # Mark as workspace default
|
||||
)
|
||||
|
||||
db.add(default_config)
|
||||
db.commit()
|
||||
|
||||
business_logger.info(
|
||||
"Created default memory config for workspace",
|
||||
extra={
|
||||
"workspace_id": str(workspace_id),
|
||||
"config_id": str(config_id),
|
||||
"config_name": default_config.config_name,
|
||||
}
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user