""" Session helper utilities for managing user profile sessions. Feature: Fix profile session restoration when Flask session cache expires """ import logging from typing import Optional from .backend_client import BackendAPIClient logger = logging.getLogger(__name__) def ensure_profile_session(user_id: str) -> str: """ Ensure user has a profile session, restoring or creating via API if needed. This handles cases where Flask session cache expires but the user's profile session still exists in the backend API. Args: user_id: User's ID from OAuth Returns: Profile session ID (backend session_id for contact_id="user-profile") Raises: Exception: If unable to restore or create profile session """ backend_api = BackendAPIClient() # Try to find existing user-profile session in backend try: sessions = backend_api.list_sessions(user_id=user_id) # Look for existing profile session (contact_id="user-profile") for session_data in sessions: contact_id = session_data.get("contact_id") if contact_id == "user-profile": session_id = session_data.get("session_id") logger.info( f"[SESSION_RESTORE] Found existing profile session for user {user_id}: " f"session_id={session_id}" ) return session_id except Exception as e: logger.warning( f"[SESSION_RESTORE] Failed to list sessions for user {user_id}: {e}. " f"Will attempt to create new profile session." ) # No existing profile session found - create new one try: logger.info(f"[SESSION_CREATE] Creating new profile session for user {user_id}") response = backend_api.create_session( user_id=user_id, contact_id="user-profile", description=f"{user_id}'s Profile", is_reference=False ) session_id = response.get("session_id") if not session_id: raise ValueError("Backend did not return session_id") logger.info( f"[SESSION_CREATE] Created new profile session for user {user_id}: " f"session_id={session_id}" ) return session_id except Exception as e: logger.error( f"[SESSION_CREATE] Failed to create profile session for user {user_id}: {e}", exc_info=True ) raise Exception(f"Failed to initialize profile session: {str(e)}") def get_or_restore_profile_session(user_id: str, cached_session_id: Optional[str]) -> str: """ Get profile session ID from cache or restore from backend. This is a convenience wrapper that checks the cache first before hitting the backend API. Args: user_id: User's ID from OAuth cached_session_id: Profile session ID from Flask session (may be None) Returns: Profile session ID Raises: Exception: If unable to restore or create profile session """ if cached_session_id: return cached_session_id logger.warning( f"[SESSION_CACHE_MISS] Profile session not in Flask session for user {user_id}, " f"restoring from backend" ) return ensure_profile_session(user_id)