diff --git a/src/main/java/ssu/eatssu/domain/auth/presentation/OAuthController.java b/src/main/java/ssu/eatssu/domain/auth/presentation/OAuthController.java
index d425ae70..e70f81d2 100644
--- a/src/main/java/ssu/eatssu/domain/auth/presentation/OAuthController.java
+++ b/src/main/java/ssu/eatssu/domain/auth/presentation/OAuthController.java
@@ -1,11 +1,5 @@
package ssu.eatssu.domain.auth.presentation;
-import io.swagger.v3.oas.annotations.Operation;
-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.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -14,6 +8,7 @@
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import ssu.eatssu.domain.auth.dto.*;
+import ssu.eatssu.domain.auth.presentation.docs.OAuthControllerDocs;
import ssu.eatssu.domain.auth.service.OAuthService;
import ssu.eatssu.domain.user.dto.Tokens;
import ssu.eatssu.global.handler.response.BaseResponse;
@@ -24,19 +19,12 @@
@RestController
@RequestMapping("/oauths")
@RequiredArgsConstructor
-@Tag(name = "Oauth", description = "Oauth API")
-public class OAuthController {
+public class OAuthController implements OAuthControllerDocs {
private final OAuthService oauthService;
// TODO : 로그인 & 회원 가입 마이그레이션 이후에 지울 것.
- @Operation(summary = "카카오 회원가입, 로그인 [인증 토큰 필요 X]", description = """
- 카카오 회원가입, 로그인 API 입니다.
- 가입된 회원일 경우 카카오 로그인, 미가입 회원일 경우 회원가입 후 자동 로그인됩니다.
- """)
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "카카오 회원가입/로그인 성공")
- })
+ @Override
@PostMapping("/kakao")
public BaseResponse kakaoLogin(@Valid @RequestBody KakaoLoginRequest request) {
long startTime = System.currentTimeMillis();
@@ -48,13 +36,7 @@ public BaseResponse kakaoLogin(@Valid @RequestBody KakaoLoginRequest req
return BaseResponse.success(tokens);
}
- @Operation(summary = "카카오 회원가입, 로그인 V2 [인증 토큰 필요 X]", description = """
- 카카오 회원가입, 로그인 V2 API 입니다.
- 가입된 회원일 경우 카카오 로그인, 미가입 회원일 경우 회원가입 후 자동 로그인됩니다.
- """)
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "카카오 회원가입/로그인 성공")
- })
+ @Override
@PostMapping("/v2/kakao")
public BaseResponse kakaoLoginV2(@Valid @RequestBody KakaoLoginRequestV2 request) {
long startTime = System.currentTimeMillis();
@@ -67,46 +49,28 @@ public BaseResponse kakaoLoginV2(@Valid @RequestBody KakaoLoginRequestV2
}
// TODO : 로그인 & 회원 가입 마이그레이션 이후에 지울 것.
- @Operation(summary = "애플 회원가입, 로그인 [인증 토큰 필요 X]", description = """
- 애플 로그인, 회원가입 API 입니다.
- 가입된 회원일 경우 카카오 로그인, 미가입 회원일 경우 회원가입 후 자동 로그인됩니다.
- """)
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "애플 회원가입/로그인 성공")
- })
+ @Override
@PostMapping("/apple")
public BaseResponse appleLogin(@Valid @RequestBody AppleLoginRequest request) {
Tokens tokens = oauthService.appleLogin(request);
return BaseResponse.success(tokens);
}
- @Operation(summary = "애플 회원가입, 로그인 V2 [인증 토큰 필요 X]", description = """
- 애플 로그인, 회원가입 API V2 입니다.
- 가입된 회원일 경우 카카오 로그인, 미가입 회원일 경우 회원가입 후 자동 로그인됩니다.
- """)
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "애플 회원가입/로그인 성공")
- })
+ @Override
@PostMapping("/v2/apple")
public BaseResponse appleLoginV2(@Valid @RequestBody AppleLoginRequestV2 request) {
Tokens tokens = oauthService.appleLoginV2(request);
return BaseResponse.success(tokens);
}
- @Operation(summary = "토큰 재발급", description = "accessToken, refreshToken 재발급 API 입니다.")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "토큰 재발급 성공")
- })
+ @Override
@PostMapping("/reissue/token")
public BaseResponse refreshToken() {
Tokens tokens = oauthService.refreshTokens(getLoginUser());
return BaseResponse.success(tokens);
}
- @Operation(summary = "유효한 토큰 확인 [인증 토큰 필요 X]", description = "해당 토큰이 유효하면 true 반환하는, 유효하지 않은 false 반환하는 API 입니다")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "유효한 토큰인지 확인 성공")
- })
+ @Override
@PostMapping("/valid/token")
public BaseResponse validToken(@Valid @RequestBody ValidRequest request) {
Boolean response = oauthService.validToken(request);
diff --git a/src/main/java/ssu/eatssu/domain/auth/presentation/docs/OAuthControllerDocs.java b/src/main/java/ssu/eatssu/domain/auth/presentation/docs/OAuthControllerDocs.java
new file mode 100644
index 00000000..213af66a
--- /dev/null
+++ b/src/main/java/ssu/eatssu/domain/auth/presentation/docs/OAuthControllerDocs.java
@@ -0,0 +1,65 @@
+package ssu.eatssu.domain.auth.presentation.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 ssu.eatssu.domain.auth.dto.AppleLoginRequest;
+import ssu.eatssu.domain.auth.dto.AppleLoginRequestV2;
+import ssu.eatssu.domain.auth.dto.KakaoLoginRequest;
+import ssu.eatssu.domain.auth.dto.KakaoLoginRequestV2;
+import ssu.eatssu.domain.auth.dto.ValidRequest;
+import ssu.eatssu.domain.user.dto.Tokens;
+import ssu.eatssu.global.handler.response.BaseResponse;
+
+@Tag(name = "Oauth", description = "Oauth API")
+public interface OAuthControllerDocs {
+
+ @Operation(summary = "카카오 회원가입, 로그인 [인증 토큰 필요 X]", description = """
+ 카카오 회원가입, 로그인 API 입니다.
+ 가입된 회원일 경우 카카오 로그인, 미가입 회원일 경우 회원가입 후 자동 로그인됩니다.
+ """)
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "카카오 회원가입/로그인 성공")
+ })
+ BaseResponse kakaoLogin(KakaoLoginRequest request);
+
+ @Operation(summary = "카카오 회원가입, 로그인 V2 [인증 토큰 필요 X]", description = """
+ 카카오 회원가입, 로그인 V2 API 입니다.
+ 가입된 회원일 경우 카카오 로그인, 미가입 회원일 경우 회원가입 후 자동 로그인됩니다.
+ """)
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "카카오 회원가입/로그인 성공")
+ })
+ BaseResponse kakaoLoginV2(KakaoLoginRequestV2 request);
+
+ @Operation(summary = "애플 회원가입, 로그인 [인증 토큰 필요 X]", description = """
+ 애플 로그인, 회원가입 API 입니다.
+ 가입된 회원일 경우 카카오 로그인, 미가입 회원일 경우 회원가입 후 자동 로그인됩니다.
+ """)
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "애플 회원가입/로그인 성공")
+ })
+ BaseResponse appleLogin(AppleLoginRequest request);
+
+ @Operation(summary = "애플 회원가입, 로그인 V2 [인증 토큰 필요 X]", description = """
+ 애플 로그인, 회원가입 API V2 입니다.
+ 가입된 회원일 경우 카카오 로그인, 미가입 회원일 경우 회원가입 후 자동 로그인됩니다.
+ """)
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "애플 회원가입/로그인 성공")
+ })
+ BaseResponse appleLoginV2(AppleLoginRequestV2 request);
+
+ @Operation(summary = "토큰 재발급", description = "accessToken, refreshToken 재발급 API 입니다.")
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "토큰 재발급 성공")
+ })
+ BaseResponse refreshToken();
+
+ @Operation(summary = "유효한 토큰 확인 [인증 토큰 필요 X]", description = "해당 토큰이 유효하면 true 반환하는, 유효하지 않은 false 반환하는 API 입니다")
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "유효한 토큰인지 확인 성공")
+ })
+ BaseResponse validToken(ValidRequest request);
+}
diff --git a/src/main/java/ssu/eatssu/domain/inquiry/presentation/InquiryController.java b/src/main/java/ssu/eatssu/domain/inquiry/presentation/InquiryController.java
index 081a050b..99fa6b28 100644
--- a/src/main/java/ssu/eatssu/domain/inquiry/presentation/InquiryController.java
+++ b/src/main/java/ssu/eatssu/domain/inquiry/presentation/InquiryController.java
@@ -1,11 +1,5 @@
package ssu.eatssu.domain.inquiry.presentation;
-import io.swagger.v3.oas.annotations.Operation;
-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 lombok.RequiredArgsConstructor;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.PostMapping;
@@ -15,6 +9,7 @@
import ssu.eatssu.domain.auth.security.CustomUserDetails;
import ssu.eatssu.domain.inquiry.dto.CreateInquiryRequest;
import ssu.eatssu.domain.inquiry.entity.Inquiry;
+import ssu.eatssu.domain.inquiry.presentation.docs.InquiryControllerDocs;
import ssu.eatssu.domain.inquiry.service.InquiryService;
import ssu.eatssu.domain.slack.entity.SlackChannel;
import ssu.eatssu.domain.slack.entity.SlackMessageFormat;
@@ -28,17 +23,12 @@
@RestController
@RequiredArgsConstructor
@RequestMapping("/inquiries")
-@Tag(name = "Inquiry", description = "문의 API")
-public class InquiryController {
+public class InquiryController implements InquiryControllerDocs {
private final SlackService slackService;
private final InquiryService inquiryService;
- @Operation(summary = "문의 작성", description = "문의를 작성하는 API 입니다.")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "문의 작성 성공"),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
- })
+ @Override
@PostMapping("/")
public BaseResponse writeInquiry(@RequestBody CreateInquiryRequest createInquiryRequest,
@AuthenticationPrincipal CustomUserDetails customUserDetails) {
diff --git a/src/main/java/ssu/eatssu/domain/inquiry/presentation/docs/InquiryControllerDocs.java b/src/main/java/ssu/eatssu/domain/inquiry/presentation/docs/InquiryControllerDocs.java
new file mode 100644
index 00000000..9a81493d
--- /dev/null
+++ b/src/main/java/ssu/eatssu/domain/inquiry/presentation/docs/InquiryControllerDocs.java
@@ -0,0 +1,24 @@
+package ssu.eatssu.domain.inquiry.presentation.docs;
+
+import io.swagger.v3.oas.annotations.Operation;
+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 ssu.eatssu.domain.auth.security.CustomUserDetails;
+import ssu.eatssu.domain.inquiry.dto.CreateInquiryRequest;
+import ssu.eatssu.global.handler.response.BaseResponse;
+
+@Tag(name = "Inquiry", description = "문의 API")
+public interface InquiryControllerDocs {
+
+ @Operation(summary = "문의 작성", description = "문의를 작성하는 API 입니다.")
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "문의 작성 성공"),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema =
+ @Schema(implementation = BaseResponse.class)))
+ })
+ BaseResponse writeInquiry(CreateInquiryRequest createInquiryRequest,
+ CustomUserDetails customUserDetails);
+}
diff --git a/src/main/java/ssu/eatssu/domain/menu/presentation/rest/MealController.java b/src/main/java/ssu/eatssu/domain/menu/presentation/rest/MealController.java
index d2206241..4b6bcc77 100644
--- a/src/main/java/ssu/eatssu/domain/menu/presentation/rest/MealController.java
+++ b/src/main/java/ssu/eatssu/domain/menu/presentation/rest/MealController.java
@@ -1,12 +1,5 @@
package ssu.eatssu.domain.menu.presentation.rest;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.Parameter;
-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 lombok.RequiredArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.DeleteMapping;
@@ -22,6 +15,7 @@
import ssu.eatssu.domain.menu.presentation.dto.request.MealCreateWithPriceRequest;
import ssu.eatssu.domain.menu.presentation.dto.response.MealDetailResponse;
import ssu.eatssu.domain.menu.presentation.dto.response.MenusInMealResponse;
+import ssu.eatssu.domain.menu.presentation.rest.docs.MealControllerDocs;
import ssu.eatssu.domain.menu.service.MealService;
import ssu.eatssu.domain.restaurant.entity.Restaurant;
import ssu.eatssu.domain.restaurant.entity.RestaurantType;
@@ -36,27 +30,16 @@
@RestController
@RequiredArgsConstructor
@RequestMapping("/meals")
-@Tag(name = "Meal", description = "식단 API")
-public class MealController {
+public class MealController implements MealControllerDocs {
private final MealService mealService;
- @Operation(summary = "식단 추가 [인증 토큰 필요 X]", description = """
- 식단을 추가하는 API 입니다.
- 변동메뉴 식당(학생식당, 도담, 기숙사 식당)의 특정날짜(yyyyMMdd), 특정시간대(아침/점심/저녁)에 해당하는 식단을 추가합니다.
- 이미 존재하는 식단일 경우 중복저장 되지 않도록 처리합니다.(별도의 ErrorResponse 응답 X)
- """)
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "식단 추가 성공"),
- @ApiResponse(responseCode = "400", description = "지원하지 않는 식당(고정 메뉴 식당)", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "400", description = "잘못된 날짜형식", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 식당", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
- })
+ @Override
@PostMapping("")
public BaseResponse createMeal(
- @Parameter(schema = @Schema(type = "string", format = "date", example = "20240101")) @RequestParam("date") @DateTimeFormat(pattern = "yyyyMMdd") Date date,
- @Parameter(description = "식당이름") @RequestParam("restaurant") Restaurant restaurant,
- @Parameter(description = "시간대") @RequestParam("time") TimePart timePart,
+ @RequestParam("date") @DateTimeFormat(pattern = "yyyyMMdd") Date date,
+ @RequestParam("restaurant") Restaurant restaurant,
+ @RequestParam("time") TimePart timePart,
@RequestBody CreateMealRequest mealCreateRequest) {
if (RestaurantType.isFixedType(restaurant)) {
throw new BaseException(NOT_SUPPORT_RESTAURANT);
@@ -66,23 +49,12 @@ public BaseResponse createMeal(
return BaseResponse.success();
}
- @Operation(summary = "식단 추가 [인증 토큰 필요 X]", description = """
- 식단을 추가하는 API 입니다.
- 변동메뉴 식당(학생식당, 도담, 기숙사 식당)의 특정날짜(yyyyMMdd), 특정시간대(아침/점심/저녁)에 해당하는 식단을 추가합니다.
- 이미 존재하는 식단일 경우 중복저장 되지 않도록 처리합니다.(별도의 ErrorResponse 응답 X)
- 가격을 외부에서 입력받습니다.
- """)
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "식단 추가 성공"),
- @ApiResponse(responseCode = "400", description = "지원하지 않는 식당(고정 메뉴 식당)", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "400", description = "잘못된 날짜형식", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 식당", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
- })
+ @Override
@PostMapping("/with-price")
public BaseResponse createMealWithPrice(
- @Parameter(schema = @Schema(type = "string", format = "date", example = "20240101")) @RequestParam("date") @DateTimeFormat(pattern = "yyyyMMdd") Date date,
- @Parameter(description = "식당이름") @RequestParam("restaurant") Restaurant restaurant,
- @Parameter(description = "시간대") @RequestParam("time") TimePart timePart,
+ @RequestParam("date") @DateTimeFormat(pattern = "yyyyMMdd") Date date,
+ @RequestParam("restaurant") Restaurant restaurant,
+ @RequestParam("time") TimePart timePart,
@RequestBody MealCreateWithPriceRequest request) {
if (RestaurantType.isFixedType(restaurant)) {
throw new BaseException(NOT_SUPPORT_RESTAURANT);
@@ -92,50 +64,29 @@ public BaseResponse createMealWithPrice(
return BaseResponse.success();
}
- @Operation(summary = "변동 메뉴 식단 리스트 조회 [인증 토큰 필요 X]", description = """
- 변동 메뉴 식단 리스트를 조회하는 API 입니다.
- 변동 메뉴 식당 (학생 식당, 도담, 기숙사 식당) 의 특정날짜(yyyyMMdd), 특정시간대(아침/점심/저녁)에 해당하는 식단 목록을 조회합니다.
- 일반적으로 학생식당과 도담의 경우 식단 여러 개가 조회되고 기숙사식당은 한 개만 조회됩니다.)
- """)
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "식단 리스트 조회 성공"),
- @ApiResponse(responseCode = "400", description = "지원 하지 않는 식당 (고정 메뉴 식당)", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "404", description = "존재 하지 않는 식당", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
- })
+ @Override
@GetMapping("")
public BaseResponse> getMealDetail(
- @Parameter(schema = @Schema(type = "string", format = "date", example = "20240101")) @RequestParam("date") @DateTimeFormat(pattern = "yyyyMMdd") Date date,
- @Parameter(description = "식당 이름") @RequestParam("restaurant") Restaurant restaurant,
- @Parameter(description = "시간대") @RequestParam("time") TimePart timePart) {
+ @RequestParam("date") @DateTimeFormat(pattern = "yyyyMMdd") Date date,
+ @RequestParam("restaurant") Restaurant restaurant,
+ @RequestParam("time") TimePart timePart) {
return BaseResponse.success(
mealService.getMealDetailsByDateAndRestaurantAndTimePart(date, restaurant, timePart));
}
- @Operation(summary = "식단 삭제 [인증 토큰 필요 X]", description = "식단을 삭제하는 API 입니다.")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "식단 삭제 성공"),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 식단", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
- })
+ @Override
@DeleteMapping("/{mealId}")
public BaseResponse> deleteMeal(
- @Parameter(description = "mealId") @PathVariable("mealId") Long mealId) {
+ @PathVariable("mealId") Long mealId) {
mealService.deleteByMealId(mealId);
return BaseResponse.success();
}
- @Operation(summary = "메뉴 정보 리스트 조회 [인증 토큰 필요 X]", description = """
- 메뉴 정보 리스트를 조회하는 API 입니다.
- 식단식별자(mealId)로 해당 식단에 속하는 메뉴 정보 목록을 조회합니다.")
- """)
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "메뉴 정보 리스트 조회 성공"),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 식단", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
- })
+ @Override
@GetMapping("/{mealId}/menus-info")
- public BaseResponse getMenusInMeal(@Parameter(description = "mealId")
- @PathVariable("mealId") Long mealId) {
+ public BaseResponse getMenusInMeal(@PathVariable("mealId") Long mealId) {
return BaseResponse.success(mealService.getMenusInMealByMealId(mealId));
}
}
diff --git a/src/main/java/ssu/eatssu/domain/menu/presentation/rest/MenuController.java b/src/main/java/ssu/eatssu/domain/menu/presentation/rest/MenuController.java
index 008cf8ca..4eaa67e6 100644
--- a/src/main/java/ssu/eatssu/domain/menu/presentation/rest/MenuController.java
+++ b/src/main/java/ssu/eatssu/domain/menu/presentation/rest/MenuController.java
@@ -1,17 +1,12 @@
package ssu.eatssu.domain.menu.presentation.rest;
-import io.swagger.v3.oas.annotations.Operation;
-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 lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import ssu.eatssu.domain.menu.presentation.dto.response.MenuRestaurantResponse;
+import ssu.eatssu.domain.menu.presentation.rest.docs.MenuControllerDocs;
import ssu.eatssu.domain.menu.service.MenuService;
import ssu.eatssu.domain.restaurant.entity.Restaurant;
import ssu.eatssu.domain.user.entity.Language;
@@ -20,23 +15,11 @@
@RestController
@RequiredArgsConstructor
@RequestMapping("/menus")
-@Tag(name = "Menu", description = "메뉴 API")
-public class MenuController {
+public class MenuController implements MenuControllerDocs {
private final MenuService menuService;
- @Operation(summary = "고정 메뉴 리스트 조회 [인증 토큰 필요 X]",
- description =
- """
- 고정 메뉴 리스트를 조회하는 API 입니다.
- 메뉴가 고정된 식당(푸드코트, 스낵코너, 더 키친)의 메뉴 리스트를 조회합니다.
- """
- )
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "메뉴 리스트 조회 성공"),
- @ApiResponse(responseCode = "400", description = "지원하지 않는 식당(변동 메뉴 식당)", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 식당", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
- })
+ @Override
@GetMapping
public BaseResponse getMenus(
@RequestParam("restaurant") Restaurant restaurant,
diff --git a/src/main/java/ssu/eatssu/domain/menu/presentation/rest/docs/MealControllerDocs.java b/src/main/java/ssu/eatssu/domain/menu/presentation/rest/docs/MealControllerDocs.java
new file mode 100644
index 00000000..7d60a1ea
--- /dev/null
+++ b/src/main/java/ssu/eatssu/domain/menu/presentation/rest/docs/MealControllerDocs.java
@@ -0,0 +1,100 @@
+package ssu.eatssu.domain.menu.presentation.rest.docs;
+
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+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 ssu.eatssu.domain.menu.entity.constants.TimePart;
+import ssu.eatssu.domain.menu.presentation.dto.request.CreateMealRequest;
+import ssu.eatssu.domain.menu.presentation.dto.request.MealCreateWithPriceRequest;
+import ssu.eatssu.domain.menu.presentation.dto.response.MealDetailResponse;
+import ssu.eatssu.domain.menu.presentation.dto.response.MenusInMealResponse;
+import ssu.eatssu.domain.restaurant.entity.Restaurant;
+import ssu.eatssu.global.handler.response.BaseResponse;
+
+import java.util.Date;
+import java.util.List;
+
+@Tag(name = "Meal", description = "식단 API")
+public interface MealControllerDocs {
+
+ @Operation(summary = "식단 추가 [인증 토큰 필요 X]", description = """
+ 식단을 추가하는 API 입니다.
+ 변동메뉴 식당(학생식당, 도담, 기숙사 식당)의 특정날짜(yyyyMMdd), 특정시간대(아침/점심/저녁)에 해당하는 식단을 추가합니다.
+ 이미 존재하는 식단일 경우 중복저장 되지 않도록 처리합니다.(별도의 ErrorResponse 응답 X)
+ """)
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "식단 추가 성공"),
+ @ApiResponse(responseCode = "400", description = "지원하지 않는 식당(고정 메뉴 식당)", content =
+ @Content(schema = @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "400", description = "잘못된 날짜형식", content = @Content(schema =
+ @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 식당", content = @Content(schema =
+ @Schema(implementation = BaseResponse.class)))
+ })
+ BaseResponse createMeal(
+ @Parameter(schema = @Schema(type = "string", format = "date", example = "20240101")) Date date,
+ @Parameter(description = "식당이름") Restaurant restaurant,
+ @Parameter(description = "시간대") TimePart timePart,
+ CreateMealRequest mealCreateRequest);
+
+ @Operation(summary = "식단 추가 [인증 토큰 필요 X]", description = """
+ 식단을 추가하는 API 입니다.
+ 변동메뉴 식당(학생식당, 도담, 기숙사 식당)의 특정날짜(yyyyMMdd), 특정시간대(아침/점심/저녁)에 해당하는 식단을 추가합니다.
+ 이미 존재하는 식단일 경우 중복저장 되지 않도록 처리합니다.(별도의 ErrorResponse 응답 X)
+ 가격을 외부에서 입력받습니다.
+ """)
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "식단 추가 성공"),
+ @ApiResponse(responseCode = "400", description = "지원하지 않는 식당(고정 메뉴 식당)", content =
+ @Content(schema = @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "400", description = "잘못된 날짜형식", content = @Content(schema =
+ @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 식당", content = @Content(schema =
+ @Schema(implementation = BaseResponse.class)))
+ })
+ BaseResponse createMealWithPrice(
+ @Parameter(schema = @Schema(type = "string", format = "date", example = "20240101")) Date date,
+ @Parameter(description = "식당이름") Restaurant restaurant,
+ @Parameter(description = "시간대") TimePart timePart,
+ MealCreateWithPriceRequest request);
+
+ @Operation(summary = "변동 메뉴 식단 리스트 조회 [인증 토큰 필요 X]", description = """
+ 변동 메뉴 식단 리스트를 조회하는 API 입니다.
+ 변동 메뉴 식당 (학생 식당, 도담, 기숙사 식당) 의 특정날짜(yyyyMMdd), 특정시간대(아침/점심/저녁)에 해당하는 식단 목록을 조회합니다.
+ 일반적으로 학생식당과 도담의 경우 식단 여러 개가 조회되고 기숙사식당은 한 개만 조회됩니다.)
+ """)
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "식단 리스트 조회 성공"),
+ @ApiResponse(responseCode = "400", description = "지원 하지 않는 식당 (고정 메뉴 식당)", content =
+ @Content(schema = @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "404", description = "존재 하지 않는 식당", content = @Content(schema =
+ @Schema(implementation = BaseResponse.class)))
+ })
+ BaseResponse> getMealDetail(
+ @Parameter(schema = @Schema(type = "string", format = "date", example = "20240101")) Date date,
+ @Parameter(description = "식당 이름") Restaurant restaurant,
+ @Parameter(description = "시간대") TimePart timePart);
+
+ @Operation(summary = "식단 삭제 [인증 토큰 필요 X]", description = "식단을 삭제하는 API 입니다.")
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "식단 삭제 성공"),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 식단", content = @Content(schema =
+ @Schema(implementation = BaseResponse.class)))
+ })
+ BaseResponse> deleteMeal(@Parameter(description = "mealId") Long mealId);
+
+ @Operation(summary = "메뉴 정보 리스트 조회 [인증 토큰 필요 X]", description = """
+ 메뉴 정보 리스트를 조회하는 API 입니다.
+ 식단식별자(mealId)로 해당 식단에 속하는 메뉴 정보 목록을 조회합니다.")
+ """)
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "메뉴 정보 리스트 조회 성공"),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 식단", content = @Content(schema =
+ @Schema(implementation = BaseResponse.class)))
+ })
+ BaseResponse getMenusInMeal(@Parameter(description = "mealId") Long mealId);
+}
diff --git a/src/main/java/ssu/eatssu/domain/menu/presentation/rest/docs/MenuControllerDocs.java b/src/main/java/ssu/eatssu/domain/menu/presentation/rest/docs/MenuControllerDocs.java
new file mode 100644
index 00000000..b23367bc
--- /dev/null
+++ b/src/main/java/ssu/eatssu/domain/menu/presentation/rest/docs/MenuControllerDocs.java
@@ -0,0 +1,32 @@
+package ssu.eatssu.domain.menu.presentation.rest.docs;
+
+import io.swagger.v3.oas.annotations.Operation;
+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 ssu.eatssu.domain.menu.presentation.dto.response.MenuRestaurantResponse;
+import ssu.eatssu.domain.restaurant.entity.Restaurant;
+import ssu.eatssu.domain.user.entity.Language;
+import ssu.eatssu.global.handler.response.BaseResponse;
+
+@Tag(name = "Menu", description = "메뉴 API")
+public interface MenuControllerDocs {
+
+ @Operation(summary = "고정 메뉴 리스트 조회 [인증 토큰 필요 X]",
+ description =
+ """
+ 고정 메뉴 리스트를 조회하는 API 입니다.
+ 메뉴가 고정된 식당(푸드코트, 스낵코너, 더 키친)의 메뉴 리스트를 조회합니다.
+ """
+ )
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "메뉴 리스트 조회 성공"),
+ @ApiResponse(responseCode = "400", description = "지원하지 않는 식당(변동 메뉴 식당)", content =
+ @Content(schema = @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 식당", content = @Content(schema =
+ @Schema(implementation = BaseResponse.class)))
+ })
+ BaseResponse getMenus(Restaurant restaurant, Language language);
+}
diff --git a/src/main/java/ssu/eatssu/domain/partnership/presentation/PartnershipController.java b/src/main/java/ssu/eatssu/domain/partnership/presentation/PartnershipController.java
index 0e76475e..9e1dfc51 100644
--- a/src/main/java/ssu/eatssu/domain/partnership/presentation/PartnershipController.java
+++ b/src/main/java/ssu/eatssu/domain/partnership/presentation/PartnershipController.java
@@ -1,11 +1,5 @@
package ssu.eatssu.domain.partnership.presentation;
-import io.swagger.v3.oas.annotations.Operation;
-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 lombok.RequiredArgsConstructor;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.GetMapping;
@@ -17,6 +11,7 @@
import ssu.eatssu.domain.auth.security.CustomUserDetails;
import ssu.eatssu.domain.partnership.dto.CreatePartnershipRequest;
import ssu.eatssu.domain.partnership.dto.PartnershipResponse;
+import ssu.eatssu.domain.partnership.presentation.docs.PartnershipControllerDocs;
import ssu.eatssu.domain.partnership.service.PartnershipService;
import ssu.eatssu.global.handler.response.BaseResponse;
@@ -25,41 +20,24 @@
@RestController
@RequestMapping("/partnerships")
@RequiredArgsConstructor
-@Tag(name = "Partnership", description = "제휴 API")
-public class PartnershipController {
+public class PartnershipController implements PartnershipControllerDocs {
private final PartnershipService partnershipService;
- @Operation(summary = "제휴 등록", description = "제휴를 등록하는 API 입니다.")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "제휴 등록 성공"),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 대학", content = @Content(schema =
- @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 학과", content = @Content(schema =
- @Schema(implementation = BaseResponse.class))),
- })
+ @Override
@PostMapping
public BaseResponse> createPartnership(@RequestBody CreatePartnershipRequest request) {
partnershipService.createPartnership(request);
return BaseResponse.success();
}
- @Operation(summary = "식당별 전체 제휴 조회", description = "식당별 전체 제휴를 조회하는 API 입니다.")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "제휴 조회 성공"),
- })
+ @Override
@GetMapping
public BaseResponse> getAllPartnerships(@AuthenticationPrincipal CustomUserDetails userDetails) {
return BaseResponse.success(partnershipService.getAllPartnerships(userDetails));
}
- @Operation(summary = "제휴 찜 등록하기/취소하기", description = "제휴 찜 등록하기/취소하기(토글) API 입니다.")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "제휴 찜 등록/취소 성공"),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 제휴", content = @Content(schema =
- @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- })
+ @Override
@PostMapping("/{partnershipId}/like")
public BaseResponse> togglePartnershipLike(
@PathVariable Long partnershipId,
diff --git a/src/main/java/ssu/eatssu/domain/partnership/presentation/docs/PartnershipControllerDocs.java b/src/main/java/ssu/eatssu/domain/partnership/presentation/docs/PartnershipControllerDocs.java
new file mode 100644
index 00000000..b2b30e19
--- /dev/null
+++ b/src/main/java/ssu/eatssu/domain/partnership/presentation/docs/PartnershipControllerDocs.java
@@ -0,0 +1,44 @@
+package ssu.eatssu.domain.partnership.presentation.docs;
+
+import io.swagger.v3.oas.annotations.Operation;
+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 ssu.eatssu.domain.auth.security.CustomUserDetails;
+import ssu.eatssu.domain.partnership.dto.CreatePartnershipRequest;
+import ssu.eatssu.domain.partnership.dto.PartnershipResponse;
+import ssu.eatssu.global.handler.response.BaseResponse;
+
+import java.util.List;
+
+@Tag(name = "Partnership", description = "제휴 API")
+public interface PartnershipControllerDocs {
+
+ @Operation(summary = "제휴 등록", description = "제휴를 등록하는 API 입니다.")
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "제휴 등록 성공"),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 대학", content = @Content(schema =
+ @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 학과", content = @Content(schema =
+ @Schema(implementation = BaseResponse.class))),
+ })
+ BaseResponse> createPartnership(CreatePartnershipRequest request);
+
+ @Operation(summary = "식당별 전체 제휴 조회", description = "식당별 전체 제휴를 조회하는 API 입니다.")
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "제휴 조회 성공"),
+ })
+ BaseResponse> getAllPartnerships(CustomUserDetails userDetails);
+
+ @Operation(summary = "제휴 찜 등록하기/취소하기", description = "제휴 찜 등록하기/취소하기(토글) API 입니다.")
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "제휴 찜 등록/취소 성공"),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 제휴", content = @Content(schema =
+ @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema =
+ @Schema(implementation = BaseResponse.class))),
+ })
+ BaseResponse> togglePartnershipLike(Long partnershipId, CustomUserDetails userDetails);
+}
diff --git a/src/main/java/ssu/eatssu/domain/report/presentation/ReportController.java b/src/main/java/ssu/eatssu/domain/report/presentation/ReportController.java
index e760a02c..1e3499e9 100644
--- a/src/main/java/ssu/eatssu/domain/report/presentation/ReportController.java
+++ b/src/main/java/ssu/eatssu/domain/report/presentation/ReportController.java
@@ -1,11 +1,5 @@
package ssu.eatssu.domain.report.presentation;
-import io.swagger.v3.oas.annotations.Operation;
-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 lombok.RequiredArgsConstructor;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.GetMapping;
@@ -16,6 +10,7 @@
import ssu.eatssu.domain.auth.security.CustomUserDetails;
import ssu.eatssu.domain.report.dto.ReportCreateRequest;
import ssu.eatssu.domain.report.dto.ReportTypeList;
+import ssu.eatssu.domain.report.presentation.docs.ReportControllerDocs;
import ssu.eatssu.domain.report.service.ReportService;
import ssu.eatssu.domain.review.entity.Report;
import ssu.eatssu.domain.slack.entity.SlackChannel;
@@ -26,13 +21,12 @@
@RestController
@RequiredArgsConstructor
@RequestMapping("/reports")
-@Tag(name = "Report", description = "신고 API")
-public class ReportController {
+public class ReportController implements ReportControllerDocs {
private final ReportService reportService;
private final SlackService slackService;
- @Operation(summary = "리뷰 신고 사유 종류 조회", description = "리뷰 신고 사유 종류를 조회하는 API 입니다.")
+ @Override
@GetMapping("/types")
public BaseResponse getReportType() {
ReportTypeList reportTypeList = reportService.getReportType();
@@ -42,13 +36,8 @@ public BaseResponse getReportType() {
/**
* 리뷰 신고
*/
- @Operation(summary = "리뷰 신고하기", description = "리뷰를 신고하는 API 입니다.")
+ @Override
@PostMapping("")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "리뷰 신고 성공", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 리뷰", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
- })
public BaseResponse reportReview(@RequestBody ReportCreateRequest createReportRequest,
@AuthenticationPrincipal CustomUserDetails customUserDetails) {
Report report = reportService.reportReview(customUserDetails, createReportRequest);
diff --git a/src/main/java/ssu/eatssu/domain/report/presentation/docs/ReportControllerDocs.java b/src/main/java/ssu/eatssu/domain/report/presentation/docs/ReportControllerDocs.java
new file mode 100644
index 00000000..b8c9b205
--- /dev/null
+++ b/src/main/java/ssu/eatssu/domain/report/presentation/docs/ReportControllerDocs.java
@@ -0,0 +1,30 @@
+package ssu.eatssu.domain.report.presentation.docs;
+
+import io.swagger.v3.oas.annotations.Operation;
+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 ssu.eatssu.domain.auth.security.CustomUserDetails;
+import ssu.eatssu.domain.report.dto.ReportCreateRequest;
+import ssu.eatssu.domain.report.dto.ReportTypeList;
+import ssu.eatssu.global.handler.response.BaseResponse;
+
+@Tag(name = "Report", description = "신고 API")
+public interface ReportControllerDocs {
+
+ @Operation(summary = "리뷰 신고 사유 종류 조회", description = "리뷰 신고 사유 종류를 조회하는 API 입니다.")
+ BaseResponse getReportType();
+
+ @Operation(summary = "리뷰 신고하기", description = "리뷰를 신고하는 API 입니다.")
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "리뷰 신고 성공", content = @Content(schema =
+ @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema =
+ @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 리뷰", content = @Content(schema =
+ @Schema(implementation = BaseResponse.class)))
+ })
+ BaseResponse reportReview(ReportCreateRequest createReportRequest, CustomUserDetails customUserDetails);
+}
diff --git a/src/main/java/ssu/eatssu/domain/review/presentation/ReviewController.java b/src/main/java/ssu/eatssu/domain/review/presentation/ReviewController.java
index 35439833..3d208384 100644
--- a/src/main/java/ssu/eatssu/domain/review/presentation/ReviewController.java
+++ b/src/main/java/ssu/eatssu/domain/review/presentation/ReviewController.java
@@ -1,16 +1,6 @@
package ssu.eatssu.domain.review.presentation;
-import io.swagger.v3.oas.annotations.Hidden;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.Parameter;
-import io.swagger.v3.oas.annotations.enums.ParameterIn;
-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 lombok.RequiredArgsConstructor;
-import org.springdoc.core.annotations.ParameterObject;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
@@ -37,6 +27,7 @@
import ssu.eatssu.domain.review.dto.ReviewUpdateRequest;
import ssu.eatssu.domain.review.dto.SavedReviewImage;
import ssu.eatssu.domain.review.dto.UploadReviewRequest;
+import ssu.eatssu.domain.review.presentation.docs.ReviewControllerDocs;
import ssu.eatssu.domain.review.service.ReviewService;
import ssu.eatssu.domain.slice.dto.SliceResponse;
import ssu.eatssu.domain.slice.service.SliceService;
@@ -47,33 +38,19 @@
@RestController
@RequiredArgsConstructor
@RequestMapping("/reviews")
-@Tag(name = "Review", description = "리뷰 API")
-public class ReviewController {
+public class ReviewController implements ReviewControllerDocs {
private final ReviewService reviewService;
private final SliceService sliceService;
- @Operation(summary = "리뷰 리스트 조회 [인증 토큰 필수 X]", description = """
- 리뷰 리스트를 조회하는 API 입니다.
- menuType=FIX 의 경우 menuId 파라미터를 넣어주세요.
- menuType=CHANGE 의 경우 mealId 파라미터를 넣어주세요.
- 커서 기반 페이지네이션으로 리뷰 리스트를 조회합니다.
- 페이징 기본 값 = {size=20, sort=date, direction=desc}
- """)
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "리뷰 리스트 조회 성공"),
- @ApiResponse(responseCode = "400", description = "쿼리 파라미터 누락", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 메뉴", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 식단", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
- })
+ @Override
@GetMapping("")
public BaseResponse> getReviews(
- @Parameter(description = "타입(변동메뉴(식단)/고정메뉴)") @RequestParam("menuType") MenuType menuType,
- @Parameter(description = "menuId(고정메뉴)") @RequestParam(value = "menuId", required = false) Long menuId,
- @Parameter(description = "mealId(변동메뉴)") @RequestParam(value = "mealId", required = false) Long mealId,
- @Parameter(description = "마지막으로 조회된 reviewId값(첫 조회시 값 필요 없음)", in = ParameterIn.QUERY)
+ @RequestParam("menuType") MenuType menuType,
+ @RequestParam(value = "menuId", required = false) Long menuId,
+ @RequestParam(value = "mealId", required = false) Long mealId,
@RequestParam(value = "lastReviewId", required = false) Long lastReviewId,
- @ParameterObject @PageableDefault(size = 20, sort = "date", direction = Sort.Direction.DESC) Pageable pageable,
+ @PageableDefault(size = 20, sort = "date", direction = Sort.Direction.DESC) Pageable pageable,
@AuthenticationPrincipal CustomUserDetails customUserDetails) {
SliceResponse myReviews = sliceService.findReviewsV1(menuType, menuId, mealId,
pageable, lastReviewId, customUserDetails);
@@ -81,23 +58,12 @@ public BaseResponse> getReviews(
return BaseResponse.success(myReviews);
}
- @Hidden
- @Operation(summary = "리뷰 작성", description = """
- 리뷰를 작성하는 API 입니다.
- reviewCreate는 application/json, multipartFileList는 multipart/form-data로 요청해주세요.
- 사진은 여러장 첨부 가능합니다.(기획상으로는 한 장만 첨부하도록 제한이 있지만 API 스펙 자체는 여러 장 첨부 가능)
- """)
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "리뷰 작성 성공"),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 메뉴", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "500", description = "이미지 업로드 실패", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
- })
+ @Override
@PostMapping(value = "/{menuId}",
consumes = {MediaType.APPLICATION_JSON_VALUE, MediaType.MULTIPART_FORM_DATA_VALUE},
produces = MediaType.APPLICATION_JSON_VALUE)
public BaseResponse> writeReview(
- @Parameter(description = "menuId") @PathVariable("menuId") Long menuId,
+ @PathVariable("menuId") Long menuId,
@RequestPart ReviewCreateRequest createReviewRequest,
@RequestPart(value = "multipartFileList", required = false) List multipartFileList,
@AuthenticationPrincipal CustomUserDetails customUserDetails) {
@@ -109,11 +75,7 @@ public BaseResponse> writeReview(
/**
* 리뷰 이미지 업로드
*/
- @Operation(summary = "리뷰 이미지 업로드", description = "리뷰 이미지를 업로드하고 이미지 URL 을 반환합니다.")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "이미지 업로드 및 URL 반환 성공"),
- @ApiResponse(responseCode = "500", description = "이미지 업로드 실패", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
- })
+ @Override
@PostMapping(value = "/upload/image",
consumes = MediaType.MULTIPART_FORM_DATA_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
@@ -121,86 +83,43 @@ public BaseResponse uploadReviewImage(@RequestPart(value = "im
return BaseResponse.success(reviewService.uploadImage(image));
}
- @Operation(summary = "리뷰 작성", description = "리뷰를 작성하는 API 입니다.")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "리뷰 작성 성공"),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 메뉴", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- })
+ @Override
@PostMapping("/write/{menuId}")
- public BaseResponse> writeReview(@Parameter(description = "menuId") @PathVariable("menuId") Long menuId,
+ public BaseResponse> writeReview(@PathVariable("menuId") Long menuId,
@RequestBody UploadReviewRequest uploadReviewRequest,
@AuthenticationPrincipal CustomUserDetails customUserDetails) {
reviewService.uploadReview(customUserDetails, menuId, uploadReviewRequest);
return BaseResponse.success();
}
- @Operation(summary = "리뷰 수정(글 수정)", description = """
- 리뷰 내용을 수정하는 API 입니다.
- 글 수정만 가능하며 사진 수정은 지원하지 않습니다.
- """)
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "리뷰 수정 성공"),
- @ApiResponse(responseCode = "403", description = "리뷰에 대한 권한이 없음", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 리뷰", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
- })
+ @Override
@PatchMapping("/{reviewId}")
- public BaseResponse> updateReview(@Parameter(description = "reviewId")
- @PathVariable("reviewId") Long reviewId,
+ public BaseResponse> updateReview(@PathVariable("reviewId") Long reviewId,
@RequestBody ReviewUpdateRequest request,
@AuthenticationPrincipal CustomUserDetails customUserDetails) {
reviewService.updateReview(customUserDetails, reviewId, request);
return BaseResponse.success();
}
- @Operation(summary = "리뷰 삭제", description = "리뷰를 삭제하는 API 입니다.")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "리뷰 삭제 성공"),
- @ApiResponse(responseCode = "403", description = "리뷰에 대한 권한이 없음", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 리뷰", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
- })
+ @Override
@DeleteMapping("/{reviewId}")
public BaseResponse> deleteReview(
- @Parameter(description = "reviewId") @PathVariable("reviewId") Long reviewId,
+ @PathVariable("reviewId") Long reviewId,
@AuthenticationPrincipal CustomUserDetails customUserDetails) {
reviewService.deleteReview(customUserDetails, reviewId);
return BaseResponse.success();
}
- @Operation(summary = "식단(변동 메뉴) 리뷰 정보 조회(메뉴명, 평점 등등) [인증 토큰 필요 X]", description = """
- 식단 리뷰 정보를 조회하는 API 입니다.
- 메뉴명 리스트, 리뷰 수, 메인 평점, 양 평점, 맛 평점, 각 평점의 개수를 조회합니다.
- """)
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "리뷰 정보 조회 성공"),
- @ApiResponse(responseCode = "400", description = "쿼리 파라미터 누락", content = @Content(schema =
- @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 식단", content = @Content(schema =
- @Schema(implementation = BaseResponse.class)))
- })
+ @Override
@GetMapping("/meals/{mealId}")
public BaseResponse getMealReviews(
- @Parameter(description = "mealId")
@PathVariable(value = "mealId") Long mealId) {
return BaseResponse.success(reviewService.findMealReviews(mealId));
}
- @Operation(summary = "고정 메뉴 리뷰 정보 조회(메뉴명, 평점 등등) [인증 토큰 필요 X]", description = """
- 고정 메뉴 리뷰 정보를 조회하는 API 입니다.
- 메뉴명, 리뷰 수, 메인 평점, 양 평점, 맛 평점, 각 평점의 개수를 조회합니다.
- """)
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "리뷰 정보 조회 성공"),
- @ApiResponse(responseCode = "400", description = "쿼리 파라미터 누락", content = @Content(schema =
- @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 메뉴", content = @Content(schema =
- @Schema(implementation = BaseResponse.class)))
- })
+ @Override
@GetMapping("/menus/{menuId}")
public BaseResponse getMainReviews(
- @Parameter(description = "menuId")
@PathVariable(value = "menuId") Long menuId) {
return BaseResponse.success(reviewService.findMenuReviews(menuId));
}
diff --git a/src/main/java/ssu/eatssu/domain/review/presentation/ReviewControllerV2.java b/src/main/java/ssu/eatssu/domain/review/presentation/ReviewControllerV2.java
index c19382e2..70ad0783 100644
--- a/src/main/java/ssu/eatssu/domain/review/presentation/ReviewControllerV2.java
+++ b/src/main/java/ssu/eatssu/domain/review/presentation/ReviewControllerV2.java
@@ -1,16 +1,7 @@
package ssu.eatssu.domain.review.presentation;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.Parameter;
-import io.swagger.v3.oas.annotations.enums.ParameterIn;
-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.validation.Valid;
import lombok.RequiredArgsConstructor;
-import org.springdoc.core.annotations.ParameterObject;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
@@ -37,6 +28,7 @@
import ssu.eatssu.domain.review.dto.ReviewTranslationResponse;
import ssu.eatssu.domain.review.dto.UpdateMealReviewRequest;
import ssu.eatssu.domain.review.dto.ValidMenuForViewResponse;
+import ssu.eatssu.domain.review.presentation.docs.ReviewControllerV2Docs;
import ssu.eatssu.domain.review.service.ReviewServiceV2;
import ssu.eatssu.domain.review.service.ReviewTranslationService;
import ssu.eatssu.domain.slice.dto.SliceResponse;
@@ -47,18 +39,11 @@
@RestController
@RequiredArgsConstructor
@RequestMapping("/v2/reviews")
-@Tag(name = "Review V2", description = "리뷰 V2 API")
-public class ReviewControllerV2 {
+public class ReviewControllerV2 implements ReviewControllerV2Docs {
private final ReviewServiceV2 reviewServiceV2;
private final ReviewTranslationService reviewTranslationService;
- @Operation(summary = "meal(식단)에 대한 리뷰 작성", description = "리뷰를 작성하는 API 입니다.")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "리뷰 작성 성공"),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 식단", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 메뉴", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- })
+ @Override
@PostMapping("/meal")
public BaseResponse> createMealReview(
@Valid @RequestBody CreateMealReviewRequest createMealReviewRequest,
@@ -67,37 +52,18 @@ public BaseResponse> createMealReview(
return BaseResponse.success();
}
- @Operation(summary = "특정 식당 모든 리뷰 정보 조회(리뷰 개수, 평점 등등)", description = """
- 특정 식당 모든 리뷰 정보를 조회하는 API 입니다.
- 리뷰 개수, 별점 별 개수, 리뷰 평점, 좋아요 개수, 싫어요 개수를 조회합니다.
- """)
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "리뷰 정보 조회 성공"),
- @ApiResponse(responseCode = "400", description = "path parameter 누락", content = @Content(schema =
- @Schema(implementation = BaseResponse.class)))
- })
+ @Override
@GetMapping("/statistics/restaurant")
public BaseResponse getRestaurantReviews(
- @Parameter(description = "restaurant")
@RequestParam Restaurant restaurant
) {
return BaseResponse.success(reviewServiceV2.findRestaurantReviews(restaurant));
}
- @Operation(summary = "meal(식단)에 대한 리뷰 리스트 조회", description = """
- 리뷰 리스트를 조회하는 API 입니다.
- 커서 기반 페이지네이션으로 리뷰 리스트를 조회합니다.
- 페이징 기본 값 = {size=20, sort=date, direction=desc}
- """)
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "리뷰 리스트 조회 성공"),
- @ApiResponse(responseCode = "400", description = "쿼리 파라미터 누락", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
- })
+ @Override
@GetMapping("/list/meal")
public BaseResponse> getMealReviewList(
- @Parameter(description = "mealId")
@RequestParam Long mealId,
- @Parameter(description = "마지막으로 조회된 reviewId값(첫 조회시 값 필요 없음)", in = ParameterIn.QUERY)
@RequestParam(value = "lastReviewId", required = false) Long lastReviewId,
@AuthenticationPrincipal CustomUserDetails customUserDetails) {
Pageable pageable = PageRequest.of(0, 20, Sort.by(Sort.Direction.DESC, "id"));
@@ -106,113 +72,52 @@ public BaseResponse> getMealReviewList(
return BaseResponse.success(myReviews);
}
- @Operation(summary = "리뷰 수정(글 수정)", description = """
- 리뷰 내용을 수정하는 API 입니다.
- 글 수정만 가능하며 사진 수정은 지원하지 않습니다.
- """)
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "리뷰 수정 성공"),
- @ApiResponse(responseCode = "403", description = "리뷰에 대한 권한이 없음", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 리뷰", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema =
- @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 메뉴", content = @Content(schema =
- @Schema(implementation = BaseResponse.class)))
- })
+ @Override
@PatchMapping("/{reviewId}")
- public BaseResponse> updateReview(@Parameter(description = "reviewId")
- @PathVariable("reviewId") Long reviewId,
+ public BaseResponse> updateReview(@PathVariable("reviewId") Long reviewId,
@RequestBody UpdateMealReviewRequest request,
@AuthenticationPrincipal CustomUserDetails customUserDetails) {
reviewServiceV2.updateReview(customUserDetails, reviewId, request);
return BaseResponse.success();
}
- @Operation(summary = "리뷰 삭제", description = "리뷰를 삭제하는 API 입니다.")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "리뷰 삭제 성공"),
- @ApiResponse(responseCode = "403", description = "리뷰에 대한 권한이 없음", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 리뷰", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
- })
+ @Override
@DeleteMapping("/{reviewId}")
public BaseResponse> deleteReview(
- @Parameter(description = "reviewId") @PathVariable("reviewId") Long reviewId,
+ @PathVariable("reviewId") Long reviewId,
@AuthenticationPrincipal CustomUserDetails customUserDetails) {
reviewServiceV2.deleteReview(customUserDetails, reviewId);
return BaseResponse.success();
}
- @Operation(summary = "리뷰 번역", description = """
- 리뷰 내용을 DeepL로 번역하는 API 입니다.
- 같은 리뷰/언어 조합은 캐시된 결과를 반환합니다.
- 현재는 language=EN만 지원합니다.
- """)
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "리뷰 번역 성공"),
- @ApiResponse(responseCode = "400", description = "지원하지 않는 언어이거나 번역할 내용이 없음", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 리뷰", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "429", description = "번역 API 사용량 한도 초과", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "503", description = "번역 시간 초과 또는 실패", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
- })
+ @Override
@PostMapping("/{reviewId}/translate")
public BaseResponse translateReview(
- @Parameter(description = "reviewId") @PathVariable("reviewId") Long reviewId,
- @Parameter(description = "번역 대상 언어(현재 EN만 지원)") @RequestParam Language language) {
+ @PathVariable("reviewId") Long reviewId,
+ @RequestParam Language language) {
return BaseResponse.success(reviewTranslationService.translateReview(reviewId, language));
}
- @Operation(summary = "식단(변동 메뉴) 리뷰 정보 조회 V2(메뉴명, 평점 등등) [인증 토큰 필요 X]", description = """
- 식단 리뷰 정보를 조회하는 API 입니다.
- 메뉴명 리스트, 리뷰 수, 메인 평점, 좋아요 개수, 싫어요 개수, 각 평점의 개수를 조회합니다.
- """)
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "리뷰 정보 조회 성공"),
- @ApiResponse(responseCode = "400", description = "쿼리 파라미터 누락", content = @Content(schema =
- @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 식단", content = @Content(schema =
- @Schema(implementation = BaseResponse.class)))
- })
+ @Override
@GetMapping("/statistics/meals/{mealId}")
public BaseResponse getMealReviews(
- @Parameter(description = "mealId")
@PathVariable(value = "mealId") Long mealId) {
return BaseResponse.success(reviewServiceV2.findMealReviews(mealId));
}
- @Operation(summary = "고정 메뉴 리뷰 정보 조회 V2(메뉴명, 평점 등등) [인증 토큰 필요 X]", description = """
- 고정 메뉴 리뷰 정보를 조회하는 API 입니다.
- 메뉴명, 리뷰 수, 메인 평점, 좋아요 개수, 싫어요 개수, 각 평점의 개수를 조회합니다.
- """)
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "리뷰 정보 조회 성공"),
- @ApiResponse(responseCode = "400", description = "쿼리 파라미터 누락", content = @Content(schema =
- @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 메뉴", content = @Content(schema =
- @Schema(implementation = BaseResponse.class)))
- })
+ @Override
@GetMapping("/statistics/menus/{menuId}")
public BaseResponse getMainReviews(
- @Parameter(description = "menuId")
@PathVariable(value = "menuId") Long menuId) {
return BaseResponse.success(reviewServiceV2.findMenuReviews(menuId));
}
- @Operation(summary = "menu 에 대한 리뷰 리스트 조회", description = """
- 리뷰 리스트를 조회하는 API 입니다.
- 커서 기반 페이지네이션으로 리뷰 리스트를 조회합니다.
- 페이징 기본 값 = {size=20, sort=date, direction=desc}
- """)
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "리뷰 리스트 조회 성공"),
- @ApiResponse(responseCode = "400", description = "쿼리 파라미터 누락", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
- })
+ @Override
@GetMapping("/list/menu")
public BaseResponse> getMenuReviewList(
- @Parameter(description = "menuId(고정메뉴)") @RequestParam(value = "menuId") Long menuId,
- @Parameter(description = "마지막으로 조회된 reviewId값(첫 조회시 값 필요 없음)", in = ParameterIn.QUERY)
+ @RequestParam(value = "menuId") Long menuId,
@RequestParam(value = "lastReviewId", required = false) Long lastReviewId,
- @ParameterObject @PageableDefault(size = 20, sort = "date", direction = Sort.Direction.DESC) Pageable pageable,
+ @PageableDefault(size = 20, sort = "date", direction = Sort.Direction.DESC) Pageable pageable,
@AuthenticationPrincipal CustomUserDetails customUserDetails) {
SliceResponse myReviews = reviewServiceV2.findMenuReviewList(menuId,
pageable,
@@ -222,12 +127,7 @@ public BaseResponse> getMenuReviewList(
return BaseResponse.success(myReviews);
}
- @Operation(summary = "menu에 대한 리뷰 작성", description = "리뷰를 작성하는 API 입니다.")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "리뷰 작성 성공"),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 메뉴", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- })
+ @Override
@PostMapping("/menu")
public BaseResponse> createMenuReview(@Valid @RequestBody CreateMenuReviewRequestV2 createMenuReviewRequestV2,
@AuthenticationPrincipal CustomUserDetails customUserDetails) {
@@ -235,15 +135,11 @@ public BaseResponse> createMenuReview(@Valid @RequestBody CreateMenuReviewRequ
return BaseResponse.success();
}
- @Operation(summary = "내가 쓴 리뷰 리스트 조회", description = "내가 쓴 리뷰 리스트를 조회하는 API V2 입니다.")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "내가 쓴 리뷰 리스트 조회 성공"),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
- })
+ @Override
@GetMapping("/my")
public BaseResponse> getMyReviews(
- @Parameter(description = "마지막으로 조회된 reviewId값(첫 조회시 값 필요 없음)", in = ParameterIn.QUERY) @RequestParam(required = false) Long lastReviewId,
- @ParameterObject @PageableDefault(size = 20, sort = "date", direction = Sort.Direction.DESC) Pageable pageable,
+ @RequestParam(required = false) Long lastReviewId,
+ @PageableDefault(size = 20, sort = "date", direction = Sort.Direction.DESC) Pageable pageable,
@AuthenticationPrincipal CustomUserDetails customUserDetails) {
SliceResponse myReviews = reviewServiceV2.findMyReviews(customUserDetails,
lastReviewId,
@@ -251,14 +147,9 @@ public BaseResponse> getMyReviews(
return BaseResponse.success(myReviews);
}
- @Operation(summary = "식단 id를 통해 리뷰 작성할 수 있는 메뉴들 조회", description = "리뷰 작성할 수 있는 메뉴들 조회하는 API입니다. (노션 문서 > 리뷰v2 기능명세서> 리뷰에 제외되는 메뉴 참고")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "리뷰 작성할 수 있는 메뉴들 조회 성공"),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 메뉴", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
- })
+ @Override
@GetMapping("/meal/valid-for-review/{mealId}")
public BaseResponse getValidMenuForReview(
- @Parameter(description = "mealId")
@PathVariable("mealId") Long mealId) {
ValidMenuForViewResponse validMenuForViewResponse = reviewServiceV2.validMenuForReview(mealId);
return BaseResponse.success(validMenuForViewResponse);
diff --git a/src/main/java/ssu/eatssu/domain/review/presentation/docs/ReviewControllerDocs.java b/src/main/java/ssu/eatssu/domain/review/presentation/docs/ReviewControllerDocs.java
new file mode 100644
index 00000000..51b3ee02
--- /dev/null
+++ b/src/main/java/ssu/eatssu/domain/review/presentation/docs/ReviewControllerDocs.java
@@ -0,0 +1,137 @@
+package ssu.eatssu.domain.review.presentation.docs;
+
+import io.swagger.v3.oas.annotations.Hidden;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.enums.ParameterIn;
+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 org.springdoc.core.annotations.ParameterObject;
+import org.springframework.data.domain.Pageable;
+import org.springframework.web.multipart.MultipartFile;
+import ssu.eatssu.domain.auth.security.CustomUserDetails;
+import ssu.eatssu.domain.menu.entity.constants.MenuType;
+import ssu.eatssu.domain.review.dto.MealReviewsResponse;
+import ssu.eatssu.domain.review.dto.MenuReviewResponse;
+import ssu.eatssu.domain.review.dto.ReviewCreateRequest;
+import ssu.eatssu.domain.review.dto.ReviewDetailV1;
+import ssu.eatssu.domain.review.dto.ReviewUpdateRequest;
+import ssu.eatssu.domain.review.dto.SavedReviewImage;
+import ssu.eatssu.domain.review.dto.UploadReviewRequest;
+import ssu.eatssu.domain.slice.dto.SliceResponse;
+import ssu.eatssu.global.handler.response.BaseResponse;
+
+import java.util.List;
+
+@Tag(name = "Review", description = "리뷰 API")
+public interface ReviewControllerDocs {
+
+ @Operation(summary = "리뷰 리스트 조회 [인증 토큰 필수 X]", description = """
+ 리뷰 리스트를 조회하는 API 입니다.
+ menuType=FIX 의 경우 menuId 파라미터를 넣어주세요.
+ menuType=CHANGE 의 경우 mealId 파라미터를 넣어주세요.
+ 커서 기반 페이지네이션으로 리뷰 리스트를 조회합니다.
+ 페이징 기본 값 = {size=20, sort=date, direction=desc}
+ """)
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "리뷰 리스트 조회 성공"),
+ @ApiResponse(responseCode = "400", description = "쿼리 파라미터 누락", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 메뉴", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 식단", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
+ })
+ BaseResponse> getReviews(
+ @Parameter(description = "타입(변동메뉴(식단)/고정메뉴)") MenuType menuType,
+ @Parameter(description = "menuId(고정메뉴)") Long menuId,
+ @Parameter(description = "mealId(변동메뉴)") Long mealId,
+ @Parameter(description = "마지막으로 조회된 reviewId값(첫 조회시 값 필요 없음)", in = ParameterIn.QUERY) Long lastReviewId,
+ @ParameterObject Pageable pageable,
+ CustomUserDetails customUserDetails);
+
+ @Hidden
+ @Operation(summary = "리뷰 작성", description = """
+ 리뷰를 작성하는 API 입니다.
+ reviewCreate는 application/json, multipartFileList는 multipart/form-data로 요청해주세요.
+ 사진은 여러장 첨부 가능합니다.(기획상으로는 한 장만 첨부하도록 제한이 있지만 API 스펙 자체는 여러 장 첨부 가능)
+ """)
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "리뷰 작성 성공"),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 메뉴", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "500", description = "이미지 업로드 실패", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
+ })
+ BaseResponse> writeReview(
+ @Parameter(description = "menuId") Long menuId,
+ ReviewCreateRequest createReviewRequest,
+ List multipartFileList,
+ CustomUserDetails customUserDetails);
+
+ @Operation(summary = "리뷰 이미지 업로드", description = "리뷰 이미지를 업로드하고 이미지 URL 을 반환합니다.")
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "이미지 업로드 및 URL 반환 성공"),
+ @ApiResponse(responseCode = "500", description = "이미지 업로드 실패", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
+ })
+ BaseResponse uploadReviewImage(MultipartFile image);
+
+ @Operation(summary = "리뷰 작성", description = "리뷰를 작성하는 API 입니다.")
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "리뷰 작성 성공"),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 메뉴", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
+ })
+ BaseResponse> writeReview(@Parameter(description = "menuId") Long menuId,
+ UploadReviewRequest uploadReviewRequest,
+ CustomUserDetails customUserDetails);
+
+ @Operation(summary = "리뷰 수정(글 수정)", description = """
+ 리뷰 내용을 수정하는 API 입니다.
+ 글 수정만 가능하며 사진 수정은 지원하지 않습니다.
+ """)
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "리뷰 수정 성공"),
+ @ApiResponse(responseCode = "403", description = "리뷰에 대한 권한이 없음", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 리뷰", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
+ })
+ BaseResponse> updateReview(@Parameter(description = "reviewId") Long reviewId,
+ ReviewUpdateRequest request,
+ CustomUserDetails customUserDetails);
+
+ @Operation(summary = "리뷰 삭제", description = "리뷰를 삭제하는 API 입니다.")
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "리뷰 삭제 성공"),
+ @ApiResponse(responseCode = "403", description = "리뷰에 대한 권한이 없음", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 리뷰", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
+ })
+ BaseResponse> deleteReview(@Parameter(description = "reviewId") Long reviewId,
+ CustomUserDetails customUserDetails);
+
+ @Operation(summary = "식단(변동 메뉴) 리뷰 정보 조회(메뉴명, 평점 등등) [인증 토큰 필요 X]", description = """
+ 식단 리뷰 정보를 조회하는 API 입니다.
+ 메뉴명 리스트, 리뷰 수, 메인 평점, 양 평점, 맛 평점, 각 평점의 개수를 조회합니다.
+ """)
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "리뷰 정보 조회 성공"),
+ @ApiResponse(responseCode = "400", description = "쿼리 파라미터 누락", content = @Content(schema =
+ @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 식단", content = @Content(schema =
+ @Schema(implementation = BaseResponse.class)))
+ })
+ BaseResponse getMealReviews(@Parameter(description = "mealId") Long mealId);
+
+ @Operation(summary = "고정 메뉴 리뷰 정보 조회(메뉴명, 평점 등등) [인증 토큰 필요 X]", description = """
+ 고정 메뉴 리뷰 정보를 조회하는 API 입니다.
+ 메뉴명, 리뷰 수, 메인 평점, 양 평점, 맛 평점, 각 평점의 개수를 조회합니다.
+ """)
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "리뷰 정보 조회 성공"),
+ @ApiResponse(responseCode = "400", description = "쿼리 파라미터 누락", content = @Content(schema =
+ @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 메뉴", content = @Content(schema =
+ @Schema(implementation = BaseResponse.class)))
+ })
+ BaseResponse getMainReviews(@Parameter(description = "menuId") Long menuId);
+}
diff --git a/src/main/java/ssu/eatssu/domain/review/presentation/docs/ReviewControllerV2Docs.java b/src/main/java/ssu/eatssu/domain/review/presentation/docs/ReviewControllerV2Docs.java
new file mode 100644
index 00000000..01a2d1e9
--- /dev/null
+++ b/src/main/java/ssu/eatssu/domain/review/presentation/docs/ReviewControllerV2Docs.java
@@ -0,0 +1,178 @@
+package ssu.eatssu.domain.review.presentation.docs;
+
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.enums.ParameterIn;
+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 org.springdoc.core.annotations.ParameterObject;
+import org.springframework.data.domain.Pageable;
+import ssu.eatssu.domain.auth.security.CustomUserDetails;
+import ssu.eatssu.domain.restaurant.entity.Restaurant;
+import ssu.eatssu.domain.review.dto.CreateMealReviewRequest;
+import ssu.eatssu.domain.review.dto.CreateMenuReviewRequestV2;
+import ssu.eatssu.domain.review.dto.MealReviewResponse;
+import ssu.eatssu.domain.review.dto.MealReviewsV2Response;
+import ssu.eatssu.domain.review.dto.MenuReviewsV2Response;
+import ssu.eatssu.domain.review.dto.RestaurantReviewResponse;
+import ssu.eatssu.domain.review.dto.ReviewDetail;
+import ssu.eatssu.domain.review.dto.ReviewTranslationResponse;
+import ssu.eatssu.domain.review.dto.UpdateMealReviewRequest;
+import ssu.eatssu.domain.review.dto.ValidMenuForViewResponse;
+import ssu.eatssu.domain.slice.dto.SliceResponse;
+import ssu.eatssu.domain.user.dto.MyMealReviewResponse;
+import ssu.eatssu.domain.user.entity.Language;
+import ssu.eatssu.global.handler.response.BaseResponse;
+
+@Tag(name = "Review V2", description = "리뷰 V2 API")
+public interface ReviewControllerV2Docs {
+
+ @Operation(summary = "meal(식단)에 대한 리뷰 작성", description = "리뷰를 작성하는 API 입니다.")
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "리뷰 작성 성공"),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 식단", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 메뉴", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
+ })
+ BaseResponse> createMealReview(CreateMealReviewRequest createMealReviewRequest,
+ CustomUserDetails customUserDetails);
+
+ @Operation(summary = "특정 식당 모든 리뷰 정보 조회(리뷰 개수, 평점 등등)", description = """
+ 특정 식당 모든 리뷰 정보를 조회하는 API 입니다.
+ 리뷰 개수, 별점 별 개수, 리뷰 평점, 좋아요 개수, 싫어요 개수를 조회합니다.
+ """)
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "리뷰 정보 조회 성공"),
+ @ApiResponse(responseCode = "400", description = "path parameter 누락", content = @Content(schema =
+ @Schema(implementation = BaseResponse.class)))
+ })
+ BaseResponse getRestaurantReviews(
+ @Parameter(description = "restaurant") Restaurant restaurant);
+
+ @Operation(summary = "meal(식단)에 대한 리뷰 리스트 조회", description = """
+ 리뷰 리스트를 조회하는 API 입니다.
+ 커서 기반 페이지네이션으로 리뷰 리스트를 조회합니다.
+ 페이징 기본 값 = {size=20, sort=date, direction=desc}
+ """)
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "리뷰 리스트 조회 성공"),
+ @ApiResponse(responseCode = "400", description = "쿼리 파라미터 누락", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
+ })
+ BaseResponse> getMealReviewList(
+ @Parameter(description = "mealId") Long mealId,
+ @Parameter(description = "마지막으로 조회된 reviewId값(첫 조회시 값 필요 없음)", in = ParameterIn.QUERY) Long lastReviewId,
+ CustomUserDetails customUserDetails);
+
+ @Operation(summary = "리뷰 수정(글 수정)", description = """
+ 리뷰 내용을 수정하는 API 입니다.
+ 글 수정만 가능하며 사진 수정은 지원하지 않습니다.
+ """)
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "리뷰 수정 성공"),
+ @ApiResponse(responseCode = "403", description = "리뷰에 대한 권한이 없음", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 리뷰", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema =
+ @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 메뉴", content = @Content(schema =
+ @Schema(implementation = BaseResponse.class)))
+ })
+ BaseResponse> updateReview(@Parameter(description = "reviewId") Long reviewId,
+ UpdateMealReviewRequest request,
+ CustomUserDetails customUserDetails);
+
+ @Operation(summary = "리뷰 삭제", description = "리뷰를 삭제하는 API 입니다.")
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "리뷰 삭제 성공"),
+ @ApiResponse(responseCode = "403", description = "리뷰에 대한 권한이 없음", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 리뷰", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
+ })
+ BaseResponse> deleteReview(@Parameter(description = "reviewId") Long reviewId,
+ CustomUserDetails customUserDetails);
+
+ @Operation(summary = "리뷰 번역", description = """
+ 리뷰 내용을 DeepL로 번역하는 API 입니다.
+ 같은 리뷰/언어 조합은 캐시된 결과를 반환합니다.
+ 현재는 language=EN만 지원합니다.
+ """)
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "리뷰 번역 성공"),
+ @ApiResponse(responseCode = "400", description = "지원하지 않는 언어이거나 번역할 내용이 없음", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 리뷰", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "429", description = "번역 API 사용량 한도 초과", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "503", description = "번역 시간 초과 또는 실패", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
+ })
+ BaseResponse translateReview(
+ @Parameter(description = "reviewId") Long reviewId,
+ @Parameter(description = "번역 대상 언어(현재 EN만 지원)") Language language);
+
+ @Operation(summary = "식단(변동 메뉴) 리뷰 정보 조회 V2(메뉴명, 평점 등등) [인증 토큰 필요 X]", description = """
+ 식단 리뷰 정보를 조회하는 API 입니다.
+ 메뉴명 리스트, 리뷰 수, 메인 평점, 좋아요 개수, 싫어요 개수, 각 평점의 개수를 조회합니다.
+ """)
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "리뷰 정보 조회 성공"),
+ @ApiResponse(responseCode = "400", description = "쿼리 파라미터 누락", content = @Content(schema =
+ @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 식단", content = @Content(schema =
+ @Schema(implementation = BaseResponse.class)))
+ })
+ BaseResponse getMealReviews(@Parameter(description = "mealId") Long mealId);
+
+ @Operation(summary = "고정 메뉴 리뷰 정보 조회 V2(메뉴명, 평점 등등) [인증 토큰 필요 X]", description = """
+ 고정 메뉴 리뷰 정보를 조회하는 API 입니다.
+ 메뉴명, 리뷰 수, 메인 평점, 좋아요 개수, 싫어요 개수, 각 평점의 개수를 조회합니다.
+ """)
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "리뷰 정보 조회 성공"),
+ @ApiResponse(responseCode = "400", description = "쿼리 파라미터 누락", content = @Content(schema =
+ @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 메뉴", content = @Content(schema =
+ @Schema(implementation = BaseResponse.class)))
+ })
+ BaseResponse getMainReviews(@Parameter(description = "menuId") Long menuId);
+
+ @Operation(summary = "menu 에 대한 리뷰 리스트 조회", description = """
+ 리뷰 리스트를 조회하는 API 입니다.
+ 커서 기반 페이지네이션으로 리뷰 리스트를 조회합니다.
+ 페이징 기본 값 = {size=20, sort=date, direction=desc}
+ """)
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "리뷰 리스트 조회 성공"),
+ @ApiResponse(responseCode = "400", description = "쿼리 파라미터 누락", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
+ })
+ BaseResponse> getMenuReviewList(
+ @Parameter(description = "menuId(고정메뉴)") Long menuId,
+ @Parameter(description = "마지막으로 조회된 reviewId값(첫 조회시 값 필요 없음)", in = ParameterIn.QUERY) Long lastReviewId,
+ @ParameterObject Pageable pageable,
+ CustomUserDetails customUserDetails);
+
+ @Operation(summary = "menu에 대한 리뷰 작성", description = "리뷰를 작성하는 API 입니다.")
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "리뷰 작성 성공"),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 메뉴", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
+ })
+ BaseResponse> createMenuReview(CreateMenuReviewRequestV2 createMenuReviewRequestV2,
+ CustomUserDetails customUserDetails);
+
+ @Operation(summary = "내가 쓴 리뷰 리스트 조회", description = "내가 쓴 리뷰 리스트를 조회하는 API V2 입니다.")
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "내가 쓴 리뷰 리스트 조회 성공"),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
+ })
+ BaseResponse> getMyReviews(
+ @Parameter(description = "마지막으로 조회된 reviewId값(첫 조회시 값 필요 없음)", in = ParameterIn.QUERY) Long lastReviewId,
+ @ParameterObject Pageable pageable,
+ CustomUserDetails customUserDetails);
+
+ @Operation(summary = "식단 id를 통해 리뷰 작성할 수 있는 메뉴들 조회", description = "리뷰 작성할 수 있는 메뉴들 조회하는 API입니다. (노션 문서 > 리뷰v2 기능명세서> 리뷰에 제외되는 메뉴 참고")
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "리뷰 작성할 수 있는 메뉴들 조회 성공"),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 메뉴", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
+ })
+ BaseResponse getValidMenuForReview(@Parameter(description = "mealId") Long mealId);
+}
diff --git a/src/main/java/ssu/eatssu/domain/user/presentation/UserController.java b/src/main/java/ssu/eatssu/domain/user/presentation/UserController.java
index 9b7fe845..4ad35db7 100644
--- a/src/main/java/ssu/eatssu/domain/user/presentation/UserController.java
+++ b/src/main/java/ssu/eatssu/domain/user/presentation/UserController.java
@@ -1,16 +1,7 @@
package ssu.eatssu.domain.user.presentation;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.Parameter;
-import io.swagger.v3.oas.annotations.enums.ParameterIn;
-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.validation.Valid;
import lombok.RequiredArgsConstructor;
-import org.springdoc.core.annotations.ParameterObject;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
@@ -40,6 +31,7 @@
import ssu.eatssu.domain.user.dto.MyReviewDetail;
import ssu.eatssu.domain.user.dto.NicknameUpdateRequest;
import ssu.eatssu.domain.user.dto.UpdateDepartmentRequest;
+import ssu.eatssu.domain.user.presentation.docs.UserControllerDocs;
import ssu.eatssu.domain.user.service.UserService;
import ssu.eatssu.global.handler.response.BaseResponse;
@@ -48,66 +40,27 @@
@RestController
@RequiredArgsConstructor
@RequestMapping("/users")
-@Tag(name = "User", description = "유저 API")
-public class UserController {
+public class UserController implements UserControllerDocs {
private final UserService userService;
private final SliceService sliceService;
private final PartnershipService partnershipService;
private final ReviewServiceV2 reviewServiceV2;
- @Operation(summary = "이메일 중복 체크", description = """
- 이메일 중복 체크 API 입니다.
- 중복되지 않은 이메일이면 true 를 반환합니다
- """)
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "중복되지 않은 이메일")
- })
+ @Override
@PostMapping("/validate/email/{email}") //todo: 중복인 경우 error throw, 중복 아니면 ApiReposne return
public BaseResponse validateDuplicatedEmail(
- @Parameter(description = "이메일") @PathVariable String email) {
+ @PathVariable String email) {
return BaseResponse.success(userService.validateDuplicatedEmail(email));
}
- @Operation(summary = "닉네임 중복 및 유효성 체크", description = """
- 닉네임 중복 및 유효성 체크 API 입니다.
- 유효하고 중복되지 않은 닉네임이면 true 를 반환합니다
- """)
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "유효하고 중복되지 않은 닉네임"),
- @ApiResponse(responseCode = "400", description = "숫자로만 이루어진 닉네임", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "400", description = "연속된 공백을 포함하는 닉네임", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "400", description = "연속된 하이폰을 사용하는 닉네임", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "400", description = "첫 글자가 한글,영문,숫자가 아닌 경우", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "400", description = "마지막 글자가 한글,영문,숫자가 아닌 경우", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "400", description = "한글,영문,숫자,공백,하이폰(-)이외의 문자를 쓴 경우", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "400", description = "닉네임이 1자 이상 16이하가 아닌 경우", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "400", description = "서비스명/브랜드명 단독 닉네임", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "400", description = "관리자로 혼동될 수 있는 닉네임", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "400", description = "욕설/비속어가 이름에 포함되는 경우", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
- })
+ @Override
@GetMapping("/validate/nickname")
- public BaseResponse validateNickname(@Parameter(description = "닉네임")
- @RequestParam(value = "nickname") String nickname) {
+ public BaseResponse validateNickname(@RequestParam(value = "nickname") String nickname) {
return BaseResponse.success(userService.validateNickname(nickname));
}
- @Operation(summary = "닉네임 수정", description = "닉네임 수정 API 입니다.")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "닉네임 수정 성공"),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "400", description = "숫자로만 이루어진 닉네임", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "400", description = "연속된 공백을 포함하는 닉네임", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "400", description = "연속된 하이폰을 사용하는 닉네임", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "400", description = "첫 글자가 한글,영문,숫자가 아닌 경우", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "400", description = "마지막 글자가 한글,영문,숫자가 아닌 경우", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "400", description = "한글,영문,숫자,공백,하이폰(-)이외의 문자를 쓴 경우", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "400", description = "닉네임이 1자 이상 16이하가 아닌 경우", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "400", description = "서비스명/브랜드명 단독 닉네임", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "400", description = "관리자로 혼동될 수 있는 닉네임", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "400", description = "욕설/비속어가 이름에 포함되는 경우", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "409", description = "중복된 닉네임", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
- })
+ @Override
@PatchMapping("/nickname")
public BaseResponse> updateNickname(
@Valid @RequestBody NicknameUpdateRequest updateNicknameRequest,
@@ -116,12 +69,7 @@ public BaseResponse> updateNickname(
return BaseResponse.success();
}
- @Operation(summary = "언어 설정 수정", description = "유저의 언어 설정을 수정하는 API 입니다.")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "언어 설정 수정 성공"),
- @ApiResponse(responseCode = "400", description = "지원하지 않는 언어 또는 누락된 언어 설정", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
- })
+ @Override
@PatchMapping("/language")
public BaseResponse> updateLanguage(
@Valid @RequestBody LanguageUpdateRequest request,
@@ -130,36 +78,24 @@ public BaseResponse> updateLanguage(
return BaseResponse.success();
}
- @Operation(summary = "언어 설정 조회", description = "유저의 언어 설정을 조회하는 API 입니다.")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "언어 설정 조회 성공"),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
- })
+ @Override
@GetMapping("/language")
public BaseResponse getLanguage(
@AuthenticationPrincipal CustomUserDetails userDetails) {
return BaseResponse.success(userService.findLanguage(userDetails));
}
- @Operation(summary = "유저 탈퇴", description = "유저 탈퇴 API 입니다.")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "유저 탈퇴 성공"),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
- })
+ @Override
@DeleteMapping("")
public BaseResponse withdraw(@AuthenticationPrincipal CustomUserDetails userDetails) {
return BaseResponse.success(userService.withdraw(userDetails));
}
- @Operation(summary = "내가 쓴 리뷰 리스트 조회", description = "내가 쓴 리뷰 리스트를 조회하는 API 입니다.")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "내가 쓴 리뷰 리스트 조회 성공"),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
- })
+ @Override
@GetMapping("/reviews")
public BaseResponse> getMyReviewList(
- @Parameter(description = "마지막으로 조회된 reviewId값(첫 조회시 값 필요 없음)", in = ParameterIn.QUERY) @RequestParam(required = false) Long lastReviewId,
- @ParameterObject @PageableDefault(size = 20, sort = "date", direction = Sort.Direction.DESC) Pageable pageable,
+ @RequestParam(required = false) Long lastReviewId,
+ @PageableDefault(size = 20, sort = "date", direction = Sort.Direction.DESC) Pageable pageable,
@AuthenticationPrincipal CustomUserDetails customUserDetails) {
SliceResponse myReviews = sliceService.findMyReviews(customUserDetails,
pageable,
@@ -168,37 +104,21 @@ public BaseResponse> getMyReviewList(
}
- @Operation(summary = "마이페이지 정보 조회", description = "마이페이지 정보를 조회하는 API 입니다.")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "마이페이지 정보 조회 성공"),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
- })
+ @Override
@GetMapping("/mypage")
public BaseResponse getMyPage(
@AuthenticationPrincipal CustomUserDetails customUserDetails) {
return BaseResponse.success(userService.findMyPage(customUserDetails));
}
- @Operation(summary = "유저가 찜한 제휴 조회", description = "유저가 찜한 제휴를 조회하는 API 입니다.")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "유저가 찜한 제휴 조회 성공"),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema =
- @Schema(implementation = BaseResponse.class))),
- })
+ @Override
@GetMapping("/partnerships")
public BaseResponse> getUserLikedPartnerships(
@AuthenticationPrincipal CustomUserDetails userDetails) {
return BaseResponse.success(partnershipService.getUserLikedPartnerships(userDetails));
}
- @Operation(summary = "유저의 학과 등록", description = "유저의 학과를 등록하는 API 입니다.")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "유저의 학과 등록 성공"),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema =
- @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 학과", content = @Content(schema =
- @Schema(implementation = BaseResponse.class))),
- })
+ @Override
@PostMapping("/department")
public BaseResponse> registerDepartment(@RequestBody UpdateDepartmentRequest request,
@AuthenticationPrincipal CustomUserDetails userDetails) {
@@ -206,14 +126,7 @@ public BaseResponse> registerDepartment(@RequestBody UpdateDepartmentRequest r
return BaseResponse.success();
}
- @Operation(summary = "유저의 단과대/학과 제휴 조회", description = "유저의 단과대/학과 제휴를 조회하는 API 입니다.")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "유저의 단과대/학과 제휴 조회 성공"),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema =
- @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "400", description = "유저의 학과 정보가 등록되지 않음", content = @Content(schema =
- @Schema(implementation = BaseResponse.class))),
- })
+ @Override
@GetMapping("/department/partnerships")
public BaseResponse> getUserDepartmentPartnerships(
@AuthenticationPrincipal CustomUserDetails userDetails) {
@@ -221,28 +134,17 @@ public BaseResponse> getUserDepartmentPartnerships(
}
- @Operation(summary = "유저의 학과 조회", description = "유저의 학과를 조회하는 API 입니다.")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "유저의 학과 조회 성공"),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema =
- @Schema(implementation = BaseResponse.class))),
- @ApiResponse(responseCode = "400", description = "유저의 학과 정보가 등록되지 않음", content = @Content(schema =
- @Schema(implementation = BaseResponse.class))),
- })
+ @Override
@GetMapping("/department")
public BaseResponse getDepartment(@AuthenticationPrincipal CustomUserDetails userDetails) {
return BaseResponse.success(userService.getDepartment(userDetails));
}
- @Operation(summary = "내가 쓴 리뷰 리스트 조회", description = "내가 쓴 리뷰 리스트를 조회하는 API V2 입니다.")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "내가 쓴 리뷰 리스트 조회 성공"),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
- })
+ @Override
@GetMapping("/v2/reviews")
public BaseResponse> getMyReviews(
- @Parameter(description = "마지막으로 조회된 reviewId값(첫 조회시 값 필요 없음)", in = ParameterIn.QUERY) @RequestParam(required = false) Long lastReviewId,
- @ParameterObject @PageableDefault(size = 20, sort = "date", direction = Sort.Direction.DESC) Pageable pageable,
+ @RequestParam(required = false) Long lastReviewId,
+ @PageableDefault(size = 20, sort = "date", direction = Sort.Direction.DESC) Pageable pageable,
@AuthenticationPrincipal CustomUserDetails customUserDetails) {
SliceResponse myReviews = reviewServiceV2.findMyReviews(customUserDetails,
lastReviewId,
@@ -250,11 +152,7 @@ public BaseResponse> getMyReviews(
return BaseResponse.success(myReviews);
}
- @Operation(summary = "단과대 조회", description = "숭실대학교 단과대학 들을 조회하는 API입니다.(토큰 불필요)")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "단과대 리스트 조회 성공"),
- @ApiResponse(responseCode = "404", description = "존재하지 않는 단과대", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
- })
+ @Override
@GetMapping("/lookup/colleges")
public BaseResponse> getColleges(
@AuthenticationPrincipal CustomUserDetails userDetails) {
@@ -262,10 +160,7 @@ public BaseResponse> getColleges(
return BaseResponse.success(getCollegeResponses);
}
- @Operation(summary = "단과대에 따른 학과 조회", description = "단과대학을 입력하면 단과대에 속한 숭실대학교 학과를 조회하는 API입니다.(토큰 불필요)")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "단과대 리스트 조회 성공"),
- })
+ @Override
@GetMapping("/lookup/departments")
public BaseResponse> getDepartments(@RequestParam Long collegeId,
@AuthenticationPrincipal CustomUserDetails userDetails) {
diff --git a/src/main/java/ssu/eatssu/domain/user/presentation/docs/UserControllerDocs.java b/src/main/java/ssu/eatssu/domain/user/presentation/docs/UserControllerDocs.java
new file mode 100644
index 00000000..06bfcd62
--- /dev/null
+++ b/src/main/java/ssu/eatssu/domain/user/presentation/docs/UserControllerDocs.java
@@ -0,0 +1,178 @@
+package ssu.eatssu.domain.user.presentation.docs;
+
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.enums.ParameterIn;
+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 org.springdoc.core.annotations.ParameterObject;
+import org.springframework.data.domain.Pageable;
+import ssu.eatssu.domain.auth.security.CustomUserDetails;
+import ssu.eatssu.domain.partnership.dto.PartnershipResponse;
+import ssu.eatssu.domain.slice.dto.SliceResponse;
+import ssu.eatssu.domain.user.dto.DepartmentResponse;
+import ssu.eatssu.domain.user.dto.GetCollegeResponse;
+import ssu.eatssu.domain.user.dto.GetDepartmentResponse;
+import ssu.eatssu.domain.user.dto.LanguageResponse;
+import ssu.eatssu.domain.user.dto.LanguageUpdateRequest;
+import ssu.eatssu.domain.user.dto.MyMealReviewResponse;
+import ssu.eatssu.domain.user.dto.MyPageResponse;
+import ssu.eatssu.domain.user.dto.MyReviewDetail;
+import ssu.eatssu.domain.user.dto.NicknameUpdateRequest;
+import ssu.eatssu.domain.user.dto.UpdateDepartmentRequest;
+import ssu.eatssu.global.handler.response.BaseResponse;
+
+import java.util.List;
+
+@Tag(name = "User", description = "유저 API")
+public interface UserControllerDocs {
+
+ @Operation(summary = "이메일 중복 체크", description = """
+ 이메일 중복 체크 API 입니다.
+ 중복되지 않은 이메일이면 true 를 반환합니다
+ """)
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "중복되지 않은 이메일")
+ })
+ BaseResponse validateDuplicatedEmail(@Parameter(description = "이메일") String email);
+
+ @Operation(summary = "닉네임 중복 및 유효성 체크", description = """
+ 닉네임 중복 및 유효성 체크 API 입니다.
+ 유효하고 중복되지 않은 닉네임이면 true 를 반환합니다
+ """)
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "유효하고 중복되지 않은 닉네임"),
+ @ApiResponse(responseCode = "400", description = "숫자로만 이루어진 닉네임", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "400", description = "연속된 공백을 포함하는 닉네임", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "400", description = "연속된 하이폰을 사용하는 닉네임", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "400", description = "첫 글자가 한글,영문,숫자가 아닌 경우", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "400", description = "마지막 글자가 한글,영문,숫자가 아닌 경우", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "400", description = "한글,영문,숫자,공백,하이폰(-)이외의 문자를 쓴 경우", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "400", description = "닉네임이 1자 이상 16이하가 아닌 경우", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "400", description = "서비스명/브랜드명 단독 닉네임", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "400", description = "관리자로 혼동될 수 있는 닉네임", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "400", description = "욕설/비속어가 이름에 포함되는 경우", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
+ })
+ BaseResponse validateNickname(@Parameter(description = "닉네임") String nickname);
+
+ @Operation(summary = "닉네임 수정", description = "닉네임 수정 API 입니다.")
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "닉네임 수정 성공"),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "400", description = "숫자로만 이루어진 닉네임", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "400", description = "연속된 공백을 포함하는 닉네임", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "400", description = "연속된 하이폰을 사용하는 닉네임", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "400", description = "첫 글자가 한글,영문,숫자가 아닌 경우", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "400", description = "마지막 글자가 한글,영문,숫자가 아닌 경우", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "400", description = "한글,영문,숫자,공백,하이폰(-)이외의 문자를 쓴 경우", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "400", description = "닉네임이 1자 이상 16이하가 아닌 경우", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "400", description = "서비스명/브랜드명 단독 닉네임", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "400", description = "관리자로 혼동될 수 있는 닉네임", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "400", description = "욕설/비속어가 이름에 포함되는 경우", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "409", description = "중복된 닉네임", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
+ })
+ BaseResponse> updateNickname(NicknameUpdateRequest updateNicknameRequest, CustomUserDetails userDetails);
+
+ @Operation(summary = "언어 설정 수정", description = "유저의 언어 설정을 수정하는 API 입니다.")
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "언어 설정 수정 성공"),
+ @ApiResponse(responseCode = "400", description = "지원하지 않는 언어 또는 누락된 언어 설정", content = @Content(schema = @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
+ })
+ BaseResponse> updateLanguage(LanguageUpdateRequest request, CustomUserDetails userDetails);
+
+ @Operation(summary = "언어 설정 조회", description = "유저의 언어 설정을 조회하는 API 입니다.")
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "언어 설정 조회 성공"),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
+ })
+ BaseResponse getLanguage(CustomUserDetails userDetails);
+
+ @Operation(summary = "유저 탈퇴", description = "유저 탈퇴 API 입니다.")
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "유저 탈퇴 성공"),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
+ })
+ BaseResponse withdraw(CustomUserDetails userDetails);
+
+ @Operation(summary = "내가 쓴 리뷰 리스트 조회", description = "내가 쓴 리뷰 리스트를 조회하는 API 입니다.")
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "내가 쓴 리뷰 리스트 조회 성공"),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
+ })
+ BaseResponse> getMyReviewList(
+ @Parameter(description = "마지막으로 조회된 reviewId값(첫 조회시 값 필요 없음)", in = ParameterIn.QUERY) Long lastReviewId,
+ @ParameterObject Pageable pageable,
+ CustomUserDetails customUserDetails);
+
+ @Operation(summary = "마이페이지 정보 조회", description = "마이페이지 정보를 조회하는 API 입니다.")
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "마이페이지 정보 조회 성공"),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
+ })
+ BaseResponse getMyPage(CustomUserDetails customUserDetails);
+
+ @Operation(summary = "유저가 찜한 제휴 조회", description = "유저가 찜한 제휴를 조회하는 API 입니다.")
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "유저가 찜한 제휴 조회 성공"),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema =
+ @Schema(implementation = BaseResponse.class))),
+ })
+ BaseResponse> getUserLikedPartnerships(CustomUserDetails userDetails);
+
+ @Operation(summary = "유저의 학과 등록", description = "유저의 학과를 등록하는 API 입니다.")
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "유저의 학과 등록 성공"),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema =
+ @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 학과", content = @Content(schema =
+ @Schema(implementation = BaseResponse.class))),
+ })
+ BaseResponse> registerDepartment(UpdateDepartmentRequest request, CustomUserDetails userDetails);
+
+ @Operation(summary = "유저의 단과대/학과 제휴 조회", description = "유저의 단과대/학과 제휴를 조회하는 API 입니다.")
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "유저의 단과대/학과 제휴 조회 성공"),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema =
+ @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "400", description = "유저의 학과 정보가 등록되지 않음", content = @Content(schema =
+ @Schema(implementation = BaseResponse.class))),
+ })
+ BaseResponse> getUserDepartmentPartnerships(CustomUserDetails userDetails);
+
+ @Operation(summary = "유저의 학과 조회", description = "유저의 학과를 조회하는 API 입니다.")
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "유저의 학과 조회 성공"),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema =
+ @Schema(implementation = BaseResponse.class))),
+ @ApiResponse(responseCode = "400", description = "유저의 학과 정보가 등록되지 않음", content = @Content(schema =
+ @Schema(implementation = BaseResponse.class))),
+ })
+ BaseResponse getDepartment(CustomUserDetails userDetails);
+
+ @Operation(summary = "내가 쓴 리뷰 리스트 조회", description = "내가 쓴 리뷰 리스트를 조회하는 API V2 입니다.")
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "내가 쓴 리뷰 리스트 조회 성공"),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 유저", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
+ })
+ BaseResponse> getMyReviews(
+ @Parameter(description = "마지막으로 조회된 reviewId값(첫 조회시 값 필요 없음)", in = ParameterIn.QUERY) Long lastReviewId,
+ @ParameterObject Pageable pageable,
+ CustomUserDetails customUserDetails);
+
+ @Operation(summary = "단과대 조회", description = "숭실대학교 단과대학 들을 조회하는 API입니다.(토큰 불필요)")
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "단과대 리스트 조회 성공"),
+ @ApiResponse(responseCode = "404", description = "존재하지 않는 단과대", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
+ })
+ BaseResponse> getColleges(CustomUserDetails userDetails);
+
+ @Operation(summary = "단과대에 따른 학과 조회", description = "단과대학을 입력하면 단과대에 속한 숭실대학교 학과를 조회하는 API입니다.(토큰 불필요)")
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "단과대 리스트 조회 성공"),
+ })
+ BaseResponse> getDepartments(Long collegeId, CustomUserDetails userDetails);
+}