"""List posts use case. This module implements the use case for listing blog posts. Provides multiple query methods including filtering by author, tag, and search. """ from app.application.dtos.post import PostResponseDTO from app.application.interfaces import TransactionManager from app.domain.entities import Post from app.domain.repositories import PostRepository class ListPostsUseCase: """Use case for listing blog posts with filtering. Provides various methods to query posts with different criteria including pagination support for large result sets. Attributes: _post_repo: Repository for post data access. _tx_manager: Transaction manager for transaction control. Example: >>> use_case = ListPostsUseCase(post_repo, tx_manager) >>> posts = await use_case.published_posts(limit=10, offset=0) """ def __init__( self, post_repo: PostRepository, tx_manager: TransactionManager, ) -> None: """Initialize use case with dependencies. Args: post_repo: Repository for post operations. tx_manager: Transaction manager instance. """ self._post_repo = post_repo self._tx_manager = tx_manager async def all_posts(self) -> list[PostResponseDTO]: """Get all posts. Returns: List of PostResponseDTO for all posts. """ posts = await self._post_repo.get_all() return [self._map_to_dto(post) for post in posts] async def published_posts( self, limit: int | None = None, offset: int | None = None, ) -> list[PostResponseDTO]: """Get all published posts. Args: limit: Maximum number of posts to return. offset: Number of posts to skip. Returns: List of PostResponseDTO for published posts. """ posts = await self._post_repo.get_published(limit=limit, offset=offset) return [self._map_to_dto(post) for post in posts] async def by_author( self, author_id: str, limit: int | None = None, offset: int | None = None, ) -> list[PostResponseDTO]: """Get posts by author. Args: author_id: Identifier of the author. limit: Maximum number of posts to return. offset: Number of posts to skip. Returns: List of PostResponseDTO for posts by the author. """ posts = await self._post_repo.get_by_author(author_id, limit=limit, offset=offset) return [self._map_to_dto(post) for post in posts] async def by_tag( self, tag: str, limit: int | None = None, offset: int | None = None, ) -> list[PostResponseDTO]: """Get posts by tag. Args: tag: Tag to filter by. limit: Maximum number of posts to return. offset: Number of posts to skip. Returns: List of PostResponseDTO for posts with the tag. """ posts = await self._post_repo.get_by_tag(tag, limit=limit, offset=offset) return [self._map_to_dto(post) for post in posts] async def search( self, query: str, limit: int | None = None, offset: int | None = None, ) -> list[PostResponseDTO]: """Search posts. Args: query: Search query string. limit: Maximum number of posts to return. offset: Number of posts to skip. Returns: List of PostResponseDTO for matching posts. """ posts = await self._post_repo.search(query, limit=limit, offset=offset) return [self._map_to_dto(post) for post in posts] def _map_to_dto(self, post: Post) -> PostResponseDTO: """Map domain entity to response DTO. Args: post: Domain post entity. Returns: PostResponseDTO with all post attributes. """ return PostResponseDTO( id=post.id, title=post.title.value, content=post.content.value, slug=post.slug.value, author_id=post.author_id, published=post.published, tags=post.tags.copy(), created_at=post.created_at, updated_at=post.updated_at, )