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 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 ): from domains.users.repo import get_user_by_username from domains.notifications.service import send_join_request 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("Group not found") sender = await get_user_by_id(db, sender_id) if not sender: raise ValueError("Sender not found") if not sender.is_admin: membership = await get_group_member(db, group_id_uuid, sender_id) if not membership: raise ValueError("Not a group member") # 2. Check if target user exists target_user = await get_user_by_username(db, target_username) if not target_user: raise ValueError("User not found") # 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="Group Invitation", description=f"You have been invited to join group {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("User already in group") 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("Permission denied") await delete_group_member(db, group_id_uuid, target_user_id_uuid)