diff --git a/build.gradle b/build.gradle index a6f602bb..d7c2a754 100644 --- a/build.gradle +++ b/build.gradle @@ -47,6 +47,7 @@ dependencies { implementation "com.querydsl:querydsl-jpa:${queryDslVersion}" implementation "com.querydsl:querydsl-apt:${queryDslVersion}" implementation('org.flywaydb:flyway-core:6.4.2') + implementation 'org.springdoc:springdoc-openapi-ui:1.6.9' runtimeOnly 'mysql:mysql-connector-java' compileOnly 'org.projectlombok:lombok' diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/auth/adaptor/in/web/signin/SignInApiPresentation.java b/src/main/java/com/plzgraduate/myongjigraduatebe/auth/adaptor/in/web/signin/SignInApiPresentation.java new file mode 100644 index 00000000..4924752a --- /dev/null +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/auth/adaptor/in/web/signin/SignInApiPresentation.java @@ -0,0 +1,22 @@ +package com.plzgraduate.myongjigraduatebe.auth.adaptor.in.web.signin; + +import javax.validation.Valid; + +import org.springframework.web.bind.annotation.RequestBody; + +import com.plzgraduate.myongjigraduatebe.auth.application.port.in.TokenResponse; +import com.plzgraduate.myongjigraduatebe.core.meta.LoginUser; + +import io.swagger.v3.oas.annotations.Hidden; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; + +@Tag(name = "SignIn", description = "로그인 API") +public interface SignInApiPresentation { + + @Operation(summary = "로그인") + TokenResponse signIn(@Valid @RequestBody SignInRequest signInRequest); + + @Hidden + String check(@LoginUser Long userId); +} diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/auth/adaptor/in/web/signin/SignInController.java b/src/main/java/com/plzgraduate/myongjigraduatebe/auth/adaptor/in/web/signin/SignInController.java index bcba5cfa..f19e860f 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/auth/adaptor/in/web/signin/SignInController.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/auth/adaptor/in/web/signin/SignInController.java @@ -17,7 +17,7 @@ @WebAdapter @RequestMapping("api/v1/auth") @RequiredArgsConstructor -public class SignInController { +public class SignInController implements SignInApiPresentation { private final SignInUseCase signInUseCase; diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/auth/adaptor/in/web/signin/SignInRequest.java b/src/main/java/com/plzgraduate/myongjigraduatebe/auth/adaptor/in/web/signin/SignInRequest.java index c019ece8..c1d77a54 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/auth/adaptor/in/web/signin/SignInRequest.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/auth/adaptor/in/web/signin/SignInRequest.java @@ -4,6 +4,7 @@ import com.plzgraduate.myongjigraduatebe.auth.application.port.in.signin.SignInCommand; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -13,9 +14,11 @@ public class SignInRequest { @NotBlank(message = "아아디를 입력해주세요.") + @Schema(name = "authId", example = "plzgraduate") private String authId; @NotBlank(message = "비밀번호를 입력해주세요.") + @Schema(name = "password", example = "Plz1231343!") private String password; @Builder diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/auth/adaptor/in/web/token/TokenApiPresentation.java b/src/main/java/com/plzgraduate/myongjigraduatebe/auth/adaptor/in/web/token/TokenApiPresentation.java new file mode 100644 index 00000000..8a6d2ba9 --- /dev/null +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/auth/adaptor/in/web/token/TokenApiPresentation.java @@ -0,0 +1,15 @@ +package com.plzgraduate.myongjigraduatebe.auth.adaptor.in.web.token; + +import javax.validation.Valid; + +import org.springframework.web.bind.annotation.RequestBody; + +import com.plzgraduate.myongjigraduatebe.auth.application.port.in.AccessTokenResponse; + +import io.swagger.v3.oas.annotations.tags.Tag; + +@Tag(name = "Token", description = "토큰 발급 API") +public interface TokenApiPresentation { + + AccessTokenResponse newToken(@Valid @RequestBody TokenRequest tokenRequest); +} diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/auth/adaptor/in/web/token/TokenController.java b/src/main/java/com/plzgraduate/myongjigraduatebe/auth/adaptor/in/web/token/TokenController.java index 602eecdd..521277c5 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/auth/adaptor/in/web/token/TokenController.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/auth/adaptor/in/web/token/TokenController.java @@ -15,7 +15,7 @@ @WebAdapter @RequiredArgsConstructor @RequestMapping("/api/v1/auth") -public class TokenController { +public class TokenController implements TokenApiPresentation { private final TokenUseCase tokenUseCase; diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/auth/adaptor/in/web/token/TokenRequest.java b/src/main/java/com/plzgraduate/myongjigraduatebe/auth/adaptor/in/web/token/TokenRequest.java index e4200057..771900b4 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/auth/adaptor/in/web/token/TokenRequest.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/auth/adaptor/in/web/token/TokenRequest.java @@ -4,6 +4,7 @@ import com.plzgraduate.myongjigraduatebe.auth.application.port.in.token.TokenCommand; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -13,6 +14,7 @@ public class TokenRequest { @NotBlank(message = "unexpected token") + @Schema(name = "refreshToken", example = "7f734e1b-669d-430e-ac78-270e3863db50") private String refreshToken; @Builder diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/auth/application/port/in/AccessTokenResponse.java b/src/main/java/com/plzgraduate/myongjigraduatebe/auth/application/port/in/AccessTokenResponse.java index 3210041e..e0d08cb6 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/auth/application/port/in/AccessTokenResponse.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/auth/application/port/in/AccessTokenResponse.java @@ -1,5 +1,6 @@ package com.plzgraduate.myongjigraduatebe.auth.application.port.in; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -7,6 +8,8 @@ @Getter @NoArgsConstructor public class AccessTokenResponse { + + @Schema(name = "accessToken", example = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c") private String accessToken; @Builder diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/auth/application/port/in/TokenResponse.java b/src/main/java/com/plzgraduate/myongjigraduatebe/auth/application/port/in/TokenResponse.java index c8da79a6..9b33df87 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/auth/application/port/in/TokenResponse.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/auth/application/port/in/TokenResponse.java @@ -1,5 +1,6 @@ package com.plzgraduate.myongjigraduatebe.auth.application.port.in; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -8,7 +9,10 @@ @NoArgsConstructor public class TokenResponse { + @Schema(name = "accessToken", example = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c") private String accessToken; + + @Schema(name = "refreshToken", example = "7f734e1b-669d-430e-ac78-270e3863db50") private String refreshToken; @Builder diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/core/HealthCheckController.java b/src/main/java/com/plzgraduate/myongjigraduatebe/core/HealthCheckController.java index 4e300349..064e7c9e 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/core/HealthCheckController.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/core/HealthCheckController.java @@ -5,8 +5,11 @@ import com.plzgraduate.myongjigraduatebe.core.meta.WebAdapter; +import io.swagger.v3.oas.annotations.Hidden; + @WebAdapter @RequestMapping("/api/v1") +@Hidden public class HealthCheckController { @GetMapping("/health") diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/core/config/SecurityConfig.java b/src/main/java/com/plzgraduate/myongjigraduatebe/core/config/SecurityConfig.java index 890d8dbc..5223e5d4 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/core/config/SecurityConfig.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/core/config/SecurityConfig.java @@ -59,7 +59,13 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { API_V1_PREFIX + "/users/{student-number}/auth-id", // 아이디 찾기 API_V1_PREFIX + "/users/{student-number}/validate", // 유저 검증 API_V1_PREFIX + "/users/password", // 비밀번호 재설정 - API_V1_PREFIX + "/health" //헬스체크 + API_V1_PREFIX + "/health", //헬스체크 + "/api-docs", + "/swagger-custom-ui.html", + "/v3/api-docs/**", + "/swagger-ui/**", + "/api-docs/**", + "/swagger-ui.html" ).permitAll() .anyRequest().authenticated() .and() diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/core/config/SwaggerConfig.java b/src/main/java/com/plzgraduate/myongjigraduatebe/core/config/SwaggerConfig.java new file mode 100644 index 00000000..69279cd6 --- /dev/null +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/core/config/SwaggerConfig.java @@ -0,0 +1,19 @@ +package com.plzgraduate.myongjigraduatebe.core.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Info; + +@Configuration +public class SwaggerConfig { + + @Bean + public OpenAPI springOpenApi() { + return new OpenAPI().info(new Info() + .title("Myongji-Graduate API Documentation") + .description("졸업을 부탁해 서비스의 API 명세서입니다.") + .version("v2.0.0")); + } +} diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/adpater/in/web/CalculateGraduationApiPresentation.java b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/adpater/in/web/CalculateGraduationApiPresentation.java new file mode 100644 index 00000000..0185ad76 --- /dev/null +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/adpater/in/web/CalculateGraduationApiPresentation.java @@ -0,0 +1,14 @@ +package com.plzgraduate.myongjigraduatebe.graduation.adpater.in.web; + +import com.plzgraduate.myongjigraduatebe.core.meta.LoginUser; +import com.plzgraduate.myongjigraduatebe.graduation.application.port.in.response.GraduationResponse; + +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; + +@Tag(name = "CalculateGraduation", description = "유저의 졸업 결과를 계산하는 API") +public interface CalculateGraduationApiPresentation { + + @Parameter(name = "userId", description = "로그인한 유저의 PK값") + GraduationResponse calculate(@LoginUser Long userId); +} diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/adpater/in/web/CalculateGraduationController.java b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/adpater/in/web/CalculateGraduationController.java index 43810359..a5c383bd 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/adpater/in/web/CalculateGraduationController.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/adpater/in/web/CalculateGraduationController.java @@ -13,7 +13,7 @@ @WebAdapter @RequestMapping("/api/v1/graduation") @RequiredArgsConstructor -public class CalculateGraduationController { +public class CalculateGraduationController implements CalculateGraduationApiPresentation { private final CalculateGraduationUseCase calculateGraduationUseCase; diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/port/in/response/BasicInfoResponse.java b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/port/in/response/BasicInfoResponse.java index 7e499aa9..44dd4dee 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/port/in/response/BasicInfoResponse.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/port/in/response/BasicInfoResponse.java @@ -3,16 +3,22 @@ import com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationResult; import com.plzgraduate.myongjigraduatebe.user.domain.model.User; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Getter; @Getter public class BasicInfoResponse { + @Schema(name = "name", example = "홍길동") private final String name; + @Schema(name = "studentNumber", example = "60202000") private final String studentNumber; + @Schema(name = "major", example = "응용소프트웨어전공") private final String major; + @Schema(name = "totalCredit", example = "132") private final int totalCredit; + @Schema(name = "takenCredit", example = "50") private final double takenCredit; @Builder diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/port/in/response/ChapelResultResponse.java b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/port/in/response/ChapelResultResponse.java index e0dcf5c5..4468c799 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/port/in/response/ChapelResultResponse.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/port/in/response/ChapelResultResponse.java @@ -2,13 +2,16 @@ import com.plzgraduate.myongjigraduatebe.graduation.domain.model.ChapelResult; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Getter; @Getter public class ChapelResultResponse { + @Schema(name = "takenCount", example = "4") private final int takenCount; + @Schema(name = "completed", example = "true") private final boolean completed; @Builder diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/port/in/response/DetailGraduationCategoryResultResponse.java b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/port/in/response/DetailGraduationCategoryResultResponse.java index 1f9778a6..6bc7b217 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/port/in/response/DetailGraduationCategoryResultResponse.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/port/in/response/DetailGraduationCategoryResultResponse.java @@ -5,17 +5,22 @@ import com.plzgraduate.myongjigraduatebe.graduation.domain.model.DetailCategoryResult; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Getter; @Getter public class DetailGraduationCategoryResultResponse { + @Schema(name = "categoryName", example = "공통교양(기독교)") private final String categoryName; + @Schema(name = "totalCredits", example = "4") private final int totalCredits; + @Schema(name = "takenCredits", example = "4") private final int takenCredits; private final List takenLectures; private final List haveToLectures; + @Schema(name = "completed", example = "true") private final boolean completed; @Builder diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/port/in/response/DetailGraduationResultResponse.java b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/port/in/response/DetailGraduationResultResponse.java index 2115f977..584f054b 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/port/in/response/DetailGraduationResultResponse.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/port/in/response/DetailGraduationResultResponse.java @@ -5,15 +5,19 @@ import com.plzgraduate.myongjigraduatebe.graduation.domain.model.DetailGraduationResult; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Getter; @Getter public class DetailGraduationResultResponse { + @Schema(name = "totalCredit", example = "12") private final int totalCredit; + @Schema(name = "takenCredit", example = "9") private final double takenCredit; private final List detailCategory; + @Schema(name = "completed", example = "false") private final boolean completed; @Builder diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/port/in/response/GraduationResponse.java b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/port/in/response/GraduationResponse.java index edc300bd..bca04f67 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/port/in/response/GraduationResponse.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/port/in/response/GraduationResponse.java @@ -6,6 +6,7 @@ import com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationResult; import com.plzgraduate.myongjigraduatebe.user.domain.model.User; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Getter; @@ -20,6 +21,7 @@ public class GraduationResponse { private final DetailGraduationResultResponse major; private final RestResultResponse normalCulture; private final RestResultResponse freeElective; + @Schema(name = "graduated", example = "false") private final boolean graduated; @Builder diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/port/in/response/LectureResponse.java b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/port/in/response/LectureResponse.java index 3196f055..e14cf547 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/port/in/response/LectureResponse.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/port/in/response/LectureResponse.java @@ -2,15 +2,20 @@ import com.plzgraduate.myongjigraduatebe.lecture.domain.model.Lecture; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Getter; @Getter public class LectureResponse { + @Schema(name = "id", example = "6") private final Long id; + @Schema(name = "code", example = "KMA02103") private final String code; + @Schema(name = "name", example = "종교와과학") private final String name; + @Schema(name = "credit", example = "2") private final int credit; @Builder diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/port/in/response/RestResultResponse.java b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/port/in/response/RestResultResponse.java index 75731c86..c61e7260 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/port/in/response/RestResultResponse.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/port/in/response/RestResultResponse.java @@ -3,14 +3,18 @@ import com.plzgraduate.myongjigraduatebe.graduation.domain.model.FreeElectiveGraduationResult; import com.plzgraduate.myongjigraduatebe.graduation.domain.model.NormalCultureGraduationResult; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Getter; @Getter public class RestResultResponse { + @Schema(name = "totalCredit", example = "10") private final int totalCredit; + @Schema(name = "takenCredit", example = "5") private final int takenCredit; + @Schema(name = "completed", example = "false") private final boolean completed; @Builder diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/service/coreculture/CoreCultureDetailCategoryManager.java b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/service/coreculture/CoreCultureDetailCategoryManager.java index 91687d3a..c710ba57 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/service/coreculture/CoreCultureDetailCategoryManager.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/service/coreculture/CoreCultureDetailCategoryManager.java @@ -70,13 +70,19 @@ private void calculateFreeElectiveLeftCredit(User user, Set taken, private void calculateNormalLeftCredit(Set taken, Set finishedTakenLecture, DetailCategoryResult commonCultureDetailCategoryResult) { - int normalLeftCredit = finishedTakenLecture.stream() + List cultureAndArtExceptionLectures = finishedTakenLecture.stream() .filter(takenLecture -> 문화와예술_예외_과목.contains(takenLecture.getLecture()) && takenLecture.getYear() == 2022 && takenLecture.getSemester() == FIRST) - .mapToInt(takenLecture -> takenLecture.getLecture().getCredit()) - .sum(); - taken.removeAll(문화와예술_예외_과목); - commonCultureDetailCategoryResult.addNormalLeftCredit(normalLeftCredit); + .collect(Collectors.toList()); + if (!cultureAndArtExceptionLectures.isEmpty()) { + cultureAndArtExceptionLectures.stream() + .map(TakenLecture::getLecture) + .forEach(taken::remove); + int normalLeftCredit = cultureAndArtExceptionLectures.stream() + .mapToInt(exceptionLecture -> exceptionLecture.getLecture().getCredit()) + .sum(); + commonCultureDetailCategoryResult.addNormalLeftCredit(normalLeftCredit); + } } } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/lecture/adapter/in/web/SearchLectureApiPresentation.java b/src/main/java/com/plzgraduate/myongjigraduatebe/lecture/adapter/in/web/SearchLectureApiPresentation.java new file mode 100644 index 00000000..e2346b73 --- /dev/null +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/lecture/adapter/in/web/SearchLectureApiPresentation.java @@ -0,0 +1,19 @@ +package com.plzgraduate.myongjigraduatebe.lecture.adapter.in.web; + +import javax.validation.constraints.Size; + +import org.springframework.web.bind.annotation.RequestParam; + +import com.plzgraduate.myongjigraduatebe.lecture.application.port.in.search.SearchLectureResponse; + +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; + +@Tag(name = "SearchLecture", description = "type과 keyword를 통해 과목정보를 검색하는 API") +public interface SearchLectureApiPresentation { + + SearchLectureResponse searchLecture( + @Parameter(name = "type", description = "과목명 또는 과목코드") @RequestParam(defaultValue = "name") String type, + @Parameter(name = "keyword", description = "검색어 2자리 이상") @RequestParam @Size(min = 2, message = "검색어를 2자리 이상 입력해주세요.") String keyword + ); +} diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/lecture/adapter/in/web/SearchLectureController.java b/src/main/java/com/plzgraduate/myongjigraduatebe/lecture/adapter/in/web/SearchLectureController.java index 26a2cbdf..b039fefb 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/lecture/adapter/in/web/SearchLectureController.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/lecture/adapter/in/web/SearchLectureController.java @@ -18,7 +18,7 @@ @RequiredArgsConstructor @RequestMapping("/api/v1/lectures") @Validated -public class SearchLectureController { +public class SearchLectureController implements SearchLectureApiPresentation { private final SearchLectureUseCase searchLectureUseCase; diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/lecture/application/port/in/search/LectureResponse.java b/src/main/java/com/plzgraduate/myongjigraduatebe/lecture/application/port/in/search/LectureResponse.java index e482dde2..9af79bb0 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/lecture/application/port/in/search/LectureResponse.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/lecture/application/port/in/search/LectureResponse.java @@ -2,15 +2,21 @@ import com.plzgraduate.myongjigraduatebe.lecture.domain.model.Lecture; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Getter; @Getter public class LectureResponse { + @Schema(name = "id", example = "18") private final Long id; + @Schema(name = "lectureCode", example = "KMA02137") private final String lectureCode; + @Schema(name = "name", example = "4차산업혁명시대의진로선택") private final String name; + @Schema(name = "credit", example = "2") private final int credit; + @Schema(name = "isRevoked", example = "false") private final boolean isRevoked; @Builder diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/adaptor/in/web/ParsingTextApiPresentation.java b/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/adaptor/in/web/ParsingTextApiPresentation.java new file mode 100644 index 00000000..194b176c --- /dev/null +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/adaptor/in/web/ParsingTextApiPresentation.java @@ -0,0 +1,17 @@ +package com.plzgraduate.myongjigraduatebe.parsing.adaptor.in.web; + +import javax.validation.Valid; + +import org.springframework.web.bind.annotation.RequestBody; + +import com.plzgraduate.myongjigraduatebe.core.meta.LoginUser; + +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; + +@Tag(name = "ParsingText", description = "파싱 텍스트를 등록하는 API") +public interface ParsingTextApiPresentation { + + @Parameter(name = "userId", description = "로그인한 유저의 PK값") + void enrollParsingText(@LoginUser Long userId, @Valid @RequestBody ParsingTextRequest parsingTextRequest); +} diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/adaptor/in/web/ParsingTextController.java b/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/adaptor/in/web/ParsingTextController.java index 9ed00849..20e5aa96 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/adaptor/in/web/ParsingTextController.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/adaptor/in/web/ParsingTextController.java @@ -17,7 +17,7 @@ @WebAdapter @RequestMapping("/api/v1/parsing-text") @RequiredArgsConstructor -public class ParsingTextController { +public class ParsingTextController implements ParsingTextApiPresentation{ private final ParsingTextUseCase parsingTextUseCase; private final ParsingTextHistoryUseCase parsingTextHistoryUseCase; diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/adaptor/in/web/ParsingTextRequest.java b/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/adaptor/in/web/ParsingTextRequest.java index bf40989d..b2bad2a3 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/adaptor/in/web/ParsingTextRequest.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/adaptor/in/web/ParsingTextRequest.java @@ -4,6 +4,7 @@ import com.plzgraduate.myongjigraduatebe.parsing.application.port.in.ParsingTextCommand; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -13,6 +14,7 @@ class ParsingTextRequest { @NotNull(message = "parsingText는 null값이 될 수 없습니다.") + @Schema(name = "parsingText", example = "2023/12/08|1/1|ICT융합대학 융합소프트웨어학부 데이터테크놀로지전공, 나경호(60202455), 현학적 - 재학, 이수 - 3, 입학 - 신입학(2020/03/02)|토익 - 715, 영어교과목면제 - 면제없음, 최종학적변동 - 2/1전과(2023/01/27), 전과내역 - 기계공학과|편입생 인정학점 - 교양 0, 전공 0, 자유선택 0, 성경과인간이해 0|교환학생 인정학점 - 학문기초교양 0, 일반교양 0, 전공 0, 복수전공학문기초교양 0, 복수전공 0, 연계전공 0, 부전공 0, 자유선택 0|공통교양 16.5, 핵심교양 6, 학문기초교양 6, 일반교양 12, 전공 9, 복수전공 0, 연계전공 0, 부전공 0, 교직 0, 자유선택 7|총 취득학점 - 56.5, 총점 - 230.5, 평균평점 - 4.43|이수구분|수강년도/학기|한글코드|과목코드|과목명|학점|등급|중복|공통교양|2020년 2학기|교필141|KMA02141|4차산업혁명과미래사회진로선택|2|P|공통교양|2020년 2학기|교필122|KMA02122|기독교와문화|2|A+|공통교양|2023년 1학기|교필105|KMA02105|발표와토의|3|A0|공통교양|2020년 1학기|교필127|KMA00101|성서와인간이해|2|A+|공통교양|2020년 1학기|교필123|KMA02123|영어3|2|A+|공통교양|2020년 2학기|교필124|KMA02124|영어4|2|A+|공통교양|2020년 1학기|교필125|KMA02125|영어회화3|1|A0|공통교양|2020년 2학기|교필126|KMA02126|영어회화4|1|A+|공통교양|2020년 1학기|교필101|KMA02101|채플|0.5|P|공통교양|2020년 2학기|교필101|KMA02101|채플|0.5|P|공통교양|2023년 1학기|교필101|KMA02101|채플|0.5|P|핵심교양|2023년 1학기|교선128|KMA02128|글로벌문화|3|A0|핵심교양|2023년 1학기|교선114|KMA02114|민주주의와현대사회|3|A+|학문기초교양|2020년 1학기|기자111|KME02111|물리학1|3|A+|학문기초교양|2020년 1학기|기자101|KME02101|미적분학1|3|A+|일반교양|2020년 2학기|기자112|KME02112|물리학2|3|A+|일반교양|2020년 1학기|기자113|KME02113|물리학실험1|1|A+|일반교양|2020년 2학기|기자114|KME02114|물리학실험2|1|A+|일반교양|2020년 2학기|기자102|KME02102|미적분학2|3|A+|일반교양|2020년 1학기|기자121|KME02121|일반화학|3|A+|일반교양|2020년 1학기|기자122|KME02122|일반화학실험|1|A+|전공1단계|2023년 1학기|데테202|HED01202|R통계분석|3|A+|전공1단계|2023년 1학기|융소102|HEB01102|기초프로그래밍|3|A+|전공1단계|2023년 1학기|데테201|HED01201|자료구조|3|A+|자유선택|2020년 2학기|공과100|JEA00100|공학입문설계|3|A+|자유선택|2020년 1학기|기계207|JEP01207|기계신입생세미나|1|P|자유선택|2020년 2학기|기계209|JEP02209|정역학|3|A+|") private String parsingText; @Builder diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/takenlecture/adaptor/in/web/find/FindTakenLectureApiPresentation.java b/src/main/java/com/plzgraduate/myongjigraduatebe/takenlecture/adaptor/in/web/find/FindTakenLectureApiPresentation.java new file mode 100644 index 00000000..61e1f408 --- /dev/null +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/takenlecture/adaptor/in/web/find/FindTakenLectureApiPresentation.java @@ -0,0 +1,14 @@ +package com.plzgraduate.myongjigraduatebe.takenlecture.adaptor.in.web.find; + +import com.plzgraduate.myongjigraduatebe.core.meta.LoginUser; +import com.plzgraduate.myongjigraduatebe.takenlecture.application.port.in.find.FindTakenLectureResponse; + +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; + +@Tag(name = "FindTakenLecture", description = "사용자의 수강과목을 조회하는 API") +public interface FindTakenLectureApiPresentation { + + @Parameter(name = "userId", description = "로그인한 유저의 PK값") + FindTakenLectureResponse getTakenLectures(@LoginUser Long userId); +} diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/takenlecture/adaptor/in/web/find/FindTakenLectureController.java b/src/main/java/com/plzgraduate/myongjigraduatebe/takenlecture/adaptor/in/web/find/FindTakenLectureController.java index c6819ed3..2a2db8b1 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/takenlecture/adaptor/in/web/find/FindTakenLectureController.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/takenlecture/adaptor/in/web/find/FindTakenLectureController.java @@ -13,7 +13,7 @@ @WebAdapter @RequestMapping("/api/v1/taken-lectures") @RequiredArgsConstructor -public class FindTakenLectureController { +public class FindTakenLectureController implements FindTakenLectureApiPresentation { private final FindTakenLectureUseCase findTakenLectureUseCase; diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/takenlecture/adaptor/in/web/update/UpdateTakenLectureApiPresentation.java b/src/main/java/com/plzgraduate/myongjigraduatebe/takenlecture/adaptor/in/web/update/UpdateTakenLectureApiPresentation.java new file mode 100644 index 00000000..9b72c612 --- /dev/null +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/takenlecture/adaptor/in/web/update/UpdateTakenLectureApiPresentation.java @@ -0,0 +1,17 @@ +package com.plzgraduate.myongjigraduatebe.takenlecture.adaptor.in.web.update; + +import javax.validation.Valid; + +import org.springframework.web.bind.annotation.RequestBody; + +import com.plzgraduate.myongjigraduatebe.core.meta.LoginUser; + +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; + +@Tag(name = "UpdateTakenLecture", description = "수강과목을 수정하는 API") +public interface UpdateTakenLectureApiPresentation { + + @Parameter(name = "userId", description = "로그인한 유저의 PK값") + void updateTakenLectures(@LoginUser Long userId, @Valid @RequestBody UpdateTakenLectureRequest updateTakenLectureRequest); +} diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/takenlecture/adaptor/in/web/update/UpdateTakenLectureController.java b/src/main/java/com/plzgraduate/myongjigraduatebe/takenlecture/adaptor/in/web/update/UpdateTakenLectureController.java index 838fb027..c594cb25 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/takenlecture/adaptor/in/web/update/UpdateTakenLectureController.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/takenlecture/adaptor/in/web/update/UpdateTakenLectureController.java @@ -15,7 +15,7 @@ @WebAdapter @RequestMapping("/api/v1/taken-lectures") @RequiredArgsConstructor -public class UpdateTakenLectureController { +public class UpdateTakenLectureController implements UpdateTakenLectureApiPresentation { private final UpdateTakenLectureUseCase updateTakenLectureUseCase; @PostMapping("/update") diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/takenlecture/adaptor/in/web/update/UpdateTakenLectureRequest.java b/src/main/java/com/plzgraduate/myongjigraduatebe/takenlecture/adaptor/in/web/update/UpdateTakenLectureRequest.java index 6ee9fcd7..6a341f7f 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/takenlecture/adaptor/in/web/update/UpdateTakenLectureRequest.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/takenlecture/adaptor/in/web/update/UpdateTakenLectureRequest.java @@ -4,6 +4,7 @@ import com.plzgraduate.myongjigraduatebe.takenlecture.application.port.in.update.UpdateTakenLectureCommand; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -12,8 +13,10 @@ @NoArgsConstructor public class UpdateTakenLectureRequest { + @Schema(name = "deletedTakenLectures", example = "102, 2") private List deletedTakenLectures; + @Schema(name = "addedTakenLectures", example = "103, 104") private List addedTakenLectures; @Builder diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/takenlecture/application/port/in/find/FindTakenLectureResponse.java b/src/main/java/com/plzgraduate/myongjigraduatebe/takenlecture/application/port/in/find/FindTakenLectureResponse.java index b33449f6..5b82045a 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/takenlecture/application/port/in/find/FindTakenLectureResponse.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/takenlecture/application/port/in/find/FindTakenLectureResponse.java @@ -2,6 +2,7 @@ import java.util.List; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -9,6 +10,8 @@ @Getter @NoArgsConstructor public class FindTakenLectureResponse { + + @Schema(name = "totalCredit", example = "115") private int totalCredit; private List takenLectures; diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/takenlecture/application/port/in/find/TakenLectureResponse.java b/src/main/java/com/plzgraduate/myongjigraduatebe/takenlecture/application/port/in/find/TakenLectureResponse.java index e454ffe9..ffabaff7 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/takenlecture/application/port/in/find/TakenLectureResponse.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/takenlecture/application/port/in/find/TakenLectureResponse.java @@ -2,17 +2,24 @@ import com.plzgraduate.myongjigraduatebe.takenlecture.domain.model.TakenLecture; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Getter; @Getter public class TakenLectureResponse { + @Schema(name = "id", example = "135") private final Long id; + @Schema(name = "year", example = "2023") private final String year; + @Schema(name = "semester", example = "1학기") private final String semester; + @Schema(name = "lectureCode", example = "HED01413") private final String lectureCode; + @Schema(name = "lectureName", example = "캡스톤디자인") private final String lectureName; + @Schema(name = "credit", example = "3") private final int credit; @Builder diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/findauthid/FindAuthIdApiPresentation.java b/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/findauthid/FindAuthIdApiPresentation.java new file mode 100644 index 00000000..6ff11d13 --- /dev/null +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/findauthid/FindAuthIdApiPresentation.java @@ -0,0 +1,16 @@ +package com.plzgraduate.myongjigraduatebe.user.adaptor.in.web.findauthid; + +import org.springframework.web.bind.annotation.PathVariable; + +import com.plzgraduate.myongjigraduatebe.user.application.port.in.find.UserAuthIdResponse; + +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.enums.ParameterIn; +import io.swagger.v3.oas.annotations.tags.Tag; + +@Tag(name = "FindAuthId", description = "학번으로 해당 학생의 아이디를 조회하는 API") +public interface FindAuthIdApiPresentation { + + UserAuthIdResponse findUserAuthId( + @Parameter(name = "studentNumber", description = "학번", in = ParameterIn.PATH) @PathVariable("student-number") String studentNumber); +} diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/findauthid/FindAuthIdController.java b/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/findauthid/FindAuthIdController.java index cc78eca1..3a4060da 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/findauthid/FindAuthIdController.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/findauthid/FindAuthIdController.java @@ -13,7 +13,7 @@ @WebAdapter @RequestMapping("/api/v1/users") @RequiredArgsConstructor -public class FindAuthIdController { +public class FindAuthIdController implements FindAuthIdApiPresentation { private final FindUserAuthIdUseCase findUserAuthIdUseCase; diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/finduserinformation/FindUserInformationApiPresentation.java b/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/finduserinformation/FindUserInformationApiPresentation.java new file mode 100644 index 00000000..5d60f829 --- /dev/null +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/finduserinformation/FindUserInformationApiPresentation.java @@ -0,0 +1,14 @@ +package com.plzgraduate.myongjigraduatebe.user.adaptor.in.web.finduserinformation; + +import com.plzgraduate.myongjigraduatebe.core.meta.LoginUser; +import com.plzgraduate.myongjigraduatebe.user.application.port.in.find.UserInformationResponse; + +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; + +@Tag(name = "FindUserInformation", description = "로그인 한 회원 정보를 조회하는 API") +public interface FindUserInformationApiPresentation { + + @Parameter(name = "userId", description = "로그인한 유저의 PK값") + UserInformationResponse getUserInformation(@LoginUser Long userId); +} diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/finduserinformation/FindUserInformationController.java b/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/finduserinformation/FindUserInformationController.java index f772686e..af481908 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/finduserinformation/FindUserInformationController.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/finduserinformation/FindUserInformationController.java @@ -13,7 +13,7 @@ @WebAdapter @RequestMapping("/api/v1/users/me") @RequiredArgsConstructor -public class FindUserInformationController { +public class FindUserInformationController implements FindUserInformationApiPresentation { private final FindUserInformationUseCase findUserInformationUseCase; diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/resetpassword/ResetPasswordApiPresentation.java b/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/resetpassword/ResetPasswordApiPresentation.java new file mode 100644 index 00000000..97c5ea51 --- /dev/null +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/resetpassword/ResetPasswordApiPresentation.java @@ -0,0 +1,29 @@ +package com.plzgraduate.myongjigraduatebe.user.adaptor.in.web.resetpassword; + +import javax.validation.Valid; + +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; + +import com.plzgraduate.myongjigraduatebe.user.application.port.in.validate.ValidateUserResponse; + +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.tags.Tag; + +@Tag(name = "ResetPassword", description = "학번으로 유저 정보 조회 후 로그인 이아디와 일치하는지 확인하는 API") +public interface ResetPasswordApiPresentation { + + @Operation(description = "학번으로 유저 정보 조회 후 로그인 이아디와 일치하는지 확인") + @Parameter(name = "auth-id", description = "아이디") + ValidateUserResponse validateUser( + @Parameter(name = "studentNumber", description = "학번", in = ParameterIn.PATH) + @PathVariable("student-number") String studentNumber, + @RequestParam("auth-id") String authId); + + @PatchMapping("/password") + void resetPassword(@Valid @RequestBody ResetPasswordRequest resetPasswordRequest); +} diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/resetpassword/ResetPasswordController.java b/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/resetpassword/ResetPasswordController.java index 7669b8d1..1102380c 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/resetpassword/ResetPasswordController.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/resetpassword/ResetPasswordController.java @@ -19,7 +19,7 @@ @WebAdapter @RequestMapping("api/v1/users") @RequiredArgsConstructor -public class ResetPasswordController { +public class ResetPasswordController implements ResetPasswordApiPresentation { private final ValidateUserUseCase validateUserUseCase; private final ResetPasswordUseCase resetPasswordUseCase; diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/resetpassword/ResetPasswordRequest.java b/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/resetpassword/ResetPasswordRequest.java index af6156d7..f0255392 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/resetpassword/ResetPasswordRequest.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/resetpassword/ResetPasswordRequest.java @@ -5,6 +5,7 @@ import com.plzgraduate.myongjigraduatebe.user.application.port.in.resetpassword.ResetPasswordCommand; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -14,14 +15,17 @@ public class ResetPasswordRequest { @NotBlank(message = "아이디를 입력해주세요.") + @Schema(name = "authId", example = "plzgraduate") private String authId; @NotBlank(message = "비밀번호를 입력해주세요.") @Pattern(regexp = "^(?=.*[!@#$%^&*])(?=.*[a-zA-Z0-9]).{8,20}$", message = "비밀번호는 특수문자를 포함한 8자에서 20자 사이여야합니다.") + @Schema(name = "newPassword", example = "Plz1231343!?") private String newPassword; @NotBlank(message = "비밀번호 확인을 입력해주세요.") @Pattern(regexp = "^(?=.*[!@#$%^&*])(?=.*[a-zA-Z0-9]).{8,20}$", message = "비밀번호는 특수문자를 포함한 8자에서 20자 사이여야합니다.") + @Schema(name = "passwordCheck", example = "Plz1231343!?") private String passwordCheck; @Builder diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/signup/SignUpApiPresentation.java b/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/signup/SignUpApiPresentation.java new file mode 100644 index 00000000..4500bbf2 --- /dev/null +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/signup/SignUpApiPresentation.java @@ -0,0 +1,29 @@ +package com.plzgraduate.myongjigraduatebe.user.adaptor.in.web.signup; + +import javax.validation.Valid; + +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; + +import com.plzgraduate.myongjigraduatebe.user.application.port.in.check.AuthIdDuplicationResponse; +import com.plzgraduate.myongjigraduatebe.user.application.port.in.check.StudentNumberDuplicationResponse; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; + +@Tag(name = "SignUp", description = "회원가입을 진행하는 API") +public interface SignUpApiPresentation { + + @Operation(description = "회원가입을 진행한다.") + void signUp(@Valid @RequestBody SignUpRequest signUpRequest); + + @Operation(description = "로그인 아이디 중복 여부를 체크한다.") + @Parameter(name = "auth-id", description = "아이디") + AuthIdDuplicationResponse checkAuthIdDuplication(@RequestParam("auth-id") String authId); + + @Operation(description = "학번 중복 여부를 체크한다.") + @Parameter(name = "student-number", description = "학번") + StudentNumberDuplicationResponse checkStudentNumberDuplication( + @RequestParam("student-number") String studentNumber); +} diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/signup/SignUpController.java b/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/signup/SignUpController.java index 7555c788..6ac98ffb 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/signup/SignUpController.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/signup/SignUpController.java @@ -20,7 +20,7 @@ @WebAdapter @RequestMapping("/api/v1/users") @RequiredArgsConstructor -public class SignUpController { +public class SignUpController implements SignUpApiPresentation { private final SignUpUseCase signUpUseCase; private final CheckAuthIdDuplicationUseCase checkAuthIdDuplicationUseCase; diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/signup/SignUpRequest.java b/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/signup/SignUpRequest.java index 479be0e6..a9998a17 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/signup/SignUpRequest.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/signup/SignUpRequest.java @@ -7,6 +7,7 @@ import com.plzgraduate.myongjigraduatebe.user.application.port.in.signup.SignUpCommand; import com.plzgraduate.myongjigraduatebe.user.domain.model.EnglishLevel; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -17,17 +18,21 @@ public class SignUpRequest { @NotBlank(message = "아이디를 입력해주세요.") @Size(min = 6, max = 20, message = "아이디는 6자에서 20자 사이여야합니다.") + @Schema(name = "authId", example = "plzgraduate") private String authId; @NotBlank(message = "비밀번호를 입력해주세요.") @Pattern(regexp = "^(?=.*[!@#$%^&*])(?=.*[a-zA-Z0-9]).{8,20}$", message = "비밀번호는 특수문자를 포함한 8자에서 20자 사이여야합니다.") + @Schema(name = "password", example = "Plz1231343!") private String password; @NotBlank(message = "비밀번호를 입력해주세요.") @Pattern(regexp = "\\d{8}", message = "학번은 8자리 숫자여야 합니다.") + @Schema(name = "studentNumber", example = "60202000") private String studentNumber; @NotBlank(message = "영어레벨을 입력해주세요.") + @Schema(name = "engLv", example = "ENG34") private String engLv; @Builder diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/withdraw/WithDrawApiPresentation.java b/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/withdraw/WithDrawApiPresentation.java new file mode 100644 index 00000000..467df438 --- /dev/null +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/withdraw/WithDrawApiPresentation.java @@ -0,0 +1,15 @@ +package com.plzgraduate.myongjigraduatebe.user.adaptor.in.web.withdraw; + +import org.springframework.web.bind.annotation.RequestBody; + +import com.plzgraduate.myongjigraduatebe.core.meta.LoginUser; + +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; + +@Tag(name = "WithDraw", description = "유저의 회원 탈퇴 요청을 수행하는 API") +public interface WithDrawApiPresentation { + + @Parameter(name = "userId", description = "로그인한 유저의 PK값") + void withDraw(@LoginUser Long userId, @RequestBody WithDrawRequest withDrawRequest); +} diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/withdraw/WithDrawController.java b/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/withdraw/WithDrawController.java index bd0d2c0e..f1d87d08 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/withdraw/WithDrawController.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/withdraw/WithDrawController.java @@ -13,7 +13,7 @@ @WebAdapter @RequestMapping("/api/v1/users/me") @RequiredArgsConstructor -public class WithDrawController { +public class WithDrawController implements WithDrawApiPresentation { private final WithDrawUserUseCase withDrawUserUseCase; diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/withdraw/WithDrawRequest.java b/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/withdraw/WithDrawRequest.java index 2b7ee453..9c258bb9 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/withdraw/WithDrawRequest.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/user/adaptor/in/web/withdraw/WithDrawRequest.java @@ -4,6 +4,7 @@ import com.plzgraduate.myongjigraduatebe.user.application.port.in.withdraw.WithDrawCommand; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -13,6 +14,7 @@ public class WithDrawRequest { @NotBlank(message = "비밀번호를 입력해주세요.") + @Schema(name = "password", example = "Plz1231343!") private String password; @Builder diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/user/application/port/in/check/AuthIdDuplicationResponse.java b/src/main/java/com/plzgraduate/myongjigraduatebe/user/application/port/in/check/AuthIdDuplicationResponse.java index 459d5942..9a2fc87f 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/user/application/port/in/check/AuthIdDuplicationResponse.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/user/application/port/in/check/AuthIdDuplicationResponse.java @@ -1,14 +1,15 @@ package com.plzgraduate.myongjigraduatebe.user.application.port.in.check; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @Getter public class AuthIdDuplicationResponse { - + @Schema(name = "authId", example = "plzgraduate") private final String authId; - + @Schema(name = "notDuplicated", example = "true") private final boolean notDuplicated; @Builder diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/user/application/port/in/check/StudentNumberDuplicationResponse.java b/src/main/java/com/plzgraduate/myongjigraduatebe/user/application/port/in/check/StudentNumberDuplicationResponse.java index 55737cdd..c511ea41 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/user/application/port/in/check/StudentNumberDuplicationResponse.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/user/application/port/in/check/StudentNumberDuplicationResponse.java @@ -1,13 +1,15 @@ package com.plzgraduate.myongjigraduatebe.user.application.port.in.check; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Getter; @Getter public class StudentNumberDuplicationResponse { + @Schema(name = "studentNumber", example = "60202000") private final String studentNumber; - + @Schema(name = "notDuplicated", example = "true") private final boolean notDuplicated; @Builder diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/user/application/port/in/find/UserAuthIdResponse.java b/src/main/java/com/plzgraduate/myongjigraduatebe/user/application/port/in/find/UserAuthIdResponse.java index dabbf834..e284df0c 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/user/application/port/in/find/UserAuthIdResponse.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/user/application/port/in/find/UserAuthIdResponse.java @@ -1,5 +1,6 @@ package com.plzgraduate.myongjigraduatebe.user.application.port.in.find; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -8,7 +9,9 @@ @NoArgsConstructor public class UserAuthIdResponse { + @Schema(name = "authId", example = "plzgraduate") private String authId; + @Schema(name = "studentNumber", example = "60202000") private String studentNumber; @Builder diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/user/application/port/in/find/UserInformationResponse.java b/src/main/java/com/plzgraduate/myongjigraduatebe/user/application/port/in/find/UserInformationResponse.java index adad734c..5f64f471 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/user/application/port/in/find/UserInformationResponse.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/user/application/port/in/find/UserInformationResponse.java @@ -1,15 +1,17 @@ package com.plzgraduate.myongjigraduatebe.user.application.port.in.find; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Getter; @Getter public class UserInformationResponse { + @Schema(name = "studentNumber", example = "60202000") private final String studentNumber; - + @Schema(name = "studentName", example = "홍길동") private final String studentName; - + @Schema(name = "major", example = "디지털콘텐츠디자인학과") private final String major; @Builder diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/user/application/port/in/validate/ValidateUserResponse.java b/src/main/java/com/plzgraduate/myongjigraduatebe/user/application/port/in/validate/ValidateUserResponse.java index 3e37e29a..efc37a50 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/user/application/port/in/validate/ValidateUserResponse.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/user/application/port/in/validate/ValidateUserResponse.java @@ -1,11 +1,13 @@ package com.plzgraduate.myongjigraduatebe.user.application.port.in.validate; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Getter; @Getter public class ValidateUserResponse { + @Schema(name = "passedUserValidation", example = "true") private final boolean passedUserValidation; @Builder diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 5be19015..7f27501e 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -29,6 +29,30 @@ jwt: secret-key: "coffee" expiry-seconds: 10800000 +springdoc: + api-docs: + path: /api-docs + groups: + enabled: true + + swagger-ui: + path: /swagger-custom-ui.html + enabled: true + groups-order: DESC + tags-sorter: alpha + operations-sorter: method + display-request-duration: true + doc-expansion: none + + cache: + disabled: true + + show-actuator: true + override-with-generic-response: false + model-and-view-allowed: true + default-produces-media-type: application/json + default-consumes-media-type: application/json + --- spring: config: diff --git a/src/test/java/com/plzgraduate/myongjigraduatebe/graduation/domain/service/coreculture/CoreCultureDetailCategoryManagerTest.java b/src/test/java/com/plzgraduate/myongjigraduatebe/graduation/domain/service/coreculture/CoreCultureDetailCategoryManagerTest.java index cf29e1af..92cefcb4 100644 --- a/src/test/java/com/plzgraduate/myongjigraduatebe/graduation/domain/service/coreculture/CoreCultureDetailCategoryManagerTest.java +++ b/src/test/java/com/plzgraduate/myongjigraduatebe/graduation/domain/service/coreculture/CoreCultureDetailCategoryManagerTest.java @@ -138,6 +138,58 @@ static Stream ictUsers() { ); } + @DisplayName("4차산업혁명시대의예술 과목은 2022년 1학기 이후 수강한 경우에는 핵심교양으로 인정된다.") + @Test + void generateCompletedCultureArtDetailCategoryResult_Case_A() { + + //given + User user = UserFixture.경영학과_19학번_ENG34(); + Set takenLectures = new HashSet<>((Set.of( + TakenLecture.of(user, mockLectureMap.get("KMA02155"), 2022, Semester.SECOND) + ))); + TakenLectureInventory takenLectureInventory = TakenLectureInventory.from(takenLectures); + Set graduationLectures = 핵심교양_문화와예술(); + CoreCultureCategory coreCultureCategory = CULTURE_ART; + int categoryTotalCredit = coreCultureCategory.getTotalCredit(); + + //when + DetailCategoryResult detailCategoryResult = manager.generate(user, + takenLectureInventory, graduationLectures, coreCultureCategory); + + //then + assertThat(detailCategoryResult) + .extracting("detailCategoryName", "isCompleted", "totalCredits", "normalLeftCredit", + "freeElectiveLeftCredit") + .contains(coreCultureCategory.getName(), true, categoryTotalCredit, 0, 0); + assertThat(detailCategoryResult.getTakenLectures()).contains(mockLectureMap.get("KMA02155")); + } + + @DisplayName("문화리터러시와창의적스토리텔링 과목은 2022년 1학기 이후 수강한 경우에는 핵심교양으로 인정된다.") + @Test + void generateCompletedCultureArtDetailCategoryResult_Case_B() { + + //given + User user = UserFixture.경영학과_19학번_ENG34(); + Set takenLectures = new HashSet<>((Set.of( + TakenLecture.of(user, mockLectureMap.get("KMA02156"), 2022, Semester.SECOND) + ))); + TakenLectureInventory takenLectureInventory = TakenLectureInventory.from(takenLectures); + Set graduationLectures = 핵심교양_문화와예술(); + CoreCultureCategory coreCultureCategory = CULTURE_ART; + int categoryTotalCredit = coreCultureCategory.getTotalCredit(); + + //when + DetailCategoryResult detailCategoryResult = manager.generate(user, + takenLectureInventory, graduationLectures, coreCultureCategory); + + //then + assertThat(detailCategoryResult) + .extracting("detailCategoryName", "isCompleted", "totalCredits", "normalLeftCredit", + "freeElectiveLeftCredit") + .contains(coreCultureCategory.getName(), true, categoryTotalCredit, 0, 0); + assertThat(detailCategoryResult.getTakenLectures()).contains(mockLectureMap.get("KMA02156")); + } + @DisplayName("4차산업혁명시대의예술, 문화리터러시와창의적스토리텔링 과목은 2022년 1학기에 수강한 경우에는 핵심교양이 아닌 일반교양으로 인정된다.") @Test void generateUnCompletedCultureArtDetailCategoryResultWith_2022_First() {