from fastapi import APIRouter, Depends, HTTPException from fastapi.responses import Response from pydantic import BaseModel from typing import Optional from auth_utils import get_current_user from groups_db_utils import ( create_group, get_group, get_user_groups, add_group_member, remove_group_member, share_recipe_to_group, get_group_recipes, ) from notification_db_utils import create_notification router = APIRouter(prefix="/groups", tags=["groups"]) class GroupCreate(BaseModel): name: str description: str = "" is_private: bool = False @router.post("") def create_group_endpoint( data: GroupCreate, current_user: dict = Depends(get_current_user) ): """Create a new group""" return create_group( name=data.name, description=data.description, created_by=current_user["user_id"], is_private=data.is_private ) @router.get("") def get_user_groups_endpoint( current_user: dict = Depends(get_current_user) ): """Get all groups user is member of""" return get_user_groups(current_user["user_id"]) @router.get("/{group_id}") def get_group_endpoint( group_id: int, current_user: dict = Depends(get_current_user) ): """Get group details""" group = get_group(group_id) if not group: raise HTTPException(status_code=404, detail="Group not found") return group @router.post("/{group_id}/members/{user_id}") def add_group_member_endpoint( group_id: int, user_id: int, current_user: dict = Depends(get_current_user) ): """Add a member to a group""" # Get group name group = get_group(group_id) result = add_group_member(group_id, user_id, current_user["user_id"]) if "error" in result: raise HTTPException(status_code=403, detail=result["error"]) # Notify the added user if group: create_notification( user_id=user_id, type="group_invite", message=f"{current_user['display_name']} הוסיף אותך לקבוצה '{group['name']}'" , related_id=group_id ) return result @router.delete("/{group_id}/members/{user_id}") def remove_group_member_endpoint( group_id: int, user_id: int, current_user: dict = Depends(get_current_user) ): """Remove a member from a group""" result = remove_group_member(group_id, user_id, current_user["user_id"]) if "error" in result: raise HTTPException(status_code=403, detail=result["error"]) return Response(status_code=204) @router.post("/{group_id}/recipes/{recipe_id}") def share_recipe_to_group_endpoint( group_id: int, recipe_id: int, current_user: dict = Depends(get_current_user) ): """Share a recipe to a group""" from groups_db_utils import get_db_connection from psycopg2.extras import RealDictCursor from db_utils import get_conn # Get group members and names conn = get_db_connection() cur = conn.cursor(cursor_factory=RealDictCursor) try: cur.execute( """SELECT gm.user_id, g.name as group_name FROM group_members gm JOIN groups g ON gm.group_id = g.id WHERE gm.group_id = %s AND gm.user_id != %s""", (group_id, current_user["user_id"]) ) members = cur.fetchall() finally: cur.close() conn.close() # Get recipe name recipe_conn = get_conn() recipe_cur = recipe_conn.cursor(cursor_factory=RealDictCursor) try: recipe_cur.execute("SELECT name FROM recipes WHERE id = %s", (recipe_id,)) recipe = recipe_cur.fetchone() finally: recipe_cur.close() recipe_conn.close() result = share_recipe_to_group(recipe_id, group_id, current_user["user_id"]) if "error" in result: raise HTTPException(status_code=403, detail=result["error"]) # Notify all group members except the sharer if members and recipe: group_name = members[0]["group_name"] if members else "" for member in members: create_notification( user_id=member["user_id"], type="recipe_shared", message=f"{current_user['display_name']} שיתף מתכון '{recipe['name']}' בקבוצה '{group_name}'", related_id=recipe_id ) return result @router.get("/{group_id}/recipes") def get_group_recipes_endpoint( group_id: int, current_user: dict = Depends(get_current_user) ): """Get all recipes shared to a group""" result = get_group_recipes(group_id, current_user["user_id"]) if isinstance(result, dict) and "error" in result: raise HTTPException(status_code=403, detail=result["error"]) return result