diff --git a/src/main/java/inha/gdgoc/domain/recruit/member/controller/RecruitMemberController.java b/src/main/java/inha/gdgoc/domain/recruit/member/controller/RecruitMemberController.java index 7499a74..3cdeae7 100644 --- a/src/main/java/inha/gdgoc/domain/recruit/member/controller/RecruitMemberController.java +++ b/src/main/java/inha/gdgoc/domain/recruit/member/controller/RecruitMemberController.java @@ -10,7 +10,6 @@ import static inha.gdgoc.domain.recruit.member.controller.message.RecruitMemberMessage.PHONE_NUMBER_DUPLICATION_CHECK_SUCCESS; import static inha.gdgoc.domain.recruit.member.controller.message.RecruitMemberMessage.STUDENT_ID_DUPLICATION_CHECK_SUCCESS; -import inha.gdgoc.domain.recruit.member.dto.request.ApplicationRequest; import inha.gdgoc.domain.recruit.member.dto.request.CheckEmailRequest; import inha.gdgoc.domain.recruit.member.dto.request.CheckPhoneNumberRequest; import inha.gdgoc.domain.recruit.member.dto.request.CheckStudentIdRequest; @@ -50,6 +49,7 @@ import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; +import java.util.Map; @Tag(name = "Recruit - Members", description = "리크루팅 지원자 관리 API") @RequestMapping("/api/v1/recruit/member") @@ -69,7 +69,7 @@ public class RecruitMemberController { @PostMapping(value = "/apply", consumes = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity> recruitMemberAdd( - @RequestBody ApplicationRequest applicationRequest + @RequestBody Map applicationRequest ) { recruitMemberService.addRecruitMember(applicationRequest); @@ -78,7 +78,7 @@ public ResponseEntity> recruitMemberAdd( @PostMapping(value = "/apply", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) public ResponseEntity> recruitMemberAddMultipart( - @RequestPart("request") ApplicationRequest applicationRequest, + @RequestPart("request") Map applicationRequest, @RequestPart(value = "file", required = false) MultipartFile file ) { recruitMemberService.addRecruitMember(applicationRequest); diff --git a/src/main/java/inha/gdgoc/domain/recruit/member/dto/request/RecruitMemberRequest.java b/src/main/java/inha/gdgoc/domain/recruit/member/dto/request/RecruitMemberRequest.java index 6b53560..b50c087 100644 --- a/src/main/java/inha/gdgoc/domain/recruit/member/dto/request/RecruitMemberRequest.java +++ b/src/main/java/inha/gdgoc/domain/recruit/member/dto/request/RecruitMemberRequest.java @@ -17,11 +17,9 @@ @Getter public class RecruitMemberRequest { private String name; - private String grade; private String studentId; private String enrolledClassification; private String phoneNumber; - private String nationality; private String email; private String gender; @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy.MM.dd") @@ -33,11 +31,9 @@ public RecruitMember toEntity(AdmissionSemester admissionSemester) { String cleanPhone = phoneNumber.replaceAll("[^0-9]", ""); return RecruitMember.builder() .name(name) - .grade(grade) .studentId(studentId) .enrolledClassification(EnrolledClassification.fromStatus(enrolledClassification)) .phoneNumber(cleanPhone) - .nationality(nationality) .email(email) .gender(Gender.fromType(gender)) .birth(birth) diff --git a/src/main/java/inha/gdgoc/domain/recruit/member/entity/RecruitMember.java b/src/main/java/inha/gdgoc/domain/recruit/member/entity/RecruitMember.java index 6b8c903..92373fe 100644 --- a/src/main/java/inha/gdgoc/domain/recruit/member/entity/RecruitMember.java +++ b/src/main/java/inha/gdgoc/domain/recruit/member/entity/RecruitMember.java @@ -38,9 +38,6 @@ public class RecruitMember extends BaseEntity { @Column(name = "name", nullable = false) private String name; - @Column(name = "grade", nullable = false) - private String grade; - @Column(name = "student_id", nullable = false, unique = true) private String studentId; @@ -51,9 +48,6 @@ public class RecruitMember extends BaseEntity { @Column(name = "phone_number", nullable = false, unique = true) private String phoneNumber; - @Column(name = "nationality", nullable = false) - private String nationality; - @Column(name = "email", nullable = false) private String email; diff --git a/src/main/java/inha/gdgoc/domain/recruit/member/service/RecruitMemberService.java b/src/main/java/inha/gdgoc/domain/recruit/member/service/RecruitMemberService.java index d1db87b..8e2e972 100644 --- a/src/main/java/inha/gdgoc/domain/recruit/member/service/RecruitMemberService.java +++ b/src/main/java/inha/gdgoc/domain/recruit/member/service/RecruitMemberService.java @@ -6,6 +6,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import inha.gdgoc.domain.recruit.member.dto.request.ApplicationRequest; import inha.gdgoc.domain.recruit.member.dto.request.RecruitMemberMemoRequest; +import inha.gdgoc.domain.recruit.member.dto.request.RecruitMemberRequest; import inha.gdgoc.domain.recruit.member.dto.response.CheckEmailResponse; import inha.gdgoc.domain.recruit.member.dto.response.CheckPhoneNumberResponse; import inha.gdgoc.domain.recruit.member.dto.response.CheckStudentIdResponse; @@ -19,7 +20,9 @@ import inha.gdgoc.domain.recruit.member.repository.RecruitMemberMemoRepository; import inha.gdgoc.domain.recruit.member.repository.RecruitMemberRepository; import inha.gdgoc.global.util.SemesterCalculator; +import java.util.HashMap; import java.util.List; +import java.util.Map; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -36,12 +39,24 @@ public class RecruitMemberService { private final SemesterCalculator semesterCalculator; @Transactional - public void addRecruitMember(ApplicationRequest applicationRequest) { - RecruitMember member = applicationRequest.getMember() + public void addRecruitMember(Map requestPayload) { + RecruitMemberRequest memberRequest; + Map answers; + + if (requestPayload.containsKey("member")) { + ApplicationRequest applicationRequest = objectMapper.convertValue(requestPayload, ApplicationRequest.class); + memberRequest = applicationRequest.getMember(); + answers = normalizeAnswers(applicationRequest.getAnswers()); + } else { + memberRequest = buildMemberFromNumberedPayload(requestPayload); + answers = buildAnswersFromNumberedPayload(requestPayload); + } + + RecruitMember member = memberRequest .toEntity(semesterCalculator.currentSemester()); recruitMemberRepository.save(member); - List answers = applicationRequest.getAnswers().entrySet().stream() + List answerEntities = answers.entrySet().stream() .map(entry -> { try { // Object → JSON String 변환 @@ -54,7 +69,7 @@ public void addRecruitMember(ApplicationRequest applicationRequest) { }) .toList(); - answerRepository.saveAll(answers); + answerRepository.saveAll(answerEntities); } @Transactional @@ -123,4 +138,64 @@ private String normalizePhoneNumber(String phoneNumber) { return phoneNumber.replaceAll("[^0-9]", ""); } + @SuppressWarnings("unchecked") + private RecruitMemberRequest buildMemberFromNumberedPayload(Map payload) { + Map step2 = asMap(payload.get("2")); + Map step3 = asMap(payload.get("3")); + Map step4 = asMap(payload.get("4")); + Map step5 = asMap(payload.get("5")); + Map step11 = asMap(payload.get("11")); + + Map member = new HashMap<>(); + member.put("name", step2.get("name")); + member.put("studentId", step2.get("studentId")); + member.put("enrolledClassification", step2.get("enrolledClassification")); + member.put("phoneNumber", step3.get("phoneNumber")); + member.put("email", step4.get("email")); + member.put("gender", step4.get("gender")); + member.put("birth", step4.get("birth")); + member.put("major", step5.get("major")); + member.put("isPayed", step11.getOrDefault("isPayed", false)); + + return objectMapper.convertValue(member, RecruitMemberRequest.class); + } + + private Map buildAnswersFromNumberedPayload(Map payload) { + Map step8 = asMap(payload.get("8")); + Map step9 = asMap(payload.get("9")); + Map step10 = asMap(payload.get("10")); + + Map answers = new HashMap<>(); + putIfPresent(answers, "gdgInterest", step8.get("gdgInterest")); + putIfPresent(answers, "gdgWish", step9.get("gdgWish")); + putIfPresent(answers, "gdgFeedback", step10.get("gdgFeedback")); + + return answers; + } + + @SuppressWarnings("unchecked") + private Map asMap(Object value) { + if (value instanceof Map raw) { + return (Map) raw; + } + return Map.of(); + } + + private void putIfPresent(Map target, String key, Object value) { + if (value != null) { + target.put(key, value); + } + } + + private Map normalizeAnswers(Map rawAnswers) { + Map answers = new HashMap<>(); + if (rawAnswers == null) { + return answers; + } + putIfPresent(answers, "gdgInterest", rawAnswers.get("gdgInterest")); + putIfPresent(answers, "gdgWish", rawAnswers.get("gdgWish")); + putIfPresent(answers, "gdgFeedback", rawAnswers.get("gdgFeedback")); + return answers; + } + } diff --git a/src/main/resources/db/migration/V20260214__alter_recruit_member_grade_nationality_nullable.sql b/src/main/resources/db/migration/V20260214__alter_recruit_member_grade_nationality_nullable.sql new file mode 100644 index 0000000..d9845dd --- /dev/null +++ b/src/main/resources/db/migration/V20260214__alter_recruit_member_grade_nationality_nullable.sql @@ -0,0 +1,10 @@ +ALTER TABLE IF EXISTS recruit_member + DROP COLUMN IF EXISTS grade, + DROP COLUMN IF EXISTS nationality; + +ALTER TABLE IF EXISTS answer + DROP COLUMN IF EXISTS gdg_user_motive, + DROP COLUMN IF EXISTS gdg_user_story, + DROP COLUMN IF EXISTS gdg_period, + DROP COLUMN IF EXISTS gdg_route, + DROP COLUMN IF EXISTS gdg_expect;