generated from pricelees/issue-pr-template
feat: 새로운 테마 API 정의 및 컨트롤러 구현
This commit is contained in:
parent
6b2f8d9488
commit
7fd6b030dd
56
src/main/kotlin/roomescape/theme/docs/ThemeApiV2.kt
Normal file
56
src/main/kotlin/roomescape/theme/docs/ThemeApiV2.kt
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
package roomescape.theme.docs
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.Operation
|
||||||
|
import io.swagger.v3.oas.annotations.responses.ApiResponse
|
||||||
|
import io.swagger.v3.oas.annotations.responses.ApiResponses
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag
|
||||||
|
import jakarta.validation.Valid
|
||||||
|
import org.springframework.http.ResponseEntity
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody
|
||||||
|
import roomescape.auth.web.support.Admin
|
||||||
|
import roomescape.auth.web.support.LoginRequired
|
||||||
|
import roomescape.common.dto.response.CommonApiResponse
|
||||||
|
import roomescape.theme.web.AdminThemeDetailRetrieveResponse
|
||||||
|
import roomescape.theme.web.AdminThemeSummaryRetrieveListResponse
|
||||||
|
import roomescape.theme.web.ThemeCreateRequestV2
|
||||||
|
import roomescape.theme.web.ThemeCreateResponseV2
|
||||||
|
import roomescape.theme.web.ThemeUpdateRequest
|
||||||
|
import roomescape.theme.web.ThemeRetrieveListResponseV2
|
||||||
|
|
||||||
|
@Tag(name = "5. 관리자 테마 API", description = "관리자 페이지에서 테마를 조회 / 추가 / 삭제할 때 사용합니다.")
|
||||||
|
interface ThemeAPIV2 {
|
||||||
|
|
||||||
|
@Admin
|
||||||
|
@Operation(summary = "모든 테마 조회", description = "관리자 페이지에서 요약된 테마 목록을 조회합니다.", tags = ["관리자 로그인이 필요한 API"])
|
||||||
|
@ApiResponses(ApiResponse(responseCode = "200", description = "성공", useReturnTypeSchema = true))
|
||||||
|
fun findAdminThemes(): ResponseEntity<CommonApiResponse<AdminThemeSummaryRetrieveListResponse>>
|
||||||
|
|
||||||
|
@Admin
|
||||||
|
@Operation(summary = "테마 상세 조회", description = "해당 테마의 상세 정보를 조회합니다.", tags = ["관리자 로그인이 필요한 API"])
|
||||||
|
@ApiResponses(ApiResponse(responseCode = "200", description = "성공", useReturnTypeSchema = true))
|
||||||
|
fun findAdminThemeDetail(@PathVariable("id") id: Long): ResponseEntity<CommonApiResponse<AdminThemeDetailRetrieveResponse>>
|
||||||
|
|
||||||
|
@Admin
|
||||||
|
@Operation(summary = "테마 추가", tags = ["관리자 로그인이 필요한 API"])
|
||||||
|
@ApiResponses(ApiResponse(responseCode = "201", description = "성공", useReturnTypeSchema = true))
|
||||||
|
fun createTheme(@Valid @RequestBody themeCreateRequestV2: ThemeCreateRequestV2): ResponseEntity<CommonApiResponse<ThemeCreateResponseV2>>
|
||||||
|
|
||||||
|
@Admin
|
||||||
|
@Operation(summary = "테마 삭제", tags = ["관리자 로그인이 필요한 API"])
|
||||||
|
@ApiResponses(ApiResponse(responseCode = "204", description = "성공", useReturnTypeSchema = true))
|
||||||
|
fun deleteTheme(@PathVariable id: Long): ResponseEntity<CommonApiResponse<Unit>>
|
||||||
|
|
||||||
|
@Admin
|
||||||
|
@Operation(summary = "테마 수정", tags = ["관리자 로그인이 필요한 API"])
|
||||||
|
@ApiResponses(ApiResponse(responseCode = "200", description = "성공", useReturnTypeSchema = true))
|
||||||
|
fun updateTheme(
|
||||||
|
@PathVariable id: Long,
|
||||||
|
@Valid @RequestBody themeUpdateRequest: ThemeUpdateRequest
|
||||||
|
): ResponseEntity<CommonApiResponse<Unit>>
|
||||||
|
|
||||||
|
@LoginRequired
|
||||||
|
@Operation(summary = "예약 페이지에서 모든 테마 조회", description = "모든 테마를 조회합니다.", tags = ["로그인이 필요한 API"])
|
||||||
|
@ApiResponses(ApiResponse(responseCode = "200", description = "성공", useReturnTypeSchema = true))
|
||||||
|
fun findUserThemes(): ResponseEntity<CommonApiResponse<ThemeRetrieveListResponseV2>>
|
||||||
|
}
|
||||||
60
src/main/kotlin/roomescape/theme/web/ThemeControllerV2.kt
Normal file
60
src/main/kotlin/roomescape/theme/web/ThemeControllerV2.kt
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
package roomescape.theme.web
|
||||||
|
|
||||||
|
import org.springframework.http.ResponseEntity
|
||||||
|
import org.springframework.web.bind.annotation.*
|
||||||
|
import roomescape.common.dto.response.CommonApiResponse
|
||||||
|
import roomescape.theme.business.ThemeServiceV2
|
||||||
|
import roomescape.theme.docs.ThemeAPIV2
|
||||||
|
import java.net.URI
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
class ThemeControllerV2(
|
||||||
|
private val themeService: ThemeServiceV2,
|
||||||
|
) : ThemeAPIV2 {
|
||||||
|
|
||||||
|
@GetMapping("/v2/themes")
|
||||||
|
override fun findUserThemes(): ResponseEntity<CommonApiResponse<ThemeRetrieveListResponseV2>> {
|
||||||
|
val response = themeService.findThemesForReservation()
|
||||||
|
|
||||||
|
return ResponseEntity.ok(CommonApiResponse(response))
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/admin/themes")
|
||||||
|
override fun findAdminThemes(): ResponseEntity<CommonApiResponse<AdminThemeSummaryRetrieveListResponse>> {
|
||||||
|
val response = themeService.findAdminThemes()
|
||||||
|
|
||||||
|
return ResponseEntity.ok(CommonApiResponse(response))
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/admin/themes/{id}")
|
||||||
|
override fun findAdminThemeDetail(@PathVariable id: Long): ResponseEntity<CommonApiResponse<AdminThemeDetailRetrieveResponse>> {
|
||||||
|
val response = themeService.findAdminThemeDetail(id)
|
||||||
|
|
||||||
|
return ResponseEntity.ok(CommonApiResponse(response))
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/admin/themes")
|
||||||
|
override fun createTheme(themeCreateRequestV2: ThemeCreateRequestV2): ResponseEntity<CommonApiResponse<ThemeCreateResponseV2>> {
|
||||||
|
val response = themeService.createTheme(themeCreateRequestV2)
|
||||||
|
|
||||||
|
return ResponseEntity.created(URI.create("/admin/themes/${response.id}"))
|
||||||
|
.body(CommonApiResponse(response))
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/admin/themes/{id}")
|
||||||
|
override fun deleteTheme(@PathVariable id: Long): ResponseEntity<CommonApiResponse<Unit>> {
|
||||||
|
themeService.deleteTheme(id)
|
||||||
|
|
||||||
|
return ResponseEntity.noContent().build()
|
||||||
|
}
|
||||||
|
|
||||||
|
@PatchMapping("/admin/themes/{id}")
|
||||||
|
override fun updateTheme(
|
||||||
|
@PathVariable id: Long,
|
||||||
|
themeUpdateRequest: ThemeUpdateRequest
|
||||||
|
): ResponseEntity<CommonApiResponse<Unit>> {
|
||||||
|
themeService.updateTheme(id, themeUpdateRequest)
|
||||||
|
|
||||||
|
return ResponseEntity.ok().build()
|
||||||
|
}
|
||||||
|
}
|
||||||
151
src/main/kotlin/roomescape/theme/web/ThemeDtoV2.kt
Normal file
151
src/main/kotlin/roomescape/theme/web/ThemeDtoV2.kt
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
package roomescape.theme.web
|
||||||
|
|
||||||
|
import roomescape.theme.infrastructure.persistence.v2.Difficulty
|
||||||
|
import roomescape.theme.infrastructure.persistence.v2.ThemeEntityV2
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
|
data class ThemeCreateRequestV2(
|
||||||
|
val name: String,
|
||||||
|
val description: String,
|
||||||
|
val thumbnailUrl: String,
|
||||||
|
val difficulty: Difficulty,
|
||||||
|
val price: Int,
|
||||||
|
val minParticipants: Short,
|
||||||
|
val maxParticipants: Short,
|
||||||
|
val availableMinutes: Short,
|
||||||
|
val expectedMinutesFrom: Short,
|
||||||
|
val expectedMinutesTo: Short,
|
||||||
|
val isOpen: Boolean
|
||||||
|
)
|
||||||
|
|
||||||
|
data class ThemeCreateResponseV2(
|
||||||
|
val id: Long
|
||||||
|
)
|
||||||
|
|
||||||
|
fun ThemeCreateRequestV2.toEntity(id: Long) = ThemeEntityV2(
|
||||||
|
id = id,
|
||||||
|
name = this.name,
|
||||||
|
description = this.description,
|
||||||
|
thumbnailUrl = this.thumbnailUrl,
|
||||||
|
difficulty = this.difficulty,
|
||||||
|
price = this.price,
|
||||||
|
minParticipants = this.minParticipants,
|
||||||
|
maxParticipants = this.maxParticipants,
|
||||||
|
availableMinutes = this.availableMinutes,
|
||||||
|
expectedMinutesFrom = this.expectedMinutesFrom,
|
||||||
|
expectedMinutesTo = this.expectedMinutesTo,
|
||||||
|
isOpen = this.isOpen
|
||||||
|
)
|
||||||
|
|
||||||
|
data class ThemeUpdateRequest(
|
||||||
|
val name: String? = null,
|
||||||
|
val description: String? = null,
|
||||||
|
val thumbnailUrl: String? = null,
|
||||||
|
val difficulty: Difficulty? = null,
|
||||||
|
val price: Int? = null,
|
||||||
|
val minParticipants: Short? = null,
|
||||||
|
val maxParticipants: Short? = null,
|
||||||
|
val availableMinutes: Short? = null,
|
||||||
|
val expectedMinutesFrom: Short? = null,
|
||||||
|
val expectedMinutesTo: Short? = null,
|
||||||
|
val isOpen: Boolean? = null,
|
||||||
|
)
|
||||||
|
|
||||||
|
data class AdminThemeSummaryRetrieveResponse(
|
||||||
|
val id: Long,
|
||||||
|
val name: String,
|
||||||
|
val difficulty: Difficulty,
|
||||||
|
val price: Int,
|
||||||
|
val isOpen: Boolean
|
||||||
|
)
|
||||||
|
|
||||||
|
fun ThemeEntityV2.toAdminThemeSummaryResponse() = AdminThemeSummaryRetrieveResponse(
|
||||||
|
id = this.id,
|
||||||
|
name = this.name,
|
||||||
|
difficulty = this.difficulty,
|
||||||
|
price = this.price,
|
||||||
|
isOpen = this.isOpen
|
||||||
|
)
|
||||||
|
|
||||||
|
data class AdminThemeSummaryRetrieveListResponse(
|
||||||
|
val themes: List<AdminThemeSummaryRetrieveResponse>
|
||||||
|
)
|
||||||
|
|
||||||
|
fun List<ThemeEntityV2>.toAdminThemeSummaryListResponse() = AdminThemeSummaryRetrieveListResponse(
|
||||||
|
themes = this.map { it.toAdminThemeSummaryResponse() }
|
||||||
|
)
|
||||||
|
|
||||||
|
data class AdminThemeDetailRetrieveResponse(
|
||||||
|
val id: Long,
|
||||||
|
val name: String,
|
||||||
|
val description: String,
|
||||||
|
val thumbnailUrl: String,
|
||||||
|
val difficulty: Difficulty,
|
||||||
|
val price: Int,
|
||||||
|
val minParticipants: Short,
|
||||||
|
val maxParticipants: Short,
|
||||||
|
val availableMinutes: Short,
|
||||||
|
val expectedMinutesFrom: Short,
|
||||||
|
val expectedMinutesTo: Short,
|
||||||
|
val isOpen: Boolean,
|
||||||
|
val createdAt: LocalDateTime,
|
||||||
|
val createdBy: String,
|
||||||
|
val updatedAt: LocalDateTime,
|
||||||
|
val updatedBy: String,
|
||||||
|
)
|
||||||
|
|
||||||
|
fun ThemeEntityV2.toAdminThemeDetailResponse(createUserName: String, updateUserName: String) =
|
||||||
|
AdminThemeDetailRetrieveResponse(
|
||||||
|
id = this.id,
|
||||||
|
name = this.name,
|
||||||
|
description = this.description,
|
||||||
|
thumbnailUrl = this.thumbnailUrl,
|
||||||
|
difficulty = this.difficulty,
|
||||||
|
price = this.price,
|
||||||
|
minParticipants = this.minParticipants,
|
||||||
|
maxParticipants = this.maxParticipants,
|
||||||
|
availableMinutes = this.availableMinutes,
|
||||||
|
expectedMinutesFrom = this.expectedMinutesFrom,
|
||||||
|
expectedMinutesTo = this.expectedMinutesTo,
|
||||||
|
isOpen = this.isOpen,
|
||||||
|
createdAt = this.createdAt,
|
||||||
|
createdBy = createUserName,
|
||||||
|
updatedAt = this.updatedAt,
|
||||||
|
updatedBy = updateUserName
|
||||||
|
)
|
||||||
|
|
||||||
|
data class ThemeRetrieveResponseV2(
|
||||||
|
val id: Long,
|
||||||
|
val name: String,
|
||||||
|
val thumbnailUrl: String,
|
||||||
|
val description: String,
|
||||||
|
val difficulty: Difficulty,
|
||||||
|
val price: Int,
|
||||||
|
val minParticipants: Short,
|
||||||
|
val maxParticipants: Short,
|
||||||
|
val availableMinutes: Short,
|
||||||
|
val expectedMinutesFrom: Short,
|
||||||
|
val expectedMinutesTo: Short
|
||||||
|
)
|
||||||
|
|
||||||
|
fun ThemeEntityV2.toRetrieveResponse() = ThemeRetrieveResponseV2(
|
||||||
|
id = this.id,
|
||||||
|
name = this.name,
|
||||||
|
thumbnailUrl = this.thumbnailUrl,
|
||||||
|
description = this.description,
|
||||||
|
difficulty = this.difficulty,
|
||||||
|
price = this.price,
|
||||||
|
minParticipants = this.minParticipants,
|
||||||
|
maxParticipants = this.maxParticipants,
|
||||||
|
availableMinutes = this.availableMinutes,
|
||||||
|
expectedMinutesFrom = this.expectedMinutesFrom,
|
||||||
|
expectedMinutesTo = this.expectedMinutesTo
|
||||||
|
)
|
||||||
|
|
||||||
|
data class ThemeRetrieveListResponseV2(
|
||||||
|
val themes: List<ThemeRetrieveResponseV2>
|
||||||
|
)
|
||||||
|
|
||||||
|
fun List<ThemeEntityV2>.toRetrieveListResponse() = ThemeRetrieveListResponseV2(
|
||||||
|
themes = this.map { it.toRetrieveResponse() }
|
||||||
|
)
|
||||||
Loading…
x
Reference in New Issue
Block a user