From cbc631b2c20fd5348fa99fa7198f8d9511280b8e Mon Sep 17 00:00:00 2001 From: KIM MIN WOO <79193811+minwoo1999@users.noreply.github.com> Date: Sun, 13 Jul 2025 17:23:02 +0900 Subject: [PATCH 1/7] =?UTF-8?q?[BOOK-131]=20refactor:=20apis=20-=20apis?= =?UTF-8?q?=EB=AA=A8=EB=93=88=20=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81=20ser?= =?UTF-8?q?vice=20=EB=B0=98=ED=99=98=20DTO=EB=A1=9C=20=ED=86=B5=EC=9D=BC?= =?UTF-8?q?=20(#34)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../book/dto/request/UpsertUserBookRequest.kt | 38 +++++++++++++++++++ .../book/dto/response/BookCreateResponse.kt | 24 ++++++++++++ .../book/dto/response/BookDetailResponse.kt | 1 + .../book/dto/response/UserBookResponse.kt | 6 +-- .../book/service/BookManagementService.kt | 7 ++-- .../yapp/apis/book/service/UserBookService.kt | 19 ++++++++-- .../org/yapp/apis/book/usecase/BookUseCase.kt | 26 +++++++++---- 7 files changed, 103 insertions(+), 18 deletions(-) create mode 100644 apis/src/main/kotlin/org/yapp/apis/book/dto/request/UpsertUserBookRequest.kt create mode 100644 apis/src/main/kotlin/org/yapp/apis/book/dto/response/BookCreateResponse.kt diff --git a/apis/src/main/kotlin/org/yapp/apis/book/dto/request/UpsertUserBookRequest.kt b/apis/src/main/kotlin/org/yapp/apis/book/dto/request/UpsertUserBookRequest.kt new file mode 100644 index 00000000..1fcfec1d --- /dev/null +++ b/apis/src/main/kotlin/org/yapp/apis/book/dto/request/UpsertUserBookRequest.kt @@ -0,0 +1,38 @@ +package org.yapp.apis.book.dto.request + +import org.yapp.domain.userbook.BookStatus +import java.util.UUID + + +data class UpsertUserBookRequest private constructor( + val userId: UUID, + val bookIsbn: String, + val bookTitle: String, + val bookAuthor: String, + val bookPublisher: String, + val bookCoverImageUrl: String, + val status: BookStatus +) { + companion object { + + fun of( + userId: UUID, + bookIsbn: String, + bookTitle: String, + bookAuthor: String, + bookPublisher: String, + bookCoverImageUrl: String, + status: BookStatus + ): UpsertUserBookRequest { + return UpsertUserBookRequest( + userId = userId, + bookIsbn = bookIsbn, + bookTitle = bookTitle, + bookAuthor = bookAuthor, + bookPublisher = bookPublisher, + bookCoverImageUrl = bookCoverImageUrl, + status = status + ) + } + } +} diff --git a/apis/src/main/kotlin/org/yapp/apis/book/dto/response/BookCreateResponse.kt b/apis/src/main/kotlin/org/yapp/apis/book/dto/response/BookCreateResponse.kt new file mode 100644 index 00000000..8b4526ee --- /dev/null +++ b/apis/src/main/kotlin/org/yapp/apis/book/dto/response/BookCreateResponse.kt @@ -0,0 +1,24 @@ +package org.yapp.apis.book.dto.response + +import org.yapp.domain.book.vo.BookVO + +data class BookCreateResponse private constructor( + val isbn: String, + val title: String, + val author: String, + val publisher: String, + val coverImageUrl: String +) { + companion object { + + fun from(bookVO: BookVO): BookCreateResponse { + return BookCreateResponse( + isbn = bookVO.isbn, + title = bookVO.title, + author = bookVO.author, + publisher = bookVO.publisher, + coverImageUrl = bookVO.coverImageUrl + ) + } + } +} diff --git a/apis/src/main/kotlin/org/yapp/apis/book/dto/response/BookDetailResponse.kt b/apis/src/main/kotlin/org/yapp/apis/book/dto/response/BookDetailResponse.kt index 3ea5900b..baa96ea9 100644 --- a/apis/src/main/kotlin/org/yapp/apis/book/dto/response/BookDetailResponse.kt +++ b/apis/src/main/kotlin/org/yapp/apis/book/dto/response/BookDetailResponse.kt @@ -29,6 +29,7 @@ data class BookDetailResponse private constructor( ) { companion object { + fun from(response: AladinBookDetailResponse): BookDetailResponse { val bookItem = response.item?.firstOrNull() ?: throw IllegalArgumentException("No book item found in detail response.") diff --git a/apis/src/main/kotlin/org/yapp/apis/book/dto/response/UserBookResponse.kt b/apis/src/main/kotlin/org/yapp/apis/book/dto/response/UserBookResponse.kt index b325bdaa..c12d8e6c 100644 --- a/apis/src/main/kotlin/org/yapp/apis/book/dto/response/UserBookResponse.kt +++ b/apis/src/main/kotlin/org/yapp/apis/book/dto/response/UserBookResponse.kt @@ -1,9 +1,9 @@ package org.yapp.apis.book.dto.response import org.yapp.domain.userbook.BookStatus -import org.yapp.domain.userbook.UserBook +import org.yapp.domain.userbook.vo.UserBookVO import java.time.format.DateTimeFormatter -import java.util.* +import java.util.UUID data class UserBookResponse private constructor( val userBookId: UUID, @@ -20,7 +20,7 @@ data class UserBookResponse private constructor( companion object { fun from( - userBook: UserBook, + userBook: UserBookVO, ): UserBookResponse { return UserBookResponse( userBookId = userBook.id, diff --git a/apis/src/main/kotlin/org/yapp/apis/book/service/BookManagementService.kt b/apis/src/main/kotlin/org/yapp/apis/book/service/BookManagementService.kt index 5e119b14..97ce18dc 100644 --- a/apis/src/main/kotlin/org/yapp/apis/book/service/BookManagementService.kt +++ b/apis/src/main/kotlin/org/yapp/apis/book/service/BookManagementService.kt @@ -2,17 +2,17 @@ package org.yapp.apis.book.service import org.springframework.stereotype.Service import org.yapp.apis.book.dto.request.BookCreateRequest -import org.yapp.domain.book.Book +import org.yapp.apis.book.dto.response.BookCreateResponse import org.yapp.domain.book.BookDomainService @Service class BookManagementService( private val bookDomainService: BookDomainService ) { - fun findOrCreateBook(request: BookCreateRequest): Book { + fun findOrCreateBook(request: BookCreateRequest): BookCreateResponse { val isbn = request.validIsbn() - return bookDomainService.findByIsbn(isbn) + val bookVO = bookDomainService.findByIsbn(isbn) ?: bookDomainService.save( isbn = isbn, title = request.validTitle(), @@ -22,6 +22,7 @@ class BookManagementService( publicationYear = request.publicationYear, description = request.description ) + return BookCreateResponse.from(bookVO) } } diff --git a/apis/src/main/kotlin/org/yapp/apis/book/service/UserBookService.kt b/apis/src/main/kotlin/org/yapp/apis/book/service/UserBookService.kt index 23972439..b3d919a3 100644 --- a/apis/src/main/kotlin/org/yapp/apis/book/service/UserBookService.kt +++ b/apis/src/main/kotlin/org/yapp/apis/book/service/UserBookService.kt @@ -1,6 +1,8 @@ package org.yapp.apis.book.service import org.springframework.stereotype.Service +import org.yapp.apis.book.dto.request.UpsertUserBookRequest +import org.yapp.apis.book.dto.response.UserBookResponse import org.yapp.domain.book.Book import org.yapp.domain.userbook.UserBookDomainService import org.yapp.domain.userbook.BookStatus @@ -10,9 +12,18 @@ import java.util.* class UserBookService( private val userBookDomainService: UserBookDomainService ) { - fun upsertUserBook(userId: UUID, book: Book, status: BookStatus) = - userBookDomainService.upsertUserBook(userId, book, status) + fun upsertUserBook(upsertUserBookRequest: UpsertUserBookRequest): UserBookResponse = + UserBookResponse.from( + userBookDomainService.upsertUserBook( + upsertUserBookRequest.userId, + upsertUserBookRequest.bookIsbn, + upsertUserBookRequest.bookPublisher, + upsertUserBookRequest.bookAuthor, + upsertUserBookRequest.bookTitle, + upsertUserBookRequest.bookCoverImageUrl, + ) + ) - fun findAllUserBooks(userId: UUID) = - userBookDomainService.findAllUserBooks(userId) + fun findAllUserBooks(userId: UUID): List = + userBookDomainService.findAllUserBooks(userId).map { UserBookResponse.from(it) } } diff --git a/apis/src/main/kotlin/org/yapp/apis/book/usecase/BookUseCase.kt b/apis/src/main/kotlin/org/yapp/apis/book/usecase/BookUseCase.kt index e0e2d713..34a06fed 100644 --- a/apis/src/main/kotlin/org/yapp/apis/book/usecase/BookUseCase.kt +++ b/apis/src/main/kotlin/org/yapp/apis/book/usecase/BookUseCase.kt @@ -11,6 +11,7 @@ import org.yapp.apis.book.dto.response.BookDetailResponse import org.yapp.apis.book.dto.response.BookSearchResponse import org.yapp.apis.book.dto.response.UserBookResponse import org.yapp.apis.book.constant.BookQueryServiceQualifier +import org.yapp.apis.book.dto.request.UpsertUserBookRequest import org.yapp.apis.book.service.BookManagementService import org.yapp.apis.book.service.BookQueryService import org.yapp.apis.book.service.UserBookService @@ -20,10 +21,12 @@ import java.util.UUID @UseCase @Transactional(readOnly = true) class BookUseCase( - private val userAuthService: UserAuthService, - private val userBookService: UserBookService, + @Qualifier(BookQueryServiceQualifier.ALADIN) private val bookQueryService: BookQueryService, + + private val userAuthService: UserAuthService, + private val userBookService: UserBookService, private val bookManagementService: BookManagementService ) { fun searchBooks(request: BookSearchRequest): BookSearchResponse { @@ -38,13 +41,21 @@ class BookUseCase( fun upsertBookToMyLibrary(userId: UUID, request: UserBookRegisterRequest): UserBookResponse { userAuthService.validateUserExists(userId) - val detail = bookQueryService.getBookDetail(BookDetailRequest.of(request.validBookIsbn())) - - val book = bookManagementService.findOrCreateBook(BookCreateRequest.create(detail)) + val bookDetailResponse = bookQueryService.getBookDetail(BookDetailRequest.of(request.validBookIsbn())) - val userBook = userBookService.upsertUserBook(userId, book, request.bookStatus) + val bookCreateResponse = bookManagementService.findOrCreateBook(BookCreateRequest.create(bookDetailResponse)) + val upsertUserBookRequest = UpsertUserBookRequest.of( + userId = userId, + bookIsbn = bookCreateResponse.isbn, + bookTitle = bookCreateResponse.title, + bookAuthor = bookCreateResponse.author, + bookPublisher = bookCreateResponse.publisher, + bookCoverImageUrl = bookCreateResponse.coverImageUrl, + status = request.bookStatus + ) + val userBookResponse = userBookService.upsertUserBook(upsertUserBookRequest) - return UserBookResponse.from(userBook) + return userBookResponse } @@ -52,6 +63,5 @@ class BookUseCase( userAuthService.validateUserExists(userId) return userBookService.findAllUserBooks(userId) - .map(UserBookResponse::from) } } From 7139dbaa0232ae7554fdaa646a40b3f8d7e89d45 Mon Sep 17 00:00:00 2001 From: KIM MIN WOO <79193811+minwoo1999@users.noreply.github.com> Date: Sun, 13 Jul 2025 17:23:31 +0900 Subject: [PATCH 2/7] =?UTF-8?q?[BOOK-131]=20refactor:=20domain=20-=20domai?= =?UTF-8?q?nservice=20=EB=B0=98=ED=99=98=20VO=EB=A1=9C=20=ED=86=B5?= =?UTF-8?q?=EC=9D=BC=20(#34)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/yapp/domain/book/BookDomainService.kt | 16 ++++---- .../kotlin/org/yapp/domain/book/vo/BookVO.kt | 32 +++++++++++++++ .../org/yapp/domain/userbook/UserBook.kt | 16 +++++--- .../domain/userbook/UserBookDomainService.kt | 33 +++++++++++----- .../org/yapp/domain/userbook/vo/UserBookVO.kt | 39 +++++++++++++++++++ 5 files changed, 111 insertions(+), 25 deletions(-) create mode 100644 domain/src/main/kotlin/org/yapp/domain/book/vo/BookVO.kt create mode 100644 domain/src/main/kotlin/org/yapp/domain/userbook/vo/UserBookVO.kt diff --git a/domain/src/main/kotlin/org/yapp/domain/book/BookDomainService.kt b/domain/src/main/kotlin/org/yapp/domain/book/BookDomainService.kt index f8176b9c..b8e22cde 100644 --- a/domain/src/main/kotlin/org/yapp/domain/book/BookDomainService.kt +++ b/domain/src/main/kotlin/org/yapp/domain/book/BookDomainService.kt @@ -1,13 +1,14 @@ package org.yapp.domain.book +import org.yapp.domain.book.vo.BookVO import org.yapp.globalutils.annotation.DomainService @DomainService class BookDomainService( private val bookRepository: BookRepository ) { - fun findByIsbn(isbn: String): Book? { - return bookRepository.findByIsbn(isbn) + fun findByIsbn(isbn: String): BookVO? { + return bookRepository.findByIsbn(isbn)?.let { BookVO.newInstance(it) } } fun save( @@ -18,12 +19,8 @@ class BookDomainService( coverImageUrl: String, publicationYear: Int? = null, description: String? = null - ): Book { - findByIsbn(isbn)?.let { - return it - } - - val book = Book.create( + ): BookVO { + val book = bookRepository.findByIsbn(isbn) ?: Book.create( isbn = isbn, title = title, author = author, @@ -33,6 +30,7 @@ class BookDomainService( description = description ) - return bookRepository.save(book) + val savedBook = bookRepository.save(book) + return BookVO.newInstance(savedBook) } } diff --git a/domain/src/main/kotlin/org/yapp/domain/book/vo/BookVO.kt b/domain/src/main/kotlin/org/yapp/domain/book/vo/BookVO.kt new file mode 100644 index 00000000..d75c39f2 --- /dev/null +++ b/domain/src/main/kotlin/org/yapp/domain/book/vo/BookVO.kt @@ -0,0 +1,32 @@ +package org.yapp.domain.book.vo + +import org.yapp.domain.book.Book + +data class BookVO private constructor( + val isbn: String, + val title: String, + val author: String, + val publisher: String, + val coverImageUrl: String, + val publicationYear: Int?, + val description: String? +) { + companion object { + /** + * ✨ BookVO를 생성하는 팩토리 메서드 + */ + fun newInstance( + book: Book + ): BookVO { + return BookVO( + book.isbn, + book.title, + book.author, + book.publisher, + book.coverImageUrl, + book.publicationYear, + book.description + ) + } + } +} diff --git a/domain/src/main/kotlin/org/yapp/domain/userbook/UserBook.kt b/domain/src/main/kotlin/org/yapp/domain/userbook/UserBook.kt index 5d3ac971..5c8d00e7 100644 --- a/domain/src/main/kotlin/org/yapp/domain/userbook/UserBook.kt +++ b/domain/src/main/kotlin/org/yapp/domain/userbook/UserBook.kt @@ -27,18 +27,22 @@ data class UserBook private constructor( companion object { fun create( userId: UUID, - book: Book, + coverImageUrl: String, + bookIsbn: String, + publisher: String, + title: String, + author: String, initialStatus: BookStatus = BookStatus.BEFORE_READING ): UserBook { val now = LocalDateTime.now() return UserBook( id = UuidGenerator.create(), - coverImageUrl = book.coverImageUrl, - publisher = book.publisher, - title = book.title, - author = book.author, + coverImageUrl = coverImageUrl, + publisher = publisher, + title = title, + author = author, userId = userId, - bookIsbn = book.isbn, + bookIsbn = bookIsbn, status = initialStatus, createdAt = now, updatedAt = now, diff --git a/domain/src/main/kotlin/org/yapp/domain/userbook/UserBookDomainService.kt b/domain/src/main/kotlin/org/yapp/domain/userbook/UserBookDomainService.kt index e8acaa4f..4bd159c4 100644 --- a/domain/src/main/kotlin/org/yapp/domain/userbook/UserBookDomainService.kt +++ b/domain/src/main/kotlin/org/yapp/domain/userbook/UserBookDomainService.kt @@ -1,6 +1,7 @@ package org.yapp.domain.userbook import org.yapp.domain.book.Book +import org.yapp.domain.userbook.vo.UserBookVO import org.yapp.globalutils.annotation.DomainService import java.util.UUID @@ -8,19 +9,31 @@ import java.util.UUID class UserBookDomainService( private val userBookRepository: UserBookRepository ) { + fun upsertUserBook( + userId: UUID, + bookIsbn: String, + bookTitle: String, + bookAuthor: String, + bookPublisher: String, + bookCoverImageUrl: String, + ): UserBookVO { + val userBook = userBookRepository.findByUserIdAndBookIsbn(userId, bookIsbn) + ?.apply { updateStatus(status) } + ?: UserBook.create( + userId = userId, + bookIsbn = bookIsbn, + title = bookTitle, + author = bookAuthor, + publisher = bookPublisher, + coverImageUrl = bookCoverImageUrl, + ) - fun upsertUserBook(userId: UUID, book: Book, status: BookStatus): UserBook { - val existing = userBookRepository.findByUserIdAndBookIsbn(userId, book.isbn) - return if (existing != null) { - val updated = existing.updateStatus(status) - userBookRepository.save(updated) - } else { - val created = UserBook.create(userId, book, status) - userBookRepository.save(created) - } + val savedUserBook = userBookRepository.save(userBook) + return UserBookVO.newInstance(savedUserBook) } - fun findAllUserBooks(userId: UUID): List { + fun findAllUserBooks(userId: UUID): List { return userBookRepository.findAllByUserId(userId) + .map(UserBookVO::newInstance) } } diff --git a/domain/src/main/kotlin/org/yapp/domain/userbook/vo/UserBookVO.kt b/domain/src/main/kotlin/org/yapp/domain/userbook/vo/UserBookVO.kt new file mode 100644 index 00000000..66a3e490 --- /dev/null +++ b/domain/src/main/kotlin/org/yapp/domain/userbook/vo/UserBookVO.kt @@ -0,0 +1,39 @@ +package org.yapp.domain.userbook.vo + +import org.yapp.domain.userbook.BookStatus +import org.yapp.domain.userbook.UserBook +import java.time.LocalDateTime +import java.util.UUID + +data class UserBookVO private constructor( + val id: UUID, + val userId: UUID, + val bookIsbn: String, + val coverImageUrl: String, + val publisher: String, + val title: String, + val author: String, + val status: BookStatus, + val createdAt: LocalDateTime, + val updatedAt: LocalDateTime +) { + + companion object { + fun newInstance( + userBook: UserBook, + ): UserBookVO { + return UserBookVO( + id = userBook.id, + userId = userBook.userId, + bookIsbn = userBook.bookIsbn, + coverImageUrl = userBook.coverImageUrl, + publisher = userBook.publisher, + title = userBook.title, + author = userBook.author, + status = userBook.status, + createdAt = userBook.createdAt, + updatedAt = userBook.updatedAt + ) + } + } +} From 2bd8c08fcd54dc657806161010794404000bc292 Mon Sep 17 00:00:00 2001 From: KIM MIN WOO <79193811+minwoo1999@users.noreply.github.com> Date: Mon, 14 Jul 2025 22:58:09 +0900 Subject: [PATCH 3/7] =?UTF-8?q?[BOOK-131]=20refactor:=20apis=20-=20from=20?= =?UTF-8?q?=EC=BB=A8=EB=B2=A4=EC=85=98=EC=97=90=20=EB=A7=9E=EA=B2=8C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20(#34)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yapp/apis/book/dto/request/BookCreateRequest.kt | 3 +-- .../kotlin/org/yapp/apis/book/usecase/BookUseCase.kt | 10 +++------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/apis/src/main/kotlin/org/yapp/apis/book/dto/request/BookCreateRequest.kt b/apis/src/main/kotlin/org/yapp/apis/book/dto/request/BookCreateRequest.kt index fb3323d3..82e5a1d8 100644 --- a/apis/src/main/kotlin/org/yapp/apis/book/dto/request/BookCreateRequest.kt +++ b/apis/src/main/kotlin/org/yapp/apis/book/dto/request/BookCreateRequest.kt @@ -3,7 +3,6 @@ package org.yapp.apis.book.dto.request import jakarta.validation.constraints.NotBlank import jakarta.validation.constraints.Size import org.yapp.apis.book.dto.response.BookDetailResponse -import org.yapp.domain.book.Book data class BookCreateRequest private constructor( @field:NotBlank(message = "ISBN은 필수입니다.") @@ -32,7 +31,7 @@ data class BookCreateRequest private constructor( companion object { - fun create(bookDetail: BookDetailResponse): BookCreateRequest { + fun from(bookDetail: BookDetailResponse): BookCreateRequest { val finalIsbn = bookDetail.isbn ?: bookDetail.isbn13 ?: throw IllegalArgumentException("ISBN이 존재하지 않습니다.") diff --git a/apis/src/main/kotlin/org/yapp/apis/book/usecase/BookUseCase.kt b/apis/src/main/kotlin/org/yapp/apis/book/usecase/BookUseCase.kt index 34a06fed..c5977d63 100644 --- a/apis/src/main/kotlin/org/yapp/apis/book/usecase/BookUseCase.kt +++ b/apis/src/main/kotlin/org/yapp/apis/book/usecase/BookUseCase.kt @@ -24,7 +24,7 @@ class BookUseCase( @Qualifier(BookQueryServiceQualifier.ALADIN) private val bookQueryService: BookQueryService, - + private val userAuthService: UserAuthService, private val userBookService: UserBookService, private val bookManagementService: BookManagementService @@ -43,14 +43,10 @@ class BookUseCase( val bookDetailResponse = bookQueryService.getBookDetail(BookDetailRequest.of(request.validBookIsbn())) - val bookCreateResponse = bookManagementService.findOrCreateBook(BookCreateRequest.create(bookDetailResponse)) + val bookCreateResponse = bookManagementService.findOrCreateBook(BookCreateRequest.from(bookDetailResponse)) val upsertUserBookRequest = UpsertUserBookRequest.of( userId = userId, - bookIsbn = bookCreateResponse.isbn, - bookTitle = bookCreateResponse.title, - bookAuthor = bookCreateResponse.author, - bookPublisher = bookCreateResponse.publisher, - bookCoverImageUrl = bookCreateResponse.coverImageUrl, + bookCreateResponse, status = request.bookStatus ) val userBookResponse = userBookService.upsertUserBook(upsertUserBookRequest) From 1fbeb41822c11dffb9a81d4b33209548df3d62a1 Mon Sep 17 00:00:00 2001 From: KIM MIN WOO <79193811+minwoo1999@users.noreply.github.com> Date: Mon, 14 Jul 2025 22:59:15 +0900 Subject: [PATCH 4/7] =?UTF-8?q?[BOOK-131]=20refactor:=20apis=20-=20UserBoo?= =?UTF-8?q?kService=20=ED=83=80=EC=9E=85=EC=A7=80=EC=A0=95=20(#34)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yapp/apis/book/dto/response/BookCreateResponse.kt | 1 - .../org/yapp/apis/book/service/UserBookService.kt | 10 ++++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/apis/src/main/kotlin/org/yapp/apis/book/dto/response/BookCreateResponse.kt b/apis/src/main/kotlin/org/yapp/apis/book/dto/response/BookCreateResponse.kt index 8b4526ee..2da8a59e 100644 --- a/apis/src/main/kotlin/org/yapp/apis/book/dto/response/BookCreateResponse.kt +++ b/apis/src/main/kotlin/org/yapp/apis/book/dto/response/BookCreateResponse.kt @@ -10,7 +10,6 @@ data class BookCreateResponse private constructor( val coverImageUrl: String ) { companion object { - fun from(bookVO: BookVO): BookCreateResponse { return BookCreateResponse( isbn = bookVO.isbn, diff --git a/apis/src/main/kotlin/org/yapp/apis/book/service/UserBookService.kt b/apis/src/main/kotlin/org/yapp/apis/book/service/UserBookService.kt index b3d919a3..df9690db 100644 --- a/apis/src/main/kotlin/org/yapp/apis/book/service/UserBookService.kt +++ b/apis/src/main/kotlin/org/yapp/apis/book/service/UserBookService.kt @@ -6,6 +6,7 @@ import org.yapp.apis.book.dto.response.UserBookResponse import org.yapp.domain.book.Book import org.yapp.domain.userbook.UserBookDomainService import org.yapp.domain.userbook.BookStatus +import org.yapp.domain.userbook.vo.UserBookVO import java.util.* @Service @@ -21,9 +22,14 @@ class UserBookService( upsertUserBookRequest.bookAuthor, upsertUserBookRequest.bookTitle, upsertUserBookRequest.bookCoverImageUrl, + upsertUserBookRequest.status ) ) - fun findAllUserBooks(userId: UUID): List = - userBookDomainService.findAllUserBooks(userId).map { UserBookResponse.from(it) } + fun findAllUserBooks(userId: UUID): List { + val userBooks: List = userBookDomainService.findAllUserBooks(userId) + return userBooks.map { userBook: UserBookVO -> + UserBookResponse.from(userBook) + } + } } From 6a43f8797ce1984852298862b462b3123b46a41e Mon Sep 17 00:00:00 2001 From: KIM MIN WOO <79193811+minwoo1999@users.noreply.github.com> Date: Mon, 14 Jul 2025 22:59:55 +0900 Subject: [PATCH 5/7] =?UTF-8?q?[BOOK-131]=20refactor:=20domain=20-=20VO=20?= =?UTF-8?q?init=20=EA=B2=80=EC=A6=9D=EC=BD=94=EB=93=9C=20=20(#34)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/kotlin/org/yapp/domain/book/vo/BookVO.kt | 10 +++++++--- .../kotlin/org/yapp/domain/userbook/vo/UserBookVO.kt | 10 ++++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/domain/src/main/kotlin/org/yapp/domain/book/vo/BookVO.kt b/domain/src/main/kotlin/org/yapp/domain/book/vo/BookVO.kt index d75c39f2..2262ecd5 100644 --- a/domain/src/main/kotlin/org/yapp/domain/book/vo/BookVO.kt +++ b/domain/src/main/kotlin/org/yapp/domain/book/vo/BookVO.kt @@ -11,10 +11,14 @@ data class BookVO private constructor( val publicationYear: Int?, val description: String? ) { + init { + require(isbn.isNotBlank()) { "ISBN은 비어 있을 수 없습니다." } + require(title.isNotBlank()) { "제목은 비어 있을 수 없습니다." } + require(author.isNotBlank()) { "저자는 비어 있을 수 없습니다." } + publicationYear?.let { require(it > 0) { "출판 연도는 0보다 커야 합니다." } } + } + companion object { - /** - * ✨ BookVO를 생성하는 팩토리 메서드 - */ fun newInstance( book: Book ): BookVO { diff --git a/domain/src/main/kotlin/org/yapp/domain/userbook/vo/UserBookVO.kt b/domain/src/main/kotlin/org/yapp/domain/userbook/vo/UserBookVO.kt index 66a3e490..99d6fa0a 100644 --- a/domain/src/main/kotlin/org/yapp/domain/userbook/vo/UserBookVO.kt +++ b/domain/src/main/kotlin/org/yapp/domain/userbook/vo/UserBookVO.kt @@ -17,6 +17,16 @@ data class UserBookVO private constructor( val createdAt: LocalDateTime, val updatedAt: LocalDateTime ) { + init { + require(bookIsbn.isNotBlank()) { "도서 ISBN은 비어 있을 수 없습니다." } + require(coverImageUrl.isNotBlank()) { "표지 이미지 URL은 비어 있을 수 없습니다." } + require(publisher.isNotBlank()) { "출판사는 비어 있을 수 없습니다." } + require(title.isNotBlank()) { "도서 제목은 비어 있을 수 없습니다." } + require(author.isNotBlank()) { "저자는 비어 있을 수 없습니다." } + require(createdAt.isBefore(updatedAt) || createdAt == updatedAt) { + "생성일(createdAt)은 수정일(updatedAt)보다 이후일 수 없습니다." + } + } companion object { fun newInstance( From dbf348e4f8f5cb7234e44edeb6f91b1d73bbd836 Mon Sep 17 00:00:00 2001 From: KIM MIN WOO <79193811+minwoo1999@users.noreply.github.com> Date: Mon, 14 Jul 2025 23:00:13 +0900 Subject: [PATCH 6/7] =?UTF-8?q?[BOOK-131]=20refactor:=20domain=20-=20?= =?UTF-8?q?=EB=B9=A0=EC=A7=84=ED=95=84=EB=93=9C=20=EC=B6=94=EA=B0=80=20=20?= =?UTF-8?q?(#34)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/org/yapp/domain/userbook/UserBookDomainService.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/domain/src/main/kotlin/org/yapp/domain/userbook/UserBookDomainService.kt b/domain/src/main/kotlin/org/yapp/domain/userbook/UserBookDomainService.kt index 4bd159c4..78db78c0 100644 --- a/domain/src/main/kotlin/org/yapp/domain/userbook/UserBookDomainService.kt +++ b/domain/src/main/kotlin/org/yapp/domain/userbook/UserBookDomainService.kt @@ -16,6 +16,7 @@ class UserBookDomainService( bookAuthor: String, bookPublisher: String, bookCoverImageUrl: String, + status: BookStatus ): UserBookVO { val userBook = userBookRepository.findByUserIdAndBookIsbn(userId, bookIsbn) ?.apply { updateStatus(status) } From 8b0ca4800908676e1021e5df7963cd85879fdddd Mon Sep 17 00:00:00 2001 From: KIM MIN WOO <79193811+minwoo1999@users.noreply.github.com> Date: Mon, 14 Jul 2025 23:00:33 +0900 Subject: [PATCH 7/7] =?UTF-8?q?[BOOK-131]=20refactor:=20apis=20-=20dto?= =?UTF-8?q?=EC=9E=90=EC=B2=B4=EB=A5=BC=20=EB=84=98=EA=B8=B0=EB=8A=94?= =?UTF-8?q?=EB=B0=A9=EC=8B=9D=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD=20=20?= =?UTF-8?q?(#34)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../book/dto/request/UpsertUserBookRequest.kt | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/apis/src/main/kotlin/org/yapp/apis/book/dto/request/UpsertUserBookRequest.kt b/apis/src/main/kotlin/org/yapp/apis/book/dto/request/UpsertUserBookRequest.kt index 1fcfec1d..386290f0 100644 --- a/apis/src/main/kotlin/org/yapp/apis/book/dto/request/UpsertUserBookRequest.kt +++ b/apis/src/main/kotlin/org/yapp/apis/book/dto/request/UpsertUserBookRequest.kt @@ -1,5 +1,7 @@ package org.yapp.apis.book.dto.request +import org.yapp.apis.book.dto.response.BookCreateResponse +import org.yapp.apis.book.dto.response.UserBookResponse import org.yapp.domain.userbook.BookStatus import java.util.UUID @@ -14,23 +16,18 @@ data class UpsertUserBookRequest private constructor( val status: BookStatus ) { companion object { - fun of( userId: UUID, - bookIsbn: String, - bookTitle: String, - bookAuthor: String, - bookPublisher: String, - bookCoverImageUrl: String, + bookCreateResponse: BookCreateResponse, status: BookStatus ): UpsertUserBookRequest { return UpsertUserBookRequest( userId = userId, - bookIsbn = bookIsbn, - bookTitle = bookTitle, - bookAuthor = bookAuthor, - bookPublisher = bookPublisher, - bookCoverImageUrl = bookCoverImageUrl, + bookIsbn = bookCreateResponse.isbn, + bookTitle = bookCreateResponse.title, + bookAuthor = bookCreateResponse.author, + bookPublisher = bookCreateResponse.publisher, + bookCoverImageUrl = bookCreateResponse.coverImageUrl, status = status ) }