Skip to content

Commit 60c1efa

Browse files
authored
Merge pull request #28 from Nexters/feature/27-update-resort-dates-and-status
[#27] 스키장 개장일/폐장일 업데이트 API 추가 및 운영 상태 업데이트 Batch 추가 및 조회 필드 추가
2 parents 45da12b + 4dc9292 commit 60c1efa

File tree

10 files changed

+216
-7
lines changed

10 files changed

+216
-7
lines changed
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package nexters.weski.batch
2+
3+
import io.swagger.v3.oas.annotations.Operation
4+
import io.swagger.v3.oas.annotations.media.Content
5+
import io.swagger.v3.oas.annotations.media.Schema
6+
import io.swagger.v3.oas.annotations.tags.Tag
7+
import nexters.weski.ski_resort.SkiResortService
8+
import org.springframework.web.bind.annotation.PostMapping
9+
import org.springframework.web.bind.annotation.RequestBody
10+
import org.springframework.web.bind.annotation.RestController
11+
12+
13+
@Tag(name = "스키장 개장일/폐장일 업데이트 API", description = "스키장 개장일/폐장일을 업데이트")
14+
@RestController
15+
class ResortBatchController(
16+
private val resortService: SkiResortService
17+
) {
18+
@Operation(
19+
summary = "스키장 개장일/폐장일 업데이트 API",
20+
description = """
21+
스키장 개장일을 업데이트하면 해당 스키장의 개장일이 변경됩니다.
22+
date : OPENING_DATE, CLOSING_DATE 중 하나를 선택합니다.
23+
resortId는 다음과 같습니다.
24+
1, 지산 리조트
25+
2, 곤지암 스키장
26+
3, 비발디파크
27+
4, 엘리시안 강촌
28+
5, 웰리힐리파크
29+
6, 휘닉스파크
30+
7, 하이원 스키장
31+
8, 용평스키장 모나
32+
9, 무주덕유산
33+
10, 에덴벨리(양산)
34+
11, 오투리조트
35+
"""
36+
)
37+
@PostMapping("/batch/resort-date")
38+
fun updateResortDate(
39+
@RequestBody
40+
@io.swagger.v3.oas.annotations.parameters.RequestBody(
41+
description = "스키장 개장일/폐장일 업데이트 요청",
42+
required = true,
43+
content = [Content(
44+
mediaType = "application/json",
45+
schema = Schema(implementation = ResortDateUpdateRequest::class)
46+
)]
47+
)
48+
request: ResortDateUpdateRequest
49+
) {
50+
resortService.updateResortDate(
51+
resortId = request.resortId,
52+
dateType = request.dateType,
53+
date = request.date
54+
)
55+
}
56+
57+
@Operation(
58+
summary = "스키장 운영상태 업데이트",
59+
description = """
60+
스키장 운영상태를 업데이트하면 해당 스키장의 개장일과 폐장일을 기준으로 운영상태가 변경됩니다.
61+
스키장 운영상태는 다음과 같습니다.
62+
- 예정
63+
- 운영중
64+
- 운영종료
65+
"""
66+
)
67+
@PostMapping("/batch/resort-status")
68+
fun updateResortStatus() {
69+
resortService.updateSkiResortStatus()
70+
}
71+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package nexters.weski.batch
2+
3+
import io.swagger.v3.oas.annotations.media.Schema
4+
import java.time.LocalDate
5+
6+
class ResortDateUpdateRequest (
7+
@Schema(
8+
description = "스키장 ID",
9+
example = "1"
10+
)
11+
val resortId: Long,
12+
13+
@Schema(
14+
description = "날짜 타입 (OPENING_DATE: 개장일, CLOSING_DATE: 폐장일)",
15+
example = "OPENING_DATE"
16+
)
17+
val dateType: DateType,
18+
19+
@Schema(
20+
description = "날짜 (yyyy-MM-dd 형식)",
21+
example = "2024-11-30"
22+
)
23+
val date: LocalDate
24+
)
25+
26+
enum class DateType {
27+
@Schema(description = "개장일")
28+
OPENING_DATE,
29+
30+
@Schema(description = "폐장일")
31+
CLOSING_DATE
32+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package nexters.weski.batch
2+
3+
import nexters.weski.ski_resort.SkiResortService
4+
import org.springframework.scheduling.annotation.Scheduled
5+
import org.springframework.stereotype.Component
6+
7+
@Component
8+
class ResortStatusUpdateScheduler(
9+
private val skiResortService: SkiResortService
10+
) {
11+
@Scheduled(cron = "15 0 0 * * ?")
12+
fun scheduleResortStatusUpdate() {
13+
skiResortService.updateSkiResortStatus()
14+
}
15+
}

src/main/kotlin/nexters/weski/common/config/SwaggerConfig.kt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package nexters.weski.common.config
22

33
import io.swagger.v3.oas.models.OpenAPI
44
import io.swagger.v3.oas.models.info.Info
5+
import org.springdoc.core.models.GroupedOpenApi
56
import org.springframework.context.annotation.Bean
67
import org.springframework.context.annotation.Configuration
78
import org.springframework.web.filter.ForwardedHeaderFilter
@@ -24,6 +25,22 @@ class SwaggerConfig {
2425
)
2526
}
2627

28+
@Bean
29+
fun userApi(): GroupedOpenApi {
30+
return GroupedOpenApi.builder()
31+
.group("API for WE-SKI Client")
32+
.pathsToMatch("/api/**")
33+
.build()
34+
}
35+
36+
@Bean
37+
fun productApi(): GroupedOpenApi {
38+
return GroupedOpenApi.builder()
39+
.group("BATCH for ADMIN")
40+
.pathsToMatch("/batch/**")
41+
.build()
42+
}
43+
2744
@Bean
2845
fun forwardedHeaderFilter(): ForwardedHeaderFilter {
2946
return ForwardedHeaderFilter()

src/main/kotlin/nexters/weski/ski_resort/SkiResortResponseDto.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ data class SkiResortResponseDto(
1111
val resortId: Long,
1212
val name: String,
1313
val status: String,
14+
val openingDate: String,
15+
val closingDate: String,
1416
val openSlopes: Int,
1517
val currentWeather: SimpleCurrentWeatherDto,
1618
val weeklyWeather: List<WeeklyWeatherDto>
@@ -25,6 +27,8 @@ data class SkiResortResponseDto(
2527
resortId = skiResort.resortId,
2628
name = skiResort.name,
2729
status = skiResort.status.name,
30+
openingDate = skiResort.openingDate?.toString() ?: "미정",
31+
closingDate = skiResort.closingDate?.toString() ?: "미정",
2832
openSlopes = skiResort.openSlopes,
2933
currentWeather = currentWeather?.let {
3034
SimpleCurrentWeatherDto(

src/main/kotlin/nexters/weski/ski_resort/SkiResortService.kt

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package nexters.weski.ski_resort
22

3+
import nexters.weski.batch.DateType
34
import nexters.weski.weather.CurrentWeatherRepository
45
import nexters.weski.weather.DailyWeatherRepository
56
import org.springframework.stereotype.Service
7+
import java.time.LocalDate
68

79
@Service
810
class SkiResortService(
@@ -19,4 +21,36 @@ class SkiResortService(
1921
SkiResortResponseDto.fromEntity(skiResort, currentWeather, weeklyWeather)
2022
}
2123
}
24+
25+
fun updateResortDate(resortId: Long, dateType: DateType, date: LocalDate) {
26+
val skiResort = skiResortRepository.findById(resortId)
27+
.orElseThrow { IllegalArgumentException("해당 ID의 스키장이 존재하지 않습니다.") }
28+
29+
val updatedSkiResort = when (dateType) {
30+
DateType.OPENING_DATE -> skiResort.copy(openingDate = date)
31+
DateType.CLOSING_DATE -> skiResort.copy(closingDate = date)
32+
}
33+
34+
skiResortRepository.save(updatedSkiResort)
35+
}
36+
37+
fun updateSkiResortStatus() {
38+
val skiResorts = skiResortRepository.findAll()
39+
val today = LocalDate.now()
40+
41+
skiResorts.forEach { skiResort ->
42+
val openingDate = skiResort.openingDate
43+
val closingDate = skiResort.closingDate
44+
45+
val newStatus = when {
46+
today.isBefore(openingDate) -> ResortStatus.예정
47+
closingDate != null && today.isAfter(closingDate) -> ResortStatus.운영종료
48+
else -> ResortStatus.운영중
49+
}
50+
51+
val updatedSkiResort = skiResort.copy(status = newStatus)
52+
skiResortRepository.save(updatedSkiResort)
53+
}
54+
}
55+
2256
}

src/test/kotlin/nexters/weski/ski_resort/SkiResortControllerTest.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ class SkiResortControllerTest @Autowired constructor(
4343
)
4444
// Given
4545
val skiResorts = listOf(
46-
SkiResortResponseDto(1, "스키장 A", ResortStatus.운영중.name, 3, currentWeather, weeklyWeather),
47-
SkiResortResponseDto(2, "스키장 B", ResortStatus.운영중.name, 4, currentWeather, weeklyWeather),
46+
SkiResortResponseDto(1, "스키장 A", ResortStatus.운영중.name, "미정", "미정", 3, currentWeather, weeklyWeather),
47+
SkiResortResponseDto(2, "스키장 B", ResortStatus.운영중.name, "미정", "미정", 4, currentWeather, weeklyWeather),
4848
)
4949
every { skiResortService.getAllSkiResortsAndWeather() } returns skiResorts
5050

src/test/kotlin/nexters/weski/ski_resort/SkiResortServiceTest.kt

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,34 @@ class SkiResortServiceTest {
2222
fun `getAllSkiResorts should return list of SkiResortDto`() {
2323
// Given
2424
val skiResorts = listOf(
25-
SkiResort(1, "스키장 A", ResortStatus.운영중, null, null, 5, 10),
26-
SkiResort(2, "스키장 B", ResortStatus.예정, null, null, 0, 8)
25+
SkiResort(
26+
resortId = 1,
27+
name = "스키장 A",
28+
status = ResortStatus.운영중,
29+
openingDate = null,
30+
closingDate = null,
31+
openSlopes = 3,
32+
totalSlopes = 8,
33+
xCoordinate = "12.0",
34+
yCoordinate = "34.0",
35+
detailedAreaCode = "11D20201",
36+
broadAreaCode = "11D20000"
37+
),
38+
SkiResort(
39+
resortId = 2,
40+
name = "스키장 B",
41+
status = ResortStatus.운영중,
42+
openingDate = null,
43+
closingDate = null,
44+
openSlopes = 3,
45+
totalSlopes = 8,
46+
xCoordinate = "12.0",
47+
yCoordinate = "34.0",
48+
detailedAreaCode = "11D20201",
49+
broadAreaCode = "11D20000"
50+
)
2751
)
28-
every { skiResortRepository.findAll() } returns skiResorts
52+
every { skiResortRepository.findAllByOrderByOpeningDateAsc() } returns skiResorts
2953
every { currentWeatherRepository.findBySkiResortResortId(any()) } returns null
3054
every { dailyWeatherRepository.findAllBySkiResortResortId(any()) } returns emptyList()
3155

src/test/kotlin/nexters/weski/snow_maker/SnowMakerServiceTest.kt

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,19 @@ class SnowMakerServiceTest {
3636
// Given
3737
val resortId = 1L
3838
val isPositive = true
39-
val skiResort = SkiResort(resortId, "스키장 A", ResortStatus.운영중, null, null, 5, 10)
39+
val skiResort = SkiResort(
40+
resortId = 1,
41+
name = "스키장 A",
42+
status = ResortStatus.운영중,
43+
openingDate = null,
44+
closingDate = null,
45+
openSlopes = 3,
46+
totalSlopes = 8,
47+
xCoordinate = "12.0",
48+
yCoordinate = "34.0",
49+
detailedAreaCode = "11D20201",
50+
broadAreaCode = "11D20000"
51+
)
4052
val snowMakerVote = SnowMakerVote(
4153
isPositive = isPositive,
4254
skiResort = skiResort

src/test/kotlin/nexters/weski/weather/WeatherServiceTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class WeatherServiceTest {
2929
resortId, -5, -2, -8, -10, "눈이 내리고 있습니다.", "", skiResort
3030
)
3131
every { currentWeatherRepository.findBySkiResortResortId(resortId) } returns currentWeather
32-
every { hourlyWeatherRepository.findAll() } returns listOf()
32+
every { hourlyWeatherRepository.findBySkiResortResortId(resortId) } returns listOf()
3333
every { dailyWeatherRepository.findAllBySkiResortResortId(resortId) } returns listOf()
3434

3535
// When

0 commit comments

Comments
 (0)