"""Update post use case.""" from uuid import UUID from app.application.dtos.post import PostResponseDTO, UpdatePostDTO from app.application.interfaces import TransactionManager from app.domain.entities import Post from app.domain.exceptions import ForbiddenException, NotFoundException from app.domain.repositories import PostRepository from app.domain.value_objects import Content, Title class UpdatePostUseCase: """Use case for updating a blog post.""" def __init__( self, post_repo: PostRepository, tx_manager: TransactionManager, ) -> None: self._post_repo = post_repo self._tx_manager = tx_manager async def execute( self, post_id: UUID, dto: UpdatePostDTO, current_user_id: str, ) -> PostResponseDTO: """Execute the use case.""" post = await self._post_repo.get_by_id(post_id) if not post: raise NotFoundException(f"Post with id '{post_id}' not found") # Check authorization if post.author_id != current_user_id: raise ForbiddenException("You can only update your own posts") # Update fields if dto.title is not None: post.update_title(Title(dto.title)) if dto.content is not None: post.update_content(Content(dto.content)) if dto.tags is not None: # Replace all tags for tag in post.tags[:]: post.remove_tag(tag) for tag in dto.tags: post.add_tag(tag) # Persist changes await self._post_repo.update(post) # Commit transaction await self._tx_manager.commit() return self._map_to_dto(post) def _map_to_dto(self, post: Post) -> PostResponseDTO: """Map domain entity to response DTO.""" 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, )