diff --git a/apis/src/main/kotlin/org/yapp/apis/readingrecord/dto/response/ReadingRecordResponse.kt b/apis/src/main/kotlin/org/yapp/apis/readingrecord/dto/response/ReadingRecordResponse.kt index e97d6ead..609d9f11 100644 --- a/apis/src/main/kotlin/org/yapp/apis/readingrecord/dto/response/ReadingRecordResponse.kt +++ b/apis/src/main/kotlin/org/yapp/apis/readingrecord/dto/response/ReadingRecordResponse.kt @@ -30,7 +30,16 @@ data class ReadingRecordResponse private constructor( val createdAt: String, @Schema(description = "수정 일시", example = "2023-01-01T12:00:00") - val updatedAt: String + val updatedAt: String, + + @Schema(description = "도서 제목", example = "클린 코드") + val bookTitle: String?, + + @Schema(description = "출판사", example = "인사이트") + val bookPublisher: String?, + + @Schema(description = "도서 썸네일 URL", example = "https://example.com/book-cover.jpg") + val bookCoverImageUrl: String? ) { companion object { private val dateTimeFormatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME @@ -44,7 +53,10 @@ data class ReadingRecordResponse private constructor( review = readingRecordInfoVO.review.value, emotionTags = readingRecordInfoVO.emotionTags, createdAt = readingRecordInfoVO.createdAt.format(dateTimeFormatter), - updatedAt = readingRecordInfoVO.updatedAt.format(dateTimeFormatter) + updatedAt = readingRecordInfoVO.updatedAt.format(dateTimeFormatter), + bookTitle = readingRecordInfoVO.bookTitle, + bookPublisher = readingRecordInfoVO.bookPublisher, + bookCoverImageUrl = readingRecordInfoVO.bookCoverImageUrl ) } } diff --git a/domain/src/main/kotlin/org/yapp/domain/readingrecord/ReadingRecordDomainService.kt b/domain/src/main/kotlin/org/yapp/domain/readingrecord/ReadingRecordDomainService.kt index 7326949e..2e892847 100644 --- a/domain/src/main/kotlin/org/yapp/domain/readingrecord/ReadingRecordDomainService.kt +++ b/domain/src/main/kotlin/org/yapp/domain/readingrecord/ReadingRecordDomainService.kt @@ -7,6 +7,7 @@ import org.yapp.domain.readingrecordtag.ReadingRecordTag import org.yapp.domain.readingrecordtag.ReadingRecordTagRepository import org.yapp.domain.tag.Tag import org.yapp.domain.tag.TagRepository +import org.yapp.domain.userbook.UserBookRepository import org.yapp.globalutils.annotation.DomainService import java.util.UUID @@ -14,7 +15,8 @@ import java.util.UUID class ReadingRecordDomainService( private val readingRecordRepository: ReadingRecordRepository, private val tagRepository: TagRepository, - private val readingRecordTagRepository: ReadingRecordTagRepository + private val readingRecordTagRepository: ReadingRecordTagRepository, + private val userBookRepository: UserBookRepository ) { fun createReadingRecord( @@ -46,7 +48,15 @@ class ReadingRecordDomainService( } readingRecordTagRepository.saveAll(readingRecordTags) - return ReadingRecordInfoVO.newInstance(savedReadingRecord, tags.map { it.name }) + val userBook = userBookRepository.findById(userBookId) + + return ReadingRecordInfoVO.newInstance( + readingRecord = savedReadingRecord, + emotionTags = tags.map { it.name }, + bookTitle = userBook?.title, + bookPublisher = userBook?.publisher, + bookCoverImageUrl = userBook?.coverImageUrl + ) } fun findReadingRecordsByDynamicCondition( @@ -55,11 +65,21 @@ class ReadingRecordDomainService( pageable: Pageable ): Page { val page = readingRecordRepository.findReadingRecordsByDynamicCondition(userBookId, sort, pageable) + + // Get the UserBook entity to get the book thumbnail, title, and publisher + val userBook = userBookRepository.findById(userBookId) + return page.map { readingRecord -> val readingRecordTags = readingRecordTagRepository.findByReadingRecordId(readingRecord.id.value) val tagIds = readingRecordTags.map { it.tagId.value } val tags = tagRepository.findByIds(tagIds) - ReadingRecordInfoVO.newInstance(readingRecord, tags.map { it.name }) + ReadingRecordInfoVO.newInstance( + readingRecord = readingRecord, + emotionTags = tags.map { it.name }, + bookTitle = userBook?.title, + bookPublisher = userBook?.publisher, + bookCoverImageUrl = userBook?.coverImageUrl + ) } } diff --git a/domain/src/main/kotlin/org/yapp/domain/readingrecord/vo/ReadingRecordInfoVO.kt b/domain/src/main/kotlin/org/yapp/domain/readingrecord/vo/ReadingRecordInfoVO.kt index 649f3549..4b840393 100644 --- a/domain/src/main/kotlin/org/yapp/domain/readingrecord/vo/ReadingRecordInfoVO.kt +++ b/domain/src/main/kotlin/org/yapp/domain/readingrecord/vo/ReadingRecordInfoVO.kt @@ -11,7 +11,10 @@ data class ReadingRecordInfoVO private constructor( val review: ReadingRecord.Review, val emotionTags: List, val createdAt: LocalDateTime, - val updatedAt: LocalDateTime + val updatedAt: LocalDateTime, + val bookTitle: String? = null, + val bookPublisher: String? = null, + val bookCoverImageUrl: String? = null ) { init { require(emotionTags.size <= 3) { "Maximum 3 emotion tags are allowed" } @@ -23,7 +26,10 @@ data class ReadingRecordInfoVO private constructor( companion object { fun newInstance( readingRecord: ReadingRecord, - emotionTags: List + emotionTags: List, + bookTitle: String? = null, + bookPublisher: String? = null, + bookCoverImageUrl: String? = null ): ReadingRecordInfoVO { return ReadingRecordInfoVO( id = readingRecord.id, @@ -33,7 +39,10 @@ data class ReadingRecordInfoVO private constructor( review = readingRecord.review, emotionTags = emotionTags, createdAt = readingRecord.createdAt ?: throw IllegalStateException("createdAt은 null일 수 없습니다."), - updatedAt = readingRecord.updatedAt ?: throw IllegalStateException("updatedAt은 null일 수 없습니다.") + updatedAt = readingRecord.updatedAt ?: throw IllegalStateException("updatedAt은 null일 수 없습니다."), + bookTitle = bookTitle, + bookPublisher = bookPublisher, + bookCoverImageUrl = bookCoverImageUrl ) } } diff --git a/domain/src/main/kotlin/org/yapp/domain/userbook/UserBookRepository.kt b/domain/src/main/kotlin/org/yapp/domain/userbook/UserBookRepository.kt index b89b51d2..4bd6c64b 100644 --- a/domain/src/main/kotlin/org/yapp/domain/userbook/UserBookRepository.kt +++ b/domain/src/main/kotlin/org/yapp/domain/userbook/UserBookRepository.kt @@ -10,6 +10,7 @@ interface UserBookRepository { fun findByUserIdAndBookIsbn(userId: UUID, isbn: String): UserBook? fun findByBookIdAndUserId(bookId: UUID, userId: UUID): UserBook? fun findByIdAndUserId(id: UUID, userId: UUID): UserBook? + fun findById(id: UUID): UserBook? fun save(userBook: UserBook): UserBook diff --git a/infra/src/main/kotlin/org/yapp/infra/external/aladin/AladinApi.kt b/infra/src/main/kotlin/org/yapp/infra/external/aladin/AladinApi.kt index 1293a41d..1680564d 100644 --- a/infra/src/main/kotlin/org/yapp/infra/external/aladin/AladinApi.kt +++ b/infra/src/main/kotlin/org/yapp/infra/external/aladin/AladinApi.kt @@ -22,7 +22,8 @@ class AladinApi( fun lookupBook(request: AladinBookLookupRequest): Result { return runCatching { - val aladinApiParams = request.toMap() + val aladinApiParams = request.toMap().toMutableMap() + aladinApiParams["Cover"] = "Big" aladinRestClient.itemLookUp(ttbKey, aladinApiParams) // Map으로 전달 } } diff --git a/infra/src/main/kotlin/org/yapp/infra/userbook/repository/impl/UserBookRepositoryImpl.kt b/infra/src/main/kotlin/org/yapp/infra/userbook/repository/impl/UserBookRepositoryImpl.kt index 16cfaae0..dade4f4a 100644 --- a/infra/src/main/kotlin/org/yapp/infra/userbook/repository/impl/UserBookRepositoryImpl.kt +++ b/infra/src/main/kotlin/org/yapp/infra/userbook/repository/impl/UserBookRepositoryImpl.kt @@ -28,6 +28,10 @@ class UserBookRepositoryImpl( return jpaUserBookRepository.findByIdAndUserId(id, userId)?.toDomain() } + override fun findById(id: UUID): UserBook? { + return jpaUserBookRepository.findById(id).orElse(null)?.toDomain() + } + override fun save(userBook: UserBook): UserBook { val savedEntity = jpaUserBookRepository.saveAndFlush(UserBookEntity.fromDomain(userBook)) return savedEntity.toDomain()