"""Post repository interface. This module extends the base repository interface with post-specific query methods including slug lookup, author filtering, search, and like management. """ from abc import abstractmethod from uuid import UUID from app.domain.entities.like import PostLike from app.domain.entities.post import Post from app.domain.repositories.base import Repository class PostRepository(Repository[Post]): """Repository interface for Blog Posts. Extends the generic repository with post-specific operations including slug-based lookup, author filtering, tag filtering, and full-text search capabilities. Example: >>> posts = await repo.get_by_author("user-123", limit=10) >>> exists = await repo.slug_exists("my-first-post") """ @abstractmethod async def get_by_slug(self, slug: str) -> Post | None: """Get post by slug. Args: slug: URL-friendly slug identifier. Returns: Post instance if found, None otherwise. """ ... @abstractmethod async def get_by_author( self, author_id: str, limit: int | None = None, offset: int | None = None, ) -> list[Post]: """Get all 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 posts by the specified author. """ ... @abstractmethod async def get_published( self, limit: int | None = None, offset: int | None = None, ) -> list[Post]: """Get all published posts. Args: limit: Maximum number of posts to return. offset: Number of posts to skip. Returns: List of published posts. """ ... @abstractmethod async def get_by_tag( self, tag: str, limit: int | None = None, offset: int | None = None, ) -> list[Post]: """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 posts with the specified tag. """ ... @abstractmethod async def slug_exists(self, slug: str) -> bool: """Check if slug already exists. Args: slug: Slug to check for existence. Returns: True if slug exists, False otherwise. """ ... @abstractmethod async def get_like(self, post_id: UUID, liked_by: str) -> PostLike | None: """Get a like by post and user/device. Args: post_id: UUID of the post. liked_by: User ID or device ID. Returns: PostLike if found, None otherwise. """ ... @abstractmethod async def add_like(self, like: PostLike) -> None: """Add a new like. Args: like: PostLike entity to add. """ ... @abstractmethod async def remove_like(self, post_id: UUID, liked_by: str) -> None: """Remove a like by post and user/device. Args: post_id: UUID of the post. liked_by: User ID or device ID. """ ... @abstractmethod async def search( self, query: str, limit: int | None = None, offset: int | None = None, ) -> list[Post]: """Search posts by query string. Args: query: Search query string. limit: Maximum number of posts to return. offset: Number of posts to skip. Returns: List of posts matching the search query. """ ...