From eb7461e9b60be70bfbd852be75b694cf61bc64ba Mon Sep 17 00:00:00 2001 From: pricelees Date: Fri, 18 Jul 2025 05:01:31 +0900 Subject: [PATCH] =?UTF-8?q?refactor:=20ReservationController=20=EC=BD=94?= =?UTF-8?q?=ED=8B=80=EB=A6=B0=20=EC=A0=84=ED=99=98=20=EB=B0=8F=20Swagger?= =?UTF-8?q?=20=EC=BD=94=EB=93=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../reservation/docs/ReservationAPI.kt | 138 +++++++ .../reservation/web/ReservationController.kt | 372 +++++++----------- 2 files changed, 271 insertions(+), 239 deletions(-) create mode 100644 src/main/java/roomescape/reservation/docs/ReservationAPI.kt diff --git a/src/main/java/roomescape/reservation/docs/ReservationAPI.kt b/src/main/java/roomescape/reservation/docs/ReservationAPI.kt new file mode 100644 index 00000000..05fe2883 --- /dev/null +++ b/src/main/java/roomescape/reservation/docs/ReservationAPI.kt @@ -0,0 +1,138 @@ +package roomescape.reservation.docs + +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.Parameter +import io.swagger.v3.oas.annotations.headers.Header +import io.swagger.v3.oas.annotations.media.Schema +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.HttpHeaders +import org.springframework.http.ResponseEntity +import org.springframework.web.bind.annotation.PathVariable +import org.springframework.web.bind.annotation.RequestBody +import org.springframework.web.bind.annotation.RequestParam +import roomescape.auth.web.support.Admin +import roomescape.auth.web.support.LoginRequired +import roomescape.auth.web.support.MemberId +import roomescape.common.dto.response.CommonApiResponse +import roomescape.reservation.web.* +import java.time.LocalDate + +@Tag(name = "3. 예약 API", description = "예약 및 대기 정보를 추가 / 조회 / 삭제할 때 사용합니다.") +interface ReservationAPI { + + @Admin + @Operation(summary = "모든 예약 정보 조회", tags = ["관리자 로그인이 필요한 API"]) + @ApiResponses(ApiResponse(responseCode = "200", description = "성공", useReturnTypeSchema = true)) + fun getAllReservations(): ResponseEntity> + + @LoginRequired + @Operation(summary = "자신의 예약 및 대기 조회", tags = ["로그인이 필요한 API"]) + @ApiResponses(ApiResponse(responseCode = "200", description = "성공", useReturnTypeSchema = true)) + fun getMemberReservations( + @MemberId @Parameter(hidden = true) memberId: Long + ): ResponseEntity> + + @Admin + @Operation(summary = "관리자의 예약 검색", description = "특정 조건에 해당되는 예약 검색", tags = ["관리자 로그인이 필요한 API"]) + @ApiResponses( + ApiResponse(responseCode = "200", description = "성공", useReturnTypeSchema = true) + ) + fun getReservationBySearching( + @RequestParam(required = false) themeId: Long?, + @RequestParam(required = false) memberId: Long?, + @RequestParam(required = false) dateFrom: LocalDate?, + @RequestParam(required = false) dateTo: LocalDate? + ): ResponseEntity> + + @Admin + @Operation(summary = "관리자의 예약 취소", tags = ["관리자 로그인이 필요한 API"]) + @ApiResponses( + ApiResponse(responseCode = "204", description = "성공"), + ) + fun removeReservation( + @MemberId @Parameter(hidden = true) memberId: Long, + @PathVariable("id") reservationId: Long + ): ResponseEntity> + + @LoginRequired + @Operation(summary = "예약 추가", tags = ["로그인이 필요한 API"]) + @ApiResponses( + ApiResponse( + responseCode = "201", + description = "성공", + useReturnTypeSchema = true, + headers = [Header(name = HttpHeaders.LOCATION, description = "생성된 예약 정보 URL", schema = Schema(example = "/reservations/1"))] + ) + ) + fun saveReservation( + @Valid @RequestBody reservationRequest: ReservationRequest, + @MemberId @Parameter(hidden = true) memberId: Long + ): ResponseEntity> + + @Admin + @Operation(summary = "관리자 예약 추가", tags = ["관리자 로그인이 필요한 API"]) + @ApiResponses( + ApiResponse( + responseCode = "201", + description = "성공", + useReturnTypeSchema = true, + headers = [Header(name = HttpHeaders.LOCATION, description = "생성된 예약 정보 URL", schema = Schema(example = "/reservations/1"))], + ) + ) + fun saveReservationByAdmin( + @Valid @RequestBody adminReservationRequest: AdminReservationRequest, + ): ResponseEntity> + + @Admin + @Operation(summary = "모든 예약 대기 조회", tags = ["관리자 로그인이 필요한 API"]) + @ApiResponses(ApiResponse(responseCode = "200", description = "성공", useReturnTypeSchema = true)) + fun getAllWaiting(): ResponseEntity> + + @LoginRequired + @Operation(summary = "예약 대기 신청", tags = ["로그인이 필요한 API"]) + @ApiResponses( + ApiResponse( + responseCode = "201", + description = "성공", + useReturnTypeSchema = true, + headers = [Header(name = HttpHeaders.LOCATION, description = "생성된 예약 정보 URL", schema = Schema(example = "/reservations/1"))] + ) + ) + fun saveWaiting( + @Valid @RequestBody waitingRequest: WaitingRequest, + @MemberId @Parameter(hidden = true) memberId: Long, + ): ResponseEntity> + + @LoginRequired + @Operation(summary = "예약 대기 취소", tags = ["로그인이 필요한 API"]) + @ApiResponses( + ApiResponse(responseCode = "204", description = "성공"), + ) + fun deleteWaiting( + @MemberId @Parameter(hidden = true) memberId: Long, + @PathVariable("id") @Parameter(description = "예약 ID") reservationId: Long + ): ResponseEntity> + + @Admin + @Operation(summary = "대기 중인 예약 승인", tags = ["관리자 로그인이 필요한 API"]) + @ApiResponses( + ApiResponse(responseCode = "200", description = "성공"), + ) + fun approveWaiting( + @MemberId @Parameter(hidden = true) memberId: Long, + @PathVariable("id") @Parameter(description = "예약 ID") reservationId: Long + ): ResponseEntity> + + @Admin + @Operation(summary = "대기 중인 예약 거절", tags = ["관리자 로그인이 필요한 API"]) + @ApiResponses( + ApiResponse(responseCode = "204", description = "대기 중인 예약 거절 성공"), + ) + fun denyWaiting( + @MemberId @Parameter(hidden = true) memberId: Long, + @PathVariable("id") @Parameter(description = "예약 ID") reservationId: Long + ): ResponseEntity> +} diff --git a/src/main/java/roomescape/reservation/web/ReservationController.kt b/src/main/java/roomescape/reservation/web/ReservationController.kt index 1fe53e0d..4b3d7e98 100644 --- a/src/main/java/roomescape/reservation/web/ReservationController.kt +++ b/src/main/java/roomescape/reservation/web/ReservationController.kt @@ -1,265 +1,159 @@ -package roomescape.reservation.web; +package roomescape.reservation.web -import java.time.LocalDate; - -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.ResponseStatus; -import org.springframework.web.bind.annotation.RestController; - -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.headers.Header; -import io.swagger.v3.oas.annotations.media.Content; -import io.swagger.v3.oas.annotations.media.Schema; -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.servlet.http.HttpServletResponse; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import roomescape.auth.web.support.Admin; -import roomescape.auth.web.support.LoginRequired; -import roomescape.auth.web.support.MemberId; -import roomescape.common.dto.response.RoomescapeApiResponse; -import roomescape.common.dto.response.RoomescapeErrorResponse; -import roomescape.common.exception.RoomescapeException; -import roomescape.payment.infrastructure.client.TossPaymentClient; -import roomescape.payment.web.PaymentApprove; -import roomescape.payment.web.PaymentCancel; -import roomescape.reservation.business.ReservationService; -import roomescape.reservation.business.ReservationWithPaymentService; +import io.swagger.v3.oas.annotations.Parameter +import jakarta.validation.Valid +import org.springframework.http.ResponseEntity +import org.springframework.web.bind.annotation.* +import roomescape.auth.web.support.MemberId +import roomescape.common.dto.response.CommonApiResponse +import roomescape.common.exception.RoomescapeException +import roomescape.payment.infrastructure.client.TossPaymentClient +import roomescape.payment.web.PaymentApprove +import roomescape.payment.web.PaymentCancel +import roomescape.reservation.business.ReservationService +import roomescape.reservation.business.ReservationWithPaymentService +import roomescape.reservation.docs.ReservationAPI +import java.net.URI +import java.time.LocalDate @RestController -@Tag(name = "3. 예약 API", description = "예약 및 대기 정보를 추가 / 조회 / 삭제할 때 사용합니다.") -public class ReservationController { +class ReservationController( + private val reservationWithPaymentService: ReservationWithPaymentService, + private val reservationService: ReservationService, + private val paymentClient: TossPaymentClient +) : ReservationAPI { + @GetMapping("/reservations") + override fun getAllReservations(): ResponseEntity> { + val response: ReservationsResponse = reservationService.findAllReservations() - private final ReservationWithPaymentService reservationWithPaymentService; - private final ReservationService reservationService; - private final TossPaymentClient paymentClient; + return ResponseEntity.ok(CommonApiResponse(response)) + } - public ReservationController(ReservationWithPaymentService reservationWithPaymentService, - ReservationService reservationService, TossPaymentClient paymentClient) { - this.reservationWithPaymentService = reservationWithPaymentService; - this.reservationService = reservationService; - this.paymentClient = paymentClient; - } + @GetMapping("/reservations-mine") + override fun getMemberReservations( + @MemberId @Parameter(hidden = true) memberId: Long + ): ResponseEntity> { + val response: MyReservationsResponse = reservationService.findMemberReservations(memberId) - @Admin - @GetMapping("/reservations") - @ResponseStatus(HttpStatus.OK) - @Operation(summary = "모든 예약 정보 조회", tags = "관리자 로그인이 필요한 API") - @ApiResponses({ - @ApiResponse(responseCode = "200", description = "성공", useReturnTypeSchema = true) - }) - public RoomescapeApiResponse getAllReservations() { - return RoomescapeApiResponse.success(reservationService.findAllReservations()); - } + return ResponseEntity.ok(CommonApiResponse(response)) + } - @LoginRequired - @GetMapping("/reservations-mine") - @ResponseStatus(HttpStatus.OK) - @Operation(summary = "자신의 예약 및 대기 조회", tags = "로그인이 필요한 API") - @ApiResponses({ - @ApiResponse(responseCode = "200", description = "성공", useReturnTypeSchema = true) - }) - public RoomescapeApiResponse getMemberReservations( - @MemberId @Parameter(hidden = true) Long memberId) { - return RoomescapeApiResponse.success(reservationService.findMemberReservations(memberId)); - } + @GetMapping("/reservations/search") + override fun getReservationBySearching( + @RequestParam(required = false) themeId: Long?, + @RequestParam(required = false) memberId: Long?, + @RequestParam(required = false) dateFrom: LocalDate?, + @RequestParam(required = false) dateTo: LocalDate? + ): ResponseEntity> { + val response: ReservationsResponse = reservationService.findFilteredReservations(themeId, memberId, dateFrom, dateTo) - @Admin - @GetMapping("/reservations/search") - @ResponseStatus(HttpStatus.OK) - @Operation(summary = "관리자의 예약 검색", description = "특정 조건에 해당되는 예약 검색", tags = "관리자 로그인이 필요한 API") - @ApiResponses({ - @ApiResponse(responseCode = "200", description = "성공", useReturnTypeSchema = true), - @ApiResponse(responseCode = "400", description = "날짜 범위를 지정할 때, 종료 날짜는 시작 날짜 이전일 수 없습니다.", - content = @Content(schema = @Schema(implementation = RoomescapeErrorResponse.class))) - }) - public RoomescapeApiResponse getReservationBySearching( - @RequestParam(required = false) @Parameter(description = "테마 ID") Long themeId, - @RequestParam(required = false) @Parameter(description = "회원 ID") Long memberId, - @RequestParam(required = false) @Parameter(description = "yyyy-MM-dd 형식으로 입력해주세요", example = "2024-06-10") LocalDate dateFrom, - @RequestParam(required = false) @Parameter(description = "yyyy-MM-dd 형식으로 입력해주세요", example = "2024-06-10") LocalDate dateTo - ) { - return RoomescapeApiResponse.success( - reservationService.findFilteredReservations(themeId, memberId, dateFrom, dateTo)); - } + return ResponseEntity.ok(CommonApiResponse(response)) + } - @Admin - @DeleteMapping("/reservations/{id}") - @ResponseStatus(HttpStatus.NO_CONTENT) - @Operation(summary = "관리자의 예약 취소", tags = "관리자 로그인이 필요한 API") - @ApiResponses({ - @ApiResponse(responseCode = "204", description = "성공"), - @ApiResponse(responseCode = "404", description = "예약 또는 결제 정보를 찾을 수 없습니다.", - content = @Content(schema = @Schema(implementation = RoomescapeErrorResponse.class))), - }) - public RoomescapeApiResponse removeReservation( - @MemberId @Parameter(hidden = true) Long memberId, - @NotNull(message = "reservationId는 null일 수 없습니다.") @PathVariable("id") @Parameter(description = "예약 ID") Long reservationId - ) { + @DeleteMapping("/reservations/{id}") + override fun removeReservation( + @MemberId @Parameter(hidden = true) memberId: Long, + @PathVariable("id") reservationId: Long + ): ResponseEntity> { + if (reservationWithPaymentService.isNotPaidReservation(reservationId)) { + reservationService.removeReservationById(reservationId, memberId) + return ResponseEntity.noContent().build() + } - if (reservationWithPaymentService.isNotPaidReservation(reservationId)) { - reservationService.removeReservationById(reservationId, memberId); - return RoomescapeApiResponse.success(); - } + val paymentCancelRequest = reservationWithPaymentService.removeReservationWithPayment( + reservationId, memberId) + val paymentCancelResponse = paymentClient.cancelPayment(paymentCancelRequest) + reservationWithPaymentService.updateCanceledTime(paymentCancelRequest.paymentKey, + paymentCancelResponse.canceledAt) - PaymentCancel.Request paymentCancelRequest = reservationWithPaymentService.removeReservationWithPayment( - reservationId, memberId); + return ResponseEntity.noContent().build() + } - PaymentCancel.Response paymentCancelResponse = paymentClient.cancelPayment(paymentCancelRequest); + @PostMapping("/reservations") + override fun saveReservation( + @Valid @RequestBody reservationRequest: ReservationRequest, + @MemberId @Parameter(hidden = true) memberId: Long + ): ResponseEntity> { + val paymentRequest: PaymentApprove.Request = reservationRequest.paymentRequest + val paymentResponse: PaymentApprove.Response = paymentClient.confirmPayment(paymentRequest) - reservationWithPaymentService.updateCanceledTime(paymentCancelRequest.paymentKey, - paymentCancelResponse.canceledAt); + try { + val reservationResponse: ReservationResponse = reservationWithPaymentService.addReservationWithPayment( + reservationRequest, + paymentResponse, + memberId + ) + return ResponseEntity.created(URI.create("/reservations/${reservationResponse.id}")) + .body(CommonApiResponse(reservationResponse)) + } catch (e: RoomescapeException) { + val cancelRequest = PaymentCancel.Request(paymentRequest.paymentKey, + paymentRequest.amount, e.message!!) + val paymentCancelResponse = paymentClient.cancelPayment(cancelRequest) + reservationWithPaymentService.saveCanceledPayment(paymentCancelResponse, paymentResponse.approvedAt, + paymentRequest.paymentKey) + throw e + } + } - return RoomescapeApiResponse.success(); - } + @PostMapping("/reservations/admin") + override fun saveReservationByAdmin( + @Valid @RequestBody adminReservationRequest: AdminReservationRequest + ): ResponseEntity> { + val response: ReservationResponse = + reservationService.addReservationByAdmin(adminReservationRequest) - @LoginRequired - @PostMapping("/reservations") - @ResponseStatus(HttpStatus.CREATED) - @Operation(summary = "예약 추가", tags = "로그인이 필요한 API") - @ApiResponses({ - @ApiResponse(responseCode = "201", description = "성공", useReturnTypeSchema = true, - headers = @Header(name = HttpHeaders.LOCATION, description = "생성된 예약 정보 URL", schema = @Schema(example = "/reservations/1"))) - }) - public RoomescapeApiResponse saveReservation( - @Valid @RequestBody ReservationRequest reservationRequest, - @MemberId @Parameter(hidden = true) Long memberId, - HttpServletResponse response - ) { - PaymentApprove.Request paymentRequest = reservationRequest.paymentRequest(); - PaymentApprove.Response paymentResponse = paymentClient.confirmPayment(paymentRequest); + return ResponseEntity.created(URI.create("/reservations/${response.id}")) + .body(CommonApiResponse(response)) + } - try { - ReservationResponse reservationResponse = reservationWithPaymentService.addReservationWithPayment( - reservationRequest, paymentResponse, memberId); - return getCreatedReservationResponse(reservationResponse, response); - } catch (RoomescapeException e) { - PaymentCancel.Request cancelRequest = new PaymentCancel.Request(paymentRequest.paymentKey, - paymentRequest.amount, e.getMessage()); + @GetMapping("/reservations/waiting") + override fun getAllWaiting(): ResponseEntity> { + val response: ReservationsResponse = reservationService.findAllWaiting() - PaymentCancel.Response paymentCancelResponse = paymentClient.cancelPayment(cancelRequest); + return ResponseEntity.ok(CommonApiResponse(response)) + } - reservationWithPaymentService.saveCanceledPayment(paymentCancelResponse, paymentResponse.approvedAt, - paymentRequest.paymentKey); - throw e; - } - } + @PostMapping("/reservations/waiting") + override fun saveWaiting( + @Valid @RequestBody waitingRequest: WaitingRequest, + @MemberId @Parameter(hidden = true) memberId: Long, + ): ResponseEntity> { + val response: ReservationResponse = reservationService.addWaiting( + waitingRequest, + memberId + ) - @Admin - @PostMapping("/reservations/admin") - @ResponseStatus(HttpStatus.CREATED) - @Operation(summary = "관리자 예약 추가", tags = "관리자 로그인이 필요한 API") - @ApiResponses({ - @ApiResponse(responseCode = "201", description = "성공", useReturnTypeSchema = true, - headers = @Header(name = HttpHeaders.LOCATION, description = "생성된 예약 정보 URL", schema = @Schema(example = "/reservations/1"))), - @ApiResponse(responseCode = "409", description = "예약이 이미 존재합니다.", content = @Content(schema = @Schema(implementation = RoomescapeErrorResponse.class))) - }) - public RoomescapeApiResponse saveReservationByAdmin( - @Valid @RequestBody AdminReservationRequest adminReservationRequest, - HttpServletResponse response - ) { - ReservationResponse reservationResponse = reservationService.addReservationByAdmin(adminReservationRequest); - return getCreatedReservationResponse(reservationResponse, response); - } + return ResponseEntity.created(URI.create("/reservations/${response.id}")) + .body(CommonApiResponse(response)) + } - @Admin - @GetMapping("/reservations/waiting") - @ResponseStatus(HttpStatus.OK) - @Operation(summary = "모든 예약 대기 조회", tags = "관리자 로그인이 필요한 API") - @ApiResponses({ - @ApiResponse(responseCode = "200", description = "성공", useReturnTypeSchema = true) - }) - public RoomescapeApiResponse getAllWaiting() { - return RoomescapeApiResponse.success(reservationService.findAllWaiting()); - } + @DeleteMapping("/reservations/waiting/{id}") + override fun deleteWaiting( + @MemberId @Parameter(hidden = true) memberId: Long, + @PathVariable("id") reservationId: Long + ): ResponseEntity> { + reservationService.cancelWaiting(reservationId, memberId) - @LoginRequired - @PostMapping("/reservations/waiting") - @ResponseStatus(HttpStatus.CREATED) - @Operation(summary = "예약 대기 신청", tags = "로그인이 필요한 API") - @ApiResponses({ - @ApiResponse(responseCode = "201", description = "성공", useReturnTypeSchema = true, - headers = @Header(name = HttpHeaders.LOCATION, description = "생성된 예약 정보 URL", schema = @Schema(example = "/reservations/1"))) - }) - public RoomescapeApiResponse saveWaiting( - @Valid @RequestBody WaitingRequest waitingRequest, - @MemberId @Parameter(hidden = true) Long memberId, - HttpServletResponse response - ) { - ReservationResponse reservationResponse = reservationService.addWaiting(waitingRequest, memberId); - return getCreatedReservationResponse(reservationResponse, response); - } + return ResponseEntity.noContent().build() + } - @LoginRequired - @DeleteMapping("/reservations/waiting/{id}") - @ResponseStatus(HttpStatus.NO_CONTENT) - @Operation(summary = "예약 대기 취소", tags = "로그인이 필요한 API") - @ApiResponses({ - @ApiResponse(responseCode = "204", description = "성공"), - @ApiResponse(responseCode = "404", description = "회원의 예약 대기 정보를 찾을 수 없습니다.", - content = @Content(schema = @Schema(implementation = RoomescapeErrorResponse.class))) - }) - public RoomescapeApiResponse deleteWaiting( - @MemberId @Parameter(hidden = true) Long memberId, - @NotNull(message = "reservationId는 null 또는 공백일 수 없습니다.") @PathVariable("id") @Parameter(description = "예약 ID") Long reservationId - ) { - reservationService.cancelWaiting(reservationId, memberId); - return RoomescapeApiResponse.success(); - } + @PostMapping("/reservations/waiting/{id}/approve") + override fun approveWaiting( + @MemberId @Parameter(hidden = true) memberId: Long, + @PathVariable("id") reservationId: Long + ): ResponseEntity> { + reservationService.approveWaiting(reservationId, memberId) - @Admin - @PostMapping("/reservations/waiting/{id}/approve") - @ResponseStatus(HttpStatus.OK) - @Operation(summary = "대기 중인 예약 승인", tags = "관리자 로그인이 필요한 API") - @ApiResponses({ - @ApiResponse(responseCode = "200", description = "성공"), - @ApiResponse(responseCode = "404", description = "예약 대기 정보를 찾을 수 없습니다.", - content = @Content(schema = @Schema(implementation = RoomescapeErrorResponse.class))), - @ApiResponse(responseCode = "409", description = "확정된 예약이 존재하여 대기 중인 예약을 승인할 수 없습니다.", - content = @Content(schema = @Schema(implementation = RoomescapeErrorResponse.class))) - }) - public RoomescapeApiResponse approveWaiting( - @MemberId @Parameter(hidden = true) Long memberId, - @NotNull(message = "reservationId는 null 또는 공백일 수 없습니다.") @PathVariable("id") @Parameter(description = "예약 ID") Long reservationId - ) { - reservationService.approveWaiting(reservationId, memberId); + return ResponseEntity.ok().build() + } - return RoomescapeApiResponse.success(); - } + @PostMapping("/reservations/waiting/{id}/deny") + override fun denyWaiting( + @MemberId @Parameter(hidden = true) memberId: Long, + @PathVariable("id") reservationId: Long + ): ResponseEntity> { + reservationService.denyWaiting(reservationId, memberId) - @Admin - @PostMapping("/reservations/waiting/{id}/deny") - @ResponseStatus(HttpStatus.NO_CONTENT) - @Operation(summary = "대기 중인 예약 거절", tags = "관리자 로그인이 필요한 API") - @ApiResponses({ - @ApiResponse(responseCode = "204", description = "대기 중인 예약 거절 성공"), - @ApiResponse(responseCode = "404", description = "예약 대기 정보를 찾을 수 없습니다.", - content = @Content(schema = @Schema(implementation = RoomescapeErrorResponse.class))) - }) - public RoomescapeApiResponse denyWaiting( - @MemberId @Parameter(hidden = true) Long memberId, - @NotNull(message = "reservationId는 null 또는 공백일 수 없습니다.") @PathVariable("id") @Parameter(description = "예약 ID") Long reservationId - ) { - reservationService.denyWaiting(reservationId, memberId); - - return RoomescapeApiResponse.success(); - } - - private RoomescapeApiResponse getCreatedReservationResponse( - ReservationResponse reservationResponse, - HttpServletResponse response - ) { - response.setHeader(HttpHeaders.LOCATION, "/reservations/" + reservationResponse.id); - return RoomescapeApiResponse.success(reservationResponse); - } + return ResponseEntity.noContent().build() + } }