from sqlalchemy import func, select from sqlalchemy.ext.asyncio import AsyncSession from app.models.user import User DEFAULT_PAGE_SIZE = 20 MAX_PAGE_SIZE = 200 class AgentUserError(Exception): def __init__(self, message: str) -> None: self.message = message super().__init__(message) def _list_users_filters( *, agent_id: int, username: str | None = None, role_id: int | None = None, ) -> list: conditions = [User.agent_id == agent_id] if username and username.strip(): conditions.append(User.username.ilike(f"%{username.strip()}%")) if role_id is not None: conditions.append(User.role_id == role_id) return conditions async def list_users( db: AsyncSession, *, agent_id: int, page: int = 1, page_size: int = DEFAULT_PAGE_SIZE, username: str | None = None, role_id: int | None = None, ) -> tuple[list[User], int]: page_size = min(max(page_size, 1), MAX_PAGE_SIZE) page = max(page, 1) offset = (page - 1) * page_size conditions = _list_users_filters( agent_id=agent_id, username=username, role_id=role_id, ) count_stmt = select(func.count()).select_from(User) list_stmt = select(User).order_by(User.id.desc()) if conditions: count_stmt = count_stmt.where(*conditions) list_stmt = list_stmt.where(*conditions) total = await db.scalar(count_stmt) or 0 result = await db.scalars(list_stmt.offset(offset).limit(page_size)) return list(result.all()), total