Neda/Back/domains/groups/service.py
2026-03-29 16:33:37 +03:30

199 lines
5.9 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,
delete_group,
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_user_group(
db: AsyncSession,
name: str,
owner_id: uuid.UUID,
):
group = Group(
name=name,
type=GroupType.PRIVATE,
owner_id=owner_id
)
await create_group(db, group)
# Owner becomes Manager
membership = GroupMember(
group_id=group.id,
user_id=owner_id,
role=GroupMemberRole.MANAGER
)
await add_group_member(db, membership)
return group
async def create_admin_group(
db: AsyncSession,
name: str,
owner_id: uuid.UUID,
):
group = Group(
name=name,
type=GroupType.PUBLIC,
owner_id=owner_id
)
await create_group(db, group)
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 | uuid.UUID):
group_id_uuid = group_id if isinstance(group_id, uuid.UUID) else 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_uuid))
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)
group = await get_group_by_id(db, group_id_uuid)
if not group:
raise ValueError("گروهی یافت نشد")
# 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 PermissionError("دسترسی لازم را ندارید")
if group.owner_id == target_user_id_uuid:
raise ValueError("حذف سازنده گروه مجاز نیست")
target_membership = await get_group_member(db, group_id_uuid, target_user_id_uuid)
if not target_membership:
raise ValueError("کاربر عضو این گروه نیست")
if not requesting_user.is_admin and target_membership.role != GroupMemberRole.MEMBER:
raise ValueError("حذف مدیر گروه مجاز نیست")
await delete_group_member(db, group_id_uuid, target_user_id_uuid)
async def delete_group_service(
db: AsyncSession,
group_id: str | uuid.UUID,
requesting_user
):
group_id_uuid = group_id if isinstance(group_id, uuid.UUID) else uuid.UUID(group_id)
group = await get_group_by_id(db, group_id_uuid)
if not group:
raise ValueError("گروهی یافت نشد")
# Permission check: System Admin or Group Owner
if not requesting_user.is_admin and group.owner_id != requesting_user.id:
raise ValueError("شما دسترسی لازم برای حذف گروه را ندارید (فقط سازنده گروه یا ادمین سیستم)")
await delete_group(db, group_id_uuid)