diff --git a/notification-domain/src/main/kotlin/io/github/v1servicenotification/error/ErrorCode.kt b/notification-domain/src/main/kotlin/io/github/v1servicenotification/error/ErrorCode.kt index 03ec9d7e..dc9d7d61 100644 --- a/notification-domain/src/main/kotlin/io/github/v1servicenotification/error/ErrorCode.kt +++ b/notification-domain/src/main/kotlin/io/github/v1servicenotification/error/ErrorCode.kt @@ -22,5 +22,7 @@ enum class ErrorCode( INTERNAL_SERVER_ERROR(500, "GLOBAL-500-1", "Internal Server Error."), - DEVICE_TOKEN_LENGTH(401, "DEVICE-400-1", "Device Token Length Error.") + DEVICE_TOKEN_LENGTH(401, "DEVICE-400-1", "Device Token Length Error."), + + SETTING_NOT_FOUND(404, "SETTING-404-1", "Setting Not Found.") } diff --git a/notification-domain/src/main/kotlin/io/github/v1servicenotification/setting/api/SettingApi.kt b/notification-domain/src/main/kotlin/io/github/v1servicenotification/setting/api/SettingApi.kt index de979c14..db21a695 100644 --- a/notification-domain/src/main/kotlin/io/github/v1servicenotification/setting/api/SettingApi.kt +++ b/notification-domain/src/main/kotlin/io/github/v1servicenotification/setting/api/SettingApi.kt @@ -4,7 +4,6 @@ import io.github.v1servicenotification.category.api.response.CategoryListRespons import java.util.UUID interface SettingApi { - fun activateCategory(categoryId: UUID, userId: UUID): Int - fun deActivateCategory(categoryId: UUID, userId: UUID): Int + fun activateOrDeActivateCategory(isActivate: Boolean, topic: String, userId: UUID) fun queryActivatedCategory(userId: UUID): CategoryListResponse } diff --git a/notification-domain/src/main/kotlin/io/github/v1servicenotification/setting/exception/SettingNotFoundException.kt b/notification-domain/src/main/kotlin/io/github/v1servicenotification/setting/exception/SettingNotFoundException.kt new file mode 100644 index 00000000..c352b791 --- /dev/null +++ b/notification-domain/src/main/kotlin/io/github/v1servicenotification/setting/exception/SettingNotFoundException.kt @@ -0,0 +1,11 @@ +package io.github.v1servicenotification.setting.exception + +import io.github.v1servicenotification.error.ErrorCode +import io.github.v1servicenotification.error.NotificationException + +class SettingNotFoundException private constructor(): NotificationException(ErrorCode.CATEGORY_NOT_FOUND) { + companion object { + @JvmField + val EXCEPTION = SettingNotFoundException() + } +} diff --git a/notification-domain/src/main/kotlin/io/github/v1servicenotification/setting/service/SettingApiImpl.kt b/notification-domain/src/main/kotlin/io/github/v1servicenotification/setting/service/SettingApiImpl.kt index c1bd1f5c..b92c2393 100644 --- a/notification-domain/src/main/kotlin/io/github/v1servicenotification/setting/service/SettingApiImpl.kt +++ b/notification-domain/src/main/kotlin/io/github/v1servicenotification/setting/service/SettingApiImpl.kt @@ -5,6 +5,7 @@ import io.github.v1servicenotification.category.api.response.CategoryElement import io.github.v1servicenotification.category.api.response.CategoryListResponse import io.github.v1servicenotification.setting.spi.SettingRepositorySpi import io.github.v1servicenotification.setting.api.SettingApi +import io.github.v1servicenotification.setting.exception.SettingNotFoundException import io.github.v1servicenotification.setting.spi.SettingCategorySpi import java.util.UUID @@ -12,34 +13,15 @@ import java.util.UUID class SettingApiImpl( private val settingRepositorySpi: SettingRepositorySpi, private val settingCategorySpi: SettingCategorySpi -): SettingApi { +) : SettingApi { - override fun activateCategory(categoryId: UUID, userId: UUID): Int { - return saveOrUpdateSetting( - categoryId = categoryId, - userId = userId, - isActivate = true - ) - } - - override fun deActivateCategory(categoryId: UUID, userId: UUID): Int { - return saveOrUpdateSetting( - categoryId = categoryId, - userId = userId, - isActivate = false - ) - } - - private fun saveOrUpdateSetting(categoryId: UUID, userId: UUID, isActivate: Boolean): Int { - val category = settingCategorySpi.findById(categoryId) + override fun activateOrDeActivateCategory(isActivate: Boolean, topic: String, userId: UUID) { + val category = settingCategorySpi.findByStartingWithTopic(topic) - return if (settingRepositorySpi.settingExist(category, userId)) { - settingRepositorySpi.updateSetting(category, userId, isActivate) - 204 - } else { - settingRepositorySpi.saveSetting(category, userId, isActivate) - 201 + if (!settingRepositorySpi.settingExist(category, userId)) { + throw SettingNotFoundException.EXCEPTION } + settingRepositorySpi.updateAllSetting(category, userId, isActivate) } override fun queryActivatedCategory(userId: UUID): CategoryListResponse { diff --git a/notification-domain/src/main/kotlin/io/github/v1servicenotification/setting/spi/SettingCategorySpi.kt b/notification-domain/src/main/kotlin/io/github/v1servicenotification/setting/spi/SettingCategorySpi.kt index 3340078f..7fef1258 100644 --- a/notification-domain/src/main/kotlin/io/github/v1servicenotification/setting/spi/SettingCategorySpi.kt +++ b/notification-domain/src/main/kotlin/io/github/v1servicenotification/setting/spi/SettingCategorySpi.kt @@ -1,8 +1,7 @@ package io.github.v1servicenotification.setting.spi -import io.github.v1servicenotification.category.Category -import java.util.UUID +import java.util.* interface SettingCategorySpi { - fun findById(id: UUID): Category + fun findByStartingWithTopic(topic: String): List } diff --git a/notification-domain/src/main/kotlin/io/github/v1servicenotification/setting/spi/SettingRepositorySpi.kt b/notification-domain/src/main/kotlin/io/github/v1servicenotification/setting/spi/SettingRepositorySpi.kt index fda7c572..6dff788d 100644 --- a/notification-domain/src/main/kotlin/io/github/v1servicenotification/setting/spi/SettingRepositorySpi.kt +++ b/notification-domain/src/main/kotlin/io/github/v1servicenotification/setting/spi/SettingRepositorySpi.kt @@ -2,13 +2,11 @@ package io.github.v1servicenotification.setting.spi import io.github.v1servicenotification.annotation.Spi import io.github.v1servicenotification.category.Category -import io.github.v1servicenotification.setting.Setting import java.util.UUID @Spi interface SettingRepositorySpi { - fun saveSetting(category: Category, userId: UUID, isActivated: Boolean): Setting - fun updateSetting(category: Category, userId: UUID, isActivated: Boolean): Setting - fun settingExist(category: Category, userId: UUID): Boolean + fun updateAllSetting(categoryIds: List, userId: UUID, isActivated: Boolean) + fun settingExist(categoryIds: List, userId: UUID): Boolean fun queryActivatedCategory(userId: UUID): List } diff --git a/notification-domain/src/main/kotlin/io/github/v1servicenotification/stubs/InMemoryCategoryRepository.kt b/notification-domain/src/main/kotlin/io/github/v1servicenotification/stubs/InMemoryCategoryRepository.kt index f03bcbf2..c8825a3c 100644 --- a/notification-domain/src/main/kotlin/io/github/v1servicenotification/stubs/InMemoryCategoryRepository.kt +++ b/notification-domain/src/main/kotlin/io/github/v1servicenotification/stubs/InMemoryCategoryRepository.kt @@ -34,14 +34,17 @@ class InMemoryCategoryRepository( ?: throw CategoryNotFoundException.EXCEPTION } - override fun findById(id: UUID): Category { - return categoryMap[id] - ?: throw CategoryNotFoundException.EXCEPTION - } - override fun findAllByDefaultActivated(defaultActivated: Boolean): List { return categoryMap.filter { it.value.defaultActivated == defaultActivated }.map { it.value } } + + override fun findByStartingWithTopic(topic: String): List { + return categoryMap.filter { + it.value.topic.startsWith(topic) + }.map { + it.key + } + } } diff --git a/notification-domain/src/main/kotlin/io/github/v1servicenotification/stubs/InMemorySettingRepository.kt b/notification-domain/src/main/kotlin/io/github/v1servicenotification/stubs/InMemorySettingRepository.kt index 12384cc1..69d8afab 100644 --- a/notification-domain/src/main/kotlin/io/github/v1servicenotification/stubs/InMemorySettingRepository.kt +++ b/notification-domain/src/main/kotlin/io/github/v1servicenotification/stubs/InMemorySettingRepository.kt @@ -15,32 +15,16 @@ class InMemorySettingRepository( categoryMap[category.id] = category } - fun findSetting(userId: UUID, categoryId: UUID): Setting? { - return settingMap - .filter { it.value.userId == userId && it.value.notificationCategoryId == categoryId } - .map { it.value }.firstOrNull() - } - - override fun saveSetting(category: Category, userId: UUID, isActivated: Boolean): Setting { - val setting = Setting(userId, category.id, isActivated) - settingMap[UUID.randomUUID()] = setting - - return setting - } - override fun updateSetting(category: Category, userId: UUID, isActivated: Boolean): Setting { - return settingMap.filter { - it.value.notificationCategoryId == category.id && it.value.userId == userId - }.map { - it.value.changeIsActivate(isActivated) - it.value - }[0] + override fun updateAllSetting(categoryIds: List, userId: UUID, isActivated: Boolean) { + categoryIds.forEach { + val setting = findSetting(userId, it) + setting?.changeIsActivate(isActivated) + } } - override fun settingExist(category: Category, userId: UUID): Boolean { - return settingMap.filter { - it.value.notificationCategoryId == category.id && it.value.userId == userId - }.isNotEmpty() + override fun settingExist(categoryIds: List, userId: UUID): Boolean { + return categoryIds.map { findSetting(userId, it) }.any { it != null } } override fun queryActivatedCategory(userId: UUID): List { @@ -50,6 +34,12 @@ class InMemorySettingRepository( }.map { it.value } } + private fun findSetting(userId: UUID, categoryId: UUID): Setting? { + return settingMap + .filter { it.value.userId == userId && it.value.notificationCategoryId == categoryId } + .map { it.value }.firstOrNull() + } + override fun findAllUserIdByTopicAndIsActivated(topic: String, isActivated: Boolean): List { return settingMap.values.filter { it.isActivated == isActivated && categoryMap[it.notificationCategoryId]?.topic == topic diff --git a/notification-domain/src/test/kotlin/io/github/v1servicenotification/detail/DetailApiImplTest.kt b/notification-domain/src/test/kotlin/io/github/v1servicenotification/detail/DetailApiImplTest.kt index 2c3c6f41..c465bc40 100644 --- a/notification-domain/src/test/kotlin/io/github/v1servicenotification/detail/DetailApiImplTest.kt +++ b/notification-domain/src/test/kotlin/io/github/v1servicenotification/detail/DetailApiImplTest.kt @@ -67,9 +67,11 @@ class DetailApiImplTest { topic = "ALL" ) + val categoryIds = listOf(category.id) + categorySpi.saveCategory(category) - settingSpi.saveSetting(category, userId, true) + settingSpi.updateAllSetting(categoryIds, userId, true) detailSpi.save(category) @@ -102,9 +104,11 @@ class DetailApiImplTest { topic = "ALL" ) + val categoryIds = listOf(category.id) + categorySpi.saveCategory(category) - settingSpi.saveSetting(category, userId, false) + settingSpi.updateAllSetting(categoryIds, userId, false) detailSpi.save(category) @@ -135,9 +139,11 @@ class DetailApiImplTest { topic = "ALL" ) + val categoryIds = listOf(category.id) + categorySpi.saveCategory(category) - settingSpi.saveSetting(category, userId, false) + settingSpi.updateAllSetting(categoryIds, userId, false) detailSpi.save(category) diff --git a/notification-domain/src/test/kotlin/io/github/v1servicenotification/setting/SettingApiImplTest.kt b/notification-domain/src/test/kotlin/io/github/v1servicenotification/setting/SettingApiImplTest.kt index 98eba945..3a144184 100644 --- a/notification-domain/src/test/kotlin/io/github/v1servicenotification/setting/SettingApiImplTest.kt +++ b/notification-domain/src/test/kotlin/io/github/v1servicenotification/setting/SettingApiImplTest.kt @@ -26,8 +26,11 @@ class SettingApiImplTest { settingSpi.saveCategory(category) - settingSpi.saveSetting( - category, + val categoryIds = listOf(category.id) + + + settingSpi.updateAllSetting( + categoryIds, userId, true ) @@ -39,30 +42,4 @@ class SettingApiImplTest { assertThat(result.destination).isEqualTo(category.destination) } - - @Test - fun deActivatedCategory() { - val userId = UUID.randomUUID() - val categoryId = UUID.randomUUID() - categorySpi.saveCategory( - Category(categoryId, "Test name", "Test destination", false, "ALL") - ) - Assertions.assertThat(settingApi.deActivateCategory(categoryId, userId)) - .isEqualTo(201) - Assertions.assertThat(settingApi.deActivateCategory(categoryId, userId)) - .isEqualTo(204) - } - - @Test - fun activateCategory() { - val userId = UUID.randomUUID() - val categoryId = UUID.randomUUID() - categorySpi.saveCategory( - Category(categoryId, "Test name", "Test destination", false, "ALL") - ) - assertThat(settingApi.activateCategory(categoryId, userId)) - .isEqualTo(201) - assertThat(settingApi.activateCategory(categoryId, userId)) - .isEqualTo(204) - } } diff --git a/notification-infrastructure/src/main/kotlin/io/github/v1servicenotification/domain/category/domain/repository/CustomCategoryRepositoryImpl.kt b/notification-infrastructure/src/main/kotlin/io/github/v1servicenotification/domain/category/domain/repository/CustomCategoryRepositoryImpl.kt index 3fb65fdb..6e496508 100644 --- a/notification-infrastructure/src/main/kotlin/io/github/v1servicenotification/domain/category/domain/repository/CustomCategoryRepositoryImpl.kt +++ b/notification-infrastructure/src/main/kotlin/io/github/v1servicenotification/domain/category/domain/repository/CustomCategoryRepositoryImpl.kt @@ -1,8 +1,10 @@ package io.github.v1servicenotification.domain.category.domain.repository +import com.querydsl.jpa.impl.JPAQueryFactory import io.github.v1servicenotification.category.Category import io.github.v1servicenotification.category.spi.QueryCategoryRepositorySpi import io.github.v1servicenotification.category.spi.UpdateCategoryRepositorySpi +import io.github.v1servicenotification.domain.category.domain.QCategoryEntity.categoryEntity import io.github.v1servicenotification.domain.category.exception.CategoryNotFoundException import io.github.v1servicenotification.domain.category.mapper.CategoryMapper import io.github.v1servicenotification.global.extension.findOne @@ -13,7 +15,8 @@ import java.util.UUID @Repository class CustomCategoryRepositoryImpl( private val categoryMapper: CategoryMapper, - private val categoryRepository: CategoryRepository + private val categoryRepository: CategoryRepository, + private val jpaQueryFactory: JPAQueryFactory, ) : UpdateCategoryRepositorySpi, QueryCategoryRepositorySpi, SettingCategorySpi { override fun saveCategory(category: Category) { @@ -40,13 +43,13 @@ class CustomCategoryRepositoryImpl( return categoryMapper.categoryEntityToDomain(category) } - override fun findById(id: UUID): Category { - val category = categoryRepository.findById(id) - .orElseThrow { - CategoryNotFoundException.EXCEPTION - } + override fun findByStartingWithTopic(topic: String): List { + return jpaQueryFactory + .select(categoryEntity.id) + .from(categoryEntity) + .where(categoryEntity.topic.startsWith(topic)) + .fetch() - return categoryMapper.categoryEntityToDomain(category) } override fun findAllByDefaultActivated(defaultActivated: Boolean): List { diff --git a/notification-infrastructure/src/main/kotlin/io/github/v1servicenotification/domain/setting/domain/repository/CustomSettingRepositoryImpl.kt b/notification-infrastructure/src/main/kotlin/io/github/v1servicenotification/domain/setting/domain/repository/CustomSettingRepositoryImpl.kt index 1a6e62e4..f91ea1d1 100644 --- a/notification-infrastructure/src/main/kotlin/io/github/v1servicenotification/domain/setting/domain/repository/CustomSettingRepositoryImpl.kt +++ b/notification-infrastructure/src/main/kotlin/io/github/v1servicenotification/domain/setting/domain/repository/CustomSettingRepositoryImpl.kt @@ -4,47 +4,55 @@ import com.querydsl.jpa.impl.JPAQueryFactory import io.github.v1servicenotification.category.Category import io.github.v1servicenotification.detail.spi.PostDetailSettingRepositorySpi import io.github.v1servicenotification.domain.category.domain.QCategoryEntity.categoryEntity +import io.github.v1servicenotification.domain.category.domain.repository.CategoryRepository import io.github.v1servicenotification.domain.category.mapper.CategoryMapper import io.github.v1servicenotification.domain.setting.domain.QSettingEntity.settingEntity -import io.github.v1servicenotification.domain.setting.domain.SettingEntity import io.github.v1servicenotification.domain.setting.domain.SettingId -import io.github.v1servicenotification.domain.setting.mapper.SettingMapper -import io.github.v1servicenotification.setting.Setting import io.github.v1servicenotification.setting.spi.SettingRepositorySpi import org.springframework.stereotype.Repository import java.util.UUID +import javax.transaction.Transactional @Repository class CustomSettingRepositoryImpl( private val settingRepository: SettingRepository, - private val settingMapper: SettingMapper, private val categoryMapper: CategoryMapper, - private val jpaQueryFactory: JPAQueryFactory + private val jpaQueryFactory: JPAQueryFactory, + private val categoryRepository: CategoryRepository, ) : SettingRepositorySpi, PostDetailSettingRepositorySpi { - override fun saveSetting(category: Category, userId: UUID, isActivated: Boolean): Setting { - return settingMapper.settingEntityToDomain( - settingRepository.save( - SettingEntity( - settingId = getSettingId(category, userId), - isActivated = isActivated + + @Transactional + override fun updateAllSetting(categoryIds: List, userId: UUID, isActivated: Boolean) { + categoryIds.forEach { + jpaQueryFactory + .update(settingEntity) + .set(settingEntity.isActivated, isActivated) + .where( + settingEntity.settingId.categoryEntity.id.eq(it) + .and(settingEntity.settingId.userId.eq(userId)) ) - ) - ) + .execute() + } } - override fun updateSetting(category: Category, userId: UUID, isActivated: Boolean): Setting { - return settingMapper.settingEntityToDomain( - settingRepository.save( - SettingEntity( - settingId = getSettingId(category, userId), - isActivated = isActivated - ) + override fun settingExist(categoryIds: List, userId: UUID): Boolean { + return getSettingIdList(categoryIds, userId).map { settingId -> + settingRepository.existsById(settingId) + }.all { it } + } + + private fun getSettingIdList(categoryIds: List, userId: UUID): List { + return getCategoryById(categoryIds).map { category -> + SettingId( + userId = userId, + categoryEntity = categoryMapper.categoryDomainToEntity(category) ) - ) + } } - override fun settingExist(category: Category, userId: UUID): Boolean { - return settingRepository.existsById(getSettingId(category, userId)) + private fun getCategoryById(categoryId: List): List { + return categoryRepository.findAllById(categoryId) + .map { categoryMapper.categoryEntityToDomain(it) } } override fun queryActivatedCategory(userId: UUID): List { @@ -66,13 +74,6 @@ class CustomSettingRepositoryImpl( } } - private fun getSettingId(category: Category, userId: UUID): SettingId { - return SettingId( - userId = userId, - categoryEntity = categoryMapper.categoryDomainToEntity(category) - ) - } - override fun findAllUserIdByTopicAndIsActivated(topic: String, isActivated: Boolean): List { return jpaQueryFactory .select(settingEntity.settingId.userId) diff --git a/notification-infrastructure/src/main/kotlin/io/github/v1servicenotification/domain/setting/presentation/SettingController.kt b/notification-infrastructure/src/main/kotlin/io/github/v1servicenotification/domain/setting/presentation/SettingController.kt index fa0d773c..60c59f53 100644 --- a/notification-infrastructure/src/main/kotlin/io/github/v1servicenotification/domain/setting/presentation/SettingController.kt +++ b/notification-infrastructure/src/main/kotlin/io/github/v1servicenotification/domain/setting/presentation/SettingController.kt @@ -2,22 +2,17 @@ package io.github.v1servicenotification.domain.setting.presentation import io.github.v1servicenotification.category.api.response.CategoryListResponse import io.github.v1servicenotification.global.extension.getUserId -import io.github.v1servicenotification.global.util.CustomHttpStatus import io.github.v1servicenotification.setting.api.SettingApi import io.swagger.v3.oas.annotations.Operation -import io.swagger.v3.oas.annotations.responses.ApiResponse -import io.swagger.v3.oas.annotations.responses.ApiResponses import io.swagger.v3.oas.annotations.tags.Tag import org.springframework.http.HttpStatus -import org.springframework.http.ResponseEntity import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PatchMapping -import org.springframework.web.bind.annotation.PathVariable +import org.springframework.web.bind.annotation.ResponseStatus import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController -import org.springframework.web.bind.annotation.DeleteMapping -import java.util.UUID +import org.springframework.web.bind.annotation.RequestParam @Tag(name = "알림 카테고리 활성화 설정", description = "알림 카테고리 활성화 관련 Api 입니다.") @RequestMapping("/tags") @@ -32,32 +27,13 @@ class SettingController( return settingApi.queryActivatedCategory(getUserId()) } - @Operation(summary = "알림 카테고리 활성화") - @ApiResponses(value = [ - ApiResponse(responseCode = CustomHttpStatus.CREATED), - ApiResponse(responseCode = CustomHttpStatus.NO_CONTENT) - ]) - @PatchMapping("/{category-uuid}") - fun activateNotificationCategory(@PathVariable("category-uuid") categoryId: UUID): ResponseEntity { - return ResponseEntity( - HttpStatus.valueOf( - settingApi.activateCategory(categoryId, getUserId()) - ) - ) + @Operation(summary = "알림 카테고리 활성화 / 비활성화") + @ResponseStatus(HttpStatus.NO_CONTENT) + @PatchMapping + fun activateNotificationCategory( + @RequestParam("is-activated") isActivate: Boolean, + @RequestParam("topic") topic: String + ) { + settingApi.activateOrDeActivateCategory(isActivate, topic, getUserId()) } - - @Operation(summary = "알림 카테고리 비활성회") - @ApiResponses(value = [ - ApiResponse(responseCode = CustomHttpStatus.CREATED), - ApiResponse(responseCode = CustomHttpStatus.NO_CONTENT) - ]) - @DeleteMapping("/{category-uuid}") - fun deActivateNotificationCategory(@PathVariable("category-uuid") categoryId: UUID): ResponseEntity { - return ResponseEntity( - HttpStatus.valueOf( - settingApi.deActivateCategory(categoryId, getUserId()) - ) - ) - } - -} \ No newline at end of file +}