diff --git a/adapters/in-web/src/main/kotlin/com/pokit/content/ContentController.kt b/adapters/in-web/src/main/kotlin/com/pokit/content/ContentController.kt index 2567ec99..18ac55e3 100644 --- a/adapters/in-web/src/main/kotlin/com/pokit/content/ContentController.kt +++ b/adapters/in-web/src/main/kotlin/com/pokit/content/ContentController.kt @@ -76,4 +76,15 @@ class ContentController( val response = contentUseCase.bookmarkContent(user, contentId = contentId) return ResponseEntity.ok(response) } + + @PutMapping("/{contentId}/bookmark") + @Operation(summary = "즐겨찾기 취소 API") + fun cancelBookmark( + @AuthenticationPrincipal principalUser: PrincipalUser, + @PathVariable("contentId") contentId: Long + ): ResponseEntity { + val user = principalUser.toDomain() + return contentUseCase.cancelBookmark(user, contentId) + .wrapUnit() + } } diff --git a/adapters/out-persistence/src/main/kotlin/com/pokit/out/persistence/bookmark/impl/BookMarkAdapter.kt b/adapters/out-persistence/src/main/kotlin/com/pokit/out/persistence/bookmark/impl/BookMarkAdapter.kt index 161c7ca9..09dcf529 100644 --- a/adapters/out-persistence/src/main/kotlin/com/pokit/out/persistence/bookmark/impl/BookMarkAdapter.kt +++ b/adapters/out-persistence/src/main/kotlin/com/pokit/out/persistence/bookmark/impl/BookMarkAdapter.kt @@ -16,4 +16,12 @@ class BookMarkAdapter( val savedBookmark = bookMarkRepository.save(bookmarkEntity) return savedBookmark.toDomain() } + + override fun delete(contentId: Long, userId: Long) { + bookMarkRepository.findByContentIdAndUserIdAndDeleted( + contentId, + userId, + false + )?.delete() + } } diff --git a/adapters/out-persistence/src/main/kotlin/com/pokit/out/persistence/bookmark/persist/BookMarkRepository.kt b/adapters/out-persistence/src/main/kotlin/com/pokit/out/persistence/bookmark/persist/BookMarkRepository.kt index 5bf32f9d..5fd41ad9 100644 --- a/adapters/out-persistence/src/main/kotlin/com/pokit/out/persistence/bookmark/persist/BookMarkRepository.kt +++ b/adapters/out-persistence/src/main/kotlin/com/pokit/out/persistence/bookmark/persist/BookMarkRepository.kt @@ -3,4 +3,9 @@ package com.pokit.out.persistence.bookmark.persist import org.springframework.data.jpa.repository.JpaRepository interface BookMarkRepository : JpaRepository { + fun findByContentIdAndUserIdAndDeleted( + contentId: Long, + userId: Long, + deleted: Boolean + ): BookmarkEntity? } diff --git a/adapters/out-persistence/src/main/kotlin/com/pokit/out/persistence/bookmark/persist/BookmarkEntity.kt b/adapters/out-persistence/src/main/kotlin/com/pokit/out/persistence/bookmark/persist/BookmarkEntity.kt index 3c4bfbeb..d0cdd43f 100644 --- a/adapters/out-persistence/src/main/kotlin/com/pokit/out/persistence/bookmark/persist/BookmarkEntity.kt +++ b/adapters/out-persistence/src/main/kotlin/com/pokit/out/persistence/bookmark/persist/BookmarkEntity.kt @@ -17,7 +17,14 @@ class BookmarkEntity( @Column(name = "user_id") val userId: Long, + + @Column(name = "deleted") + var deleted: Boolean = true ) { + fun delete() { + this.deleted = true + } + companion object { fun of(bookmark: Bookmark) = BookmarkEntity( diff --git a/application/src/main/kotlin/com/pokit/bookmark/port/out/BookmarkPort.kt b/application/src/main/kotlin/com/pokit/bookmark/port/out/BookmarkPort.kt index c14cd7d9..3b9645cd 100644 --- a/application/src/main/kotlin/com/pokit/bookmark/port/out/BookmarkPort.kt +++ b/application/src/main/kotlin/com/pokit/bookmark/port/out/BookmarkPort.kt @@ -4,4 +4,6 @@ import com.pokit.bookmark.model.Bookmark interface BookmarkPort { fun persist(bookmark: Bookmark): Bookmark + + fun delete(userId: Long, contentId: Long) } diff --git a/application/src/main/kotlin/com/pokit/content/port/in/ContentUseCase.kt b/application/src/main/kotlin/com/pokit/content/port/in/ContentUseCase.kt index 22d4b781..64086382 100644 --- a/application/src/main/kotlin/com/pokit/content/port/in/ContentUseCase.kt +++ b/application/src/main/kotlin/com/pokit/content/port/in/ContentUseCase.kt @@ -13,4 +13,5 @@ interface ContentUseCase { fun update(user: User, contentCommand: ContentCommand, contentId: Long): Content fun delete(user: User, contentId: Long) + fun cancelBookmark(user: User, contentId: Long) } diff --git a/application/src/main/kotlin/com/pokit/content/port/service/ContentService.kt b/application/src/main/kotlin/com/pokit/content/port/service/ContentService.kt index 0b323b39..9e6679e6 100644 --- a/application/src/main/kotlin/com/pokit/content/port/service/ContentService.kt +++ b/application/src/main/kotlin/com/pokit/content/port/service/ContentService.kt @@ -56,6 +56,12 @@ class ContentService( contentPort.delete(content) } + @Transactional + override fun cancelBookmark(user: User, contentId: Long) { + verifyContent(user.id, contentId) + bookMarkPort.delete(user.id, contentId) + } + private fun verifyContent(userId: Long, contentId: Long): Content { return contentPort.loadByUserIdAndId(userId, contentId) ?: throw NotFoundCustomException(ContentErrorCode.NOT_FOUND_CONTENT)