"""Task work log service.""" import logging from datetime import datetime, timezone from sqlalchemy import select from fabledassistant.models import async_session from fabledassistant.models.task_log import TaskLog from fabledassistant.models.note import Note logger = logging.getLogger(__name__) _UNSET = object() async def create_log( user_id: int, task_id: int, content: str, duration_minutes: int | None = None, ) -> TaskLog: async with async_session() as session: # Verify task exists and belongs to user result = await session.execute( select(Note).where(Note.id == task_id, Note.user_id == user_id) ) if result.scalars().first() is None: raise ValueError(f"Task {task_id} not found") log = TaskLog( task_id=task_id, user_id=user_id, content=content, duration_minutes=duration_minutes, ) session.add(log) await session.commit() await session.refresh(log) return log async def list_logs(user_id: int, task_id: int) -> list[TaskLog]: async with async_session() as session: result = await session.execute( select(TaskLog) .where(TaskLog.task_id == task_id, TaskLog.user_id == user_id) .order_by(TaskLog.created_at.asc()) ) return list(result.scalars().all()) async def update_log( user_id: int, log_id: int, content: str | None = None, duration_minutes: object = _UNSET, ) -> TaskLog | None: async with async_session() as session: result = await session.execute( select(TaskLog).where(TaskLog.id == log_id, TaskLog.user_id == user_id) ) log = result.scalars().first() if log is None: return None if content is not None: log.content = content if duration_minutes is not _UNSET: log.duration_minutes = duration_minutes # type: ignore[assignment] log.updated_at = datetime.now(timezone.utc) await session.commit() await session.refresh(log) return log async def delete_log(user_id: int, log_id: int) -> bool: async with async_session() as session: result = await session.execute( select(TaskLog).where(TaskLog.id == log_id, TaskLog.user_id == user_id) ) log = result.scalars().first() if log is None: return False await session.delete(log) await session.commit() return True