Files
blog.pyaqa.ru/app/application/use_cases/get_post.py
Sergey Vanyushkin 87b094220d refactor: migrate to DDD architecture with Dishka DI
Complete architectural refactoring from simple MVC to Clean Architecture/DDD pattern:

Domain Layer:

- Add entities (Post, BaseEntity) with business logic

- Add value objects (Title, Content, Slug) with validation

- Add repository interfaces (PostRepository)

- Add domain exceptions

Application Layer:

- Add use cases (CreatePost, GetPost, UpdatePost, DeletePost, ListPosts, PublishPost)

- Add DTOs for data transfer

- Add TransactionManager interface

Infrastructure Layer:

- Add SQLAlchemy models and async database connection

- Add SQLAlchemyPostRepository implementation

- Add Dishka DI container with providers

- Add error handlers and middleware

Presentation Layer:

- Add FastAPI routes with Dishka integration

- Add Pydantic schemas

- Add dependency injection using FromDishka[T]

Other Changes:

- Remove old flat structure (api/, common/, core/, modules/)

- Add hatchling build system for package scripts

- Add blog CLI command

- Update AGENTS.md with new architecture docs

- All 48 tests passing, mypy clean, ruff clean
2026-05-01 20:20:41 +03:00

50 lines
1.6 KiB
Python

"""Get post use case."""
from uuid import UUID
from app.application.dtos.post import PostResponseDTO
from app.application.interfaces import TransactionManager
from app.domain.entities import Post
from app.domain.exceptions import NotFoundException
from app.domain.repositories import PostRepository
class GetPostUseCase:
"""Use case for retrieving a post by ID or slug."""
def __init__(
self,
post_repo: PostRepository,
tx_manager: TransactionManager,
) -> None:
self._post_repo = post_repo
self._tx_manager = tx_manager
async def by_id(self, post_id: UUID) -> PostResponseDTO:
"""Get post by ID."""
post = await self._post_repo.get_by_id(post_id)
if not post:
raise NotFoundException(f"Post with id '{post_id}' not found")
return self._map_to_dto(post)
async def by_slug(self, slug: str) -> PostResponseDTO:
"""Get post by slug."""
post = await self._post_repo.get_by_slug(slug)
if not post:
raise NotFoundException(f"Post with slug '{slug}' not found")
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,
)