From 1c6139296fc90609a5d7833379420feade35c5f7 Mon Sep 17 00:00:00 2001 From: nayonsoso Date: Sun, 28 Jan 2024 04:28:13 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=ED=9A=8C=EC=9B=90=EA=B0=80=EC=9E=85=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/controller/AuthController.java | 16 +- .../auth/dto/KakaoOauthResponseDto.java | 4 - .../auth/dto/SignInResponseDto.java | 1 + .../auth/dto/SignUpRequestDto.java | 23 +++ .../{ => kakao}/FirstAccessResponseDto.java | 2 +- .../auth/dto/{ => kakao}/KakaoAccount.java | 2 +- .../auth/dto/{ => kakao}/KakaoCodeDto.java | 2 +- .../auth/dto/kakao/KakaoOauthResponseDto.java | 4 + .../auth/dto/{ => kakao}/KakaoProfile.java | 2 +- .../auth/dto/{ => kakao}/KakaoTokenDto.java | 2 +- .../dto/{ => kakao}/KakaoUserInfoDto.java | 2 +- .../auth/service/AuthService.java | 117 +++++++++++ .../auth/service/KakaoOAuthService.java | 10 +- .../security/JwtAuthenticationEntryPoint.java | 3 +- .../config/token/TokenService.java | 17 +- .../config/token/TokenValidator.java | 27 ++- .../country/CountryRepository.java | 13 ++ .../country/InterestedCountyRepository.java | 12 ++ .../custom/exception/CustomException.java | 3 +- .../exception/CustomExceptionHandler.java | 12 +- .../custom/exception/ErrorCode.java | 9 +- .../custom/response/ErrorResponse.java | 6 + .../custom/response/StatusResponse.java | 4 +- .../solidconnection/entity/Country.java | 5 +- .../entity/InterestedCountry.java | 14 +- .../entity/InterestedRegion.java | 10 +- .../solidconnection/entity/Region.java | 5 +- .../solidconnection/entity/SiteUser.java | 29 ++- .../solidconnection/entity/University.java | 4 +- .../region/InterestedRegionRepository.java | 12 ++ .../region/RegionRepository.java | 13 ++ .../solidconnection/type/CountryCode.java | 71 ++++--- .../example/solidconnection/type/Gender.java | 5 + .../solidconnection/type/RegionCode.java | 31 ++- src/main/resources/data.sql | 34 +++ src/main/resources/schema.sql | 193 +++++++++--------- 36 files changed, 528 insertions(+), 191 deletions(-) delete mode 100644 src/main/java/com/example/solidconnection/auth/dto/KakaoOauthResponseDto.java create mode 100644 src/main/java/com/example/solidconnection/auth/dto/SignUpRequestDto.java rename src/main/java/com/example/solidconnection/auth/dto/{ => kakao}/FirstAccessResponseDto.java (94%) rename src/main/java/com/example/solidconnection/auth/dto/{ => kakao}/KakaoAccount.java (89%) rename src/main/java/com/example/solidconnection/auth/dto/{ => kakao}/KakaoCodeDto.java (78%) create mode 100644 src/main/java/com/example/solidconnection/auth/dto/kakao/KakaoOauthResponseDto.java rename src/main/java/com/example/solidconnection/auth/dto/{ => kakao}/KakaoProfile.java (89%) rename src/main/java/com/example/solidconnection/auth/dto/{ => kakao}/KakaoTokenDto.java (90%) rename src/main/java/com/example/solidconnection/auth/dto/{ => kakao}/KakaoUserInfoDto.java (89%) create mode 100644 src/main/java/com/example/solidconnection/auth/service/AuthService.java create mode 100644 src/main/java/com/example/solidconnection/country/CountryRepository.java create mode 100644 src/main/java/com/example/solidconnection/country/InterestedCountyRepository.java create mode 100644 src/main/java/com/example/solidconnection/region/InterestedRegionRepository.java create mode 100644 src/main/java/com/example/solidconnection/region/RegionRepository.java create mode 100644 src/main/java/com/example/solidconnection/type/Gender.java create mode 100644 src/main/resources/data.sql diff --git a/src/main/java/com/example/solidconnection/auth/controller/AuthController.java b/src/main/java/com/example/solidconnection/auth/controller/AuthController.java index dfd043c94..15bc21377 100644 --- a/src/main/java/com/example/solidconnection/auth/controller/AuthController.java +++ b/src/main/java/com/example/solidconnection/auth/controller/AuthController.java @@ -1,11 +1,13 @@ package com.example.solidconnection.auth.controller; -import com.example.solidconnection.auth.dto.KakaoCodeDto; -import com.example.solidconnection.auth.dto.KakaoOauthResponseDto; +import com.example.solidconnection.auth.dto.SignUpRequestDto; +import com.example.solidconnection.auth.dto.kakao.KakaoCodeDto; +import com.example.solidconnection.auth.dto.kakao.KakaoOauthResponseDto; +import com.example.solidconnection.auth.service.AuthService; import com.example.solidconnection.auth.service.KakaoOAuthService; -import com.example.solidconnection.custom.exception.CustomException; import com.example.solidconnection.custom.response.CustomResponse; import com.example.solidconnection.custom.response.DataResponse; +import com.example.solidconnection.custom.response.StatusResponse; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -17,11 +19,17 @@ @RequiredArgsConstructor public class AuthController { private final KakaoOAuthService kakaoOAuthService; + private final AuthService authService; @PostMapping("/kakao") - public CustomResponse kakaoOauth(@RequestBody KakaoCodeDto kakaoCodeDto) throws CustomException { + public CustomResponse kakaoOauth(@RequestBody KakaoCodeDto kakaoCodeDto) { KakaoOauthResponseDto kakaoOauthResponseDto = kakaoOAuthService.processOauth(kakaoCodeDto.getCode()); return new DataResponse<>(kakaoOauthResponseDto); } + @PostMapping("/sign-up") + public CustomResponse signUp(@RequestBody SignUpRequestDto signUpRequestDto) { + boolean status = authService.signUp(signUpRequestDto); + return new StatusResponse(status); + } } diff --git a/src/main/java/com/example/solidconnection/auth/dto/KakaoOauthResponseDto.java b/src/main/java/com/example/solidconnection/auth/dto/KakaoOauthResponseDto.java deleted file mode 100644 index f24255e85..000000000 --- a/src/main/java/com/example/solidconnection/auth/dto/KakaoOauthResponseDto.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.example.solidconnection.auth.dto; - -public class KakaoOauthResponseDto { -} diff --git a/src/main/java/com/example/solidconnection/auth/dto/SignInResponseDto.java b/src/main/java/com/example/solidconnection/auth/dto/SignInResponseDto.java index 55c02509e..16d0cf162 100644 --- a/src/main/java/com/example/solidconnection/auth/dto/SignInResponseDto.java +++ b/src/main/java/com/example/solidconnection/auth/dto/SignInResponseDto.java @@ -1,5 +1,6 @@ package com.example.solidconnection.auth.dto; +import com.example.solidconnection.auth.dto.kakao.KakaoOauthResponseDto; import lombok.*; @Getter diff --git a/src/main/java/com/example/solidconnection/auth/dto/SignUpRequestDto.java b/src/main/java/com/example/solidconnection/auth/dto/SignUpRequestDto.java new file mode 100644 index 000000000..3bf9f72be --- /dev/null +++ b/src/main/java/com/example/solidconnection/auth/dto/SignUpRequestDto.java @@ -0,0 +1,23 @@ +package com.example.solidconnection.auth.dto; + +import com.example.solidconnection.type.Gender; +import com.example.solidconnection.type.PreparationStatus; +import lombok.*; + +import java.util.List; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class SignUpRequestDto { + private String kakaoOauthToken; + private List interestedRegions; + private List interestedCountries; + private PreparationStatus preparationStatus; + private String nickname; + private String profileImageUrl; + private Gender gender; + private String birth; +} diff --git a/src/main/java/com/example/solidconnection/auth/dto/FirstAccessResponseDto.java b/src/main/java/com/example/solidconnection/auth/dto/kakao/FirstAccessResponseDto.java similarity index 94% rename from src/main/java/com/example/solidconnection/auth/dto/FirstAccessResponseDto.java rename to src/main/java/com/example/solidconnection/auth/dto/kakao/FirstAccessResponseDto.java index a28522320..531d3e77f 100644 --- a/src/main/java/com/example/solidconnection/auth/dto/FirstAccessResponseDto.java +++ b/src/main/java/com/example/solidconnection/auth/dto/kakao/FirstAccessResponseDto.java @@ -1,4 +1,4 @@ -package com.example.solidconnection.auth.dto; +package com.example.solidconnection.auth.dto.kakao; import lombok.*; diff --git a/src/main/java/com/example/solidconnection/auth/dto/KakaoAccount.java b/src/main/java/com/example/solidconnection/auth/dto/kakao/KakaoAccount.java similarity index 89% rename from src/main/java/com/example/solidconnection/auth/dto/KakaoAccount.java rename to src/main/java/com/example/solidconnection/auth/dto/kakao/KakaoAccount.java index 47e07d23d..3c1791516 100644 --- a/src/main/java/com/example/solidconnection/auth/dto/KakaoAccount.java +++ b/src/main/java/com/example/solidconnection/auth/dto/kakao/KakaoAccount.java @@ -1,4 +1,4 @@ -package com.example.solidconnection.auth.dto; +package com.example.solidconnection.auth.dto.kakao; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/src/main/java/com/example/solidconnection/auth/dto/KakaoCodeDto.java b/src/main/java/com/example/solidconnection/auth/dto/kakao/KakaoCodeDto.java similarity index 78% rename from src/main/java/com/example/solidconnection/auth/dto/KakaoCodeDto.java rename to src/main/java/com/example/solidconnection/auth/dto/kakao/KakaoCodeDto.java index 625c99969..3c55e728d 100644 --- a/src/main/java/com/example/solidconnection/auth/dto/KakaoCodeDto.java +++ b/src/main/java/com/example/solidconnection/auth/dto/kakao/KakaoCodeDto.java @@ -1,4 +1,4 @@ -package com.example.solidconnection.auth.dto; +package com.example.solidconnection.auth.dto.kakao; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/src/main/java/com/example/solidconnection/auth/dto/kakao/KakaoOauthResponseDto.java b/src/main/java/com/example/solidconnection/auth/dto/kakao/KakaoOauthResponseDto.java new file mode 100644 index 000000000..57f4dd3da --- /dev/null +++ b/src/main/java/com/example/solidconnection/auth/dto/kakao/KakaoOauthResponseDto.java @@ -0,0 +1,4 @@ +package com.example.solidconnection.auth.dto.kakao; + +public class KakaoOauthResponseDto { +} diff --git a/src/main/java/com/example/solidconnection/auth/dto/KakaoProfile.java b/src/main/java/com/example/solidconnection/auth/dto/kakao/KakaoProfile.java similarity index 89% rename from src/main/java/com/example/solidconnection/auth/dto/KakaoProfile.java rename to src/main/java/com/example/solidconnection/auth/dto/kakao/KakaoProfile.java index 323dbb798..4f8dcf2c5 100644 --- a/src/main/java/com/example/solidconnection/auth/dto/KakaoProfile.java +++ b/src/main/java/com/example/solidconnection/auth/dto/kakao/KakaoProfile.java @@ -1,4 +1,4 @@ -package com.example.solidconnection.auth.dto; +package com.example.solidconnection.auth.dto.kakao; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/src/main/java/com/example/solidconnection/auth/dto/KakaoTokenDto.java b/src/main/java/com/example/solidconnection/auth/dto/kakao/KakaoTokenDto.java similarity index 90% rename from src/main/java/com/example/solidconnection/auth/dto/KakaoTokenDto.java rename to src/main/java/com/example/solidconnection/auth/dto/kakao/KakaoTokenDto.java index f51d9decb..5a4b65704 100644 --- a/src/main/java/com/example/solidconnection/auth/dto/KakaoTokenDto.java +++ b/src/main/java/com/example/solidconnection/auth/dto/kakao/KakaoTokenDto.java @@ -1,4 +1,4 @@ -package com.example.solidconnection.auth.dto; +package com.example.solidconnection.auth.dto.kakao; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/src/main/java/com/example/solidconnection/auth/dto/KakaoUserInfoDto.java b/src/main/java/com/example/solidconnection/auth/dto/kakao/KakaoUserInfoDto.java similarity index 89% rename from src/main/java/com/example/solidconnection/auth/dto/KakaoUserInfoDto.java rename to src/main/java/com/example/solidconnection/auth/dto/kakao/KakaoUserInfoDto.java index c2cf1d982..88f25eaf7 100644 --- a/src/main/java/com/example/solidconnection/auth/dto/KakaoUserInfoDto.java +++ b/src/main/java/com/example/solidconnection/auth/dto/kakao/KakaoUserInfoDto.java @@ -1,4 +1,4 @@ -package com.example.solidconnection.auth.dto; +package com.example.solidconnection.auth.dto.kakao; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/src/main/java/com/example/solidconnection/auth/service/AuthService.java b/src/main/java/com/example/solidconnection/auth/service/AuthService.java new file mode 100644 index 000000000..fa76f7602 --- /dev/null +++ b/src/main/java/com/example/solidconnection/auth/service/AuthService.java @@ -0,0 +1,117 @@ +package com.example.solidconnection.auth.service; + + +import com.example.solidconnection.auth.dto.SignUpRequestDto; +import com.example.solidconnection.config.token.TokenService; +import com.example.solidconnection.config.token.TokenValidator; +import com.example.solidconnection.country.CountryRepository; +import com.example.solidconnection.country.InterestedCountyRepository; +import com.example.solidconnection.custom.exception.CustomException; +import com.example.solidconnection.entity.*; +import com.example.solidconnection.region.InterestedRegionRepository; +import com.example.solidconnection.region.RegionRepository; +import com.example.solidconnection.siteuser.repository.SiteUserRepository; +import com.example.solidconnection.type.CountryCode; +import com.example.solidconnection.type.RegionCode; +import com.example.solidconnection.type.Role; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import java.util.List; +import java.util.stream.Collectors; + +import static com.example.solidconnection.custom.exception.ErrorCode.*; + +@Service +@RequiredArgsConstructor +public class AuthService { + private final TokenValidator tokenValidator; + private final TokenService tokenService; + private final SiteUserRepository siteUserRepository; + private final RegionRepository regionRepository; + private final InterestedRegionRepository interestedRegionRepository; + private final CountryRepository countryRepository; + private final InterestedCountyRepository interestedCountyRepository; + + public boolean signUp(SignUpRequestDto signUpRequestDto) { + tokenValidator.validateKakaoToken(signUpRequestDto.getKakaoOauthToken()); + validateUserNotDuplicated(signUpRequestDto); + validateNicknameDuplicated(signUpRequestDto.getNickname()); + validateBirthFormat(signUpRequestDto.getBirth()); + + SiteUser siteUser = makeSiteUserEntity(signUpRequestDto); + SiteUser savedSiteUser = siteUserRepository.save(siteUser); + + saveInterestedRegion(signUpRequestDto, savedSiteUser); + saveInterestedCountry(signUpRequestDto, savedSiteUser); + return true; + } + + private void validateUserNotDuplicated(SignUpRequestDto signUpRequestDto){ + String email = tokenService.getEmail(signUpRequestDto.getKakaoOauthToken()); + if(siteUserRepository.existsByEmail(email)){ + throw new CustomException(USER_ALREADY_EXISTED); + } + } + + private void validateNicknameDuplicated(String nickname){ + if(siteUserRepository.existsByNickname(nickname)){ + throw new CustomException(NICKNAME_ALREADY_EXISTED); + } + } + + private void validateBirthFormat(String birthInput) { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + try { + LocalDate.parse(birthInput, formatter); + } catch (DateTimeParseException e) { + throw new CustomException(INVALID_BIRTH_FORMAT); + } + } + + private SiteUser makeSiteUserEntity(SignUpRequestDto signUpRequestDto) { + return SiteUser.builder() + .email(tokenService.getEmail(signUpRequestDto.getKakaoOauthToken())) + .nickname(signUpRequestDto.getNickname()) + .preparationStage(signUpRequestDto.getPreparationStatus()) + .profileImageUrl(signUpRequestDto.getProfileImageUrl()) + .gender(signUpRequestDto.getGender()) + .birth(signUpRequestDto.getBirth()) + .role(Role.MENTEE) + .build(); + } + + private void saveInterestedCountry(SignUpRequestDto signUpRequestDto, SiteUser savedSiteUser) { + List interestedCountries = signUpRequestDto.getInterestedCountries().stream() + .map(CountryCode::getCountryCodeByKoreanName) + .map(countryCode -> { + Country country = countryRepository.findByCountryCode(countryCode) + .orElseThrow(() -> new RuntimeException("Country Code enum이랑 table이랑 다름 : " + countryCode.name())); + return InterestedCountry.builder() + .siteUser(savedSiteUser) + .country(country) + .build(); + }) + .collect(Collectors.toList()); + interestedCountyRepository.saveAll(interestedCountries); + } + + private void saveInterestedRegion(SignUpRequestDto signUpRequestDto, SiteUser savedSiteUser) { + List interestedRegions = signUpRequestDto.getInterestedRegions().stream() + .map(RegionCode::getRegionCodeByKoreanName) + .map(regionCode -> { + Region region = regionRepository.findByRegionCode(regionCode) + .orElseThrow(() -> new RuntimeException("Region Code enum이랑 table이랑 다름 : " + regionCode.name())); + return InterestedRegion.builder() + .siteUser(savedSiteUser) + .region(region) + .build(); + }) + .collect(Collectors.toList()); + interestedRegionRepository.saveAll(interestedRegions); + } + +} diff --git a/src/main/java/com/example/solidconnection/auth/service/KakaoOAuthService.java b/src/main/java/com/example/solidconnection/auth/service/KakaoOAuthService.java index 26565d28e..08d681a6c 100644 --- a/src/main/java/com/example/solidconnection/auth/service/KakaoOAuthService.java +++ b/src/main/java/com/example/solidconnection/auth/service/KakaoOAuthService.java @@ -1,6 +1,7 @@ package com.example.solidconnection.auth.service; -import com.example.solidconnection.auth.dto.*; +import com.example.solidconnection.auth.dto.SignInResponseDto; +import com.example.solidconnection.auth.dto.kakao.*; import com.example.solidconnection.config.token.TokenService; import com.example.solidconnection.config.token.TokenType; import com.example.solidconnection.custom.exception.CustomException; @@ -56,7 +57,7 @@ private String getKakaoAccessToken(String code) { ); return Objects.requireNonNull(response.getBody()).getAccessToken(); } catch (Exception e){ - throw new CustomException(KAKAO_AUTH_CODE_FAIL); + throw new CustomException(INVALID_KAKAO_AUTH_CODE); } } @@ -93,8 +94,9 @@ private KakaoUserInfoDto getKakaoUserInfo(String accessToken) { } private SignInResponseDto kakaoSignIn(String email) { - var accessToken = tokenService.generateToken(email, TokenType.ACCESS); - var refreshToken = tokenService.saveToken(email, TokenType.REFRESH); + String accessToken = tokenService.generateToken(email, TokenType.ACCESS); + String refreshToken = tokenService.generateToken(email, TokenType.REFRESH); + tokenService.saveToken(refreshToken, TokenType.REFRESH); return SignInResponseDto.builder() .registered(true) .accessToken(accessToken) diff --git a/src/main/java/com/example/solidconnection/config/security/JwtAuthenticationEntryPoint.java b/src/main/java/com/example/solidconnection/config/security/JwtAuthenticationEntryPoint.java index a7c0d94d4..2bad197e7 100644 --- a/src/main/java/com/example/solidconnection/config/security/JwtAuthenticationEntryPoint.java +++ b/src/main/java/com/example/solidconnection/config/security/JwtAuthenticationEntryPoint.java @@ -1,6 +1,5 @@ package com.example.solidconnection.config.security; -import com.example.solidconnection.custom.exception.CustomException; import com.example.solidconnection.custom.response.ErrorResponse; import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.servlet.http.HttpServletRequest; @@ -23,7 +22,7 @@ public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint { @Override public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException { - ErrorResponse errorResponse = new ErrorResponse(new CustomException(AUTHENTICATION_FAILED, authException.getMessage())); + ErrorResponse errorResponse = new ErrorResponse(AUTHENTICATION_FAILED, authException.getMessage()); response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); response.setContentType("application/json"); response.setCharacterEncoding("UTF-8"); diff --git a/src/main/java/com/example/solidconnection/config/token/TokenService.java b/src/main/java/com/example/solidconnection/config/token/TokenService.java index 6de984a76..58548f94d 100644 --- a/src/main/java/com/example/solidconnection/config/token/TokenService.java +++ b/src/main/java/com/example/solidconnection/config/token/TokenService.java @@ -29,10 +29,8 @@ public class TokenService { public String generateToken(String email, TokenType tokenType) { Claims claims = Jwts.claims().setSubject(email); - - var now = new Date(); - var expiredDate = new Date(now.getTime() + tokenType.getExpireTime()); - + Date now = new Date(); + Date expiredDate = new Date(now.getTime() + tokenType.getExpireTime()); return Jwts.builder() .setClaims(claims) .setIssuedAt(now) @@ -41,16 +39,13 @@ public String generateToken(String email, TokenType tokenType) { .compact(); } - public String saveToken(String email, TokenType tokenType) { - String token = generateToken(email, tokenType); - + public void saveToken(String token, TokenType tokenType) { redisTemplate.opsForValue().set( - tokenType.getPrefix() + email, + tokenType.getPrefix() + getClaim(token).getSubject(), token, tokenType.getExpireTime(), TimeUnit.MILLISECONDS ); - return token; } public Authentication getAuthentication(String token) { @@ -60,6 +55,10 @@ public Authentication getAuthentication(String token) { return new UsernamePasswordAuthenticationToken(userDetails, "", userDetails.getAuthorities()); } + public String getEmail(String token) { + return getClaim(token).getSubject(); + } + private Claims getClaim(String token) { return Jwts.parser() .setSigningKey(this.secretKey) diff --git a/src/main/java/com/example/solidconnection/config/token/TokenValidator.java b/src/main/java/com/example/solidconnection/config/token/TokenValidator.java index 534661af8..99d4bf3fd 100644 --- a/src/main/java/com/example/solidconnection/config/token/TokenValidator.java +++ b/src/main/java/com/example/solidconnection/config/token/TokenValidator.java @@ -10,6 +10,7 @@ import org.springframework.util.StringUtils; import java.util.Date; +import java.util.Objects; import static com.example.solidconnection.custom.exception.ErrorCode.*; @@ -23,7 +24,7 @@ public class TokenValidator { public void validateAccessToken(String token) { validateTokenNotEmpty(token); - validateAccessTokenNotExpired(token); + validateTokenNotExpired(token, TokenType.ACCESS); validateRefreshToken(token); // TODO : validateNotLogOut 함수 생성 및 추가 } @@ -35,11 +36,29 @@ private void validateRefreshToken(String token) { } } - private void validateAccessTokenNotExpired(String token) { + public void validateKakaoToken(String token) { + validateTokenNotEmpty(token); + validateTokenNotExpired(token, TokenType.KAKAO_OAUTH); + validateKakaoTokenNotUsed(token); + } + + private void validateKakaoTokenNotUsed(String token) { + String email = getClaim(token).getSubject(); + if (Objects.equals(redisTemplate.opsForValue().get(TokenType.KAKAO_OAUTH.getPrefix() + email), token)) { + throw new CustomException(INVALID_KAKAO_TOKEN); + } + } + + private void validateTokenNotExpired(String token, TokenType tokenType) { Date expiration = getClaim(token).getExpiration(); long now = new Date().getTime(); - if((expiration.getTime() - now) < 0){ - throw new CustomException(ACCESS_TOKEN_EXPIRED); + if ((expiration.getTime() - now) < 0) { + if (tokenType.equals(TokenType.ACCESS)) { + throw new CustomException(ACCESS_TOKEN_EXPIRED); + } + if (token.equals(TokenType.KAKAO_OAUTH)) { + throw new CustomException(INVALID_KAKAO_TOKEN); + } } } diff --git a/src/main/java/com/example/solidconnection/country/CountryRepository.java b/src/main/java/com/example/solidconnection/country/CountryRepository.java new file mode 100644 index 000000000..53657de3b --- /dev/null +++ b/src/main/java/com/example/solidconnection/country/CountryRepository.java @@ -0,0 +1,13 @@ +package com.example.solidconnection.country; + +import com.example.solidconnection.entity.Country; +import com.example.solidconnection.type.CountryCode; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +@Repository +public interface CountryRepository extends JpaRepository { + Optional findByCountryCode(CountryCode countryCode); +} diff --git a/src/main/java/com/example/solidconnection/country/InterestedCountyRepository.java b/src/main/java/com/example/solidconnection/country/InterestedCountyRepository.java new file mode 100644 index 000000000..907b304a1 --- /dev/null +++ b/src/main/java/com/example/solidconnection/country/InterestedCountyRepository.java @@ -0,0 +1,12 @@ +package com.example.solidconnection.country; + +import com.example.solidconnection.entity.InterestedCountry; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface InterestedCountyRepository extends JpaRepository { + List findAllBySiteUser_Email(String email); +} diff --git a/src/main/java/com/example/solidconnection/custom/exception/CustomException.java b/src/main/java/com/example/solidconnection/custom/exception/CustomException.java index 08122faf5..209d3aa7e 100644 --- a/src/main/java/com/example/solidconnection/custom/exception/CustomException.java +++ b/src/main/java/com/example/solidconnection/custom/exception/CustomException.java @@ -8,13 +8,12 @@ public class CustomException extends RuntimeException { private final String message; public CustomException(ErrorCode errorCode){ - super(errorCode.getMessage()); code = errorCode.getCode(); message = errorCode.getMessage(); } public CustomException(ErrorCode errorCode, String detail){ code = errorCode.getCode(); - message = errorCode.getMessage() + detail; + message = errorCode.getMessage() + " : " + detail; } } diff --git a/src/main/java/com/example/solidconnection/custom/exception/CustomExceptionHandler.java b/src/main/java/com/example/solidconnection/custom/exception/CustomExceptionHandler.java index e30d79134..29a5e0a3a 100644 --- a/src/main/java/com/example/solidconnection/custom/exception/CustomExceptionHandler.java +++ b/src/main/java/com/example/solidconnection/custom/exception/CustomExceptionHandler.java @@ -1,12 +1,15 @@ package com.example.solidconnection.custom.exception; import com.example.solidconnection.custom.response.ErrorResponse; +import com.fasterxml.jackson.databind.exc.InvalidFormatException; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; +import static com.example.solidconnection.custom.exception.ErrorCode.JSON_PARSING_FAILED; + @Slf4j @ControllerAdvice public class CustomExceptionHandler { @@ -16,4 +19,11 @@ protected ResponseEntity handleCustomException(CustomException e) ErrorResponse errorResponse = new ErrorResponse(e); return new ResponseEntity<>(errorResponse, HttpStatus.valueOf(e.getCode())); } -} + + @ExceptionHandler(InvalidFormatException.class) + public ResponseEntity handleInvalidFormatException(InvalidFormatException ex) { + String errorMessage = ex.getValue() + " 은(는) 유효하지 않은 값입니다."; + ErrorResponse errorResponse = new ErrorResponse(JSON_PARSING_FAILED, errorMessage); + return new ResponseEntity<>(errorResponse, HttpStatus.valueOf(JSON_PARSING_FAILED.getCode())); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/solidconnection/custom/exception/ErrorCode.java b/src/main/java/com/example/solidconnection/custom/exception/ErrorCode.java index 8640313ee..6b14c997e 100644 --- a/src/main/java/com/example/solidconnection/custom/exception/ErrorCode.java +++ b/src/main/java/com/example/solidconnection/custom/exception/ErrorCode.java @@ -7,12 +7,19 @@ @Getter @AllArgsConstructor public enum ErrorCode { + USER_ALREADY_EXISTED(HttpStatus.CONFLICT.value(), "이미 존재하는 회원입니다."), + JSON_PARSING_FAILED(HttpStatus.BAD_REQUEST.value(), "JSON 파싱 에러"), + INVALID_REGION_NAME(HttpStatus.BAD_REQUEST.value(), "지원하지 않는 지역명입니다."), + INVALID_COUNTRY_NAME(HttpStatus.BAD_REQUEST.value(), "지원하지 않는 국가명입니다."), + INVALID_BIRTH_FORMAT(HttpStatus.BAD_REQUEST.value(), "잘못된 생년월일 형식입니다."), + NICKNAME_ALREADY_EXISTED(HttpStatus.CONFLICT.value(), "이미 존재하는 닉네임입니다."), INVALID_TOKEN(HttpStatus.UNAUTHORIZED.value(), "토큰이 필요한 경로에 빈 토큰으로 요청했습니다."), AUTHENTICATION_FAILED(HttpStatus.UNAUTHORIZED.value(), "인증이 필요한 접근입니다."), EMAIL_NOT_FOUND(HttpStatus.NOT_FOUND.value(), "회원 정보를 찾을 수 없습니다."), - KAKAO_AUTH_CODE_FAIL(HttpStatus.BAD_REQUEST.value(),"잘못된 카카오 인증 코드입니다. 카카오 인증 코드는 일회용이며, 인증 만료 시간은 10분입니다."), + INVALID_KAKAO_AUTH_CODE(HttpStatus.BAD_REQUEST.value(),"사용할 수 없는 카카오 인증 코드입니다. 카카오 인증 코드는 일회용이며, 인증 만료 시간은 10분입니다."), KAKAO_USER_INFO_FAIL(HttpStatus.BAD_REQUEST.value(),"카카오 사용자 정보 조회에 실패했습니다."), ACCESS_TOKEN_EXPIRED(HttpStatus.UNAUTHORIZED.value(),"액세스 토큰이 만료되었습니다. 재발급 api를 호출해주세요."), + INVALID_KAKAO_TOKEN(HttpStatus.UNAUTHORIZED.value(),"사용할 수 없는 카카오 로그인 토큰입니다."), REFRESH_TOKEN_EXPIRED(HttpStatus.UNAUTHORIZED.value(),"리프레시 토큰이 만료되었습니다. 다시 로그인을 진행해주세요."), ; diff --git a/src/main/java/com/example/solidconnection/custom/response/ErrorResponse.java b/src/main/java/com/example/solidconnection/custom/response/ErrorResponse.java index 7a2d6aa19..5ad96a938 100644 --- a/src/main/java/com/example/solidconnection/custom/response/ErrorResponse.java +++ b/src/main/java/com/example/solidconnection/custom/response/ErrorResponse.java @@ -1,6 +1,7 @@ package com.example.solidconnection.custom.response; import com.example.solidconnection.custom.exception.CustomException; +import com.example.solidconnection.custom.exception.ErrorCode; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.Setter; @@ -21,4 +22,9 @@ private static class ErrorDetail { public ErrorResponse(CustomException e) { this.error = new ErrorDetail(e.getCode(), e.getMessage()); } + + public ErrorResponse(ErrorCode e, String detail){ + String detailedMessage = e.getMessage() + " : " + detail; + this.error = new ErrorDetail(e.getCode(), detailedMessage); + } } diff --git a/src/main/java/com/example/solidconnection/custom/response/StatusResponse.java b/src/main/java/com/example/solidconnection/custom/response/StatusResponse.java index b9cd7684f..6a1e5d453 100644 --- a/src/main/java/com/example/solidconnection/custom/response/StatusResponse.java +++ b/src/main/java/com/example/solidconnection/custom/response/StatusResponse.java @@ -4,9 +4,9 @@ @Getter public class StatusResponse extends CustomResponse { - private final Boolean status; + private final boolean status; - StatusResponse(Boolean status) { + public StatusResponse(boolean status) { this.status = status; } } diff --git a/src/main/java/com/example/solidconnection/entity/Country.java b/src/main/java/com/example/solidconnection/entity/Country.java index 0a7d106c4..b6f5cb0ae 100644 --- a/src/main/java/com/example/solidconnection/entity/Country.java +++ b/src/main/java/com/example/solidconnection/entity/Country.java @@ -12,12 +12,9 @@ public class Country { @Enumerated(EnumType.STRING) private CountryCode countryCode; - @Column(nullable = false, length = 100) - private String name; - // 연관 관계 @ManyToOne - @JoinColumn(name = "region_id") + @JoinColumn(name = "region_code") private Region region; @OneToMany(mappedBy = "country") diff --git a/src/main/java/com/example/solidconnection/entity/InterestedCountry.java b/src/main/java/com/example/solidconnection/entity/InterestedCountry.java index 3e2c16329..baadab398 100644 --- a/src/main/java/com/example/solidconnection/entity/InterestedCountry.java +++ b/src/main/java/com/example/solidconnection/entity/InterestedCountry.java @@ -1,8 +1,16 @@ package com.example.solidconnection.entity; import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; @Entity +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Getter public class InterestedCountry { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -14,10 +22,6 @@ public class InterestedCountry { private SiteUser siteUser; @ManyToOne - @JoinColumn(name = "country_id") + @JoinColumn(name = "country_code") private Country country; - - @ManyToOne - @JoinColumn(name = "region_id") - private Region region; } diff --git a/src/main/java/com/example/solidconnection/entity/InterestedRegion.java b/src/main/java/com/example/solidconnection/entity/InterestedRegion.java index cdf6758b9..8bc83ee15 100644 --- a/src/main/java/com/example/solidconnection/entity/InterestedRegion.java +++ b/src/main/java/com/example/solidconnection/entity/InterestedRegion.java @@ -1,8 +1,16 @@ package com.example.solidconnection.entity; import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; @Entity +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Getter public class InterestedRegion { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -14,6 +22,6 @@ public class InterestedRegion { private SiteUser siteUser; @ManyToOne - @JoinColumn(name = "region_id") + @JoinColumn(name = "region_code") private Region region; } diff --git a/src/main/java/com/example/solidconnection/entity/Region.java b/src/main/java/com/example/solidconnection/entity/Region.java index 7be6bd3c9..6c9f0557f 100644 --- a/src/main/java/com/example/solidconnection/entity/Region.java +++ b/src/main/java/com/example/solidconnection/entity/Region.java @@ -10,7 +10,7 @@ public class Region { @Id @Column(length = 10) @Enumerated(EnumType.STRING) - private RegionCode id; + private RegionCode regionCode; // 연관 관계 @OneToMany(mappedBy = "region") @@ -19,9 +19,6 @@ public class Region { @OneToMany(mappedBy = "region") private Set interestedRegions; - @OneToMany(mappedBy = "region") - private Set interestedCountries; - @OneToMany(mappedBy = "region") private Set universities; } diff --git a/src/main/java/com/example/solidconnection/entity/SiteUser.java b/src/main/java/com/example/solidconnection/entity/SiteUser.java index eb7cdaa10..485e97ffa 100644 --- a/src/main/java/com/example/solidconnection/entity/SiteUser.java +++ b/src/main/java/com/example/solidconnection/entity/SiteUser.java @@ -1,13 +1,22 @@ package com.example.solidconnection.entity; +import com.example.solidconnection.type.Gender; import com.example.solidconnection.type.PreparationStatus; import com.example.solidconnection.type.Role; import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; import java.time.LocalDateTime; import java.util.Set; @Entity +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Getter public class SiteUser { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -19,21 +28,28 @@ public class SiteUser { @Column(nullable = false, length = 100) private String nickname; - @Column(nullable = false, length = 50) - @Enumerated(EnumType.STRING) - private PreparationStatus preparationStage; - @Column(length = 500) private String profileImageUrl; - private LocalDateTime nicknameModifiedAt; + @Column(nullable = false, length = 20) + private String birth; - private LocalDateTime quitedAt; + @Column(nullable = false, length = 50) + @Enumerated(EnumType.STRING) + private PreparationStatus preparationStage; @Column(nullable = false, length = 50) @Enumerated(EnumType.STRING) private Role role; + @Column(nullable = false, length = 20) + @Enumerated(EnumType.STRING) + private Gender gender; + + private LocalDateTime nicknameModifiedAt; + + private LocalDateTime quitedAt; + // 연관관계 @OneToMany(mappedBy = "siteUser") private Set interestedRegions; @@ -46,4 +62,5 @@ public class SiteUser { @OneToMany(mappedBy = "siteUser") private Set wishUniversities; + } diff --git a/src/main/java/com/example/solidconnection/entity/University.java b/src/main/java/com/example/solidconnection/entity/University.java index 2998087b7..90f940cb6 100644 --- a/src/main/java/com/example/solidconnection/entity/University.java +++ b/src/main/java/com/example/solidconnection/entity/University.java @@ -64,11 +64,11 @@ public class University { // 연관 관계 @ManyToOne - @JoinColumn(name = "country_id") + @JoinColumn(name = "country_code") private Country country; @ManyToOne - @JoinColumn(name = "region_id") + @JoinColumn(name = "region_code") private Region region; @OneToMany(mappedBy = "university") diff --git a/src/main/java/com/example/solidconnection/region/InterestedRegionRepository.java b/src/main/java/com/example/solidconnection/region/InterestedRegionRepository.java new file mode 100644 index 000000000..b7e3bb4ec --- /dev/null +++ b/src/main/java/com/example/solidconnection/region/InterestedRegionRepository.java @@ -0,0 +1,12 @@ +package com.example.solidconnection.region; + +import com.example.solidconnection.entity.InterestedRegion; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface InterestedRegionRepository extends JpaRepository { + List findAllBySiteUser_Email(String email); +} diff --git a/src/main/java/com/example/solidconnection/region/RegionRepository.java b/src/main/java/com/example/solidconnection/region/RegionRepository.java new file mode 100644 index 000000000..2c99b0e08 --- /dev/null +++ b/src/main/java/com/example/solidconnection/region/RegionRepository.java @@ -0,0 +1,13 @@ +package com.example.solidconnection.region; + +import com.example.solidconnection.entity.Region; +import com.example.solidconnection.type.RegionCode; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +@Repository +public interface RegionRepository extends JpaRepository { + Optional findByRegionCode(RegionCode regionCode); +} diff --git a/src/main/java/com/example/solidconnection/type/CountryCode.java b/src/main/java/com/example/solidconnection/type/CountryCode.java index d0988bf18..abcd67407 100644 --- a/src/main/java/com/example/solidconnection/type/CountryCode.java +++ b/src/main/java/com/example/solidconnection/type/CountryCode.java @@ -1,33 +1,40 @@ package com.example.solidconnection.type; +import com.example.solidconnection.custom.exception.CustomException; + +import java.util.Arrays; +import java.util.Optional; + +import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_COUNTRY_NAME; + public enum CountryCode { - BRUNEI("브루나이"), - SINGAPORE("싱가포르"), - AZERBAIJAN("아제르바이잔"), - INDONESIA("인도네시아"), - JAPAN("일본"), - TURKEY("튀르키예"), - HONG_KONG("홍콩"), - UNITED_STATES("미국"), - CANADA("캐나다"), - AUSTRALIA("호주"), - BRAZIL("브라질"), - NETHERLANDS("네덜란드"), - NORWAY("노르웨이"), - DENMARK("덴마크"), - GERMANY("독일"), - SWEDEN("스웨덴"), - SWITZERLAND("스위스"), - SPAIN("스페인"), - UNITED_KINGDOM("영국"), - AUSTRIA("오스트리아"), - ITALY("이탈리아"), - CZECH_REPUBLIC("체코"), - PORTUGAL("포르투갈"), - FRANCE("프랑스"), - FINLAND("핀란드"), - CHINA("중국"), - TAIWAN("대만"); + BN("브루나이"), + SG("싱가포르"), + AZ("아제르바이잔"), + ID("인도네시아"), + JP("일본"), + TR("튀르키예"), + HK("홍콩"), + US("미국"), + CA("캐나다"), + AU("호주"), + BR("브라질"), + NL("네덜란드"), + NO("노르웨이"), + DK("덴마크"), + DE("독일"), + SE("스웨덴"), + CH("스위스"), + ES("스페인"), + GB("영국"), + AT("오스트리아"), + IT("이탈리아"), + CZ("체코"), + PT("포르투갈"), + FR("프랑스"), + FI("핀란드"), + CN("중국"), + TW("대만"); private final String koreanName; @@ -36,12 +43,10 @@ public enum CountryCode { } public static CountryCode getCountryCodeByKoreanName(String koreanName) { - for (CountryCode countryCode : CountryCode.values()) { - if (countryCode.getKoreanName().equals(koreanName)) { - return countryCode; - } - } - throw new IllegalArgumentException("No country found with Korean name: " + koreanName); //TODO: 에러 타입 정리 필요 + Optional matchingCountryCode = Arrays.stream(CountryCode.values()) + .filter(countryCode -> countryCode.getKoreanName().equals(koreanName)) + .findFirst(); + return matchingCountryCode.orElseThrow(() -> new CustomException(INVALID_COUNTRY_NAME, koreanName)); } public String getKoreanName() { diff --git a/src/main/java/com/example/solidconnection/type/Gender.java b/src/main/java/com/example/solidconnection/type/Gender.java new file mode 100644 index 000000000..92a78814b --- /dev/null +++ b/src/main/java/com/example/solidconnection/type/Gender.java @@ -0,0 +1,5 @@ +package com.example.solidconnection.type; + +public enum Gender { + MALE, FEMALE, PREFER_NOT_TO_SAY +} diff --git a/src/main/java/com/example/solidconnection/type/RegionCode.java b/src/main/java/com/example/solidconnection/type/RegionCode.java index db3e533fa..6a37ec6c0 100644 --- a/src/main/java/com/example/solidconnection/type/RegionCode.java +++ b/src/main/java/com/example/solidconnection/type/RegionCode.java @@ -1,7 +1,32 @@ package com.example.solidconnection.type; +import com.example.solidconnection.custom.exception.CustomException; + +import java.util.Arrays; +import java.util.Optional; + +import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_REGION_NAME; + public enum RegionCode { - EUROPE, - AMERICAS, - ASIA + ASIA("아시아권"), + AMERICAS("미주권"), + CHINA("중국권"), + EUROPE("유럽권"); + + private final String koreanName; + + RegionCode(String koreanName) { + this.koreanName = koreanName; + } + + public static RegionCode getRegionCodeByKoreanName(String koreanName) { + Optional matchingRegionCode = Arrays.stream(RegionCode.values()) + .filter(regionCode -> regionCode.getKoreanName().equals(koreanName)) + .findFirst(); + return matchingRegionCode.orElseThrow(() -> new CustomException(INVALID_REGION_NAME, koreanName)); + } + + public String getKoreanName() { + return koreanName; + } } diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql new file mode 100644 index 000000000..c7a93c878 --- /dev/null +++ b/src/main/resources/data.sql @@ -0,0 +1,34 @@ +INSERT INTO region (region_code) VALUES + ('ASIA'), + ('AMERICAS'), + ('CHINA'), + ('EUROPE'); + +INSERT INTO country (country_code, region_code) VALUES + ('BN', 'ASIA'), + ('SG', 'ASIA'), + ('AZ', 'ASIA'), + ('ID', 'ASIA'), + ('JP', 'ASIA'), + ('TR', 'EUROPE'), + ('HK', 'ASIA'), + ('US', 'AMERICAS'), + ('CA', 'AMERICAS'), + ('AU', 'AMERICAS'), + ('BR', 'AMERICAS'), + ('NL', 'EUROPE'), + ('NO', 'EUROPE'), + ('DK', 'EUROPE'), + ('DE', 'EUROPE'), + ('SE', 'EUROPE'), + ('CH', 'EUROPE'), + ('ES', 'EUROPE'), + ('GB', 'EUROPE'), + ('AT', 'EUROPE'), + ('IT', 'EUROPE'), + ('CZ', 'EUROPE'), + ('PT', 'EUROPE'), + ('FR', 'EUROPE'), + ('FI', 'EUROPE'), + ('CN', 'CHINA'), + ('TW', 'CHINA'); diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql index 703ae55b9..da64823a7 100644 --- a/src/main/resources/schema.sql +++ b/src/main/resources/schema.sql @@ -1,113 +1,118 @@ --- Country -CREATE TABLE country ( - country_code VARCHAR(255) PRIMARY KEY, - name VARCHAR(255) NOT NULL, - region_code VARCHAR(255), - FOREIGN KEY (region_code) REFERENCES region(region_code) +DROP TABLE IF EXISTS `application`, `country`, `gpa_requirement`, `interested_country`, `interested_region`, `language_requirement`, `region`, `site_user`, `university`, `wish_university`; + +CREATE TABLE `application` ( + `gpa` float NOT NULL, + `first_choice_univ_id` bigint DEFAULT NULL, + `id` bigint NOT NULL AUTO_INCREMENT, + `second_choice_univ_id` bigint DEFAULT NULL, + `site_user_id` bigint DEFAULT NULL, + `language_test_type` varchar(255) NOT NULL, + `verify_status` varchar(50) NOT NULL, + `gpa_report_url` varchar(500) NOT NULL, + `language_test_report_url` varchar(500) NOT NULL, + `language_test_score` varchar(255) NOT NULL, + PRIMARY KEY (`id`), + KEY `FK4xffa66ucb9651me7uc8ek71c` (`first_choice_univ_id`), + KEY `FK401wya8j2e7jfrx7hu6gcc4fx` (`second_choice_univ_id`), + KEY `FKs4s3hebtn7vwd0b4xt8msxsis` (`site_user_id`), + CONSTRAINT `FK401wya8j2e7jfrx7hu6gcc4fx` FOREIGN KEY (`second_choice_univ_id`) REFERENCES `university` (`id`), + CONSTRAINT `FK4xffa66ucb9651me7uc8ek71c` FOREIGN KEY (`first_choice_univ_id`) REFERENCES `university` (`id`), + CONSTRAINT `FKs4s3hebtn7vwd0b4xt8msxsis` FOREIGN KEY (`site_user_id`) REFERENCES `site_user` (`id`) ); --- GpaRequirement -CREATE TABLE gpa_requirement ( - id BIGINT AUTO_INCREMENT PRIMARY KEY, - scale VARCHAR(255) NOT NULL, - min_gpa FLOAT NOT NULL, - university_id BIGINT, - FOREIGN KEY (university_id) REFERENCES university(id) +CREATE TABLE `country` ( + `country_code` varchar(255) NOT NULL, + `region_code` varchar(10) DEFAULT NULL, + PRIMARY KEY (`country_code`) ); --- InterestedCountry -CREATE TABLE interested_country ( - id BIGINT AUTO_INCREMENT PRIMARY KEY, - site_user_id BIGINT, - country_code VARCHAR(255), - region_code VARCHAR(255), - FOREIGN KEY (site_user_id) REFERENCES site_user(id), - FOREIGN KEY (country_code) REFERENCES country(country_code), - FOREIGN KEY (region_code) REFERENCES region(region_code) +CREATE TABLE `gpa_requirement` ( + `min_gpa` float NOT NULL, + `scale` varchar(5) NOT NULL, + `id` bigint NOT NULL AUTO_INCREMENT, + `university_id` bigint DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `FK74nj7od0mj9e63ervpl0wmy4q` (`university_id`), + CONSTRAINT `FK74nj7od0mj9e63ervpl0wmy4q` FOREIGN KEY (`university_id`) REFERENCES `university` (`id`) ); --- Region -CREATE TABLE region ( - region_code VARCHAR(255) PRIMARY KEY +CREATE TABLE `interested_country` ( + `country_code` varchar(2) DEFAULT NULL, + `id` bigint NOT NULL AUTO_INCREMENT, + `site_user_id` bigint DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `FK26u5am55jefclcd7r5smk8ai7` (`site_user_id`), + CONSTRAINT `FK26u5am55jefclcd7r5smk8ai7` FOREIGN KEY (`site_user_id`) REFERENCES `site_user` (`id`) ); --- University -CREATE TABLE university ( - id BIGINT AUTO_INCREMENT PRIMARY KEY, - korean_name VARCHAR(255) NOT NULL, - english_name VARCHAR(255) NOT NULL, - internal_name VARCHAR(255) NOT NULL, - recruit_number INT, - tuition_fee_payment_type VARCHAR(255), -- Enum, adjust as needed - exchange_semester VARCHAR(255), -- Enum, adjust as needed - details_for_language TEXT, - details_for_apply TEXT, - details_for_major TEXT, - details_for_accommodation TEXT, - homepage_url VARCHAR(255), - english_course_url VARCHAR(255), - accommodation_url VARCHAR(255), - details TEXT, - logo_image_url VARCHAR(255), - background_image_url VARCHAR(255), - country_code VARCHAR(255), - region_code VARCHAR(255), - FOREIGN KEY (country_code) REFERENCES country(country_code), - FOREIGN KEY (region_code) REFERENCES region(region_code) +CREATE TABLE `interested_region` ( + `id` bigint NOT NULL AUTO_INCREMENT, + `site_user_id` bigint DEFAULT NULL, + `region_code` varchar(10) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `FKia6h0pbisqhgm3lkeya6vqo4w` (`site_user_id`), + CONSTRAINT `FKia6h0pbisqhgm3lkeya6vqo4w` FOREIGN KEY (`site_user_id`) REFERENCES `site_user` (`id`) ); --- WishUniversity -CREATE TABLE wish_university ( - id BIGINT AUTO_INCREMENT PRIMARY KEY, - university_id BIGINT, - site_user_id BIGINT, - FOREIGN KEY (university_id) REFERENCES university(id), - FOREIGN KEY (site_user_id) REFERENCES site_user(id) +CREATE TABLE `language_requirement` ( + `id` bigint NOT NULL AUTO_INCREMENT, + `university_id` bigint DEFAULT NULL, + `language_test_type` varchar(255) NOT NULL, + `min_score` varchar(255) NOT NULL, + PRIMARY KEY (`id`), + KEY `FKp723kfidkuu8kus5svxnqq5hw` (`university_id`), + CONSTRAINT `FKp723kfidkuu8kus5svxnqq5hw` FOREIGN KEY (`university_id`) REFERENCES `university` (`id`) ); --- InterestedRegion -CREATE TABLE interested_region ( - id BIGINT AUTO_INCREMENT PRIMARY KEY, - site_user_id BIGINT, - region_code VARCHAR(255), - FOREIGN KEY (site_user_id) REFERENCES site_user(id), - FOREIGN KEY (region_code) REFERENCES region(region_code) +CREATE TABLE `region` ( + `region_code` varchar(255) NOT NULL, + PRIMARY KEY (`region_code`) ); --- Application -CREATE TABLE application ( - id BIGINT AUTO_INCREMENT PRIMARY KEY, - language_test_type VARCHAR(255), -- Enum, adjust as needed - language_test_score VARCHAR(255), - language_test_report_url VARCHAR(255), - gpa FLOAT NOT NULL, - gpa_report_url VARCHAR(255), - verify_status VARCHAR(255), - first_choice_university_id BIGINT, - second_choice_university_id BIGINT, - site_user_id BIGINT, - FOREIGN KEY (first_choice_university_id) REFERENCES university(id), - FOREIGN KEY (second_choice_university_id) REFERENCES university(id), - FOREIGN KEY (site_user_id) REFERENCES site_user(id) +CREATE TABLE `site_user` ( + `id` bigint NOT NULL AUTO_INCREMENT, + `nickname_modified_at` datetime(6) DEFAULT NULL, + `quited_at` datetime(6) DEFAULT NULL, + `birth` varchar(20) NOT NULL, + `gender` varchar(255) NOT NULL, + `preparation_stage` varchar(255) NOT NULL, + `role` varchar(255) NOT NULL, + `email` varchar(100) NOT NULL, + `nickname` varchar(100) NOT NULL, + `profile_image_url` varchar(500) DEFAULT NULL, + PRIMARY KEY (`id`) ); --- LanguageRequirement -CREATE TABLE language_requirement ( - id BIGINT AUTO_INCREMENT PRIMARY KEY, - language_test_type VARCHAR(255), -- Enum, adjust as needed - min_score VARCHAR(255), - university_id BIGINT, - FOREIGN KEY (university_id) REFERENCES university(id) +CREATE TABLE `university` ( + `country_code` varchar(2) DEFAULT NULL, + `recruit_number` int NOT NULL, + `id` bigint NOT NULL AUTO_INCREMENT, + `region_code` varchar(10) DEFAULT NULL, + `exchange_semester` varchar(255) NOT NULL, + `tuition_fee_payment_type` varchar(255) NOT NULL, + `english_name` varchar(100) NOT NULL, + `internal_name` varchar(100) NOT NULL, + `korean_name` varchar(100) NOT NULL, + `accommodation_url` varchar(500) DEFAULT NULL, + `background_image_url` varchar(500) NOT NULL, + `details` varchar(500) DEFAULT NULL, + `english_course_url` varchar(500) DEFAULT NULL, + `homepage_url` varchar(500) DEFAULT NULL, + `logo_image_url` varchar(500) NOT NULL, + `details_for_accommodation` varchar(1000) DEFAULT NULL, + `details_for_apply` varchar(1000) DEFAULT NULL, + `details_for_language` varchar(1000) DEFAULT NULL, + `details_for_major` varchar(1000) DEFAULT NULL, + PRIMARY KEY (`id`) ); --- SiteUser -CREATE TABLE site_user ( - id BIGINT AUTO_INCREMENT PRIMARY KEY, - email VARCHAR(255) NOT NULL UNIQUE, - nickname VARCHAR(255) NOT NULL UNIQUE, - preparation_stage VARCHAR(255), -- Enum, adjust as needed - profile_image_url VARCHAR(255), - nickname_modified_at TIMESTAMP, - quited_at TIMESTAMP, - role VARCHAR(255) -- Enum, adjust as needed +CREATE TABLE `wish_university` ( + `id` bigint NOT NULL AUTO_INCREMENT, + `site_user_id` bigint DEFAULT NULL, + `university_id` bigint DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `FKrrhud921brslcukx6fyuh0th3` (`site_user_id`), + KEY `FKhj3gn3mqmfeiiw9jt83g7t3rk` (`university_id`), + CONSTRAINT `FKhj3gn3mqmfeiiw9jt83g7t3rk` FOREIGN KEY (`university_id`) REFERENCES `university` (`id`), + CONSTRAINT `FKrrhud921brslcukx6fyuh0th3` FOREIGN KEY (`site_user_id`) REFERENCES `site_user` (`id`) );