from sqlalchemy.orm import Session from sqlalchemy import func from typing import List, Optional from datetime import datetime from app.database.models import Session as ChatSession, Message from app.utils.helpers import generate_id class SessionService: """Service for session management operations.""" @staticmethod def create_session( db: Session, user_id: Optional[str] = None, title: str = "New Conversation" ) -> ChatSession: """ Create a new chat session. Args: db: Database session user_id: Optional user ID (None for guest users) title: Session title Returns: Created ChatSession object """ session = ChatSession( id=generate_id(), user_id=user_id, title=title ) db.add(session) db.commit() db.refresh(session) return session @staticmethod def get_user_sessions(db: Session, user_id: str) -> List[dict]: """ Get all sessions for a user with message counts. Args: db: Database session user_id: User ID Returns: List of session dictionaries with message counts """ # Query sessions with message counts sessions = db.query( ChatSession, func.count(Message.id).label('message_count') ).outerjoin( Message, ChatSession.id == Message.session_id ).filter( ChatSession.user_id == user_id ).group_by( ChatSession.id ).order_by( ChatSession.updated_at.desc() ).all() # Format response result = [] for session, message_count in sessions: result.append({ "id": session.id, "user_id": session.user_id, "title": session.title, "summary": session.summary, "created_at": session.created_at, "updated_at": session.updated_at, "message_count": message_count }) return result @staticmethod def get_session_by_id(db: Session, session_id: str) -> Optional[ChatSession]: """ Get session by ID. Args: db: Database session session_id: Session ID Returns: ChatSession object if found, None otherwise """ return db.query(ChatSession).filter(ChatSession.id == session_id).first() @staticmethod def update_session_title(db: Session, session_id: str, title: str) -> Optional[ChatSession]: """ Update session title. Args: db: Database session session_id: Session ID title: New title Returns: Updated ChatSession object if found, None otherwise """ session = db.query(ChatSession).filter(ChatSession.id == session_id).first() if not session: return None session.title = title session.updated_at = datetime.utcnow() db.commit() db.refresh(session) return session @staticmethod def delete_session(db: Session, session_id: str) -> bool: """ Delete a session and all its messages. Args: db: Database session session_id: Session ID Returns: True if deleted, False if not found """ session = db.query(ChatSession).filter(ChatSession.id == session_id).first() if not session: return False db.delete(session) db.commit() return True @staticmethod def update_session_timestamp(db: Session, session_id: str): """ Update session's updated_at timestamp. Args: db: Database session session_id: Session ID """ session = db.query(ChatSession).filter(ChatSession.id == session_id).first() if session: session.updated_at = datetime.utcnow() db.commit()