from fastapi import APIRouter, Depends, HTTPException, Query from pydantic import BaseModel from typing import List from auth_utils import get_current_user from social_db_utils import ( send_friend_request, accept_friend_request, reject_friend_request, get_friend_requests, get_friends, remove_friend, search_users, ) from notification_db_utils import create_notification from user_db_utils import get_user_by_id router = APIRouter(prefix="/friends", tags=["friends"]) class FriendRequestModel(BaseModel): receiver_id: int @router.post("/request") def send_friend_request_endpoint( request: FriendRequestModel, current_user: dict = Depends(get_current_user) ): """Send a friend request to another user""" result = send_friend_request(current_user["user_id"], request.receiver_id) if "error" in result: raise HTTPException(status_code=400, detail=result["error"]) # Create notification for receiver create_notification( user_id=request.receiver_id, type="friend_request", message=f"{current_user['display_name']} שלח לך בקשת חברות", related_id=result.get("id") ) return result @router.get("/requests") def get_friend_requests_endpoint( current_user: dict = Depends(get_current_user) ): """Get pending friend requests""" return get_friend_requests(current_user["user_id"]) @router.post("/requests/{request_id}/accept") def accept_friend_request_endpoint( request_id: int, current_user: dict = Depends(get_current_user) ): """Accept a friend request""" # Get request details before accepting from social_db_utils import get_db_connection from psycopg2.extras import RealDictCursor conn = get_db_connection() cur = conn.cursor(cursor_factory=RealDictCursor) try: cur.execute( "SELECT sender_id, receiver_id FROM friend_requests WHERE id = %s AND status = 'pending'", (request_id,) ) request_data = cur.fetchone() # Verify current user is the receiver if not request_data: raise HTTPException(status_code=404, detail="Request not found") if request_data["receiver_id"] != current_user["user_id"]: raise HTTPException(status_code=403, detail="Not authorized to accept this request") finally: cur.close() conn.close() result = accept_friend_request(request_id) if "error" in result: raise HTTPException(status_code=404, detail=result["error"]) # Create notification for sender that their request was accepted if request_data: create_notification( user_id=request_data["sender_id"], type="friend_accepted", message=f"{current_user['display_name']} קיבל את בקשת החברות שלך", related_id=current_user["user_id"] ) return result @router.post("/requests/{request_id}/reject") def reject_friend_request_endpoint( request_id: int, current_user: dict = Depends(get_current_user) ): """Reject a friend request""" # Verify current user is the receiver from social_db_utils import get_db_connection from psycopg2.extras import RealDictCursor conn = get_db_connection() cur = conn.cursor(cursor_factory=RealDictCursor) try: cur.execute( "SELECT receiver_id FROM friend_requests WHERE id = %s AND status = 'pending'", (request_id,) ) request_data = cur.fetchone() if not request_data: raise HTTPException(status_code=404, detail="Request not found") if request_data["receiver_id"] != current_user["user_id"]: raise HTTPException(status_code=403, detail="Not authorized to reject this request") finally: cur.close() conn.close() return reject_friend_request(request_id) @router.get("") def get_friends_endpoint( current_user: dict = Depends(get_current_user) ): """Get list of user's friends""" return get_friends(current_user["user_id"]) @router.delete("/{friend_id}") def remove_friend_endpoint( friend_id: int, current_user: dict = Depends(get_current_user) ): """Remove a friend""" from fastapi.responses import Response remove_friend(current_user["user_id"], friend_id) return Response(status_code=204) @router.get("/search") def search_users_for_friends_endpoint( q: str = Query(..., min_length=1), current_user: dict = Depends(get_current_user) ): """Search users to add as friends""" return search_users(q, current_user["user_id"])