Compare commits
2 Commits
fad06c45f8
...
36627d409c
Author | SHA1 | Date |
---|---|---|
Сергей Ванюшкин | 36627d409c | |
Сергей Ванюшкин | 2104f39e3b |
|
@ -1,7 +1,15 @@
|
|||
from dataclasses import dataclass
|
||||
from uuid import UUID
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class AddMenuDTO:
|
||||
title: str
|
||||
description: str | None
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class UpdateMenuDTO:
|
||||
id: UUID
|
||||
title: str | None
|
||||
description: str | None
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
from fastfood_two.application.abstractions.interactor import Interactor
|
||||
from fastfood_two.application.contracts.requests import UpdateMenuDTO
|
||||
from fastfood_two.application.contracts.responses import MenuDTO
|
||||
from fastfood_two.domain.menu.gateway import MenuGateway
|
||||
from fastfood_two.domain.menu.menu_entity import Description, MenuId, Title
|
||||
|
||||
|
||||
class UpdateMenu(Interactor[UpdateMenuDTO, MenuDTO]):
|
||||
def __init__(self, gateway: MenuGateway) -> None:
|
||||
self._menu_gateway = gateway
|
||||
|
||||
async def __call__(self, request: UpdateMenuDTO) -> MenuDTO:
|
||||
|
||||
menu = await self._menu_gateway.update_menu(
|
||||
id=MenuId(request.id),
|
||||
title=Title(request.title) if request.title else None,
|
||||
description=Description(request.description) if request.description else None,
|
||||
)
|
||||
|
||||
return MenuDTO(
|
||||
id=menu.id.value,
|
||||
title=menu.title.value,
|
||||
description=menu.description.value,
|
||||
)
|
|
@ -1,7 +1,7 @@
|
|||
from typing import Protocol
|
||||
from uuid import UUID
|
||||
|
||||
from fastfood_two.domain.menu.menu_entity import Menu
|
||||
from fastfood_two.domain.menu.menu_entity import Description, Menu, MenuId, Title
|
||||
|
||||
|
||||
class MenuGateway(Protocol):
|
||||
|
@ -14,7 +14,12 @@ class MenuGateway(Protocol):
|
|||
async def get_all_menus(self) -> list[Menu]:
|
||||
raise NotImplementedError
|
||||
|
||||
async def update_menu(self, updated_menu: Menu) -> Menu | None:
|
||||
async def update_menu(
|
||||
self,
|
||||
id: MenuId,
|
||||
title: Title | None,
|
||||
description: Description | None,
|
||||
) -> Menu:
|
||||
raise NotImplementedError
|
||||
|
||||
async def delete_menu(self, id: UUID) -> None:
|
||||
|
|
|
@ -3,7 +3,7 @@ from uuid import UUID
|
|||
from sqlalchemy import text
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from fastfood_two.domain.menu.menu_entity import Menu
|
||||
from fastfood_two.domain.menu.menu_entity import Description, Menu, MenuId, Title
|
||||
from fastfood_two.infrastructure.pg_storage.mappers.menu_mapper import (
|
||||
db_entity_to_domain,
|
||||
)
|
||||
|
@ -16,12 +16,40 @@ class MenuGatewayImpl:
|
|||
async def get_all_menus(self) -> list[Menu]:
|
||||
query = text("SELECT * FROM menu;")
|
||||
menus = await self._session.execute(query)
|
||||
return [db_entity_to_domain(menu) for menu in menus.scalars().all()]
|
||||
return [db_entity_to_domain(menu.tuple()) for menu in menus]
|
||||
|
||||
async def get_menu_by_id(self, id: UUID) -> Menu | None: ...
|
||||
|
||||
async def insert_menu(self, menu: Menu) -> Menu: ...
|
||||
async def insert_menu(self, menu: Menu) -> Menu:
|
||||
query = text("INSERT INTO menu (id, title, description) VALUES (:id, :title, :description);")
|
||||
await self._session.execute(
|
||||
query,
|
||||
{
|
||||
"id": menu.id.value,
|
||||
"title": menu.title.value,
|
||||
"description": menu.description.value,
|
||||
},
|
||||
)
|
||||
await self._session.commit()
|
||||
return menu
|
||||
|
||||
async def update_menu(self, updated_menu: Menu) -> Menu | None: ...
|
||||
async def update_menu(self, id: MenuId, title: Title | None, description: Description | None) -> Menu:
|
||||
query = text(
|
||||
"UPDATE menu SET {}{} {} WHERE id = :id RETURNING *;".format(
|
||||
"title = :title " if title is not None else "",
|
||||
"," if all([title is not None, description is not None]) else "",
|
||||
"description = :description" if description is not None else "",
|
||||
)
|
||||
)
|
||||
menu = await self._session.execute(
|
||||
query,
|
||||
{
|
||||
"id": id.value,
|
||||
"title": title.value if title else None,
|
||||
"description": description.value if description else None,
|
||||
},
|
||||
)
|
||||
await self._session.commit()
|
||||
return db_entity_to_domain(menu.one().tuple())
|
||||
|
||||
async def delete_menu(self, id: UUID) -> None: ...
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
from typing import TYPE_CHECKING
|
||||
from uuid import UUID
|
||||
|
||||
from fastfood_two.domain.menu.menu_entity import Menu
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from fastfood_two.infrastructure.pg_storage.models import SQLAMenu
|
||||
from fastfood_two.domain.menu.menu_entity import Description, Menu, MenuId, Title
|
||||
|
||||
|
||||
def db_entity_to_domain(menu: "SQLAMenu") -> Menu:
|
||||
def db_entity_to_domain(menu: tuple[UUID, str, str | None]) -> Menu:
|
||||
print(menu)
|
||||
return Menu(
|
||||
id=menu.id,
|
||||
title=menu.title,
|
||||
description=menu.description,
|
||||
id=MenuId(menu[0]),
|
||||
title=Title(menu[1]),
|
||||
description=Description(menu[2]),
|
||||
)
|
||||
|
|
|
@ -5,7 +5,9 @@ from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession, async_sessionmaker
|
|||
|
||||
from fastfood_two.application.common.logger import configure_logger
|
||||
from fastfood_two.application.config import Config
|
||||
from fastfood_two.application.usecases.menu.add_menu import AddMenu
|
||||
from fastfood_two.application.usecases.menu.get_all_menus import GetAllMenus
|
||||
from fastfood_two.application.usecases.menu.update_menu import UpdateMenu
|
||||
from fastfood_two.domain.menu.gateway import MenuGateway
|
||||
from fastfood_two.presentation.fastapi_backend.depends.config import get_settings
|
||||
from fastfood_two.presentation.fastapi_backend.depends.gateways import get_menu_gateway
|
||||
|
@ -15,7 +17,9 @@ from fastfood_two.presentation.fastapi_backend.depends.session import (
|
|||
get_session,
|
||||
)
|
||||
from fastfood_two.presentation.fastapi_backend.depends.usecases import (
|
||||
add_menu_usecase,
|
||||
get_all_menus_usecase,
|
||||
update_menu_usecase,
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
@ -38,5 +42,7 @@ def init_dependencies(app: FastAPI) -> None:
|
|||
app.dependency_overrides[MenuGateway] = get_menu_gateway
|
||||
|
||||
app.dependency_overrides[GetAllMenus] = get_all_menus_usecase
|
||||
app.dependency_overrides[AddMenu] = add_menu_usecase
|
||||
app.dependency_overrides[UpdateMenu] = update_menu_usecase
|
||||
|
||||
logger.info("Dependencies initialized")
|
||||
|
|
|
@ -4,6 +4,7 @@ from fastapi import Depends
|
|||
|
||||
from fastfood_two.application.usecases.menu.add_menu import AddMenu
|
||||
from fastfood_two.application.usecases.menu.get_all_menus import GetAllMenus
|
||||
from fastfood_two.application.usecases.menu.update_menu import UpdateMenu
|
||||
from fastfood_two.domain.menu.gateway import MenuGateway
|
||||
from fastfood_two.presentation.fastapi_backend.depends.stub import Stub
|
||||
|
||||
|
@ -14,3 +15,7 @@ def get_all_menus_usecase(gateway: Annotated[MenuGateway, Depends(Stub(MenuGatew
|
|||
|
||||
def add_menu_usecase(gateway: Annotated[MenuGateway, Depends(Stub(MenuGateway))]) -> AddMenu:
|
||||
return AddMenu(gateway=gateway)
|
||||
|
||||
|
||||
def update_menu_usecase(gateway: Annotated[MenuGateway, Depends(Stub(MenuGateway))]) -> UpdateMenu:
|
||||
return UpdateMenu(gateway=gateway)
|
||||
|
|
|
@ -4,3 +4,8 @@ from pydantic import BaseModel
|
|||
class AddMenuPDModel(BaseModel):
|
||||
title: str
|
||||
description: str | None
|
||||
|
||||
|
||||
class UpdateMenuPDModel(BaseModel):
|
||||
title: str | None = None
|
||||
description: str | None = None
|
||||
|
|
|
@ -1,13 +1,18 @@
|
|||
from typing import Annotated
|
||||
from uuid import UUID
|
||||
|
||||
from fastapi import APIRouter, Depends
|
||||
|
||||
from fastfood_two.application.contracts.requests import AddMenuDTO
|
||||
from fastfood_two.application.contracts.requests import AddMenuDTO, UpdateMenuDTO
|
||||
from fastfood_two.application.contracts.responses import MenuDTO
|
||||
from fastfood_two.application.usecases.menu.add_menu import AddMenu
|
||||
from fastfood_two.application.usecases.menu.get_all_menus import GetAllMenus
|
||||
from fastfood_two.application.usecases.menu.update_menu import UpdateMenu
|
||||
from fastfood_two.presentation.fastapi_backend.depends.stub import Stub
|
||||
from fastfood_two.presentation.fastapi_backend.pdmodels.menu import AddMenuPDModel
|
||||
from fastfood_two.presentation.fastapi_backend.pdmodels.menu import (
|
||||
AddMenuPDModel,
|
||||
UpdateMenuPDModel,
|
||||
)
|
||||
|
||||
router = APIRouter(prefix="/menu", tags=["Menu"])
|
||||
|
||||
|
@ -19,6 +24,15 @@ async def get_all_menus(
|
|||
"""Get all menus.
|
||||
|
||||
Endpoint returns list of all available food menus
|
||||
|
||||
Parameters
|
||||
----------
|
||||
None
|
||||
|
||||
Returns
|
||||
-------
|
||||
list[MenuDTO]
|
||||
list of created menu items
|
||||
"""
|
||||
menus = await usecase()
|
||||
return menus
|
||||
|
@ -29,9 +43,53 @@ async def add_menu(
|
|||
request: AddMenuPDModel,
|
||||
usecase: Annotated[AddMenu, Depends(Stub(AddMenu))],
|
||||
) -> MenuDTO:
|
||||
"""Get all menus.
|
||||
"""Add menus.
|
||||
|
||||
Endpoint returns list of all available food menus
|
||||
Endpoint allows to add new food menu
|
||||
|
||||
Parameters
|
||||
----------
|
||||
title: str
|
||||
title of the menu
|
||||
description: str
|
||||
description of the menu
|
||||
|
||||
Returns
|
||||
-------
|
||||
MenuDTO
|
||||
created menu
|
||||
"""
|
||||
menus = await usecase(request=AddMenuDTO(title=request.title, description=request.description))
|
||||
return menus
|
||||
|
||||
|
||||
@router.patch("/{menu_id}", response_model=MenuDTO)
|
||||
async def update_menu(
|
||||
menu_id: UUID,
|
||||
request: UpdateMenuPDModel,
|
||||
usecase: Annotated[UpdateMenu, Depends(Stub(UpdateMenu))],
|
||||
) -> MenuDTO:
|
||||
"""Update menus.
|
||||
|
||||
Endpoint allows to update food menu
|
||||
|
||||
Parameters
|
||||
----------
|
||||
title: str | None
|
||||
new title of the menu or None if you don't want to update it
|
||||
description: str | None
|
||||
new description of the menu or None if you don't want to update it
|
||||
|
||||
Returns
|
||||
-------
|
||||
MenuDTO
|
||||
updated menu
|
||||
"""
|
||||
menus = await usecase(
|
||||
request=UpdateMenuDTO(
|
||||
id=menu_id,
|
||||
title=request.title,
|
||||
description=request.description,
|
||||
)
|
||||
)
|
||||
return menus
|
||||
|
|
Loading…
Reference in New Issue