Neda/Back/domains/groups/service.py

152 lines
4.4 KiB
Python

import uuid
from sqlalchemy.ext.asyncio import AsyncSession
from domains.users.repo import get_user_by_id
from domains.groups.models import Group, GroupMember, GroupType, GroupMemberRole
from domains.groups.repo import (
create_group,
get_group_by_id,
add_group_member,
get_user_groups,
get_group_members_with_details,
delete_group_member,
get_group_member,
get_all_groups as repo_get_all_groups
)
from domains.realtime.presence_service import list_online_users
from domains.users.repo import get_user_by_username
from domains.notifications.service import send_join_request
async def create_new_group(
db: AsyncSession,
name: str,
creator_id: uuid.UUID,
is_admin: bool
):
group_type = GroupType.PUBLIC if is_admin else GroupType.PRIVATE
group = Group(
name=name,
type=group_type
)
await create_group(db, group)
# Creator becomes Manager
membership = GroupMember(
group_id=group.id,
user_id=creator_id,
role=GroupMemberRole.MANAGER
)
await add_group_member(db, membership)
return group
async def invite_member_to_group(
db: AsyncSession,
group_id: str | uuid.UUID,
sender_id: uuid.UUID,
target_username: str
):
group_id_uuid = group_id if isinstance(group_id, uuid.UUID) else uuid.UUID(group_id)
# 1. Check if group exists
group = await get_group_by_id(db, group_id_uuid)
if not group:
raise ValueError("گروهی یافت نشد")
sender = await get_user_by_id(db, sender_id)
if not sender:
raise ValueError("فرستنده یافت نشد")
if not sender.is_admin:
membership = await get_group_member(db, group_id_uuid, sender_id)
if not membership:
raise ValueError("شما عضو این گروه نیستید")
# 2. Check if target user exists
target_user = await get_user_by_username(db, target_username)
if not target_user:
raise ValueError("کاربری یافت نشد")
# 3. Send notification (Req 12)
return await send_join_request(
db,
sender_id=sender_id,
receiver_id=target_user.id,
group_id=group.id,
title="دعوت به گروه",
description=f"شما به گروه {group.name} دعوت شده‌اید"
)
async def add_member_to_group(
db: AsyncSession,
group_id: str | uuid.UUID,
user_id: str | uuid.UUID,
role: GroupMemberRole = GroupMemberRole.MEMBER
):
group_id_uuid = group_id if isinstance(group_id, uuid.UUID) else uuid.UUID(group_id)
user_id_uuid = user_id if isinstance(user_id, uuid.UUID) else uuid.UUID(user_id)
existing = await get_group_member(db, group_id_uuid, user_id_uuid)
if existing:
raise ValueError("کاربر از قبل عضو گروه است")
membership = GroupMember(
group_id=group_id_uuid,
user_id=user_id_uuid,
role=role
)
return await add_group_member(db, membership)
async def list_user_groups(
db: AsyncSession,
user_id: uuid.UUID
):
return await get_user_groups(db, user_id)
async def list_all_groups_admin(db: AsyncSession):
return await repo_get_all_groups(db)
async def list_group_members_api(db: AsyncSession, group_id: str):
group_id_uuid = uuid.UUID(group_id)
members_data = await get_group_members_with_details(db, group_id_uuid)
online_users = await list_online_users(str(group_id))
result = []
for member_info in members_data:
member, username = member_info
result.append({
"user_id": member.user_id,
"username": username,
"role": member.role,
"is_online": str(member.user_id) in online_users
})
return result
async def remove_member_from_group(
db: AsyncSession,
group_id: str | uuid.UUID,
target_user_id: str | uuid.UUID,
requesting_user
):
group_id_uuid = group_id if isinstance(group_id, uuid.UUID) else uuid.UUID(group_id)
target_user_id_uuid = target_user_id if isinstance(target_user_id, uuid.UUID) else uuid.UUID(target_user_id)
# Admin can remove anyone
if not requesting_user.is_admin:
membership = await get_group_member(db, group_id_uuid, requesting_user.id)
if not membership or membership.role != GroupMemberRole.MANAGER:
raise ValueError("دسترسی لازم را ندارید")
await delete_group_member(db, group_id_uuid, target_user_id_uuid)