diff --git a/api/build.gradle b/api/build.gradle index 53770cea..63e3dff8 100644 --- a/api/build.gradle +++ b/api/build.gradle @@ -1,6 +1,8 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' testImplementation 'org.springframework:spring-tx:6.1.1' + //swagger + implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.1.0' implementation project(':core') testImplementation(testFixtures(project(':core'))) diff --git a/api/src/main/java/dev/hooon/auth/AuthApiController.java b/api/src/main/java/dev/hooon/auth/AuthApiController.java index d212028d..def6a417 100644 --- a/api/src/main/java/dev/hooon/auth/AuthApiController.java +++ b/api/src/main/java/dev/hooon/auth/AuthApiController.java @@ -12,9 +12,13 @@ import dev.hooon.auth.dto.request.AuthRequest; import dev.hooon.auth.dto.response.AuthResponse; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; +@Tag(name = "Auth API") @RequestMapping("/api/auth") @RestController @RequiredArgsConstructor @@ -24,6 +28,8 @@ public class AuthApiController { @NoAuth @PostMapping("/login") + @Operation(summary = "로그인 API", description = "로그인을 한다") + @ApiResponse(responseCode = "200", useReturnTypeSchema = true) public ResponseEntity login( @Valid @RequestBody AuthRequest authRequest ) { @@ -33,6 +39,8 @@ public ResponseEntity login( @NoAuth @PostMapping("/token") + @Operation(summary = "토큰 재발급 API", description = "토큰을 재발급한다") + @ApiResponse(responseCode = "200", useReturnTypeSchema = true) public ResponseEntity reIssueAccessToken( @RequestBody TokenReIssueRequest tokenReIssueRequest ) { diff --git a/api/src/main/java/dev/hooon/bookingcancel/BookingCancelApiController.java b/api/src/main/java/dev/hooon/bookingcancel/BookingCancelApiController.java index 58d874dd..9e18e57c 100644 --- a/api/src/main/java/dev/hooon/bookingcancel/BookingCancelApiController.java +++ b/api/src/main/java/dev/hooon/bookingcancel/BookingCancelApiController.java @@ -9,8 +9,12 @@ import dev.hooon.auth.annotation.NoAuth; import dev.hooon.booking.application.BookingService; import dev.hooon.booking.dto.response.BookingCancelResponse; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; +@Tag(name = "Booking API") @RestController @RequiredArgsConstructor public class BookingCancelApiController { @@ -19,6 +23,8 @@ public class BookingCancelApiController { @NoAuth @PostMapping("/api/bookings/cancel/{booking_id}") + @Operation(summary = "예매 취소 API", description = "예매를 취소한다") + @ApiResponse(responseCode = "200", useReturnTypeSchema = true) public ResponseEntity cancelBooking( @RequestParam(name = "userId") Long userId, // TODO @PathVariable("booking_id") Long bookingId diff --git a/api/src/main/java/dev/hooon/common/config/SwaggerConfig.java b/api/src/main/java/dev/hooon/common/config/SwaggerConfig.java new file mode 100644 index 00000000..3c76df75 --- /dev/null +++ b/api/src/main/java/dev/hooon/common/config/SwaggerConfig.java @@ -0,0 +1,47 @@ +package dev.hooon.common.config; + +import static org.springframework.http.HttpHeaders.*; + +import java.util.List; + +import org.springdoc.core.models.GroupedOpenApi; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import io.swagger.v3.oas.annotations.OpenAPIDefinition; +import io.swagger.v3.oas.annotations.info.Info; +import io.swagger.v3.oas.models.Components; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.security.SecurityRequirement; +import io.swagger.v3.oas.models.security.SecurityScheme; + +@OpenAPIDefinition( + info = @Info( + title = "hooon interpark API", + description = "hooon interpark API 명세", + version = "v1")) +@Configuration +public class SwaggerConfig { + + @Bean + public OpenAPI openAPI(){ + SecurityScheme securityScheme = new SecurityScheme() + .type(SecurityScheme.Type.HTTP) + .in(SecurityScheme.In.HEADER).name(AUTHORIZATION); + SecurityRequirement securityRequirement = new SecurityRequirement().addList(AUTHORIZATION); + + return new OpenAPI() + .components(new Components().addSecuritySchemes(AUTHORIZATION, securityScheme)) + .security(List.of(securityRequirement)); + } + + @Bean + public GroupedOpenApi chatOpenApi() { + String[] paths = {"/api/**"}; + + return GroupedOpenApi.builder() + .group("API v1") + .pathsToMatch(paths) + .build(); + } +} \ No newline at end of file diff --git a/api/src/main/java/dev/hooon/common/exception/config/WebConfig.java b/api/src/main/java/dev/hooon/common/config/WebConfig.java similarity index 95% rename from api/src/main/java/dev/hooon/common/exception/config/WebConfig.java rename to api/src/main/java/dev/hooon/common/config/WebConfig.java index 2e073ea7..276a18f2 100644 --- a/api/src/main/java/dev/hooon/common/exception/config/WebConfig.java +++ b/api/src/main/java/dev/hooon/common/config/WebConfig.java @@ -1,4 +1,4 @@ -package dev.hooon.common.exception.config; +package dev.hooon.common.config; import java.util.List; diff --git a/api/src/main/java/dev/hooon/show/RankingApiController.java b/api/src/main/java/dev/hooon/show/RankingApiController.java index 0f898260..93a472fe 100644 --- a/api/src/main/java/dev/hooon/show/RankingApiController.java +++ b/api/src/main/java/dev/hooon/show/RankingApiController.java @@ -9,9 +9,13 @@ import dev.hooon.show.application.facade.RankingCacheFacade; import dev.hooon.show.dto.request.RankingRequest; import dev.hooon.show.dto.response.RankingResponse; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; +@Tag(name = "Ranking API") @RestController @RequiredArgsConstructor public class RankingApiController { @@ -20,6 +24,8 @@ public class RankingApiController { @NoAuth @GetMapping("/api/shows/ranking") + @Operation(summary = "랭킹 조회 API", description = "카테고리, 집계기간별 랭킹을 조회한다") + @ApiResponse(responseCode = "200", useReturnTypeSchema = true) public ResponseEntity getShowRanking(@Valid @ModelAttribute RankingRequest request) { RankingResponse rankingResponse = rankingCacheFacade.getShowRankingWithCache(request); return ResponseEntity.ok(rankingResponse); diff --git a/api/src/main/java/dev/hooon/show/ShowApiController.java b/api/src/main/java/dev/hooon/show/ShowApiController.java index 87050dc7..c00081fa 100644 --- a/api/src/main/java/dev/hooon/show/ShowApiController.java +++ b/api/src/main/java/dev/hooon/show/ShowApiController.java @@ -8,8 +8,12 @@ import dev.hooon.auth.annotation.NoAuth; import dev.hooon.show.application.ShowService; import dev.hooon.show.dto.response.AbleBookingDateRoundResponse; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; +@Tag(name = "Show API") @RestController @RequiredArgsConstructor public class ShowApiController { @@ -18,6 +22,8 @@ public class ShowApiController { @NoAuth @GetMapping("/api/shows/{show_id}/available") + @Operation(summary = "공연 예매가능 날짜, 회차 조회 API", description = "공연의 예매 가능한 날짜와 회차 정보를 조회한다") + @ApiResponse(responseCode = "200", useReturnTypeSchema = true) public ResponseEntity getAbleBookingDateRoundInfo( @PathVariable("show_id") Long showId ) { diff --git a/api/src/main/java/dev/hooon/show/ShowDetailApiController.java b/api/src/main/java/dev/hooon/show/ShowDetailApiController.java index 9733cae4..3ffdadaf 100644 --- a/api/src/main/java/dev/hooon/show/ShowDetailApiController.java +++ b/api/src/main/java/dev/hooon/show/ShowDetailApiController.java @@ -8,8 +8,12 @@ import dev.hooon.auth.annotation.NoAuth; import dev.hooon.show.application.ShowService; import dev.hooon.show.dto.response.ShowDetailsInfoResponse; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; +@Tag(name = "Show API") @RestController @RequiredArgsConstructor public class ShowDetailApiController { @@ -18,6 +22,8 @@ public class ShowDetailApiController { @NoAuth @GetMapping("/api/shows/{show_id}") + @Operation(summary = "공연 상세정보 조회 API", description = "공연의 상세정보를 조회한다") + @ApiResponse(responseCode = "200", useReturnTypeSchema = true) public ResponseEntity getShowDetailInfo( @PathVariable("show_id") Long showId ) { diff --git a/api/src/main/java/dev/hooon/show/ShowSeatsApiController.java b/api/src/main/java/dev/hooon/show/ShowSeatsApiController.java index 3b8cbcd9..b8d887fd 100644 --- a/api/src/main/java/dev/hooon/show/ShowSeatsApiController.java +++ b/api/src/main/java/dev/hooon/show/ShowSeatsApiController.java @@ -16,9 +16,13 @@ import dev.hooon.show.dto.request.BookedSeatQueryRequest; import dev.hooon.show.dto.response.ShowSeatResponse; import dev.hooon.show.dto.response.seats.ShowSeatsResponse; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; +@Tag(name = "Show API") @RestController @RequiredArgsConstructor public class ShowSeatsApiController { @@ -28,6 +32,8 @@ public class ShowSeatsApiController { @NoAuth @GetMapping("/api/shows/{showId}/seats") + @Operation(summary = "공연 예매할 날짜, 회차의 좌석정보 조회 API", description = "공연의 예매할 날짜, 회차에 해당하는 좌석 정보를 조회한다") + @ApiResponse(responseCode = "200", useReturnTypeSchema = true) public ResponseEntity getShowSeatsInfo( @PathVariable("showId") Long showId, @RequestParam("date") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate date, @@ -41,6 +47,8 @@ public ResponseEntity getShowSeatsInfo( @NoAuth @GetMapping("/api/shows/seats/booked") + @Operation(summary = "공연 예매할 날짜, 회차의 예매된 좌석정보 조회 API", description = "공연의 예매할 날짜, 회차에 예매된 좌석정보를 조회한다") + @ApiResponse(responseCode = "200", useReturnTypeSchema = true) public ResponseEntity getBookedSeatInfo( @Valid @ModelAttribute BookedSeatQueryRequest request ) { diff --git a/api/src/main/java/dev/hooon/ticketbooking/TicketBookingApiController.java b/api/src/main/java/dev/hooon/ticketbooking/TicketBookingApiController.java index 4794a449..3ebc9c77 100644 --- a/api/src/main/java/dev/hooon/ticketbooking/TicketBookingApiController.java +++ b/api/src/main/java/dev/hooon/ticketbooking/TicketBookingApiController.java @@ -10,9 +10,13 @@ import dev.hooon.booking.application.fascade.TicketBookingFacade; import dev.hooon.booking.dto.request.TicketBookingRequest; import dev.hooon.booking.dto.response.TicketBookingResponse; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; +@Tag(name = "Booking API") @RestController @RequiredArgsConstructor public class TicketBookingApiController { @@ -21,6 +25,8 @@ public class TicketBookingApiController { @NoAuth @PostMapping("/api/bookings") + @Operation(summary = "티켓 예매 API", description = "티켓을 예매한다") + @ApiResponse(responseCode = "200", useReturnTypeSchema = true) public ResponseEntity bookingTicket( @RequestParam(name = "userId") Long userId, // TODO @Valid @RequestBody TicketBookingRequest ticketBookingRequest diff --git a/api/src/main/java/dev/hooon/user/UserApiController.java b/api/src/main/java/dev/hooon/user/UserApiController.java index 12a1d7bd..679ed014 100644 --- a/api/src/main/java/dev/hooon/user/UserApiController.java +++ b/api/src/main/java/dev/hooon/user/UserApiController.java @@ -9,9 +9,13 @@ import dev.hooon.user.application.UserService; import dev.hooon.user.dto.request.UserJoinRequest; import dev.hooon.user.dto.response.UserJoinResponse; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; +@Tag(name = "User API") @RestController @RequiredArgsConstructor public class UserApiController { @@ -20,6 +24,8 @@ public class UserApiController { @NoAuth @PostMapping("/api/users") + @Operation(summary = "회원가입 API", description = "회원가입을 한다") + @ApiResponse(responseCode = "200", useReturnTypeSchema = true) public ResponseEntity join( final @Valid @RequestBody UserJoinRequest userJoinRequest ) { diff --git a/api/src/main/java/dev/hooon/waitingbooking/WaitingBookingApiController.java b/api/src/main/java/dev/hooon/waitingbooking/WaitingBookingApiController.java index e81c55ec..24fc6973 100644 --- a/api/src/main/java/dev/hooon/waitingbooking/WaitingBookingApiController.java +++ b/api/src/main/java/dev/hooon/waitingbooking/WaitingBookingApiController.java @@ -10,9 +10,13 @@ import dev.hooon.waitingbooking.application.facade.WaitingBookingFacade; import dev.hooon.waitingbooking.dto.request.WaitingRegisterRequest; import dev.hooon.waitingbooking.dto.response.WaitingRegisterResponse; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; +@Tag(name = "Waiting Booking API") @RestController @RequiredArgsConstructor public class WaitingBookingApiController { @@ -21,6 +25,8 @@ public class WaitingBookingApiController { @NoAuth @PostMapping("/api/waiting_bookings") + @Operation(summary = "예매대기 등록 API", description = "예매된 좌석에 대해서 예매대기를 등록한다") + @ApiResponse(responseCode = "200", useReturnTypeSchema = true) public ResponseEntity registerWaitingBooking( @RequestParam(name = "userId") Long userId, // TODO 추후에 인증정보 ArgumentResolver 가 구현되면 수정 예정 @Valid @RequestBody WaitingRegisterRequest request diff --git a/scheduler/src/test/java/dev/hooon/waitingbooking/scheduler/WaitingBookingSchedulerTest.java b/scheduler/src/test/java/dev/hooon/waitingbooking/scheduler/WaitingBookingSchedulerTest.java index 53ff19db..e1a888fa 100644 --- a/scheduler/src/test/java/dev/hooon/waitingbooking/scheduler/WaitingBookingSchedulerTest.java +++ b/scheduler/src/test/java/dev/hooon/waitingbooking/scheduler/WaitingBookingSchedulerTest.java @@ -123,8 +123,8 @@ void scheduleExpiredWaitingBookingProcess_test() { userRepository.save(user); LocalDateTime now = LocalDateTime.of(2023, 11, 16, 12, 12); - LocalDateTime beforeNow = now.minusSeconds(10); - LocalDateTime afterNow = now.plusSeconds(10); + LocalDateTime beforeNow = now.minusSeconds(100); + LocalDateTime afterNow = now.plusSeconds(100); // 스케줄러 기준시간 동적으로 조정 given(nowLocalDateTime.get()).willReturn(now);