"""Session repository. Provides storage, retrieval, and deletion of session records in the ``sessions`` table of the application SQLite database. """ from __future__ import annotations from typing import TYPE_CHECKING if TYPE_CHECKING: import aiosqlite from app.models.auth import Session async def create_session( db: aiosqlite.Connection, token: str, created_at: str, expires_at: str, ) -> Session: """Insert a new session row and return the domain model. Args: db: Active aiosqlite connection. token: Opaque random session token (hex string). created_at: ISO 8601 UTC creation timestamp. expires_at: ISO 8601 UTC expiry timestamp. Returns: The newly created :class:`~app.models.auth.Session`. """ cursor = await db.execute( "INSERT INTO sessions (token, created_at, expires_at) VALUES (?, ?, ?)", (token, created_at, expires_at), ) await db.commit() return Session( id=int(cursor.lastrowid) if cursor.lastrowid else 0, token=token, created_at=created_at, expires_at=expires_at, ) async def get_session(db: aiosqlite.Connection, token: str) -> Session | None: """Look up a session by its token. Args: db: Active aiosqlite connection. token: The session token to retrieve. Returns: The :class:`~app.models.auth.Session` if found, else ``None``. """ async with db.execute( "SELECT id, token, created_at, expires_at FROM sessions WHERE token = ?", (token,), ) as cursor: row = await cursor.fetchone() if row is None: return None return Session( id=int(row[0]), token=str(row[1]), created_at=str(row[2]), expires_at=str(row[3]), ) async def delete_session(db: aiosqlite.Connection, token: str) -> None: """Delete a session by token (logout / expiry clean-up). Args: db: Active aiosqlite connection. token: The session token to remove. """ await db.execute("DELETE FROM sessions WHERE token = ?", (token,)) await db.commit() async def delete_expired_sessions(db: aiosqlite.Connection, now_iso: str) -> int: """Remove all sessions whose ``expires_at`` timestamp is in the past. Args: db: Active aiosqlite connection. now_iso: Current UTC time as ISO 8601 string used as the cutoff. Returns: Number of rows deleted. """ cursor = await db.execute( "DELETE FROM sessions WHERE expires_at <= ?", (now_iso,), ) await db.commit() return int(cursor.rowcount)