diff --git a/src/main/java/com/moddy/server/common/exception/GlobalControllerExceptionAdvice.java b/src/main/java/com/moddy/server/common/exception/GlobalControllerExceptionAdvice.java index 372eda92..cbe49424 100644 --- a/src/main/java/com/moddy/server/common/exception/GlobalControllerExceptionAdvice.java +++ b/src/main/java/com/moddy/server/common/exception/GlobalControllerExceptionAdvice.java @@ -69,7 +69,7 @@ protected ErrorResponse handleConstraintViolationException(final ConstraintViola @ResponseStatus(HttpStatus.BAD_REQUEST) @ExceptionHandler(ValueInstantiationException.class) - protected ErrorResponse handleValueInstantiationException(final ValueInstantiationException e) { + protected ErrorResponse handleValueInstantiationException(final ValueInstantiationException e) { return ErrorResponse.error(VALIDATION_REQUEST_MISSING_EXCEPTION); } @@ -116,7 +116,7 @@ protected ErrorResponse handleNoResourceFoundException(final NoResourceFoundExce @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED) @ExceptionHandler(HttpRequestMethodNotSupportedException.class) protected ErrorResponse handleHttpRequestMethodNotSupportedException( - HttpRequestMethodNotSupportedException exception) { + HttpRequestMethodNotSupportedException e) { return ErrorResponse.error(METHOD_NOT_ALLOWED_EXCEPTION); } diff --git a/src/main/java/com/moddy/server/common/validation/prefer_hair_style/PreferHairStylesValidator.java b/src/main/java/com/moddy/server/common/validation/prefer_hair_style/PreferHairStylesValidator.java new file mode 100644 index 00000000..793c0e28 --- /dev/null +++ b/src/main/java/com/moddy/server/common/validation/prefer_hair_style/PreferHairStylesValidator.java @@ -0,0 +1,26 @@ +package com.moddy.server.common.validation.prefer_hair_style; + +import com.moddy.server.domain.prefer_hair_style.PreferHairStyle; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class PreferHairStylesValidator implements ConstraintValidator> { + + @Override + public void initialize(ValidPreferHairStyles constraintAnnotation) { + } + + @Override + public boolean isValid(List preferHairStyles, ConstraintValidatorContext context) { + + Set uniquePreferHairStyles = new HashSet<>(preferHairStyles); + if(uniquePreferHairStyles.size() != preferHairStyles.size()) return false; + if (preferHairStyles.isEmpty() || preferHairStyles == null) return false; + + return true; + } +} \ No newline at end of file diff --git a/src/main/java/com/moddy/server/common/validation/prefer_hair_style/ValidPreferHairStyles.java b/src/main/java/com/moddy/server/common/validation/prefer_hair_style/ValidPreferHairStyles.java new file mode 100644 index 00000000..ff1d06af --- /dev/null +++ b/src/main/java/com/moddy/server/common/validation/prefer_hair_style/ValidPreferHairStyles.java @@ -0,0 +1,23 @@ +package com.moddy.server.common.validation.prefer_hair_style; + +import jakarta.validation.Constraint; +import jakarta.validation.Payload; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Documented +@Constraint(validatedBy = PreferHairStylesValidator.class) +@Target({ElementType.FIELD, ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +public @interface ValidPreferHairStyles { + + String message() default "preferHairStyles는 필수 선택, 최소 1개부터 최대 6개 선택 가능합니다."; + + Class[] groups() default {}; + + Class[] payload() default {}; +} diff --git a/src/main/java/com/moddy/server/controller/model/ModelController.java b/src/main/java/com/moddy/server/controller/model/ModelController.java index e71cf6e5..07a771ce 100644 --- a/src/main/java/com/moddy/server/controller/model/ModelController.java +++ b/src/main/java/com/moddy/server/controller/model/ModelController.java @@ -19,6 +19,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.GetMapping; @@ -111,7 +112,7 @@ public SuccessNonDataResponse submitModelApplication( @Parameter(hidden = true) @UserId Long userId, @RequestPart(value = "modelImgUrl", required = false) MultipartFile modelImgUrl, @RequestPart(value = "applicationCaptureImgUrl", required = false) MultipartFile applicationCaptureImgUrl, - @RequestPart(value = "applicationInfo") ModelApplicationRequest applicationInfo) { + @RequestPart(value = "applicationInfo") @Valid ModelApplicationRequest applicationInfo) { modelService.postApplication(userId, modelImgUrl, applicationCaptureImgUrl, applicationInfo); return SuccessNonDataResponse.success(SuccessCode.CREATE_MODEL_APPLICATION_SUCCESS); } diff --git a/src/main/java/com/moddy/server/controller/model/dto/request/ModelApplicationRequest.java b/src/main/java/com/moddy/server/controller/model/dto/request/ModelApplicationRequest.java index 158b3bd7..fb79b66c 100644 --- a/src/main/java/com/moddy/server/controller/model/dto/request/ModelApplicationRequest.java +++ b/src/main/java/com/moddy/server/controller/model/dto/request/ModelApplicationRequest.java @@ -1,21 +1,32 @@ package com.moddy.server.controller.model.dto.request; +import com.moddy.server.common.validation.prefer_hair_style.ValidPreferHairStyles; import com.moddy.server.domain.hair_model_application.HairLength; import java.util.List; import com.moddy.server.domain.prefer_hair_style.HairStyle; import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; public record ModelApplicationRequest( @Schema(description = "모델의 현재 머리 기장 예시입니다.", example ="SHORT") + @Enumerated(EnumType.STRING) HairLength hairLength, - @Schema(description = "PreferHaireStyle의 예시 JSON 배열 포맷입니다.", example ="[\"NORMAL_CUT\", \"ALL_COLOR\"]") + @Schema(description = "PreferHaireStyle의 예시입니다.", example ="[\"NORMAL_CUT\", \"ALL_COLOR\"]") + @ValidPreferHairStyles List preferHairStyles, @Schema(description = "모델이 원하는 헤어스타일 예시입니다.", example = "안녕하세요 저는 숱을 많이 친 허쉬컷이 하고 싶어요 근데 머리가 곱슬이라 매직도 같이 해야지 이쁘게 될것 같아요. 그리고 머리가 얇아서 그거 감안하고 해야할것 같습니다.") + @Size(min = 0, max = 200, message = "hairDetail은 0~200 글자수 사이의 글자입니다.") + @NotBlank String hairDetail, - @Schema(description = "HairServiceRecords 의 예시 JSON 배열 포맷입니다.", example = "[{\"hairService\": \"PERM\", \"hairServiceTerm\": \"UNDER_ONE\"}, {\"hairService\": \"BLACK\", \"hairServiceTerm\": \"ABOVE_TWELVE\"}]") + @Size(min = 0, max = 3, message = "hairServiceRecord는 선택사항이며, 3개까지 추가 가능합니다.") List hairServiceRecords, @Schema(description = "모델의 인스타그램 예시입니다.", example ="hizo0") + @Pattern(regexp = "^[^@\\s]+[_\\.]+[^\\s]+$", message = "인스타 그램 아이디에는 @는 들어올 수 없지만 _와 .는 가능합니다.") String instagramId ) { public List getHairServiceRecords() { diff --git a/src/main/java/com/moddy/server/controller/model/dto/request/ModelHairServiceRequest.java b/src/main/java/com/moddy/server/controller/model/dto/request/ModelHairServiceRequest.java index 2b6fbefc..305ffd32 100644 --- a/src/main/java/com/moddy/server/controller/model/dto/request/ModelHairServiceRequest.java +++ b/src/main/java/com/moddy/server/controller/model/dto/request/ModelHairServiceRequest.java @@ -2,9 +2,13 @@ import com.moddy.server.domain.hair_service_record.ServiceRecord; import com.moddy.server.domain.hair_service_record.ServiceRecordTerm; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; public record ModelHairServiceRequest( + @Enumerated(EnumType.STRING) ServiceRecord hairService, + @Enumerated(EnumType.STRING) ServiceRecordTerm hairServiceTerm ) { }