diff --git a/src/main/java/com/cmc/mercury/domain/book/controller/BookController.java b/src/main/java/com/cmc/mercury/domain/book/controller/BookController.java new file mode 100644 index 0000000..98da516 --- /dev/null +++ b/src/main/java/com/cmc/mercury/domain/book/controller/BookController.java @@ -0,0 +1,40 @@ +package com.cmc.mercury.domain.book.controller; + +import com.cmc.mercury.domain.book.dto.BookExistResponse; +import com.cmc.mercury.domain.book.dto.BookSearchRequest; +import com.cmc.mercury.domain.book.dto.BookSearchResponse; +import com.cmc.mercury.domain.book.service.BookService; +import com.cmc.mercury.global.response.SuccessResponse; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; +import reactor.core.publisher.Mono; + +@RestController +@RequestMapping("/books") +@RequiredArgsConstructor +@Tag(name = "BookController", description = "도서 검색 관련 API") +public class BookController { + + private final BookService bookService; + + @GetMapping("/search") + @Operation(summary = "도서 검색", description = "검색어를 통해 도서 목록을 정렬하여 반환합니다.") + public Mono> searchBooks( + @ModelAttribute @Valid BookSearchRequest request) { + return bookService.searchBooks(request) + .map(SuccessResponse::ok); + } + + @GetMapping("/exist") + @Operation(summary = "기록 중복 생성 검사", + description = "isbn을 통해 해당 도서에 대한 기록을 생성한 적이 있는지의 여부를 반환합니다.") + public SuccessResponse existBooks( + @RequestParam("userId") Long testUserId, + @RequestParam String isbn13 + ) { + return SuccessResponse.ok(bookService.existBooks(testUserId, isbn13)); + } +} diff --git a/src/main/java/com/cmc/mercury/domain/book/controller/BookSearchController.java b/src/main/java/com/cmc/mercury/domain/book/controller/BookSearchController.java deleted file mode 100644 index f5e59c4..0000000 --- a/src/main/java/com/cmc/mercury/domain/book/controller/BookSearchController.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.cmc.mercury.domain.book.controller; - -import com.cmc.mercury.domain.book.dto.BookSearchRequest; -import com.cmc.mercury.domain.book.dto.BookSearchResponse; -import com.cmc.mercury.domain.book.service.BookSearchService; -import com.cmc.mercury.global.response.SuccessResponse; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.tags.Tag; -import jakarta.validation.Valid; -import lombok.RequiredArgsConstructor; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.ModelAttribute; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; -import reactor.core.publisher.Mono; - -@RestController -@RequestMapping("/books") -@RequiredArgsConstructor -@Tag(name = "BookSearchController", description = "도서 검색 관련 API") -public class BookSearchController { - - private final BookSearchService bookSearchService; - - @GetMapping("/search") - @Operation(summary = "도서 검색", description = "검색어를 통해 도서 목록을 정렬하여 반환합니다.") - public Mono> searchBooks( - @ModelAttribute @Valid BookSearchRequest request) { - return bookSearchService.searchBooks(request) - .map(SuccessResponse::ok); - } -} diff --git a/src/main/java/com/cmc/mercury/domain/book/dto/BookExistResponse.java b/src/main/java/com/cmc/mercury/domain/book/dto/BookExistResponse.java new file mode 100644 index 0000000..c57e010 --- /dev/null +++ b/src/main/java/com/cmc/mercury/domain/book/dto/BookExistResponse.java @@ -0,0 +1,15 @@ +package com.cmc.mercury.domain.book.dto; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(description = "선택된 도서의 기록이 존재하는지 여부 응답 형식") +public record BookExistResponse( + + @Schema(description = "중복 등록 여부") + boolean isRegistered, + + @Schema(description = "독서 기록이 존재할 때만 값 반환, 존재하지 않으면 null 반환") + Long recordId +) { + +} diff --git a/src/main/java/com/cmc/mercury/domain/book/repository/BookRepository.java b/src/main/java/com/cmc/mercury/domain/book/repository/BookRepository.java index dabda06..f26806f 100644 --- a/src/main/java/com/cmc/mercury/domain/book/repository/BookRepository.java +++ b/src/main/java/com/cmc/mercury/domain/book/repository/BookRepository.java @@ -10,4 +10,6 @@ public interface BookRepository extends JpaRepository { Optional findByIsbn13(String isbn13); + + boolean existsByIsbn13(String isbn13); } diff --git a/src/main/java/com/cmc/mercury/domain/book/service/BookSearchService.java b/src/main/java/com/cmc/mercury/domain/book/service/BookService.java similarity index 76% rename from src/main/java/com/cmc/mercury/domain/book/service/BookSearchService.java rename to src/main/java/com/cmc/mercury/domain/book/service/BookService.java index ebfd3ca..9c9cb0d 100644 --- a/src/main/java/com/cmc/mercury/domain/book/service/BookSearchService.java +++ b/src/main/java/com/cmc/mercury/domain/book/service/BookService.java @@ -1,7 +1,11 @@ package com.cmc.mercury.domain.book.service; +import com.cmc.mercury.domain.book.dto.BookExistResponse; import com.cmc.mercury.domain.book.dto.BookSearchRequest; import com.cmc.mercury.domain.book.dto.BookSearchResponse; +import com.cmc.mercury.domain.book.repository.BookRepository; +import com.cmc.mercury.domain.record.entity.Record; +import com.cmc.mercury.domain.record.repository.RecordRepository; import com.cmc.mercury.global.exception.CustomException; import com.cmc.mercury.global.exception.ErrorCode; import lombok.RequiredArgsConstructor; @@ -13,10 +17,15 @@ import org.springframework.web.util.UriComponentsBuilder; import reactor.core.publisher.Mono; +import java.util.Optional; + @Service @RequiredArgsConstructor @Slf4j -public class BookSearchService { +public class BookService { + + private final BookRepository bookRepository; + private final RecordRepository recordRepository; @Value("${aladin.api.url}") private String aladinUrl; @@ -81,4 +90,21 @@ private String buildSearchUrl(BookSearchRequest request) { // log.info("Built API request URL: {}", url); return url; } + + public BookExistResponse existBooks(Long testUserId, String isbn13) { + + // Book 존재 여부부터 확인 + if (!bookRepository.existsByIsbn13(isbn13)) { + return new BookExistResponse(false, null); + } + + // 사용자에게 독서 기록 존재 여부 확인 + Optional record = recordRepository.findByUser_TestUserIdAndBook_Isbn13(testUserId, isbn13); + + if (record.isEmpty()) { + return new BookExistResponse(false, null); + } + + return new BookExistResponse(true, record.get().getId()); + } } diff --git a/src/main/java/com/cmc/mercury/domain/record/repository/RecordRepository.java b/src/main/java/com/cmc/mercury/domain/record/repository/RecordRepository.java index b020157..8fde1b6 100644 --- a/src/main/java/com/cmc/mercury/domain/record/repository/RecordRepository.java +++ b/src/main/java/com/cmc/mercury/domain/record/repository/RecordRepository.java @@ -32,4 +32,6 @@ List searchRecordsByTitleOrMemoContent( @Param("testUserId") Long testUserId, @Param("keyword") String keyword, @Param("sortType") String sortType); + + Optional findByUser_TestUserIdAndBook_Isbn13(Long testUserId, String isbn13); } diff --git a/src/main/java/com/cmc/mercury/domain/record/service/RecordService.java b/src/main/java/com/cmc/mercury/domain/record/service/RecordService.java index fe707d1..4c8794d 100644 --- a/src/main/java/com/cmc/mercury/domain/record/service/RecordService.java +++ b/src/main/java/com/cmc/mercury/domain/record/service/RecordService.java @@ -36,7 +36,6 @@ public RecordResponse createRecord(Long testUserId, RecordRequest request) { User user = userTestService.getOrCreateTestUser(testUserId); // 저장되지 않은 도서면 저장 - // 유저가 해당 도서에 대한 기록을 남긴 적이 있는지 검사해야 하나? -> api만 잘 연결하면 될 듯 Book book = bookRepository.findByIsbn13(request.book().isbn13()) .orElseGet(() -> { try {