"""SQLAlchemy-backed recommended questions repository.""" from __future__ import annotations from datetime import UTC, datetime from typing import Any from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker from deerflow.persistence.recommended_questions.model import RecommendedQuestionRow def _row_to_dict(row: RecommendedQuestionRow) -> dict[str, Any]: data = row.to_dict() for key in ("created_at", "updated_at"): value = data.get(key) if isinstance(value, datetime): data[key] = value.isoformat() return data class RecommendedQuestionRepository: def __init__(self, session_factory: async_sessionmaker[AsyncSession]) -> None: self._sf = session_factory async def list_all(self) -> list[dict[str, Any]]: stmt = select(RecommendedQuestionRow).order_by(RecommendedQuestionRow.sort_order.asc(), RecommendedQuestionRow.created_at.asc()) async with self._sf() as session: result = await session.execute(stmt) return [_row_to_dict(row) for row in result.scalars()] async def get(self, question_id: str) -> dict[str, Any] | None: async with self._sf() as session: row = await session.get(RecommendedQuestionRow, question_id) return _row_to_dict(row) if row is not None else None async def create(self, data: dict[str, Any]) -> dict[str, Any]: now = datetime.now(UTC) row = RecommendedQuestionRow( id=data["id"], title=data["title"], content=data["content"], sort_order=data.get("sort_order", 0), created_at=now, updated_at=now, ) async with self._sf() as session: session.add(row) await session.commit() await session.refresh(row) return _row_to_dict(row) async def update(self, question_id: str, data: dict[str, Any]) -> dict[str, Any] | None: async with self._sf() as session: row = await session.get(RecommendedQuestionRow, question_id) if row is None: return None for key in ("title", "content", "sort_order"): if key in data: setattr(row, key, data[key]) row.updated_at = datetime.now(UTC) await session.commit() await session.refresh(row) return _row_to_dict(row) async def delete(self, question_id: str) -> bool: async with self._sf() as session: row = await session.get(RecommendedQuestionRow, question_id) if row is None: return False await session.delete(row) await session.commit() return True async def reorder(self, ordered_ids: list[str]) -> list[dict[str, Any]]: async with self._sf() as session: now = datetime.now(UTC) for index, question_id in enumerate(ordered_ids): row = await session.get(RecommendedQuestionRow, question_id) if row is not None: row.sort_order = index row.updated_at = now await session.commit() return await self.list_all()