import logging from typing import List, TypedDict import requests from decouple import config from api.models import User logger = logging.getLogger(__name__) def reverse_dhivehi_string(input_str): """ Reverses a Dhivehi string while preserving character composition. Args: input_str (str): The Dhivehi string to be reversed Returns: str: The reversed Dhivehi string """ # Reverse the string and then normalize the character order reversed_str = input_str[::-1] # List to store the corrected characters corrected_chars = [] # Iterate through the reversed string i = 0 while i < len(reversed_str): # Check if current character is a combining character if i + 1 < len(reversed_str) and "\u0300" <= reversed_str[i + 1] <= "\u036f": # If next character is a combining mark, add it before the base character corrected_chars.append(reversed_str[i + 1] + reversed_str[i]) i += 2 else: corrected_chars.append(reversed_str[i]) i += 1 return "".join(corrected_chars) class MismatchResult(TypedDict): ok: bool mismatch_fields: List[str] def check_person_api_verification( user_data: User, id_card: str | None, ) -> MismatchResult: """ Compares user data with data from the Person API and returns a verification result. :param user_data: A dictionary containing user information. Expected keys: 'id_card', 'first_name', 'last_name', 'address', 'dob', 'atoll_name', 'island_name'. :param api_data: A dictionary containing data from the Person API. Expected keys: 'nic', 'name_en', 'house_name_en', 'dob', 'atoll_en', 'island_name_en'. :return: A dictionary with 'ok' (boolean) and 'mismatch_fields' (list of strings). """ PERSON_VERIFY_BASE_URL = config("PERSON_VERIFY_BASE_URL", default="") # type: ignore if not PERSON_VERIFY_BASE_URL: raise ValueError( "PERSON_VERIFY_BASE_URL is not set in the environment variables." ) print(id_card) response = requests.get(f"{PERSON_VERIFY_BASE_URL}/api/person/{id_card}") if response.status_code != 200: logger.error( f"Failed to fetch data from Person API for ID Card '{id_card}'. " f"Status Code: {response.status_code}, Response: {response.text}" ) return {"ok": False, "mismatch_fields": ["api_error"]} api_data = response.json() if not api_data: logger.error( f"No data found in Person API for ID Card '{id_card}'. Response: {response.text}" ) return {"ok": False, "mismatch_fields": ["no_data"]} # Initialize a list to hold fields that do not match mismatch_fields = [] # Prepare user data for comparison user_full_name = f"{user_data.first_name} {user_data.last_name}".strip() user_dob_iso = user_data.dob.isoformat() if user_data.dob else None # Prepare API data for comparison api_nic = api_data.get("nic") api_name = api_data.get("name_en") api_house_name = api_data.get("house_name_en") api_dob = api_data.get("dob") api_atoll = api_data.get("atoll_en") api_island_name = api_data.get("island_name_en") # Perform comparisons and identify mismatches if user_data.id_card != api_nic: mismatch_fields.append("id_card") logger.debug(f"ID Card mismatch: User '{user_data.id_card}' vs API '{api_nic}'") if user_full_name != api_name: mismatch_fields.append("name") logger.debug(f"Name mismatch: User '{user_full_name}' vs API '{api_name}'") if user_data.address != api_house_name: mismatch_fields.append("address") logger.debug( f"Address mismatch: User '{user_data.address}' vs API '{api_house_name}'" ) # API DOB might include time component, so split it api_dob_date_only = api_dob.split("T")[0] if api_dob else None if user_dob_iso != api_dob_date_only: mismatch_fields.append("dob") logger.debug( f"DOB mismatch: User '{user_dob_iso}' vs API '{api_dob_date_only}'" ) # Use .strip() for atoll and island names due to potential whitespace user_atoll_name = user_data.atoll.name if user_data.atoll is not None else None api_atoll_stripped = api_atoll.strip() if api_atoll else None if user_atoll_name != api_atoll_stripped: mismatch_fields.append("atoll") logger.debug( f"Atoll mismatch: User '{user_atoll_name}' vs API '{api_atoll_stripped}'" ) user_island_name = user_data.island.name if user_data.island is not None else None api_island_name_stripped = api_island_name.strip() if api_island_name else None if user_island_name != api_island_name_stripped: mismatch_fields.append("island_name") logger.debug( f"Island Name mismatch: User '{user_island_name}' vs API '{api_island_name_stripped}'" ) if mismatch_fields: return {"ok": False, "mismatch_fields": mismatch_fields} else: return {"ok": True, "mismatch_fields": []}