68 lines
2.5 KiB
Python
68 lines
2.5 KiB
Python
from fastapi import HTTPException, status
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.chats.service import ensure_chat_membership
|
|
from app.messages import repository
|
|
from app.messages.models import Message
|
|
from app.messages.schemas import MessageCreateRequest, MessageUpdateRequest
|
|
|
|
|
|
async def create_chat_message(db: AsyncSession, *, sender_id: int, payload: MessageCreateRequest) -> Message:
|
|
await ensure_chat_membership(db, chat_id=payload.chat_id, user_id=sender_id)
|
|
if payload.type.value == "text" and not (payload.text and payload.text.strip()):
|
|
raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail="Text message cannot be empty")
|
|
|
|
message = await repository.create_message(
|
|
db,
|
|
chat_id=payload.chat_id,
|
|
sender_id=sender_id,
|
|
message_type=payload.type,
|
|
text=payload.text,
|
|
)
|
|
await db.commit()
|
|
await db.refresh(message)
|
|
return message
|
|
|
|
|
|
async def get_messages(
|
|
db: AsyncSession,
|
|
*,
|
|
chat_id: int,
|
|
user_id: int,
|
|
limit: int = 50,
|
|
before_id: int | None = None,
|
|
) -> list[Message]:
|
|
await ensure_chat_membership(db, chat_id=chat_id, user_id=user_id)
|
|
safe_limit = max(1, min(limit, 100))
|
|
return await repository.list_chat_messages(db, chat_id, limit=safe_limit, before_id=before_id)
|
|
|
|
|
|
async def update_message(
|
|
db: AsyncSession,
|
|
*,
|
|
message_id: int,
|
|
user_id: int,
|
|
payload: MessageUpdateRequest,
|
|
) -> Message:
|
|
message = await repository.get_message_by_id(db, message_id)
|
|
if not message:
|
|
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Message not found")
|
|
await ensure_chat_membership(db, chat_id=message.chat_id, user_id=user_id)
|
|
if message.sender_id != user_id:
|
|
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="You can edit only your own messages")
|
|
message.text = payload.text
|
|
await db.commit()
|
|
await db.refresh(message)
|
|
return message
|
|
|
|
|
|
async def delete_message(db: AsyncSession, *, message_id: int, user_id: int) -> None:
|
|
message = await repository.get_message_by_id(db, message_id)
|
|
if not message:
|
|
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Message not found")
|
|
await ensure_chat_membership(db, chat_id=message.chat_id, user_id=user_id)
|
|
if message.sender_id != user_id:
|
|
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="You can delete only your own messages")
|
|
await repository.delete_message(db, message)
|
|
await db.commit()
|