新增历史会话删除接口
This commit is contained in:
parent
0eecb9dc3c
commit
736a6653de
@ -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])
|
||||
async def send_conversation_message(
|
||||
conversation_id: int,
|
||||
|
||||
@ -71,3 +71,13 @@ class ConversationRepository:
|
||||
.options(selectinload(Conversation.messages))
|
||||
)
|
||||
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
|
||||
|
||||
@ -128,6 +128,24 @@ class ConversationService:
|
||||
raise AppException("对话创建失败", code=500, status_code=500)
|
||||
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(
|
||||
self,
|
||||
conversation_id: int,
|
||||
|
||||
19
tests/test_conversation_delete.py
Normal file
19
tests/test_conversation_delete.py
Normal 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
|
||||
Loading…
x
Reference in New Issue
Block a user