Added some comments

This commit is contained in:
James Ketr 2025-06-18 12:24:04 -07:00
parent ed2b99e8b9
commit cbd6ead5f3
3 changed files with 103 additions and 2103 deletions

View File

@ -10,6 +10,8 @@ from .mixins.job import JobMixin
from .mixins.skill import SkillMixin
from .mixins.ai import AIMixin
# RedisDatabase is the main class that combines all mixins for a
# comprehensive Redis database interface.
class RedisDatabase(
AIMixin,
BaseMixin,

File diff suppressed because it is too large Load Diff

View File

@ -11,8 +11,11 @@ from ..constants import KEY_PREFIXES
logger = logging.getLogger(__name__)
class UserMixin(DatabaseProtocol):
"""Mixin for user and candidate operations"""
"""Mixin for user operations"""
# ================
# Guests
# ================
async def set_guest(self, guest_id: str, guest_data: Dict[str, Any]) -> None:
"""Store guest data with enhanced persistence"""
try:
@ -211,6 +214,56 @@ class UserMixin(DatabaseProtocol):
logger.error(f"❌ Error getting guest statistics: {e}")
return {}
# ================
# Users
# ================
async def get_user_by_username(self, username: str) -> Optional[Dict]:
"""Get user by username specifically"""
username_key = f"{KEY_PREFIXES['users']}{username.lower()}"
data = await self.redis.get(username_key)
return self._deserialize(data) if data else None
async def get_user_rag_update_time(self, user_id: str) -> Optional[datetime]:
"""Get the last time user's RAG data was updated (returns timezone-aware UTC)"""
try:
rag_update_key = f"user:{user_id}:rag_last_update"
timestamp_str = await self.redis.get(rag_update_key)
if timestamp_str:
dt = datetime.fromisoformat(timestamp_str)
# Ensure the datetime is timezone-aware (assume UTC if naive)
if dt.tzinfo is None:
dt = dt.replace(tzinfo=timezone.utc)
else:
# Convert to UTC if it's in a different timezone
dt = dt.astimezone(timezone.utc)
return dt
logger.warning(f"⚠️ No RAG update time found for user {user_id}")
return None
except Exception as e:
logger.error(f"❌ Error getting user RAG update time: {e}")
return None
async def update_user_rag_timestamp(self, user_id: str) -> bool:
"""Set the user's RAG data update time (stores as UTC ISO format)"""
try:
update_time = datetime.now(timezone.utc)
# Ensure we're storing UTC timezone-aware format
if update_time.tzinfo is None:
update_time = update_time.replace(tzinfo=timezone.utc)
else:
update_time = update_time.astimezone(timezone.utc)
rag_update_key = f"user:{user_id}:rag_last_update"
# Store as ISO format with timezone info
timestamp_str = update_time.isoformat() # This includes timezone
await self.redis.set(rag_update_key, timestamp_str)
logger.info(f"✅ User RAG update time set for user {user_id}: {timestamp_str}")
return True
except Exception as e:
logger.error(f"❌ Error setting user RAG update time: {e}")
return False
async def set_user_by_id(self, user_id: str, user_data: Dict[str, Any]) -> bool:
"""Store user data with ID as key for direct lookup"""
try:
@ -281,7 +334,40 @@ class UserMixin(DatabaseProtocol):
"""Delete user"""
key = f"{KEY_PREFIXES['users']}{email}"
await self.redis.delete(key)
async def get_user(self, login: str) -> Optional[Dict[str, Any]]:
"""Get user by email or username"""
try:
login = login.strip().lower()
key = f"users:{login}"
data = await self.redis.get(key)
if data:
user_data = json.loads(data)
logger.info(f"👤 Retrieved user data for {login}")
return user_data
return None
except Exception as e:
logger.error(f"❌ Error retrieving user {login}: {e}")
return None
async def set_user(self, login: str, user_data: Dict[str, Any]) -> bool:
"""Store user data by email or username"""
try:
login = login.strip().lower()
key = f"users:{login}"
await self.redis.set(key, json.dumps(user_data, default=str))
logger.info(f"👤 Stored user data for {login}")
return True
except Exception as e:
logger.error(f"❌ Error storing user {login}: {e}")
return False
# ================
# Employers
# ================
async def get_employer(self, employer_id: str) -> Optional[Dict]:
"""Get employer by ID"""
key = f"{KEY_PREFIXES['employers']}{employer_id}"
@ -319,36 +405,9 @@ class UserMixin(DatabaseProtocol):
await self.redis.delete(key)
async def get_user(self, login: str) -> Optional[Dict[str, Any]]:
"""Get user by email or username"""
try:
login = login.strip().lower()
key = f"users:{login}"
data = await self.redis.get(key)
if data:
user_data = json.loads(data)
logger.info(f"👤 Retrieved user data for {login}")
return user_data
return None
except Exception as e:
logger.error(f"❌ Error retrieving user {login}: {e}")
return None
async def set_user(self, login: str, user_data: Dict[str, Any]) -> bool:
"""Store user data by email or username"""
try:
login = login.strip().lower()
key = f"users:{login}"
await self.redis.set(key, json.dumps(user_data, default=str))
logger.info(f"👤 Stored user data for {login}")
return True
except Exception as e:
logger.error(f"❌ Error storing user {login}: {e}")
return False
# Candidates operations
# ================
# Candidates
# ================
async def get_candidate(self, candidate_id: str) -> Optional[Dict]:
"""Get candidate by ID"""
key = f"{KEY_PREFIXES['candidates']}{candidate_id}"
@ -723,13 +782,6 @@ class UserMixin(DatabaseProtocol):
logger.error(f"❌ Critical error during batch candidate deletion: {e}")
raise
# User Operations
async def get_user_by_username(self, username: str) -> Optional[Dict]:
"""Get user by username specifically"""
username_key = f"{KEY_PREFIXES['users']}{username.lower()}"
data = await self.redis.get(username_key)
return self._deserialize(data) if data else None
async def find_candidate_by_username(self, username: str) -> Optional[Dict]:
"""Find candidate by username"""
all_candidates = await self.get_all_candidates()
@ -741,7 +793,6 @@ class UserMixin(DatabaseProtocol):
return None
# Batch Operations
async def get_multiple_candidates_by_usernames(self, usernames: List[str]) -> Dict[str, Dict]:
"""Get multiple candidates by their usernames efficiently"""
all_candidates = await self.get_all_candidates()
@ -787,6 +838,9 @@ class UserMixin(DatabaseProtocol):
"recent_sessions": sessions[:5] # Last 5 sessions
}
# ================
# Viewers
# ================
async def get_viewer(self, viewer_id: str) -> Optional[Dict]:
"""Get viewer by ID"""
key = f"{KEY_PREFIXES['viewers']}{viewer_id}"
@ -824,44 +878,3 @@ class UserMixin(DatabaseProtocol):
key = f"{KEY_PREFIXES['viewers']}{viewer_id}"
await self.redis.delete(key)
async def get_user_rag_update_time(self, user_id: str) -> Optional[datetime]:
"""Get the last time user's RAG data was updated (returns timezone-aware UTC)"""
try:
rag_update_key = f"user:{user_id}:rag_last_update"
timestamp_str = await self.redis.get(rag_update_key)
if timestamp_str:
dt = datetime.fromisoformat(timestamp_str)
# Ensure the datetime is timezone-aware (assume UTC if naive)
if dt.tzinfo is None:
dt = dt.replace(tzinfo=timezone.utc)
else:
# Convert to UTC if it's in a different timezone
dt = dt.astimezone(timezone.utc)
return dt
logger.warning(f"⚠️ No RAG update time found for user {user_id}")
return None
except Exception as e:
logger.error(f"❌ Error getting user RAG update time: {e}")
return None
async def update_user_rag_timestamp(self, user_id: str) -> bool:
"""Set the user's RAG data update time (stores as UTC ISO format)"""
try:
update_time = datetime.now(timezone.utc)
# Ensure we're storing UTC timezone-aware format
if update_time.tzinfo is None:
update_time = update_time.replace(tzinfo=timezone.utc)
else:
update_time = update_time.astimezone(timezone.utc)
rag_update_key = f"user:{user_id}:rag_last_update"
# Store as ISO format with timezone info
timestamp_str = update_time.isoformat() # This includes timezone
await self.redis.set(rag_update_key, timestamp_str)
logger.info(f"✅ User RAG update time set for user {user_id}: {timestamp_str}")
return True
except Exception as e:
logger.error(f"❌ Error setting user RAG update time: {e}")
return False