From 9ef87fa8c3236d8ccb386d65058c6b129efcb38e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EB=8F=99=ED=9B=88?= <2dh2@naver.com> Date: Thu, 14 May 2026 13:56:29 +0900 Subject: [PATCH 1/4] =?UTF-8?q?fix:=20=EC=83=81=EC=A0=90=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20=EC=8B=9C=20=ED=98=9C=ED=83=9D=20=EB=A7=A4=ED=95=91?= =?UTF-8?q?=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 상점 soft delete 시 남아 있는 혜택 매핑을 함께 삭제한다 - 삭제된 상점의 혜택 매핑이 조회 오류로 이어지지 않도록 데이터 정합성을 맞춘다 - 상점 삭제 API 회귀 테스트에 혜택 매핑 삭제 검증을 추가한다 --- .../AdminBenefitCategoryMapRepository.java | 7 ++++++ .../admin/shop/service/AdminShopService.java | 3 +++ .../acceptance/admin/AdminShopApiTest.java | 25 +++++++++++++++++-- 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/main/java/in/koreatech/koin/admin/benefit/repository/AdminBenefitCategoryMapRepository.java b/src/main/java/in/koreatech/koin/admin/benefit/repository/AdminBenefitCategoryMapRepository.java index 56125d12b8..721a9d4ccf 100644 --- a/src/main/java/in/koreatech/koin/admin/benefit/repository/AdminBenefitCategoryMapRepository.java +++ b/src/main/java/in/koreatech/koin/admin/benefit/repository/AdminBenefitCategoryMapRepository.java @@ -45,6 +45,13 @@ void deleteByBenefitCategoryIdAndShopIds( @Modifying @Query(""" DELETE FROM BenefitCategoryMap bcm + WHERE bcm.shop.id = :shopId + """) + void deleteByShopId(@Param("shopId") Integer shopId); + + @Modifying + @Query(""" + DELETE FROM BenefitCategoryMap bcm WHERE bcm.benefitCategory.id = :benefitId """) void deleteByBenefitCategoryId(@Param("benefitId") Integer benefitId); diff --git a/src/main/java/in/koreatech/koin/admin/shop/service/AdminShopService.java b/src/main/java/in/koreatech/koin/admin/shop/service/AdminShopService.java index 630811fe3e..e2ff22d2e7 100644 --- a/src/main/java/in/koreatech/koin/admin/shop/service/AdminShopService.java +++ b/src/main/java/in/koreatech/koin/admin/shop/service/AdminShopService.java @@ -15,6 +15,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import in.koreatech.koin.admin.benefit.repository.AdminBenefitCategoryMapRepository; import in.koreatech.koin.admin.shop.dto.shop.AdminCreateShopCategoryRequest; import in.koreatech.koin.admin.shop.dto.shop.AdminCreateShopRequest; import in.koreatech.koin.admin.shop.dto.shop.AdminModifyShopCategoriesOrderRequest; @@ -57,6 +58,7 @@ public class AdminShopService { private final AdminShopCategoryRepository adminShopCategoryRepository; private final AdminShopCategoryMapRepository adminShopCategoryMapRepository; private final AdminShopParentCategoryRepository adminShopParentCategoryRepository; + private final AdminBenefitCategoryMapRepository adminBenefitCategoryMapRepository; public AdminShopsResponse getShops(Integer page, Integer limit, Boolean isDeleted) { Integer total = adminShopRepository.countAllByIsDeleted(isDeleted); @@ -221,6 +223,7 @@ public void modifyShopCategoriesOrder(AdminModifyShopCategoriesOrderRequest requ @RefreshShopsCache public void deleteShop(Integer shopId) { Shop shop = adminShopRepository.getById(shopId); + adminBenefitCategoryMapRepository.deleteByShopId(shopId); shop.delete(); } diff --git a/src/test/java/in/koreatech/koin/acceptance/admin/AdminShopApiTest.java b/src/test/java/in/koreatech/koin/acceptance/admin/AdminShopApiTest.java index 7b40b5aa4d..d0accb3d79 100644 --- a/src/test/java/in/koreatech/koin/acceptance/admin/AdminShopApiTest.java +++ b/src/test/java/in/koreatech/koin/acceptance/admin/AdminShopApiTest.java @@ -17,6 +17,8 @@ import org.springframework.transaction.support.TransactionTemplate; import in.koreatech.koin.acceptance.AcceptanceTest; +import in.koreatech.koin.acceptance.fixture.BenefitCategoryAcceptanceFixture; +import in.koreatech.koin.acceptance.fixture.BenefitCategoryMapAcceptanceFixture; import in.koreatech.koin.acceptance.fixture.MenuAcceptanceFixture; import in.koreatech.koin.acceptance.fixture.MenuCategoryAcceptanceFixture; import in.koreatech.koin.acceptance.fixture.ShopAcceptanceFixture; @@ -24,12 +26,14 @@ import in.koreatech.koin.acceptance.fixture.ShopNotificationMessageAcceptanceFixture; import in.koreatech.koin.acceptance.fixture.ShopParentCategoryAcceptanceFixture; import in.koreatech.koin.acceptance.fixture.UserAcceptanceFixture; +import in.koreatech.koin.admin.benefit.repository.AdminBenefitCategoryMapRepository; +import in.koreatech.koin.admin.manager.model.Admin; import in.koreatech.koin.admin.shop.repository.menu.AdminMenuCategoryRepository; import in.koreatech.koin.admin.shop.repository.menu.AdminMenuRepository; import in.koreatech.koin.admin.shop.repository.shop.AdminShopCategoryRepository; import in.koreatech.koin.admin.shop.repository.shop.AdminShopParentCategoryRepository; import in.koreatech.koin.admin.shop.repository.shop.AdminShopRepository; -import in.koreatech.koin.admin.manager.model.Admin; +import in.koreatech.koin.domain.benefit.model.BenefitCategory; import in.koreatech.koin.domain.owner.model.Owner; import in.koreatech.koin.domain.shop.model.menu.Menu; import in.koreatech.koin.domain.shop.model.menu.MenuCategory; @@ -62,6 +66,9 @@ class AdminShopApiTest extends AcceptanceTest { @Autowired private AdminShopRepository adminShopRepository; + @Autowired + private AdminBenefitCategoryMapRepository adminBenefitCategoryMapRepository; + @Autowired private AdminMenuRepository adminMenuRepository; @@ -89,6 +96,12 @@ class AdminShopApiTest extends AcceptanceTest { @Autowired private MenuCategoryAcceptanceFixture menuCategoryFixture; + @Autowired + private BenefitCategoryAcceptanceFixture benefitCategoryFixture; + + @Autowired + private BenefitCategoryMapAcceptanceFixture benefitCategoryMapFixture; + private Owner owner_현수; private Owner owner_준영; private Shop shop_마슬랜; @@ -935,6 +948,8 @@ void setUp() { @Test void 어드민이_상점을_삭제한다() throws Exception { Shop shop = shopFixture.영업중이_아닌_신전_떡볶이(owner_현수); + BenefitCategory benefitCategory = benefitCategoryFixture.배달비_무료(); + benefitCategoryMapFixture.혜택_추가(shop, benefitCategory); mockMvc.perform( delete("/admin/shops/{id}", shop.getId()) @@ -943,7 +958,13 @@ void setUp() { .andExpect(status().isOk()); Shop deletedShop = adminShopRepository.getById(shop.getId()); - assertSoftly(softly -> softly.assertThat(deletedShop.isDeleted()).isTrue()); + assertSoftly(softly -> { + softly.assertThat(deletedShop.isDeleted()).isTrue(); + softly.assertThat(adminBenefitCategoryMapRepository.findAllByBenefitCategoryIdAndShopIds( + benefitCategory.getId(), + List.of(shop.getId()) + )).isEmpty(); + }); } @Test From 0fe6ef3a7ffed5e2d2a44f124c4ce689aa0a7e46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EB=8F=99=ED=9B=88?= <2dh2@naver.com> Date: Thu, 14 May 2026 14:41:04 +0900 Subject: [PATCH 2/4] =?UTF-8?q?fix:=20=EC=82=AD=EC=A0=9C=EB=90=9C=20?= =?UTF-8?q?=EC=83=81=EC=A0=90=20=ED=98=9C=ED=83=9D=20=EC=A1=B0=ED=9A=8C=20?= =?UTF-8?q?=EC=A0=9C=EC=99=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 기존 매핑 데이터가 남아 있어도 삭제된 상점은 혜택 상점 조회에서 제외한다 - 상점 목록의 혜택 상세 조회도 삭제되지 않은 상점 매핑만 반영하도록 맞춘다 - 삭제된 상점 매핑이 남아 있는 회귀 케이스를 추가해 조회 오류를 방지한다 --- .../BenefitCategoryMapRepository.java | 10 +++++++++- .../benefit/service/ShopBenefitService.java | 3 ++- .../koin/acceptance/domain/BenefitApiTest.java | 17 +++++++++++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/main/java/in/koreatech/koin/domain/benefit/repository/BenefitCategoryMapRepository.java b/src/main/java/in/koreatech/koin/domain/benefit/repository/BenefitCategoryMapRepository.java index 1555fc1731..3115293a37 100644 --- a/src/main/java/in/koreatech/koin/domain/benefit/repository/BenefitCategoryMapRepository.java +++ b/src/main/java/in/koreatech/koin/domain/benefit/repository/BenefitCategoryMapRepository.java @@ -4,17 +4,25 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.Repository; +import org.springframework.data.repository.query.Param; import in.koreatech.koin.domain.benefit.model.BenefitCategoryMap; public interface BenefitCategoryMapRepository extends Repository { - List findByBenefitCategoryId(Integer benefitCategoryId); + @Query(""" + SELECT bcm FROM BenefitCategoryMap bcm + JOIN FETCH bcm.shop s + WHERE bcm.benefitCategory.id = :benefitCategoryId + AND s.isDeleted = false + """) + List findActiveShopMapsByBenefitCategoryId(@Param("benefitCategoryId") Integer benefitCategoryId); @Query(""" SELECT bcm FROM BenefitCategoryMap bcm JOIN FETCH bcm.shop s JOIN FETCH bcm.benefitCategory bc + WHERE s.isDeleted = false """) List findAllWithFetchJoin(); diff --git a/src/main/java/in/koreatech/koin/domain/benefit/service/ShopBenefitService.java b/src/main/java/in/koreatech/koin/domain/benefit/service/ShopBenefitService.java index 9d41fb04fd..b9aae96dec 100644 --- a/src/main/java/in/koreatech/koin/domain/benefit/service/ShopBenefitService.java +++ b/src/main/java/in/koreatech/koin/domain/benefit/service/ShopBenefitService.java @@ -35,7 +35,8 @@ public BenefitCategoryResponse getBenefitCategories() { } public BenefitShopsResponse getBenefitShops(Integer benefitId) { - List benefitCategoryMaps = benefitCategoryMapRepository.findByBenefitCategoryId(benefitId); + List benefitCategoryMaps = + benefitCategoryMapRepository.findActiveShopMapsByBenefitCategoryId(benefitId); LocalDateTime now = LocalDateTime.now(clock); List innerShopResponses = benefitCategoryMaps.stream() diff --git a/src/test/java/in/koreatech/koin/acceptance/domain/BenefitApiTest.java b/src/test/java/in/koreatech/koin/acceptance/domain/BenefitApiTest.java index 8975e05bf9..afc29ebd52 100644 --- a/src/test/java/in/koreatech/koin/acceptance/domain/BenefitApiTest.java +++ b/src/test/java/in/koreatech/koin/acceptance/domain/BenefitApiTest.java @@ -101,6 +101,23 @@ void setup() { benefitCategoryMapFixture.혜택_추가(마슬랜, 배달비_무료); benefitCategoryMapFixture.혜택_추가(영업중인_티바, 배달비_무료); benefitCategoryMapFixture.혜택_추가(영업중이_아닌_신전_떡볶이, 배달비_무료); + Shop 삭제된_굿모닝살로만치킨 = shopFixture.builder() + .owner(현수_사장님) + .name("굿모닝살로만치킨") + .internalName("굿모닝살로만치킨") + .phone("010-0000-0000") + .address("천안시 동남구 병천면 1600") + .description("삭제된 상점입니다.") + .delivery(true) + .deliveryPrice(3000) + .payCard(true) + .payBank(true) + .isDeleted(true) + .isEvent(false) + .remarks("비고") + .hit(0) + .build(); + benefitCategoryMapFixture.설명이_포함된_혜택_추가(삭제된_굿모닝살로만치킨, 배달비_무료, "배달비 무료"); shopReviewFixture.리뷰_4점(성빈_학생, 마슬랜); shopReviewFixture.리뷰_4점(성빈_학생, 영업중인_티바); From 1f814f940f068eacde15c1e00d188c81b76639e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EB=8F=99=ED=9B=88?= <2dh2@naver.com> Date: Thu, 14 May 2026 14:49:32 +0900 Subject: [PATCH 3/4] =?UTF-8?q?fix:=20=ED=98=9C=ED=83=9D=20=EB=A7=A4?= =?UTF-8?q?=ED=95=91=20=EC=82=AD=EC=A0=9C=20=EC=B2=98=EB=A6=AC=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 상점 soft delete 시 혜택 매핑을 삭제하지 않도록 되돌린다 - 기존 매핑 데이터는 조회 단계의 삭제 상점 필터링으로 방어한다 - 상점 삭제 API 테스트는 soft delete 상태만 검증하도록 복원한다 --- .../AdminBenefitCategoryMapRepository.java | 7 ------ .../admin/shop/service/AdminShopService.java | 3 --- .../acceptance/admin/AdminShopApiTest.java | 23 +------------------ 3 files changed, 1 insertion(+), 32 deletions(-) diff --git a/src/main/java/in/koreatech/koin/admin/benefit/repository/AdminBenefitCategoryMapRepository.java b/src/main/java/in/koreatech/koin/admin/benefit/repository/AdminBenefitCategoryMapRepository.java index 721a9d4ccf..79c5b51ca5 100644 --- a/src/main/java/in/koreatech/koin/admin/benefit/repository/AdminBenefitCategoryMapRepository.java +++ b/src/main/java/in/koreatech/koin/admin/benefit/repository/AdminBenefitCategoryMapRepository.java @@ -42,13 +42,6 @@ void deleteByBenefitCategoryIdAndShopIds( @Param("benefitId") Integer benefitId, @Param("shopIds") List shopIds); - @Modifying - @Query(""" - DELETE FROM BenefitCategoryMap bcm - WHERE bcm.shop.id = :shopId - """) - void deleteByShopId(@Param("shopId") Integer shopId); - @Modifying @Query(""" DELETE FROM BenefitCategoryMap bcm diff --git a/src/main/java/in/koreatech/koin/admin/shop/service/AdminShopService.java b/src/main/java/in/koreatech/koin/admin/shop/service/AdminShopService.java index e2ff22d2e7..630811fe3e 100644 --- a/src/main/java/in/koreatech/koin/admin/shop/service/AdminShopService.java +++ b/src/main/java/in/koreatech/koin/admin/shop/service/AdminShopService.java @@ -15,7 +15,6 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import in.koreatech.koin.admin.benefit.repository.AdminBenefitCategoryMapRepository; import in.koreatech.koin.admin.shop.dto.shop.AdminCreateShopCategoryRequest; import in.koreatech.koin.admin.shop.dto.shop.AdminCreateShopRequest; import in.koreatech.koin.admin.shop.dto.shop.AdminModifyShopCategoriesOrderRequest; @@ -58,7 +57,6 @@ public class AdminShopService { private final AdminShopCategoryRepository adminShopCategoryRepository; private final AdminShopCategoryMapRepository adminShopCategoryMapRepository; private final AdminShopParentCategoryRepository adminShopParentCategoryRepository; - private final AdminBenefitCategoryMapRepository adminBenefitCategoryMapRepository; public AdminShopsResponse getShops(Integer page, Integer limit, Boolean isDeleted) { Integer total = adminShopRepository.countAllByIsDeleted(isDeleted); @@ -223,7 +221,6 @@ public void modifyShopCategoriesOrder(AdminModifyShopCategoriesOrderRequest requ @RefreshShopsCache public void deleteShop(Integer shopId) { Shop shop = adminShopRepository.getById(shopId); - adminBenefitCategoryMapRepository.deleteByShopId(shopId); shop.delete(); } diff --git a/src/test/java/in/koreatech/koin/acceptance/admin/AdminShopApiTest.java b/src/test/java/in/koreatech/koin/acceptance/admin/AdminShopApiTest.java index d0accb3d79..ef304c0d6a 100644 --- a/src/test/java/in/koreatech/koin/acceptance/admin/AdminShopApiTest.java +++ b/src/test/java/in/koreatech/koin/acceptance/admin/AdminShopApiTest.java @@ -17,8 +17,6 @@ import org.springframework.transaction.support.TransactionTemplate; import in.koreatech.koin.acceptance.AcceptanceTest; -import in.koreatech.koin.acceptance.fixture.BenefitCategoryAcceptanceFixture; -import in.koreatech.koin.acceptance.fixture.BenefitCategoryMapAcceptanceFixture; import in.koreatech.koin.acceptance.fixture.MenuAcceptanceFixture; import in.koreatech.koin.acceptance.fixture.MenuCategoryAcceptanceFixture; import in.koreatech.koin.acceptance.fixture.ShopAcceptanceFixture; @@ -26,14 +24,12 @@ import in.koreatech.koin.acceptance.fixture.ShopNotificationMessageAcceptanceFixture; import in.koreatech.koin.acceptance.fixture.ShopParentCategoryAcceptanceFixture; import in.koreatech.koin.acceptance.fixture.UserAcceptanceFixture; -import in.koreatech.koin.admin.benefit.repository.AdminBenefitCategoryMapRepository; import in.koreatech.koin.admin.manager.model.Admin; import in.koreatech.koin.admin.shop.repository.menu.AdminMenuCategoryRepository; import in.koreatech.koin.admin.shop.repository.menu.AdminMenuRepository; import in.koreatech.koin.admin.shop.repository.shop.AdminShopCategoryRepository; import in.koreatech.koin.admin.shop.repository.shop.AdminShopParentCategoryRepository; import in.koreatech.koin.admin.shop.repository.shop.AdminShopRepository; -import in.koreatech.koin.domain.benefit.model.BenefitCategory; import in.koreatech.koin.domain.owner.model.Owner; import in.koreatech.koin.domain.shop.model.menu.Menu; import in.koreatech.koin.domain.shop.model.menu.MenuCategory; @@ -66,9 +62,6 @@ class AdminShopApiTest extends AcceptanceTest { @Autowired private AdminShopRepository adminShopRepository; - @Autowired - private AdminBenefitCategoryMapRepository adminBenefitCategoryMapRepository; - @Autowired private AdminMenuRepository adminMenuRepository; @@ -96,12 +89,6 @@ class AdminShopApiTest extends AcceptanceTest { @Autowired private MenuCategoryAcceptanceFixture menuCategoryFixture; - @Autowired - private BenefitCategoryAcceptanceFixture benefitCategoryFixture; - - @Autowired - private BenefitCategoryMapAcceptanceFixture benefitCategoryMapFixture; - private Owner owner_현수; private Owner owner_준영; private Shop shop_마슬랜; @@ -948,8 +935,6 @@ void setUp() { @Test void 어드민이_상점을_삭제한다() throws Exception { Shop shop = shopFixture.영업중이_아닌_신전_떡볶이(owner_현수); - BenefitCategory benefitCategory = benefitCategoryFixture.배달비_무료(); - benefitCategoryMapFixture.혜택_추가(shop, benefitCategory); mockMvc.perform( delete("/admin/shops/{id}", shop.getId()) @@ -958,13 +943,7 @@ void setUp() { .andExpect(status().isOk()); Shop deletedShop = adminShopRepository.getById(shop.getId()); - assertSoftly(softly -> { - softly.assertThat(deletedShop.isDeleted()).isTrue(); - softly.assertThat(adminBenefitCategoryMapRepository.findAllByBenefitCategoryIdAndShopIds( - benefitCategory.getId(), - List.of(shop.getId()) - )).isEmpty(); - }); + assertSoftly(softly -> softly.assertThat(deletedShop.isDeleted()).isTrue()); } @Test From ac1a3a168aae02b0209563e7a98bb398ccf7c911 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EB=8F=99=ED=9B=88?= <2dh2@naver.com> Date: Thu, 14 May 2026 14:51:33 +0900 Subject: [PATCH 4/4] =?UTF-8?q?fix:=20=EC=82=AD=EC=A0=9C=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=20=EC=A0=9C=EA=B1=B0=20=EB=B2=94=EC=9C=84=20=EC=A0=95?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 혜택 매핑 삭제 처리 제거 과정에서 남은 import 순서와 공백 변경을 되돌린다 - 최종 변경 범위를 삭제된 상점 혜택 조회 필터링으로 한정한다 --- .../benefit/repository/AdminBenefitCategoryMapRepository.java | 2 +- .../in/koreatech/koin/acceptance/admin/AdminShopApiTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/in/koreatech/koin/admin/benefit/repository/AdminBenefitCategoryMapRepository.java b/src/main/java/in/koreatech/koin/admin/benefit/repository/AdminBenefitCategoryMapRepository.java index 79c5b51ca5..56125d12b8 100644 --- a/src/main/java/in/koreatech/koin/admin/benefit/repository/AdminBenefitCategoryMapRepository.java +++ b/src/main/java/in/koreatech/koin/admin/benefit/repository/AdminBenefitCategoryMapRepository.java @@ -44,7 +44,7 @@ void deleteByBenefitCategoryIdAndShopIds( @Modifying @Query(""" - DELETE FROM BenefitCategoryMap bcm + DELETE FROM BenefitCategoryMap bcm WHERE bcm.benefitCategory.id = :benefitId """) void deleteByBenefitCategoryId(@Param("benefitId") Integer benefitId); diff --git a/src/test/java/in/koreatech/koin/acceptance/admin/AdminShopApiTest.java b/src/test/java/in/koreatech/koin/acceptance/admin/AdminShopApiTest.java index ef304c0d6a..7b40b5aa4d 100644 --- a/src/test/java/in/koreatech/koin/acceptance/admin/AdminShopApiTest.java +++ b/src/test/java/in/koreatech/koin/acceptance/admin/AdminShopApiTest.java @@ -24,12 +24,12 @@ import in.koreatech.koin.acceptance.fixture.ShopNotificationMessageAcceptanceFixture; import in.koreatech.koin.acceptance.fixture.ShopParentCategoryAcceptanceFixture; import in.koreatech.koin.acceptance.fixture.UserAcceptanceFixture; -import in.koreatech.koin.admin.manager.model.Admin; import in.koreatech.koin.admin.shop.repository.menu.AdminMenuCategoryRepository; import in.koreatech.koin.admin.shop.repository.menu.AdminMenuRepository; import in.koreatech.koin.admin.shop.repository.shop.AdminShopCategoryRepository; import in.koreatech.koin.admin.shop.repository.shop.AdminShopParentCategoryRepository; import in.koreatech.koin.admin.shop.repository.shop.AdminShopRepository; +import in.koreatech.koin.admin.manager.model.Admin; import in.koreatech.koin.domain.owner.model.Owner; import in.koreatech.koin.domain.shop.model.menu.Menu; import in.koreatech.koin.domain.shop.model.menu.MenuCategory;