Spaces:
Sleeping
Sleeping
| from fastapi import HTTPException | |
| from app.core.nosql_client import db | |
| from app.utils.common_utils import is_email, is_phone, validate_identifier # Updated imports | |
| from app.schemas.user_schema import UserRegisterRequest | |
| import logging | |
| logger = logging.getLogger("user_model") | |
| class BookMyServiceUserModel: | |
| collection = db["customers"] | |
| async def find_by_email(email: str): | |
| logger.info(f"Searching for user by email: {email}") | |
| try: | |
| user = await BookMyServiceUserModel.collection.find_one({"email": email}) | |
| if user: | |
| logger.info(f"User found by email: {email}") | |
| else: | |
| logger.info(f"No user found with email: {email}") | |
| return user | |
| except Exception as e: | |
| logger.error(f"Error finding user by email {email}: {str(e)}", exc_info=True) | |
| return None | |
| async def find_by_phone(phone: str): | |
| logger.info(f"Searching for user by phone: {phone}") | |
| try: | |
| user = await BookMyServiceUserModel.collection.find_one({"phone": phone}) | |
| if user: | |
| logger.info(f"User found by phone: {phone}") | |
| else: | |
| logger.info(f"No user found with phone: {phone}") | |
| return user | |
| except Exception as e: | |
| logger.error(f"Error finding user by phone {phone}: {str(e)}", exc_info=True) | |
| return None | |
| async def find_by_mobile(mobile: str): | |
| """Legacy method for backward compatibility - redirects to find_by_phone""" | |
| logger.info(f"Legacy find_by_mobile called, redirecting to find_by_phone for: {mobile}") | |
| return await BookMyServiceUserModel.find_by_phone(mobile) | |
| async def find_by_identifier(identifier: str): | |
| logger.info(f"Finding user by identifier: {identifier}") | |
| try: | |
| # Validate and determine identifier type | |
| identifier_type = validate_identifier(identifier) | |
| logger.info(f"Identifier type determined: {identifier_type}") | |
| if identifier_type == "email": | |
| logger.info(f"Searching by email for identifier: {identifier}") | |
| user = await BookMyServiceUserModel.find_by_email(identifier) | |
| elif identifier_type == "phone": | |
| logger.info(f"Searching by phone for identifier: {identifier}") | |
| user = await BookMyServiceUserModel.find_by_phone(identifier) | |
| else: | |
| logger.error(f"Invalid identifier type: {identifier_type}") | |
| raise HTTPException(status_code=400, detail="Invalid identifier format") | |
| if not user: | |
| logger.warning(f"User not found with identifier: {identifier}") | |
| raise HTTPException(status_code=404, detail="User not found with this email or phone") | |
| logger.info(f"User found successfully for identifier: {identifier}") | |
| logger.info(f"User data keys: {list(user.keys()) if user else 'None'}") | |
| return user | |
| except ValueError as ve: | |
| logger.error(f"Validation error for identifier {identifier}: {str(ve)}") | |
| raise HTTPException(status_code=400, detail=str(ve)) | |
| except HTTPException as e: | |
| logger.error(f"HTTP error finding user by identifier {identifier}: {e.status_code} - {e.detail}") | |
| raise e | |
| except Exception as e: | |
| logger.error(f"Unexpected error finding user by identifier {identifier}: {str(e)}", exc_info=True) | |
| raise HTTPException(status_code=500, detail="Failed to find user") | |
| async def exists_by_email_or_phone(email: str = None, phone: str = None) -> bool: | |
| """Check if user exists by email or phone""" | |
| query_conditions = [] | |
| if email: | |
| query_conditions.append({"email": email}) | |
| if phone: | |
| query_conditions.append({"phone": phone}) | |
| if not query_conditions: | |
| return False | |
| query = {"$or": query_conditions} if len(query_conditions) > 1 else query_conditions[0] | |
| result = await BookMyServiceUserModel.collection.find_one(query) | |
| return result is not None | |
| async def create(user_data: UserRegisterRequest): | |
| user_dict = user_data.dict() | |
| result = await BookMyServiceUserModel.collection.insert_one(user_dict) | |
| return result.inserted_id | |
| async def update_by_identifier(identifier: str, update_fields: dict): | |
| try: | |
| identifier_type = validate_identifier(identifier) | |
| if identifier_type == "email": | |
| query = {"email": identifier} | |
| elif identifier_type == "phone": | |
| query = {"phone": identifier} | |
| else: | |
| raise HTTPException(status_code=400, detail="Invalid identifier format") | |
| result = await BookMyServiceUserModel.collection.update_one(query, {"$set": update_fields}) | |
| if result.matched_count == 0: | |
| raise HTTPException(status_code=404, detail="User not found") | |
| return result.modified_count > 0 | |
| except ValueError as ve: | |
| logger.error(f"Validation error for identifier {identifier}: {str(ve)}") | |
| raise HTTPException(status_code=400, detail=str(ve)) | |
| async def update_profile(customer_id: str, update_fields: dict): | |
| """Update user profile by customer_id""" | |
| try: | |
| from datetime import datetime | |
| # Add updated_at timestamp | |
| update_fields["updated_at"] = datetime.utcnow() | |
| result = await BookMyServiceUserModel.collection.update_one( | |
| {"customer_id": customer_id}, | |
| {"$set": update_fields} | |
| ) | |
| if result.matched_count == 0: | |
| raise HTTPException(status_code=404, detail="User not found") | |
| return result.modified_count > 0 | |
| except Exception as e: | |
| logger.error(f"Error updating profile for user {customer_id}: {str(e)}") | |
| raise HTTPException(status_code=500, detail="Failed to update profile") | |
| async def find_by_id(customer_id: str): | |
| """Find user by customer_id""" | |
| try: | |
| user = await BookMyServiceUserModel.collection.find_one({"customer_id": customer_id}) | |
| return user | |
| except Exception as e: | |
| logger.error(f"Error finding user by ID {customer_id}: {str(e)}") | |
| return None |