新增历史会话删除接口

This commit is contained in:
kx_guo 2026-09-13 17:36:22 +08:00
parent 0eecb9dc3c
commit 736a6653de
4 changed files with 57 additions and 0 deletions

View File

@ -57,6 +57,16 @@ async def get_conversation(
) )
@router.delete("/{conversation_id}", response_model=ApiResponse[None])
async def delete_conversation(
conversation_id: int,
session: DatabaseSession,
current_user: Annotated[UserAccount, Depends(require_permission("risk.assess", operate=True))],
) -> ApiResponse[None]:
await ConversationService(session).delete(conversation_id, current_user)
return ApiResponse(data=None, message="对话已删除")
@router.post("/{conversation_id}/messages", response_model=ApiResponse[ConversationData]) @router.post("/{conversation_id}/messages", response_model=ApiResponse[ConversationData])
async def send_conversation_message( async def send_conversation_message(
conversation_id: int, conversation_id: int,

View File

@ -71,3 +71,13 @@ class ConversationRepository:
.options(selectinload(Conversation.messages)) .options(selectinload(Conversation.messages))
) )
return await self.session.scalar(statement) return await self.session.scalar(statement)
async def delete_for_user(self, conversation_id: int, user_id: int) -> bool:
"""Delete a conversation only when it belongs to the requesting user."""
conversation = await self.get_for_user(conversation_id, user_id)
if conversation is None:
return False
await self.session.delete(conversation)
await self.session.flush()
return True

View File

@ -128,6 +128,24 @@ class ConversationService:
raise AppException("对话创建失败", code=500, status_code=500) raise AppException("对话创建失败", code=500, status_code=500)
return self._data(persisted, messages=[], total=0, offset=0) return self._data(persisted, messages=[], total=0, offset=0)
async def delete(self, conversation_id: int, user: UserAccount) -> None:
"""Delete one user-owned conversation and retain an audit trail."""
conversation = await self.repository.get_for_user(conversation_id, user.id)
if conversation is None:
raise AppException("对话不存在或无权访问", code=404, status_code=404)
self.session.add(
OperationAudit(
actor_user_id=user.id,
actor_emp_no=user.emp_no,
action="conversation.delete",
resource_type="conversation",
resource_id=str(conversation_id),
audit_metadata={"title": conversation.title[:120]},
)
)
await self.repository.delete_for_user(conversation_id, user.id)
async def send( async def send(
self, self,
conversation_id: int, conversation_id: int,

View File

@ -0,0 +1,19 @@
import pytest
from app.models.entities import Conversation, UserAccount
from app.services.conversations import ConversationService
@pytest.mark.asyncio
async def test_delete_conversation_rejects_conversation_owned_by_another_user() -> None:
service = object.__new__(ConversationService)
class Repository:
async def get_for_user(self, conversation_id, user_id):
return None
service.repository = Repository()
service.session = object()
with pytest.raises(Exception) as exc_info:
await service.delete(10, UserAccount(id=2, emp_no="u2", name="用户", role="user"))
assert getattr(exc_info.value, "status_code", None) == 404