"""Session service for active session management.""" import json from datetime import datetime from pathlib import Path from typing import Optional from ..models import Session _ACTIVE_SESSION_FILE = ".active_session.json" def get_active_session_path() -> Path: """Return the path to the active session file in projects/ directory.""" return Path("projects") / _ACTIVE_SESSION_FILE def get_active_session() -> Optional[Session]: """Load and return the currently active session, or None if none exists.""" path = get_active_session_path() if not path.exists(): return None with open(path, "r", encoding="utf-8") as f: data = json.load(f) # Convert started_at string back to datetime data["started_at"] = datetime.fromisoformat(data["started_at"]) if data.get("ended_at"): data["ended_at"] = datetime.fromisoformat(data["ended_at"]) return Session(**data) def set_active_session(session: Session) -> None: """Save the given session as the active session.""" path = get_active_session_path() path.parent.mkdir(parents=True, exist_ok=True) data = session.model_dump(mode="json") # Serialize datetime objects to ISO format data["started_at"] = session.started_at.isoformat() if session.ended_at: data["ended_at"] = session.ended_at.isoformat() with open(path, "w", encoding="utf-8") as f: json.dump(data, f, indent=2, ensure_ascii=False) def clear_active_session() -> None: """Remove the active session file.""" path = get_active_session_path() if path.exists(): path.unlink() def validate_no_other_active_session(project_slug: str) -> bool: """ Check if there is an active session for a different project. Returns True if no conflict exists (i.e., either no active session or the active session belongs to the same project). """ active = get_active_session() if active is None: return True return active.project_slug == project_slug