Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ class ChatMongoService(
private val userRepository: UserRepository,
private val openAiService: OpenAiService,
@Value("\${image.chat-bot}")
private val chatBotImage: String
private val chatBotImage: String,
@Value("\${image.guest}")
private val guestImage: String,
) {

val log: Logger = LoggerFactory.getLogger(ChatMongoService::class.java)
Expand Down Expand Up @@ -165,9 +167,17 @@ class ChatMongoService(
// DTO 변환
val dtoList = chatHistory.map { chat ->
val user: User? = userMap[chat.userId ?: -1]
val profileImage = when (chat.type) {
MessageType.CHAT, MessageType.BOT_REQUEST -> {
user?.profileImageUrl
}
MessageType.BOT_RESPONSE -> {
chatBotImage
}
}
Comment on lines +170 to +177
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

⚠️ Potential issue

Unify BOT_RESPONSE rendering and add guest fallback for missing user images.

  • Show “챗봇” and isMy=false for BOT_RESPONSE to match live send path.
  • Fallback to guestImage when user/profile image is null.

Apply:

-            val profileImage = when (chat.type) {
-                MessageType.CHAT, MessageType.BOT_REQUEST -> {
-                    user?.profileImageUrl
-                }
-                MessageType.BOT_RESPONSE -> {
-                    chatBotImage
-                }
-            }
-            ChatMessageResponseDTO.ChatInfoDto(
-                userName = user?.nickname ?: "알 수 없음",
-                userImage = profileImage,
-                dateTime = chat.time,
-                content = chat.message,
-                isMy = user?.id == currentUser.id,
-                type = chat.type
-            )
+            val (userName, userImage, isMy) = when (chat.type) {
+                MessageType.BOT_RESPONSE ->
+                    Triple("챗봇", chatBotImage, false)
+                MessageType.CHAT, MessageType.BOT_REQUEST ->
+                    Triple(user?.nickname ?: "알 수 없음",
+                           user?.profileImageUrl ?: guestImage,
+                           user?.id == currentUser.id)
+            }
+            ChatMessageResponseDTO.ChatInfoDto(
+                userName = userName,
+                userImage = userImage,
+                dateTime = chat.time,
+                content = chat.message,
+                isMy = isMy,
+                type = chat.type
+            )

Also applies to: 181-185

ChatMessageResponseDTO.ChatInfoDto(
userName = user?.nickname ?: "알 수 없음",
userImage = user?.profileImageUrl,
userImage = profileImage,
dateTime = chat.time,
content = chat.message,
isMy = user?.id == currentUser.id,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package busanVibe.busan.domain.home.controller

import busanVibe.busan.domain.home.dto.HomeResponseDTO
import busanVibe.busan.domain.home.enums.CurationType
import busanVibe.busan.domain.home.service.HomeQueryService
import busanVibe.busan.global.apiPayload.exception.ApiResponse
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.tags.Tag
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController

@Tag(name = "홈화면 API")
Expand All @@ -25,15 +27,16 @@ class HomeController(
}

@GetMapping("/curation")
@Operation(summary = "홈화면 큐레이션 조회 API",
@Operation(summary = "큐레이션 조회 API",
description =
"""
임의의 명소 1개, 축제 2개 반환
( 이미지 없는것 베재, 장소는 관광지만 조회 )
명소 혹은 축제에 대한 큐레이션 정보를 반환합니다.
type이 필요합니다. - [ PLACE, FESTIVAL ]
( 이미지 없는것은 베재, 장소는 관광지만 조회 )
"""
)
fun getHomeCuration(): ApiResponse<HomeResponseDTO.CurationList>{
val curations = homeQueryService.getCurations()
fun getHomeCuration(@RequestParam("type", required = true) type: CurationType): ApiResponse<HomeResponseDTO.CurationList>{
val curations = homeQueryService.getCurations(type)
return ApiResponse.onSuccess(curations)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,14 @@ class CurationConverter {
imgUrl = festival.festivalImages.first().imgUrl
)

fun toListDto(placeList: List<Place>, festivalList: List<Festival>) : HomeResponseDTO.CurationList{
val placeDtoList = placeList.map { placeToDto(it) }.toList()
val festivalDtoList = festivalList.map { festivalToDto(it) }.toList()
fun placeListToDto(placeList: List<Place>): HomeResponseDTO.CurationList {
val placeDtoList = placeList.map { placeToDto(it) }
return HomeResponseDTO.CurationList(placeDtoList)
}

return HomeResponseDTO.CurationList( placeDtoList + festivalDtoList )
fun festivalListToDto(festivalList: List<Festival>): HomeResponseDTO.CurationList {
val festivalDtoList = festivalList.map { festivalToDto(it) }
return HomeResponseDTO.CurationList(festivalDtoList)
}


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package busanVibe.busan.domain.home.enums

enum class CurationType {

PLACE,
FESTIVAL

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import busanVibe.busan.domain.festival.domain.Festival
import busanVibe.busan.domain.festival.repository.FestivalRepository
import busanVibe.busan.domain.home.converter.CurationConverter
import busanVibe.busan.domain.home.dto.HomeResponseDTO
import busanVibe.busan.domain.home.enums.CurationType
import busanVibe.busan.domain.place.domain.Place
import busanVibe.busan.domain.place.repository.PlaceRepository
import busanVibe.busan.domain.place.util.PlaceRedisUtil
Expand Down Expand Up @@ -35,31 +36,37 @@ class HomeQueryService(
}

@Transactional(readOnly = true)
fun getCurations(): HomeResponseDTO.CurationList{
fun getCurations(type: CurationType): HomeResponseDTO.CurationList{

// 자원 생성
val placeCount = 1
val festivalCount = 2

// 명소 조회
val placeList: List<Place> = placeRepository.findPlaceImageNotNull() // 이미지 데이터가 있는 Place 목록 조회
val randomPlace: List<Place> = placeList
.takeIf { it.size >= placeCount }
?.shuffled()
?.take(placeCount)
?: throw ExceptionHandler(ErrorStatus.PLACE_NOT_FOUND) // 그 중 랜덤한 항목 가져옴. list 비어있을 시 예외처리


// 축제 조회
val festivalList = festivalRepository.findFestivalImageNotNull() // 이미지 데이터가 있는 Festival 목록 조회
val randomFestival: List<Festival> = festivalList
.takeIf { it.size >= festivalCount }
?.shuffled()
?.take(festivalCount)
?: throw ExceptionHandler(ErrorStatus.FESTIVAL_NOT_FOUND) // 그 중 랜덤한 항목 가져옴. list 비어있을 시 예외처리

// DTO 생성 및 반환
return CurationConverter().toListDto(randomPlace, randomFestival)
val resultCount = 3

// 조건에 따라 조회 후 DTO 반환
return when (type) {
// 명소 조회
CurationType.PLACE -> {
val placeList: List<Place> = placeRepository.findPlaceImageNotNull() // 이미지 데이터가 있는 Place 목록 조회
val randomPlace: List<Place> = placeList
.takeIf { it.size >= resultCount }
?.shuffled()
?.take(resultCount)
?: throw ExceptionHandler(ErrorStatus.PLACE_NOT_FOUND) // 그 중 랜덤한 항목 가져옴. list 비어있을 시 예외처리
CurationConverter().placeListToDto(randomPlace)
}

// 축제 조회
CurationType.FESTIVAL -> {
val festivalList = festivalRepository.findFestivalImageNotNull() // 이미지 데이터가 있는 Festival 목록 조회
val randomFestival: List<Festival> = festivalList
.takeIf { it.size >= resultCount }
?.shuffled()
?.take(resultCount)
?: throw ExceptionHandler(ErrorStatus.FESTIVAL_NOT_FOUND) // 그 중 랜덤한 항목 가져옴. list 비어있을 시 예외처리
CurationConverter().festivalListToDto(randomFestival)
}

}
Comment on lines +39 to +68
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Don’t fail when available items < 3; degrade gracefully (align comment with behavior).

Current logic throws unless size ≥ 3, but the comment says “list empty -> exception.” Prefer returning up to 3 and only error on empty.

-        val resultCount = 3
+        val resultCount = 3
+        val converter = CurationConverter()
@@
-            CurationType.PLACE -> {
-                val placeList: List<Place> = placeRepository.findPlaceImageNotNull() // 이미지 데이터가 있는 Place 목록 조회
-                val randomPlace: List<Place> = placeList
-                    .takeIf { it.size >= resultCount }
-                    ?.shuffled()
-                    ?.take(resultCount)
-                    ?: throw ExceptionHandler(ErrorStatus.PLACE_NOT_FOUND) // 그 중 랜덤한 항목 가져옴. list 비어있을 시 예외처리
-                CurationConverter().placeListToDto(randomPlace)
-            }
+            CurationType.PLACE -> {
+                val placeList: List<Place> = placeRepository.findPlaceImageNotNull() // 이미지 데이터가 있는 Place 목록 조회
+                val randomPlace = placeList.shuffled().take(resultCount)
+                if (randomPlace.isEmpty()) throw ExceptionHandler(ErrorStatus.PLACE_NOT_FOUND) // 리스트 비어있을 때만 예외
+                converter.placeListToDto(randomPlace)
+            }
@@
-            CurationType.FESTIVAL -> {
-                val festivalList = festivalRepository.findFestivalImageNotNull() // 이미지 데이터가 있는 Festival 목록 조회
-                val randomFestival: List<Festival> = festivalList
-                    .takeIf { it.size >= resultCount }
-                    ?.shuffled()
-                    ?.take(resultCount)
-                    ?: throw ExceptionHandler(ErrorStatus.FESTIVAL_NOT_FOUND) // 그 중 랜덤한 항목 가져옴. list 비어있을 시 예외처리
-                CurationConverter().festivalListToDto(randomFestival)
-            }
+            CurationType.FESTIVAL -> {
+                val festivalList = festivalRepository.findFestivalImageNotNull() // 이미지 데이터가 있는 Festival 목록 조회
+                val randomFestival = festivalList.shuffled().take(resultCount)
+                if (randomFestival.isEmpty()) throw ExceptionHandler(ErrorStatus.FESTIVAL_NOT_FOUND) // 리스트 비어있을 때만 예외
+                converter.festivalListToDto(randomFestival)
+            }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
fun getCurations(type: CurationType): HomeResponseDTO.CurationList{
// 자원 생성
val placeCount = 1
val festivalCount = 2
// 명소 조회
val placeList: List<Place> = placeRepository.findPlaceImageNotNull() // 이미지 데이터가 있는 Place 목록 조회
val randomPlace: List<Place> = placeList
.takeIf { it.size >= placeCount }
?.shuffled()
?.take(placeCount)
?: throw ExceptionHandler(ErrorStatus.PLACE_NOT_FOUND) // 그 중 랜덤한 항목 가져옴. list 비어있을 시 예외처리
// 축제 조회
val festivalList = festivalRepository.findFestivalImageNotNull() // 이미지 데이터가 있는 Festival 목록 조회
val randomFestival: List<Festival> = festivalList
.takeIf { it.size >= festivalCount }
?.shuffled()
?.take(festivalCount)
?: throw ExceptionHandler(ErrorStatus.FESTIVAL_NOT_FOUND) // 그 중 랜덤한 항목 가져옴. list 비어있을 시 예외처리
// DTO 생성 및 반환
return CurationConverter().toListDto(randomPlace, randomFestival)
val resultCount = 3
// 조건에 따라 조회 후 DTO 반환
return when (type) {
// 명소 조회
CurationType.PLACE -> {
val placeList: List<Place> = placeRepository.findPlaceImageNotNull() // 이미지 데이터가 있는 Place 목록 조회
val randomPlace: List<Place> = placeList
.takeIf { it.size >= resultCount }
?.shuffled()
?.take(resultCount)
?: throw ExceptionHandler(ErrorStatus.PLACE_NOT_FOUND) // 그 중 랜덤한 항목 가져옴. list 비어있을 시 예외처리
CurationConverter().placeListToDto(randomPlace)
}
// 축제 조회
CurationType.FESTIVAL -> {
val festivalList = festivalRepository.findFestivalImageNotNull() // 이미지 데이터가 있는 Festival 목록 조회
val randomFestival: List<Festival> = festivalList
.takeIf { it.size >= resultCount }
?.shuffled()
?.take(resultCount)
?: throw ExceptionHandler(ErrorStatus.FESTIVAL_NOT_FOUND) // 그 중 랜덤한 항목 가져옴. list 비어있을 시 예외처리
CurationConverter().festivalListToDto(randomFestival)
}
}
fun getCurations(type: CurationType): HomeResponseDTO.CurationList{
// 자원 생성
val resultCount = 3
val converter = CurationConverter()
// 조건에 따라 조회 후 DTO 반환
return when (type) {
// 명소 조회
CurationType.PLACE -> {
val placeList: List<Place> = placeRepository.findPlaceImageNotNull() // 이미지 데이터가 있는 Place 목록 조회
val randomPlace = placeList.shuffled().take(resultCount)
if (randomPlace.isEmpty()) throw ExceptionHandler(ErrorStatus.PLACE_NOT_FOUND) // 리스트 비어있을 때만 예외
converter.placeListToDto(randomPlace)
}
// 축제 조회
CurationType.FESTIVAL -> {
val festivalList = festivalRepository.findFestivalImageNotNull() // 이미지 데이터가 있는 Festival 목록 조회
val randomFestival = festivalList.shuffled().take(resultCount)
if (randomFestival.isEmpty()) throw ExceptionHandler(ErrorStatus.FESTIVAL_NOT_FOUND) // 리스트 비어있을 때만 예외
converter.festivalListToDto(randomFestival)
}
}
}
🤖 Prompt for AI Agents
In src/main/kotlin/busanVibe/busan/domain/home/service/HomeQueryService.kt
around lines 39 to 68, the current code throws if the list size is less than 3
but the comment implies only empty lists should error; change the logic so that
you only throw ExceptionHandler(ErrorStatus.*_NOT_FOUND) when the repository
result is empty, otherwise shuffle and take up to resultCount (i.e.,
take(resultCount) on the shuffled list regardless of size), and update the
inline comments to state "return up to 3 random items; throw only if list is
empty."


}

// 가장 붐비는 곳 조회 하여 List<DTO> 반환 - 5개
Expand Down