feat(event): v2 일반 이벤트 상세 조회를 추가한다

This commit is contained in:
2026-10-29 11:02:45 +09:00
parent 8345cc25ad
commit b758a81834
4 changed files with 426 additions and 0 deletions
@@ -188,6 +188,7 @@ class SecurityConfig(
.antMatchers("/live/recommend/channel").permitAll()
.antMatchers(HttpMethod.GET, "/live/room").permitAll()
.antMatchers(HttpMethod.GET, "/event").permitAll()
.antMatchers(HttpMethod.GET, "/api/v2/events/*").permitAll()
.antMatchers(HttpMethod.GET, "/live/recommend").permitAll()
.antMatchers("/ad-tracking/app-launch").permitAll()
.antMatchers(HttpMethod.GET, "/notice/latest").permitAll()
@@ -0,0 +1,20 @@
package kr.co.vividnext.sodalive.v2.api.event.adapter.`in`.web
import kr.co.vividnext.sodalive.common.ApiResponse
import kr.co.vividnext.sodalive.member.Member
import kr.co.vividnext.sodalive.v2.api.event.application.EventDetailService
import org.springframework.security.core.annotation.AuthenticationPrincipal
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
@RestController
@RequestMapping("/api/v2/events")
class EventDetailController(private val service: EventDetailService) {
@GetMapping("/{id}")
fun getEvent(
@PathVariable id: Long,
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
) = ApiResponse.ok(service.getEvent(id, member))
}
@@ -0,0 +1,55 @@
package kr.co.vividnext.sodalive.v2.api.event.application
import kr.co.vividnext.sodalive.common.SodaException
import kr.co.vividnext.sodalive.event.EventItem
import kr.co.vividnext.sodalive.event.EventRepository
import kr.co.vividnext.sodalive.i18n.Lang
import kr.co.vividnext.sodalive.member.Member
import kr.co.vividnext.sodalive.member.MemberRole
import kr.co.vividnext.sodalive.member.auth.AuthRepository
import kr.co.vividnext.sodalive.member.contentpreference.MemberContentPreferenceService
import org.springframework.beans.factory.annotation.Value
import org.springframework.data.repository.findByIdOrNull
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import java.time.LocalDateTime
@Service
class EventDetailService(
private val repository: EventRepository,
private val authRepository: AuthRepository,
private val memberContentPreferenceService: MemberContentPreferenceService,
@Value("\${cloud.aws.cloud-front.host}")
private val cloudFrontHost: String
) {
@Transactional(readOnly = true)
fun getEvent(id: Long, member: Member?): EventItem {
if (id <= 0) throw SodaException(messageKey = "common.error.invalid_request")
val event = repository.findByIdOrNull(id)
?: throw SodaException(messageKey = "common.error.invalid_request")
val now = LocalDateTime.now()
val lang = if (memberContentPreferenceService.resolveCountryCode(member) == "JP") Lang.JA else Lang.KO
if (!event.isActive || event.startDate > now || event.endDate < now || event.lang != lang) {
throw SodaException(messageKey = "common.error.invalid_request")
}
if (member?.role != MemberRole.ADMIN) {
val isAdult = member?.id?.let { authRepository.getAuthIdByMemberId(it) != null } ?: false
if (event.isAdult != null && event.isAdult != isAdult) {
throw SodaException(messageKey = "common.error.invalid_request")
}
}
return EventItem(
id = id,
thumbnailImageUrl = imageUrl(event.thumbnailImage),
detailImageUrl = event.detailImage?.let { imageUrl(it) },
popupImageUrl = event.popupImage?.let { imageUrl(it) },
link = event.link
)
}
private fun imageUrl(image: String): String = if (image.startsWith("https://")) image else "$cloudFrontHost/$image"
}