from datetime import datetime from sqlalchemy import select, func from sqlalchemy.ext.asyncio import AsyncSession from backend.models.author import Author from backend.models.post import Post from backend.models.comment import Comment async def list_authors( db: AsyncSession, subreddit_id: int | None = None, sort_by: str = "total_comments", sort_order: str = "desc", since: datetime | None = None, until: datetime | None = None, page: int = 1, per_page: int = 25, ) -> tuple[list[dict], int]: base = select(Author) if subreddit_id or since or until: # Need to compute activity counts with filters post_count = ( select(func.count(Post.id)) .where(Post.author_id == Author.id) ) comment_count = ( select(func.count(Comment.id)) .where(Comment.author_id == Author.id) ) if subreddit_id: post_count = post_count.where(Post.subreddit_id == subreddit_id) comment_count = comment_count.join(Post).where(Post.subreddit_id == subreddit_id) if since: post_count = post_count.where(Post.created_utc >= since) comment_count = comment_count.where(Comment.created_utc >= since) if until: post_count = post_count.where(Post.created_utc <= until) comment_count = comment_count.where(Comment.created_utc <= until) base = select( Author, post_count.correlate(Author).scalar_subquery().label("filtered_posts"), comment_count.correlate(Author).scalar_subquery().label("filtered_comments"), ) else: base = select(Author) count_stmt = select(func.count()).select_from(base.subquery()) total = (await db.execute(count_stmt)).scalar() or 0 sort_col = getattr(Author, sort_by, Author.total_comments) if sort_order == "asc": base = base.order_by(sort_col.asc()) else: base = base.order_by(sort_col.desc()) base = base.offset((page - 1) * per_page).limit(per_page) result = await db.execute(base) authors = [] for row in result.all(): author = row[0] data = {c.name: getattr(author, c.name) for c in author.__table__.columns} authors.append(data) return authors, total async def get_author(db: AsyncSession, author_id: int) -> dict | None: author = await db.get(Author, author_id) if not author: return None return {c.name: getattr(author, c.name) for c in author.__table__.columns}