Files
blog.pyaqa.ru/app/application/use_cases/create_post.py
Sergey Vanyushkin ca4e8877a5 docs: add AI code generation requirements and comprehensive Google-style docstrings
- Add AI code generation requirements to AGENTS.md
- Add module-level docstrings to all 46 Python modules
- Add detailed Google-style docstrings to all classes and functions
- Remove all inline comments following self-documenting code principle
- Include Args, Returns, Raises sections in function docstrings
- Add Attributes and Examples sections to class docstrings
2026-05-02 13:15:21 +03:00

98 lines
2.9 KiB
Python

"""Create post use case.
This module implements the use case for creating new blog posts.
Handles slug generation, duplicate checking, and entity persistence.
"""
from app.application.dtos.post import CreatePostDTO, PostResponseDTO
from app.application.interfaces import TransactionManager
from app.domain.entities import Post
from app.domain.exceptions import AlreadyExistsException
from app.domain.repositories import PostRepository
class CreatePostUseCase:
"""Use case for creating a new blog post.
Encapsulates the business logic for creating posts including
slug generation from title and duplicate slug detection.
Attributes:
_post_repo: Repository for post data access.
_tx_manager: Transaction manager for commit control.
Example:
>>> use_case = CreatePostUseCase(post_repo, tx_manager)
>>> result = await use_case.execute(dto)
"""
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 execute(self, dto: CreatePostDTO) -> PostResponseDTO:
"""Execute the use case to create a new post.
Args:
dto: Data transfer object containing post creation data
including title, content, author ID, and optional tags.
Returns:
PostResponseDTO with created post data including generated ID and slug.
Raises:
AlreadyExistsException: If a post with the same slug exists.
Note:
Slug is automatically generated from the title.
"""
from app.domain.value_objects import Slug
slug = Slug.from_title(dto.title)
if await self._post_repo.slug_exists(slug.value):
raise AlreadyExistsException(f"Post with slug '{slug.value}' already exists")
post = Post.create(
title_str=dto.title,
content_str=dto.content,
author_id=dto.author_id,
tags=dto.tags or [],
)
await self._post_repo.add(post)
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.
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,
)