From 32091d6e85aab84d0247781b3f86c31fe553d615 Mon Sep 17 00:00:00 2001 From: Sergey Vanyushkin Date: Fri, 6 Sep 2024 08:34:19 +0000 Subject: [PATCH] ADD delete menu item functional --- .../application/contracts/requests.py | 5 +++ .../application/usecases/menu/delete_menu.py | 15 ++++++++ src/fastfood_two/domain/menu/gateway.py | 5 +-- .../infrastructure/menu_gateway.py | 9 +++-- .../fastapi_backend/dependencies.py | 3 ++ .../fastapi_backend/depends/usecases.py | 5 +++ .../fastapi_backend/routers/menu.py | 38 ++++++++++++++++++- 7 files changed, 72 insertions(+), 8 deletions(-) create mode 100644 src/fastfood_two/application/usecases/menu/delete_menu.py diff --git a/src/fastfood_two/application/contracts/requests.py b/src/fastfood_two/application/contracts/requests.py index 6f8041e..f365f9a 100644 --- a/src/fastfood_two/application/contracts/requests.py +++ b/src/fastfood_two/application/contracts/requests.py @@ -13,3 +13,8 @@ class UpdateMenuDTO: id: UUID title: str | None description: str | None + + +@dataclass(frozen=True) +class DeleteMenuDTO: + id: UUID diff --git a/src/fastfood_two/application/usecases/menu/delete_menu.py b/src/fastfood_two/application/usecases/menu/delete_menu.py new file mode 100644 index 0000000..35095f4 --- /dev/null +++ b/src/fastfood_two/application/usecases/menu/delete_menu.py @@ -0,0 +1,15 @@ +from fastfood_two.application.abstractions.interactor import Interactor +from fastfood_two.application.contracts.requests import DeleteMenuDTO +from fastfood_two.domain.menu.gateway import MenuGateway +from fastfood_two.domain.menu.menu_entity import MenuId + + +class DeleteMenu(Interactor[DeleteMenuDTO, None]): + def __init__(self, gateway: MenuGateway) -> None: + self._menu_gateway = gateway + + async def __call__(self, request: DeleteMenuDTO) -> None: + + await self._menu_gateway.delete_menu( + id=MenuId(request.id), + ) diff --git a/src/fastfood_two/domain/menu/gateway.py b/src/fastfood_two/domain/menu/gateway.py index 991d474..ff27da3 100644 --- a/src/fastfood_two/domain/menu/gateway.py +++ b/src/fastfood_two/domain/menu/gateway.py @@ -1,11 +1,10 @@ from typing import Protocol -from uuid import UUID from fastfood_two.domain.menu.menu_entity import Description, Menu, MenuId, Title class MenuGateway(Protocol): - async def get_menu_by_id(self, id: UUID) -> Menu | None: + async def get_menu_by_id(self, id: MenuId) -> Menu | None: raise NotImplementedError async def insert_menu(self, menu: Menu) -> Menu: @@ -22,5 +21,5 @@ class MenuGateway(Protocol): ) -> Menu: raise NotImplementedError - async def delete_menu(self, id: UUID) -> None: + async def delete_menu(self, id: MenuId) -> None: raise NotImplementedError diff --git a/src/fastfood_two/infrastructure/menu_gateway.py b/src/fastfood_two/infrastructure/menu_gateway.py index b322905..7fc6f4c 100644 --- a/src/fastfood_two/infrastructure/menu_gateway.py +++ b/src/fastfood_two/infrastructure/menu_gateway.py @@ -1,5 +1,3 @@ -from uuid import UUID - from sqlalchemy import text from sqlalchemy.ext.asyncio import AsyncSession @@ -18,7 +16,7 @@ class MenuGatewayImpl: menus = await self._session.execute(query) return [db_entity_to_domain(menu.tuple()) for menu in menus] - async def get_menu_by_id(self, id: UUID) -> Menu | None: ... + async def get_menu_by_id(self, id: MenuId) -> Menu | None: ... async def insert_menu(self, menu: Menu) -> Menu: query = text("INSERT INTO menu (id, title, description) VALUES (:id, :title, :description);") @@ -52,4 +50,7 @@ class MenuGatewayImpl: await self._session.commit() return db_entity_to_domain(menu.one().tuple()) - async def delete_menu(self, id: UUID) -> None: ... + async def delete_menu(self, id: MenuId) -> None: + query = text("DELETE FROM menu WHERE id = :id;") + await self._session.execute(query, {"id": id.value}) + await self._session.commit() diff --git a/src/fastfood_two/presentation/fastapi_backend/dependencies.py b/src/fastfood_two/presentation/fastapi_backend/dependencies.py index 75d26e1..3163774 100644 --- a/src/fastfood_two/presentation/fastapi_backend/dependencies.py +++ b/src/fastfood_two/presentation/fastapi_backend/dependencies.py @@ -6,6 +6,7 @@ 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.delete_menu import DeleteMenu 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 @@ -18,6 +19,7 @@ from fastfood_two.presentation.fastapi_backend.depends.session import ( ) from fastfood_two.presentation.fastapi_backend.depends.usecases import ( add_menu_usecase, + delete_menu_usecase, get_all_menus_usecase, update_menu_usecase, ) @@ -44,5 +46,6 @@ def init_dependencies(app: FastAPI) -> None: app.dependency_overrides[GetAllMenus] = get_all_menus_usecase app.dependency_overrides[AddMenu] = add_menu_usecase app.dependency_overrides[UpdateMenu] = update_menu_usecase + app.dependency_overrides[DeleteMenu] = delete_menu_usecase logger.info("Dependencies initialized") diff --git a/src/fastfood_two/presentation/fastapi_backend/depends/usecases.py b/src/fastfood_two/presentation/fastapi_backend/depends/usecases.py index 7956f98..35025f8 100644 --- a/src/fastfood_two/presentation/fastapi_backend/depends/usecases.py +++ b/src/fastfood_two/presentation/fastapi_backend/depends/usecases.py @@ -3,6 +3,7 @@ from typing import Annotated from fastapi import Depends from fastfood_two.application.usecases.menu.add_menu import AddMenu +from fastfood_two.application.usecases.menu.delete_menu import DeleteMenu 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 @@ -19,3 +20,7 @@ def add_menu_usecase(gateway: Annotated[MenuGateway, Depends(Stub(MenuGateway))] def update_menu_usecase(gateway: Annotated[MenuGateway, Depends(Stub(MenuGateway))]) -> UpdateMenu: return UpdateMenu(gateway=gateway) + + +def delete_menu_usecase(gateway: Annotated[MenuGateway, Depends(Stub(MenuGateway))]) -> DeleteMenu: + return DeleteMenu(gateway=gateway) diff --git a/src/fastfood_two/presentation/fastapi_backend/routers/menu.py b/src/fastfood_two/presentation/fastapi_backend/routers/menu.py index 1dbbc32..8225a4b 100644 --- a/src/fastfood_two/presentation/fastapi_backend/routers/menu.py +++ b/src/fastfood_two/presentation/fastapi_backend/routers/menu.py @@ -3,9 +3,14 @@ from uuid import UUID from fastapi import APIRouter, Depends -from fastfood_two.application.contracts.requests import AddMenuDTO, UpdateMenuDTO +from fastfood_two.application.contracts.requests import ( + AddMenuDTO, + DeleteMenuDTO, + 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.delete_menu import DeleteMenu 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 @@ -75,6 +80,9 @@ async def update_menu( Parameters ---------- + menu_id: UUID + requaired id of the menu to update + title: str | None new title of the menu or None if you don't want to update it description: str | None @@ -93,3 +101,31 @@ async def update_menu( ) ) return menus + + +@router.delete("/{menu_id}", status_code=204) +async def delete_menu( + menu_id: UUID, + usecase: Annotated[DeleteMenu, Depends(Stub(DeleteMenu))], +) -> None: + """Delete menus. + + Endpoint allows to delete food menu item + + Parameters + ---------- + menu_id: UUID + requaired id of the menu item + + Returns + ------- + None + returns only 204 status code + + """ + await usecase( + request=DeleteMenuDTO( + id=menu_id, + ) + ) + return