from datetime import datetime from typing import List, Optional from beanie import Document, Indexed from pydantic import BaseModel, EmailStr import re from decimal import Decimal from common.constants.region import UserRegion class Tags(BaseModel): skill: List[str] class SelfIntro(BaseModel): summary: str = "" content_html: str = "" tags: Tags class Photo(BaseModel): url: Optional[str] base64: str filename: str class Email(BaseModel): address: Optional[EmailStr] verified: bool = False class Mobile(BaseModel): number: Optional[str] verified: bool class FLID(BaseModel): identity: str set_by: str create_time: datetime update_time: datetime class Password(BaseModel): set_up: bool update_time: datetime expiry: datetime class BasicProfileDoc(Document): user_id: str first_name: Indexed(str) = "" # type: ignore last_name: Indexed(str) = "" # type: ignore Index for faster search spoken_language: List[str] = [] self_intro: SelfIntro photo: Photo email: Email mobile: Mobile FLID: FLID password: Password region: int = UserRegion.OTHER time_zone: Optional[str] = None class Settings: name = "basic_profile" indexes = [ "user_id", # Add index for fast querying by user_id "email.address", # This adds an index for the 'email.address' field # Compound text index for fuzzy search across multiple fields [("first_name", "text"), ("last_name", "text"), ("email.address", "text")], ] @classmethod async def fuzzy_search(cls, query: str) -> List["BasicProfileDoc"]: # Create a case-insensitive regex pattern for partial matching regex = re.compile(f".*{query}.*", re.IGNORECASE) # Perform a search on first_name, last_name, and email fields using $or results = await cls.find( { "$or": [ {"first_name": {"$regex": regex}}, {"last_name": {"$regex": regex}}, {"email.address": {"$regex": regex}}, ] } ).to_list() return results class ExpectedSalary(BaseModel): currency: str = "USD" hourly: Decimal = 0.0 class ProviderProfileDoc(Document): user_id: str expected_salary: ExpectedSalary accepting_request: bool = False class Settings: name = "provider_profile"