# ============================================================ # app/services/user_service.py - User Business Logic # ============================================================ import logging from fastapi import HTTPException, status from bson import ObjectId from app.database import get_db from app.models.user import User from datetime import datetime logger = logging.getLogger(__name__) class UserService: """User Service for managing user profiles""" @staticmethod async def get_user_profile(user_id: str) -> dict: """ Get user profile by ID Args: user_id: MongoDB user ID Returns: User profile data """ # Validate MongoDB ID format if not ObjectId.is_valid(user_id): raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Invalid user ID format" ) db = await get_db() users_collection = db["users"] try: user = await users_collection.find_one({"_id": ObjectId(user_id)}) if not user: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="User not found" ) logger.info(f"User profile fetched: {user_id}") return { "success": True, "message": "User profile retrieved successfully", "data": User.format_response(user), } except HTTPException: raise except Exception as e: logger.error(f"Error fetching user profile: {str(e)}") raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Failed to fetch user profile" ) @staticmethod async def get_current_user_profile(user_id: str) -> dict: """ Get current logged-in user profile Args: user_id: User ID from JWT token Returns: Current user profile """ return await UserService.get_user_profile(user_id) @staticmethod async def update_user_profile(user_id: str, update_data: dict) -> dict: """ Update user profile Args: user_id: MongoDB user ID update_data: Fields to update Returns: Updated user profile """ # Validate MongoDB ID format if not ObjectId.is_valid(user_id): raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Invalid user ID format" ) # Only allow updating certain fields allowed_fields = ["firstName", "lastName", "phone", "bio", "profilePicture"] filtered_data = { k: v for k, v in update_data.items() if k in allowed_fields } if not filtered_data: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="No valid fields to update" ) db = await get_db() users_collection = db["users"] filtered_data["updatedAt"] = datetime.utcnow() try: user = await users_collection.find_one_and_update( {"_id": ObjectId(user_id)}, {"$set": filtered_data}, return_document=True, ) if not user: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="User not found" ) logger.info(f"User profile updated: {user_id}") return { "success": True, "message": "User profile updated successfully", "data": User.format_response(user), } except HTTPException: raise except Exception as e: logger.error(f"Error updating user profile: {str(e)}") raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Failed to update user profile" ) # Create singleton instance user_service = UserService()