diff --git a/server/.gradle/7.6.1/checksums/checksums.lock b/server/.gradle/7.6.1/checksums/checksums.lock index eeaf46d6..018b6cfb 100644 Binary files a/server/.gradle/7.6.1/checksums/checksums.lock and b/server/.gradle/7.6.1/checksums/checksums.lock differ diff --git a/server/.gradle/7.6.1/executionHistory/executionHistory.bin b/server/.gradle/7.6.1/executionHistory/executionHistory.bin index 310f7056..acf9f7ac 100644 Binary files a/server/.gradle/7.6.1/executionHistory/executionHistory.bin and b/server/.gradle/7.6.1/executionHistory/executionHistory.bin differ diff --git a/server/.gradle/7.6.1/executionHistory/executionHistory.lock b/server/.gradle/7.6.1/executionHistory/executionHistory.lock index 57e4eac7..0f54dfb5 100644 Binary files a/server/.gradle/7.6.1/executionHistory/executionHistory.lock and b/server/.gradle/7.6.1/executionHistory/executionHistory.lock differ diff --git a/server/.gradle/7.6.1/fileHashes/fileHashes.bin b/server/.gradle/7.6.1/fileHashes/fileHashes.bin index 0bde4870..9c98e1ea 100644 Binary files a/server/.gradle/7.6.1/fileHashes/fileHashes.bin and b/server/.gradle/7.6.1/fileHashes/fileHashes.bin differ diff --git a/server/.gradle/7.6.1/fileHashes/fileHashes.lock b/server/.gradle/7.6.1/fileHashes/fileHashes.lock index 420aa004..8d7f0d40 100644 Binary files a/server/.gradle/7.6.1/fileHashes/fileHashes.lock and b/server/.gradle/7.6.1/fileHashes/fileHashes.lock differ diff --git a/server/.gradle/7.6.1/fileHashes/resourceHashesCache.bin b/server/.gradle/7.6.1/fileHashes/resourceHashesCache.bin index ce9fe4f5..dd0bffbe 100644 Binary files a/server/.gradle/7.6.1/fileHashes/resourceHashesCache.bin and b/server/.gradle/7.6.1/fileHashes/resourceHashesCache.bin differ diff --git a/server/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/server/.gradle/buildOutputCleanup/buildOutputCleanup.lock index 82e305a1..c3903b50 100644 Binary files a/server/.gradle/buildOutputCleanup/buildOutputCleanup.lock and b/server/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ diff --git a/server/.gradle/file-system.probe b/server/.gradle/file-system.probe index 1f007d86..239692fd 100644 Binary files a/server/.gradle/file-system.probe and b/server/.gradle/file-system.probe differ diff --git a/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/aggregate/AnswerAggregate.java b/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/aggregate/AnswerAggregate.java new file mode 100644 index 00000000..559b97e9 --- /dev/null +++ b/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/aggregate/AnswerAggregate.java @@ -0,0 +1,46 @@ +package com.econovation.recruit.api.applicant.aggregate; + +import static org.axonframework.modelling.command.AggregateLifecycle.apply; + +import com.econovation.recruit.api.applicant.command.CreateAnswerCommand; +import com.econovation.recruitdomain.domains.applicant.domain.MongoAnswer; +import com.econovation.recruitdomain.domains.applicant.event.aggregateevent.AnswerCreatedEvent; +import java.util.Map; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.axonframework.commandhandling.CommandHandler; +import org.axonframework.eventsourcing.EventSourcingHandler; +import org.axonframework.modelling.command.AggregateIdentifier; +import org.axonframework.spring.stereotype.Aggregate; + +@AllArgsConstructor +@Getter +@Aggregate +@Slf4j +@NoArgsConstructor +public class AnswerAggregate { + + @AggregateIdentifier private String id; + private Integer year; + private Map qna; + // Constructor for creating an AnswerAggregate + @CommandHandler + public AnswerAggregate(CreateAnswerCommand command) { + + apply(new AnswerCreatedEvent(command.getId(), command.getYear(), command.getQna())); + } + + // Event handler for AnswerCreatedEvent + @EventSourcingHandler + public void on(AnswerCreatedEvent event) { + this.id = event.getId(); + this.year = event.getYear(); + this.qna = event.getQna(); + } + + public static AnswerAggregate from(MongoAnswer answer) { + return new AnswerAggregate(answer.getId(), answer.getYear(), answer.getQna()); + } +} diff --git a/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/aggregate/AnswerCreatedEventListener.java b/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/aggregate/AnswerCreatedEventListener.java new file mode 100644 index 00000000..fec01490 --- /dev/null +++ b/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/aggregate/AnswerCreatedEventListener.java @@ -0,0 +1,27 @@ +package com.econovation.recruit.api.applicant.aggregate; + +import com.econovation.recruitdomain.domains.applicant.domain.MongoAnswer; +import com.econovation.recruitdomain.domains.applicant.domain.MongoAnswerAdaptor; +import com.econovation.recruitdomain.domains.applicant.event.aggregateevent.AnswerCreatedEvent; +import lombok.RequiredArgsConstructor; +import org.axonframework.eventhandling.EventHandler; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class AnswerCreatedEventListener { + private final MongoAnswerAdaptor answerAdaptor; + + @EventHandler + public void handle(AnswerCreatedEvent event) { + MongoAnswer answer = + MongoAnswer.builder() + .id(event.getId()) + .year(event.getYear()) + .qna(event.getQna()) + .build(); + answerAdaptor.save(answer); + + // email 전송 event처리 + } +} diff --git a/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/command/CreateAnswerCommand.java b/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/command/CreateAnswerCommand.java new file mode 100644 index 00000000..9e57a99e --- /dev/null +++ b/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/command/CreateAnswerCommand.java @@ -0,0 +1,20 @@ +package com.econovation.recruit.api.applicant.command; + +import java.util.Map; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.ToString; +import org.axonframework.modelling.command.TargetAggregateIdentifier; + +@AllArgsConstructor +@ToString +@Data +@NoArgsConstructor +@Getter +public class CreateAnswerCommand { + @TargetAggregateIdentifier private String id; + private Integer year; + private Map qna; +} diff --git a/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/controller/AnswerController.java b/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/controller/AnswerController.java deleted file mode 100644 index 99b1dd71..00000000 --- a/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/controller/AnswerController.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.econovation.recruit.api.applicant.controller; - -import com.econovation.recruit.api.applicant.docs.CreateApplicantExceptionDocs; -import com.econovation.recruit.api.applicant.usecase.ApplicantMongoLoadUseCase; -import com.econovation.recruit.api.applicant.usecase.ApplicantMongoRegisterUseCase; -import com.econovation.recruitcommon.annotation.ApiErrorExceptionsExample; -import com.econovation.recruitcommon.annotation.XssProtected; -import io.swagger.v3.oas.annotations.Operation; -import java.util.Map; -import lombok.RequiredArgsConstructor; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@RequestMapping("/api/v1") -@RequiredArgsConstructor -public class AnswerController { - private final ApplicantMongoRegisterUseCase applicantMongoRegisterUseCase; - private final ApplicantMongoLoadUseCase applicantMongoLoadUseCase; - - @Operation(summary = "지원자가 지원서를 작성합니다.", description = "반환 값은 생성된 지원자의 ID입니다.") - @ApiErrorExceptionsExample(CreateApplicantExceptionDocs.class) - @XssProtected - @PostMapping("/register") - public ResponseEntity registerMongoApplicant(@RequestBody Map qna) { - applicantMongoRegisterUseCase.execute(qna); - return new ResponseEntity<>(HttpStatus.OK); - } - - @Operation(summary = "지원자 id로 지원서를 조회합니다.") - @GetMapping("/applicants/mongo/{applicant-id}") - public ResponseEntity> getApplicantById( - @PathVariable(value = "applicant-id") String applicantId) { - return new ResponseEntity<>(applicantMongoLoadUseCase.execute(applicantId), HttpStatus.OK); - } -} diff --git a/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/controller/ApplicantController.java b/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/controller/ApplicantController.java index 38bbdf70..d5d19ee7 100644 --- a/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/controller/ApplicantController.java +++ b/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/controller/ApplicantController.java @@ -1,22 +1,19 @@ package com.econovation.recruit.api.applicant.controller; import static com.econovation.recruitcommon.consts.RecruitStatic.APPLICANT_SUCCESS_REGISTER_MESSAGE; -import static com.econovation.recruitcommon.consts.RecruitStatic.QUESTION_SUCCESS_REGISTER_MESSAGE; +import com.econovation.recruit.api.applicant.command.CreateAnswerCommand; import com.econovation.recruit.api.applicant.docs.CreateApplicantExceptionDocs; -import com.econovation.recruit.api.applicant.usecase.AnswerLoadUseCase; -import com.econovation.recruit.api.applicant.usecase.ApplicantRegisterUseCase; -import com.econovation.recruit.api.applicant.usecase.QuestionRegisterUseCase; +import com.econovation.recruit.api.applicant.dto.AnswersResponseDto; +import com.econovation.recruit.api.applicant.usecase.ApplicantQueryUseCase; import com.econovation.recruit.api.applicant.usecase.TimeTableLoadUseCase; import com.econovation.recruit.api.applicant.usecase.TimeTableRegisterUseCase; import com.econovation.recruitcommon.annotation.ApiErrorExceptionsExample; +import com.econovation.recruitcommon.annotation.TimeTrace; import com.econovation.recruitcommon.annotation.XssProtected; -import com.econovation.recruitdomain.domains.applicant.dto.BlockRequestDto; import com.econovation.recruitdomain.domains.applicant.dto.TimeTableVo; import com.econovation.recruitdomain.domains.applicant.exception.ApplicantOutOfDateException; -import com.econovation.recruitdomain.domains.dto.ApplicantPaginationResponseDto; import com.econovation.recruitdomain.domains.dto.EmailSendDto; -import com.econovation.recruitdomain.domains.dto.QuestionRequestDto; import com.econovation.recruitdomain.domains.timetable.domain.TimeTable; import com.econovation.recruitinfrastructure.apache.CommonsEmailSender; import io.swagger.v3.oas.annotations.Operation; @@ -27,9 +24,9 @@ import java.util.List; import java.util.Map; import java.util.UUID; -import javax.validation.Valid; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.axonframework.commandhandling.gateway.CommandGateway; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; @@ -45,23 +42,48 @@ @Slf4j @Tag(name = "[1.0]. 지원서 API", description = "지원서 관련 API") public class ApplicantController { - private final ApplicantRegisterUseCase applicantRegisterUseCase; private final TimeTableRegisterUseCase timeTableRegisterUseCase; private final TimeTableLoadUseCase timeTableLoadUseCase; - private final QuestionRegisterUseCase questionRegisterUseCase; - private final AnswerLoadUseCase answerLoadUseCase; + private final ApplicantQueryUseCase applicantQueryUseCase; private final CommonsEmailSender commonsEmailSender; + private final CommandGateway commandGateway; @Operation(summary = "지원자가 지원서를 작성합니다.", description = "반환 값은 생성된 지원자의 ID입니다.") @ApiErrorExceptionsExample(CreateApplicantExceptionDocs.class) @XssProtected @PostMapping("/applicants") - public ResponseEntity registerApplicant( - @RequestBody @Valid List blockElements) { - // validateOutdated(); - UUID applicantId = applicantRegisterUseCase.execute(blockElements); - return new ResponseEntity<>(applicantId, HttpStatus.OK); + @TimeTrace + public ResponseEntity registerMongoApplicant(@RequestBody Map qna) { + // validateOutdated(); + commandGateway.send(new CreateAnswerCommand(UUID.randomUUID().toString(), 21, qna)); + return new ResponseEntity<>(APPLICANT_SUCCESS_REGISTER_MESSAGE, HttpStatus.OK); + } + + @Operation(summary = "지원자 id로 지원서를 조회합니다.") + @TimeTrace + @ApiErrorExceptionsExample(CreateApplicantExceptionDocs.class) + @GetMapping("/applicants/{applicant-id}") + public ResponseEntity> getApplicantById( + @PathVariable(value = "applicant-id") String applicantId) { + return new ResponseEntity<>(applicantQueryUseCase.execute(applicantId), HttpStatus.OK); + } + + @Operation(summary = "지원자 기수로 지원서를 조회합니다. / page는 1부터 시작합니다.") + @TimeTrace + @GetMapping("/page/{page}/year/{year}/applicants") + public ResponseEntity getApplicantsByYear( + @PathVariable(value = "year") Integer year, + @PathVariable(value = "page") Integer page) { + return new ResponseEntity<>(applicantQueryUseCase.execute(year, page), HttpStatus.OK); + } + + @Operation(summary = "모든 지원자의 지원서를 조회합니다.") + @TimeTrace + @GetMapping("/applicants") + public ResponseEntity>> getApplicants() { + return new ResponseEntity<>(applicantQueryUseCase.execute(), HttpStatus.OK); } + // ------------------------------ private void validateOutdated() { // 현재 한국 시간 가져오기 @@ -80,46 +102,19 @@ private void validateOutdated() { } } - @Operation(summary = "지원자 id로 지원서를 조회합니다.") - @GetMapping("/applicants/{applicant-id}") - public ResponseEntity> getApplicantById( - @PathVariable(value = "applicant-id") String applicantId) { - return new ResponseEntity<>(answerLoadUseCase.execute(applicantId), HttpStatus.OK); - } - - @Operation(summary = "모든 지원자의 지원서를 조회합니다.") - @GetMapping("/applicants") - public ResponseEntity>> getApplicants() { - return new ResponseEntity<>(answerLoadUseCase.execute(), HttpStatus.OK); - } - - @Operation(summary = "모든 지원자의 지원서를 페이지 단위로(1페이지당 8개) 조회합니다.") - @GetMapping("/page/{page}/applicants") - public ResponseEntity getApplicantsByPage( - // TODO 정렬 기준 추가 - @PathVariable(value = "page") Integer page) { - return new ResponseEntity<>(answerLoadUseCase.execute(page), HttpStatus.OK); - } - @Operation(summary = "지원자가 면접 가능 시간을 작성합니다.") @ApiErrorExceptionsExample(CreateApplicantExceptionDocs.class) + @TimeTrace @PostMapping("/applicants/{applicant-id}/timetables") public ResponseEntity registerApplicantTimeTable( - @PathVariable(value = "applicant-id") UUID applicantId, + @PathVariable(value = "applicant-id") String applicantId, @RequestBody List startTimes) { - timeTableRegisterUseCase.execute(applicantId.toString(), startTimes); + timeTableRegisterUseCase.execute(applicantId, startTimes); return new ResponseEntity<>(APPLICANT_SUCCESS_REGISTER_MESSAGE, HttpStatus.OK); } - @Operation(summary = "면접관이 면접 질문을 추가합니다.") - @PostMapping("/questions") - public ResponseEntity registerInterviewQuestion( - @RequestBody List questions) { - questionRegisterUseCase.execute(questions); - return new ResponseEntity<>(QUESTION_SUCCESS_REGISTER_MESSAGE, HttpStatus.OK); - } - @Operation(summary = "모든 면접 가능 시간을 조회합니다.") + @TimeTrace @GetMapping("/timetables") public ResponseEntity>>> getTimeTables() { return new ResponseEntity(timeTableLoadUseCase.findAll(), HttpStatus.OK); @@ -127,6 +122,7 @@ public ResponseEntity>>> getTimeTables() { @Operation(summary = "지원자의 면접 가능 시간을 조회합니다.") @GetMapping("/applicants/{applicant-id}/timetables") + @TimeTrace public ResponseEntity> getTimeTables( @PathVariable(name = "applicant-id") String applicantId) { List timeTableDto = timeTableLoadUseCase.getTimeTableByApplicantId(applicantId); @@ -134,6 +130,7 @@ public ResponseEntity> getTimeTables( } @Operation(summary = "면접 가능 시간마다 일치하는 지원자의 정보(희망분야, 이름)를 조회합니다.") + @TimeTrace @GetMapping("/timetables/applicants") public ResponseEntity>> getApplicantsByTimeTable() { return new ResponseEntity( @@ -141,6 +138,7 @@ public ResponseEntity>> getApplicantsByTimeTable() { } @Operation(summary = "지원서 제출한 html을 email 로 전송합니다.") + @TimeTrace @PostMapping("/applicants/mail") public ResponseEntity sendEmail(@RequestBody EmailSendDto emailSendDto) { commonsEmailSender.send(emailSendDto.getEmail(), emailSendDto.getApplicantId()); diff --git a/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/docs/CreateApplicantExceptionDocs.java b/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/docs/CreateApplicantExceptionDocs.java index 0c90f1cb..ca61062d 100644 --- a/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/docs/CreateApplicantExceptionDocs.java +++ b/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/docs/CreateApplicantExceptionDocs.java @@ -5,9 +5,16 @@ import com.econovation.recruitcommon.exception.RecruitCodeException; import com.econovation.recruitcommon.interfaces.SwaggerExampleExceptions; import com.econovation.recruitdomain.domains.applicant.exception.ApplicantDuplicateSubmitException; +import com.econovation.recruitdomain.domains.applicant.exception.ApplicantWrongPositionException; @ExceptionDoc public class CreateApplicantExceptionDocs implements SwaggerExampleExceptions { @ExplainError("지원서를 중복으로 제출했을 경우") public RecruitCodeException 지원서_중복_제출 = ApplicantDuplicateSubmitException.EXCEPTION; + + @ExplainError("지원서를 잘못된 포지션으로 제출했을 경우") + public RecruitCodeException 지원서_지원_포지션_오류 = ApplicantWrongPositionException.EXCEPTION; + + @ExplainError("지원서를 중복으로 제출했을 경우") + public RecruitCodeException 지원서_중복_제출_예외 = ApplicantDuplicateSubmitException.EXCEPTION; } diff --git a/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/docs/ReadApplicantExceptionDocs.java b/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/docs/ReadApplicantExceptionDocs.java new file mode 100644 index 00000000..68eeccac --- /dev/null +++ b/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/docs/ReadApplicantExceptionDocs.java @@ -0,0 +1,13 @@ +package com.econovation.recruit.api.applicant.docs; + +import com.econovation.recruitcommon.annotation.ExceptionDoc; +import com.econovation.recruitcommon.annotation.ExplainError; +import com.econovation.recruitcommon.exception.RecruitCodeException; +import com.econovation.recruitcommon.interfaces.SwaggerExampleExceptions; +import com.econovation.recruitdomain.domains.applicant.exception.ApplicantDuplicateSubmitException; + +@ExceptionDoc +public class ReadApplicantExceptionDocs implements SwaggerExampleExceptions { + @ExplainError("지원서를 중복으로 제출했을 경우") + public RecruitCodeException 지원서_중복_제출_예외 = ApplicantDuplicateSubmitException.EXCEPTION; +} diff --git a/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/dto/AnswersResponseDto.java b/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/dto/AnswersResponseDto.java new file mode 100644 index 00000000..82652b29 --- /dev/null +++ b/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/dto/AnswersResponseDto.java @@ -0,0 +1,18 @@ +package com.econovation.recruit.api.applicant.dto; + +import com.econovation.recruit.utils.vo.PageInfo; +import java.util.List; +import java.util.Map; +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class AnswersResponseDto { + private PageInfo pageInfo; + private List> answers; + + public static AnswersResponseDto of(List> list, PageInfo pageInfo) { + return new AnswersResponseDto(pageInfo, list); + } +} diff --git a/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/handler/ApplicantRegisterEventConfirmEmailHandler.java b/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/handler/ApplicantRegisterEventConfirmEmailHandler.java index 0e9e5d51..6aae477f 100644 --- a/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/handler/ApplicantRegisterEventConfirmEmailHandler.java +++ b/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/handler/ApplicantRegisterEventConfirmEmailHandler.java @@ -1,7 +1,7 @@ package com.econovation.recruit.api.applicant.handler; import com.econovation.recruit.api.user.helper.NcpMailHelper; -import com.econovation.recruitdomain.domains.applicant.event.ApplicantRegisterEvent; +import com.econovation.recruitdomain.domains.applicant.event.domainevent.ApplicantRegisterEvent; import com.econovation.recruitinfrastructure.apache.CommonsEmailSender; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; diff --git a/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/query/AnswerQuery.java b/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/query/AnswerQuery.java new file mode 100644 index 00000000..39ce20fc --- /dev/null +++ b/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/query/AnswerQuery.java @@ -0,0 +1,12 @@ +package com.econovation.recruit.api.applicant.query; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class AnswerQuery { + private String answerId; +} diff --git a/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/query/AnswersByYearQuery.java b/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/query/AnswersByYearQuery.java new file mode 100644 index 00000000..9dc66099 --- /dev/null +++ b/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/query/AnswersByYearQuery.java @@ -0,0 +1,11 @@ +package com.econovation.recruit.api.applicant.query; + +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class AnswersByYearQuery { + private Integer year; + private Integer page; +} diff --git a/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/query/queryhandler/AnswerQueryHandler.java b/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/query/queryhandler/AnswerQueryHandler.java new file mode 100644 index 00000000..dcd9068f --- /dev/null +++ b/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/query/queryhandler/AnswerQueryHandler.java @@ -0,0 +1,30 @@ +package com.econovation.recruit.api.applicant.query.queryhandler; + +import com.econovation.recruit.api.applicant.aggregate.AnswerAggregate; +import com.econovation.recruit.api.applicant.query.AnswerQuery; +import com.econovation.recruitdomain.domains.applicant.domain.MongoAnswer; +import com.econovation.recruitdomain.domains.applicant.domain.MongoAnswerAdaptor; +import lombok.RequiredArgsConstructor; +import org.axonframework.queryhandling.QueryHandler; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class AnswerQueryHandler { + private final MongoAnswerAdaptor answerAdaptor; + + @QueryHandler + public AnswerAggregate handle(AnswerQuery query) { + MongoAnswer result = + answerAdaptor + .findById(query.getAnswerId()) + .fold( + (exception) -> { + throw exception; + }, + (answer) -> { + return answer; + }); + return new AnswerAggregate(result.getId(), result.getYear(), result.getQna()); + } +} diff --git a/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/service/AnswerCommandService.java b/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/service/AnswerCommandService.java new file mode 100644 index 00000000..5c273b24 --- /dev/null +++ b/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/service/AnswerCommandService.java @@ -0,0 +1,68 @@ +package com.econovation.recruit.api.applicant.service; + +import com.econovation.recruit.api.applicant.usecase.ApplicantCommandUseCase; +import com.econovation.recruitcommon.exception.RecruitCodeException; +import com.econovation.recruitdomain.common.aop.domainEvent.Events; +import com.econovation.recruitdomain.domains.applicant.domain.MongoAnswer; +import com.econovation.recruitdomain.domains.applicant.domain.MongoAnswerAdaptor; +import com.econovation.recruitdomain.domains.applicant.event.domainevent.ApplicantRegisterEvent; +import com.econovation.recruitdomain.domains.applicant.exception.ApplicantDuplicateSubmitException; +import com.econovation.recruitdomain.domains.applicant.exception.ApplicantWrongPositionException; +import io.vavr.collection.Seq; +import io.vavr.control.Validation; +import java.util.Map; +import java.util.UUID; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class AnswerCommandService implements ApplicantCommandUseCase { + private final MongoAnswerAdaptor answerAdaptor; + + @Value("${econovation.year}") + private Integer year; + + @Override + public UUID execute(Map qna) { + UUID id = UUID.randomUUID(); + MongoAnswer answer = MongoAnswer.builder().id(id.toString()).qna(qna).year(year).build(); + // 학번으로 중복 체크 + validateRegisterApplicant(qna); + answerAdaptor.save(answer); + + String name = qna.get("name").toString(); + String hopeField = qna.get("field").toString(); + String email = qna.get("email").toString(); + + ApplicantRegisterEvent applicantRegisterEvent = + ApplicantRegisterEvent.of(answer.getId(), name, hopeField, email); + Events.raise(applicantRegisterEvent); + return id; + } + + private Validation, Map> validateRegisterApplicant( + Map qna) { + return Validation.combine(validateDuplicateSudentId(qna), validateIsRightPosition(qna)) + .ap((a, b) -> qna); + } + + private Validation validateIsRightPosition( + Map qna) { + String field = qna.get("field").toString(); + if (field.equals("기획자") || field.equals("개발자") || field.equals("디자이너")) { + return Validation.valid(qna); + } + throw ApplicantWrongPositionException.EXCEPTION; + } + + private Validation> validateDuplicateSudentId( + Map qna) { + String studentId = qna.get("classOf").toString(); + if (answerAdaptor.existsByAnswer(studentId, year)) { + throw ApplicantDuplicateSubmitException.EXCEPTION; + } + return Validation.valid(qna); + } +} diff --git a/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/service/AnswerMongoService.java b/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/service/AnswerMongoService.java deleted file mode 100644 index 86f2d0b3..00000000 --- a/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/service/AnswerMongoService.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.econovation.recruit.api.applicant.service; - -import com.econovation.recruit.api.applicant.usecase.ApplicantMongoLoadUseCase; -import com.econovation.recruit.api.applicant.usecase.ApplicantMongoRegisterUseCase; -import com.econovation.recruitdomain.domains.applicant.domain.MongoAnswer; -import com.econovation.recruitdomain.domains.applicant.domain.MongoAnswerAdaptor; -import java.util.Map; -import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Service; - -@Service -@RequiredArgsConstructor -public class AnswerMongoService - implements ApplicantMongoRegisterUseCase, ApplicantMongoLoadUseCase { - private final MongoAnswerAdaptor answerAdaptor; - - @Value("${econovation.year}") - private Integer year; - - @Override - public void execute(Map qna) { - MongoAnswer answer = MongoAnswer.builder().qna(qna).year(year).build(); - answerAdaptor.save(answer); - } - - @Override - public Map execute(String applicantId) { - return answerAdaptor - .findById(applicantId) - .fold( - (exception) -> { - throw exception; - }, - (answer) -> { - return answer.getQna(); - }); - } -} diff --git a/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/service/AnswerService.java b/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/service/AnswerService.java deleted file mode 100644 index 0faa80a9..00000000 --- a/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/service/AnswerService.java +++ /dev/null @@ -1,163 +0,0 @@ -package com.econovation.recruit.api.applicant.service; - -import static com.econovation.recruitcommon.consts.RecruitStatic.COUNTS_PER_PAGE; - -import com.econovation.recruit.api.applicant.usecase.AnswerLoadUseCase; -import com.econovation.recruitcommon.exception.OutOfIndexException; -import com.econovation.recruitdomain.domains.applicant.adaptor.AnswerAdaptor; -import com.econovation.recruitdomain.domains.applicant.domain.Answer; -import com.econovation.recruitdomain.domains.dto.ApplicantPaginationResponseDto; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -@Service -@RequiredArgsConstructor -public class AnswerService implements AnswerLoadUseCase { - private final AnswerAdaptor answerAdaptor; - - @Override - public Map execute(String applicantId) { - List answers = answerAdaptor.findByAnswerId(applicantId); - HashMap collect = - answers.stream() - .collect( - Collectors.toMap( - answer -> answer.getQuestion().getName(), - Answer::getAnswer, - (existing, replacement) -> existing, - LinkedHashMap::new)); - - LinkedHashMap result = new LinkedHashMap<>(); - result.put("id", applicantId); - result.putAll(collect); - - return result; - } - - @Override - public List> execute(List fields) { - List answers = answerAdaptor.findAll(); - return splitByAnswersInApplicantId(fields, answers); - } - - @Override - public Map> findAllApplicantVo(List fields) { - List answers = answerAdaptor.findAll(); - if (answers.isEmpty()) { - return Collections.emptyMap(); - } - return answers.stream() - .filter(answer -> fields.contains(answer.getQuestion().getName())) - .collect( - Collectors.groupingBy( - Answer::getApplicantId, - Collectors.toMap( - answer -> answer.getQuestion().getName(), - Answer::getAnswer, - (existing, replacement) -> existing, - HashMap::new))); - } - - private List> splitByAnswersInApplicantId( - List fields, List answers) { - return answers.stream() - .collect( - Collectors.groupingBy( - Answer::getApplicantId, - Collectors.toMap( - answer -> answer.getQuestion().getName(), - Answer::getAnswer, - (existing, replacement) -> existing, - HashMap::new))) - .entrySet() - .stream() - .map( - entry -> { - HashMap map = new HashMap<>(); - map.put("id", entry.getKey()); - fields.forEach( - field -> { - if (entry.getValue().containsKey(field)) { - map.put(field, entry.getValue().get(field)); - } else { - map.put(field, ""); - } - }); - return map; - }) - .collect(Collectors.toList()); - } - - private List> splitByAnswersInApplicantId(List answers) { - // First, group the answers by applicant ID - Map> grouped = - answers.stream().collect(Collectors.groupingBy(Answer::getApplicantId)); - - // ApplicantId (지원자) 별로 그룹화 한 후에 CreatedAt으로 오름차순 정렬하여 Map을 생성한다 - return grouped.entrySet().stream() - .sorted( - Comparator.comparing( - e -> - e.getValue().stream() - .max(Comparator.comparing(Answer::getCreatedAt)) - .get() - .getCreatedAt())) - .map( - entry -> { - LinkedHashMap map = new LinkedHashMap<>(); - map.put("id", entry.getKey()); - entry.getValue() - .forEach( - answer -> - map.put( - answer.getQuestion().getName(), - answer.getAnswer())); - return map; - }) - .collect(Collectors.toList()); - } - - @Override - public List> execute(List fields, List applicantIds) { - List answers = answerAdaptor.findByAnswerIds(applicantIds); - return splitByAnswersInApplicantId(fields, answers); - } - - @Override - public List> execute() { - List answers = answerAdaptor.findAll(); - return splitByAnswersInApplicantId(answers); - } - - @Override - public ApplicantPaginationResponseDto execute(Integer page) { - if (page < 1) throw OutOfIndexException.EXCEPTION; - List answers = answerAdaptor.findAll(); - - List> results = splitByAnswersInApplicantId(answers); - Integer maxPage = results.size() / COUNTS_PER_PAGE; - results = - results.stream() - .skip((page - 1) * COUNTS_PER_PAGE) - .limit(COUNTS_PER_PAGE) - .collect(Collectors.toList()); - // maxPage - return ApplicantPaginationResponseDto.builder() - .applicants(results) - .maxPage(maxPage + 1) - .build(); - } - - @Override - public Map execute(String applicantId, List fields) { - List answers = answerAdaptor.findByAnswerId(applicantId); - return splitByAnswersInApplicantId(fields, answers).get(0); - } -} diff --git a/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/service/ApplicantService.java b/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/service/ApplicantService.java index 05fb0037..88820d2d 100644 --- a/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/service/ApplicantService.java +++ b/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/service/ApplicantService.java @@ -1,103 +1,148 @@ package com.econovation.recruit.api.applicant.service; -import com.econovation.recruit.api.applicant.usecase.ApplicantRegisterUseCase; -import com.econovation.recruitcommon.utils.Result; -import com.econovation.recruitdomain.common.aop.domainEvent.Events; +import com.econovation.recruit.api.applicant.aggregate.AnswerAggregate; +import com.econovation.recruit.api.applicant.dto.AnswersResponseDto; +import com.econovation.recruit.api.applicant.query.AnswerQuery; +import com.econovation.recruit.api.applicant.usecase.ApplicantQueryUseCase; +import com.econovation.recruit.utils.vo.PageInfo; import com.econovation.recruitdomain.domains.applicant.adaptor.AnswerAdaptor; -import com.econovation.recruitdomain.domains.applicant.adaptor.QuestionAdaptor; -import com.econovation.recruitdomain.domains.applicant.domain.Answer; -import com.econovation.recruitdomain.domains.applicant.domain.Question; -import com.econovation.recruitdomain.domains.applicant.dto.BlockRequestDto; -import com.econovation.recruitdomain.domains.applicant.event.ApplicantRegisterEvent; -import com.econovation.recruitdomain.domains.applicant.exception.AnswerEmptyFieldException; -import com.econovation.recruitdomain.domains.applicant.exception.ApplicantDuplicateSubmitException; -import com.econovation.recruitdomain.domains.applicant.exception.QuestionNotFoundException; +import com.econovation.recruitdomain.domains.applicant.domain.MongoAnswer; +import java.util.Collections; +import java.util.HashMap; import java.util.List; -import java.util.UUID; -import java.util.stream.Collectors; +import java.util.Map; import lombok.RequiredArgsConstructor; +import org.axonframework.messaging.responsetypes.ResponseTypes; +import org.axonframework.queryhandling.QueryGateway; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service @RequiredArgsConstructor -public class ApplicantService implements ApplicantRegisterUseCase { - private final QuestionAdaptor questionAdaptor; +public class ApplicantService implements ApplicantQueryUseCase { private final AnswerAdaptor answerAdaptor; + private final QueryGateway queryGateway; + + @Value("${econovation.year}") + private Integer year; + + @Transactional(readOnly = true) + public Map execute(String answerId) { + Map qna = + queryGateway + .query( + new AnswerQuery(answerId), + ResponseTypes.instanceOf(AnswerAggregate.class)) + .join() + .getQna(); + qna.put("id", answerId); + return qna; + } + + @Transactional(readOnly = true) + public AnswersResponseDto execute(Integer year, Integer page) { + long totalCount = answerAdaptor.getTotalCountByYear(year); + PageInfo pageInfo = new PageInfo(totalCount, page); + List> qnas = + answerAdaptor.findByYear(year, page).stream().map(MongoAnswer::getQna).toList(); + return AnswersResponseDto.of(qnas, pageInfo); + } + + @Override + public List> execute(List fields, Integer year, Integer page) { + AnswersResponseDto execute = execute(year, page); + return splitByAnswerFilteredByFields(fields, execute.getAnswers()); + } @Override - @Transactional - public UUID execute(List blocks) { - List questions = questionAdaptor.findAll(); - UUID applicantId = UUID.randomUUID(); + public Map> findAllApplicantVo(List fields) { + List answers = answerAdaptor.findAll(); + Map> result = new HashMap<>(); + if (answers.isEmpty()) { + return Collections.emptyMap(); + } + answers.stream() + .forEach( + answer -> { + Map map = new HashMap<>(); + fields.forEach( + field -> { + if (answer.getQna().containsKey(field)) { + map.put(field, answer.getQna().get(field)); + } + }); + result.put(answer.getId(), map); + }); + return result; + } - List results = - blocks.stream() - .map( - block -> { - Result matchingQuestionResult = - questions.stream() - .filter( - question -> - question.getName() - .equals( - block - .getName())) - .findFirst() - .map(Result::success) - .orElseThrow( - () -> - QuestionNotFoundException - .EXCEPTION); - return matchingQuestionResult - .map( - question -> - Answer.builder() - .question(question) - .answer(block.getAnswer()) - .applicantId( - applicantId.toString()) - .build()) - .getValue(); - }) - .collect(Collectors.toList()); - // classOf 가 기존에 존재하면 중복된 지원자 입니다. - String studentId = - results.stream() - .filter(answer -> answer.getQuestion().getName().equals("classOf")) - .findFirst() - .get() - .getAnswer(); + private List> splitByAnswerFilteredByFields( + List fields, List> answers) { + return answers.stream() + .map( + answer -> { + Map map = new HashMap<>(); + fields.forEach( + field -> { + if (answer.containsKey(field)) { + map.put(field, answer.get(field)); + } else { + map.put(field, ""); + } + }); + return map; + }) + .toList(); + } - // 이미 제출한 학생은 중복 지원자입니다. (학번으로 검증) - if (answerAdaptor.findByAnswer(studentId) != null) - throw ApplicantDuplicateSubmitException.EXCEPTION; + private List> splitByAnswers( + List fields, List answers) { + return answers.stream() + .map( + answer -> { + Map map = new HashMap<>(); + map.put("id", answer.getId()); + fields.forEach( + field -> { + if (answer.getQna().containsKey(field)) { + map.put(field, answer.getQna().get(field).toString()); + } + }); + return map; + }) + .toList(); + } - // Result 를 save 하게 된다. - answerAdaptor.saveAll(results); + @Override + public List> execute() { + List answers = answerAdaptor.findAll(); + return answers.stream() + .map( + answer -> { + Map map = new HashMap<>(); + map.put("id", answer.getId()); + map.putAll(answer.getQna()); + return map; + }) + .toList(); + } - String hopeField = - results.stream() - .filter(answer -> answer.getQuestion().getName().equals("field")) - .findFirst() - .map(Answer::getAnswer) - .orElseThrow(() -> AnswerEmptyFieldException.EXCEPTION); + @Override + public Map execute(String applicantId, List fields) { + AnswerAggregate join = + queryGateway + .query( + new AnswerQuery(applicantId), + ResponseTypes.instanceOf(AnswerAggregate.class)) + .join(); + MongoAnswer mongoAnswer = new MongoAnswer(join.getId(), join.getYear(), join.getQna()); + return splitByAnswers(fields, List.of(mongoAnswer)).get(0); + } - String name = - results.stream() - .filter(answer -> answer.getQuestion().getName().equals("name")) - .findFirst() - .map(Answer::getAnswer) - .orElseThrow(() -> AnswerEmptyFieldException.EXCEPTION); - String email = - results.stream() - .filter(answer -> answer.getQuestion().getName().equals("email")) - .findFirst() - .map(Answer::getAnswer) - .orElseThrow(() -> AnswerEmptyFieldException.EXCEPTION); - ApplicantRegisterEvent applicantRegisterEvent = - ApplicantRegisterEvent.of(applicantId.toString(), name, hopeField, email); - Events.raise(applicantRegisterEvent); - return applicantId; + @Override + public List> execute(List fields, Integer page) { + List byYear = answerAdaptor.findByYear(year, page); + return splitByAnswers(fields, byYear); } } diff --git a/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/service/QuestionService.java b/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/service/QuestionService.java index 77c78044..27e6f9d2 100644 --- a/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/service/QuestionService.java +++ b/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/service/QuestionService.java @@ -5,7 +5,6 @@ import com.econovation.recruitdomain.domains.applicant.domain.Question; import com.econovation.recruitdomain.domains.dto.QuestionRequestDto; import java.util.List; -import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -42,7 +41,7 @@ public void execute(List questions) { .name(question.getName()) .parentId(question.getParentId()) .build()) - .collect(Collectors.toList()); + .toList(); questionAdaptor.saveAll(filteredQuestions); } } diff --git a/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/service/TimeTableService.java b/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/service/TimeTableService.java index c5628d90..e2c7983a 100644 --- a/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/service/TimeTableService.java +++ b/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/service/TimeTableService.java @@ -2,6 +2,7 @@ import static com.econovation.recruitcommon.consts.RecruitStatic.TIMETABLE_APPLICANT_FIELD; +import com.econovation.recruit.api.applicant.usecase.ApplicantQueryUseCase; import com.econovation.recruit.api.applicant.usecase.TimeTableLoadUseCase; import com.econovation.recruit.api.applicant.usecase.TimeTableRegisterUseCase; import com.econovation.recruitdomain.domains.applicant.dto.TimeTableVo; @@ -9,7 +10,6 @@ import com.econovation.recruitdomain.domains.timetable.exception.TimeTableNotFoundException; import com.econovation.recruitdomain.out.TimeTableLoadPort; import com.econovation.recruitdomain.out.TimeTableRecordPort; -import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -23,7 +23,7 @@ public class TimeTableService implements TimeTableRegisterUseCase, TimeTableLoadUseCase { private final TimeTableLoadPort timeTableLoadPort; private final TimeTableRecordPort timeTableRecordPort; - private final AnswerService answerService; + private final ApplicantQueryUseCase applicantQueryUseCase; @Override @Transactional(readOnly = true) @@ -46,7 +46,7 @@ public List>> findAll() { entry -> { return Map.of(entry.getKey(), entry.getValue()); }) - .collect(Collectors.toList()); + .toList(); } @Override @@ -55,9 +55,7 @@ public List getTimeTableByApplicantId(String applicantId) { List timeTableByApplicantId = timeTableLoadPort.getTimeTableByApplicantId(applicantId); if (!timeTableByApplicantId.isEmpty()) { - return timeTableByApplicantId.stream() - .map(TimeTable::getStartTime) - .collect(Collectors.toList()); + return timeTableByApplicantId.stream().map(TimeTable::getStartTime).toList(); } throw TimeTableNotFoundException.EXCEPTION; } @@ -66,51 +64,27 @@ public List getTimeTableByApplicantId(String applicantId) { @Transactional(readOnly = true) public Map> findAllSimpleApplicantWithTimeTable() { List timeTables = timeTableLoadPort.findAll(); - Map> allApplicantVo = - answerService.findAllApplicantVo(TIMETABLE_APPLICANT_FIELD); + Map> allApplicantVo = + applicantQueryUseCase.findAllApplicantVo(TIMETABLE_APPLICANT_FIELD); // SimpleApplicant : {applicantId : {name(이름), field(지원분야) } - Map> collect = - timeTables.stream() - .collect( - Collectors.groupingBy( - TimeTable::getStartTime, - Collectors.mapping( - timeTable -> { - return "[" - + allApplicantVo - .get(timeTable.getApplicantId()) - .get("field") - + "] : " - + allApplicantVo - .get(timeTable.getApplicantId()) - .get("name"); - }, - Collectors.toList()))); - return collect; + return timeTables.stream() + .collect( + Collectors.groupingBy( + TimeTable::getStartTime, + Collectors.mapping( + timeTable -> { + return "[" + + allApplicantVo + .get(timeTable.getApplicantId()) + .get("field") + + "] : " + + allApplicantVo + .get(timeTable.getApplicantId()) + .get("name"); + }, + Collectors.toList()))); } - /* private List toList(HashMap param) { - List chunkTimeTable = new LinkedList<>(); - Gson gson = new Gson(); - // JsonParser Deprecated -> JsonParser static import 변경 - JsonElement startTime = JsonParser.parseString(param.get("startTime").toString()); - JsonElement endTime = JsonParser.parseString(param.get("endTime").toString()); - JsonElement day = JsonParser.parseString(param.get("day").toString()); - // JsonElement -> List으로 파싱 - - List startTimes = - gson.fromJson(startTime, (new TypeToken>() {}).getType()); - List endTimes = - gson.fromJson(endTime, (new TypeToken>() {}).getType()); - List days = gson.fromJson(day, (new TypeToken>() {}).getType()); - - for (int i = 0; i < startTimes.size(); i++) { - chunkTimeTable.add( - new TimeTableInsertDto(startTimes.get(i))); - } - return chunkTimeTable; - }*/ - @Override public void execute(String applicantId, List startTimes) { List timeTableList = new LinkedList<>(); diff --git a/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/usecase/AnswerLoadUseCase.java b/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/usecase/AnswerLoadUseCase.java deleted file mode 100644 index b5dd765d..00000000 --- a/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/usecase/AnswerLoadUseCase.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.econovation.recruit.api.applicant.usecase; - -import com.econovation.recruitcommon.annotation.UseCase; -import com.econovation.recruitdomain.domains.dto.ApplicantPaginationResponseDto; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -@UseCase -public interface AnswerLoadUseCase { - Map execute(String applicantId); - - List> execute(List fields, List applicantIds); - - List> execute(); - - ApplicantPaginationResponseDto execute(Integer page); - // List> execute(Integer page, String sortType); - - Map execute(String applicantId, List fields); - - List> execute(List fields); - - Map> findAllApplicantVo(List fields); -} diff --git a/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/usecase/ApplicantMongoLoadUseCase.java b/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/usecase/ApplicantCommandUseCase.java similarity index 56% rename from server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/usecase/ApplicantMongoLoadUseCase.java rename to server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/usecase/ApplicantCommandUseCase.java index 38c2bdda..eb69f371 100644 --- a/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/usecase/ApplicantMongoLoadUseCase.java +++ b/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/usecase/ApplicantCommandUseCase.java @@ -2,8 +2,9 @@ import com.econovation.recruitcommon.annotation.UseCase; import java.util.Map; +import java.util.UUID; @UseCase -public interface ApplicantMongoLoadUseCase { - Map execute(String applicantId); +public interface ApplicantCommandUseCase { + UUID execute(Map blocks); } diff --git a/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/usecase/ApplicantMongoRegisterUseCase.java b/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/usecase/ApplicantMongoRegisterUseCase.java deleted file mode 100644 index af780b2c..00000000 --- a/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/usecase/ApplicantMongoRegisterUseCase.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.econovation.recruit.api.applicant.usecase; - -import com.econovation.recruitcommon.annotation.UseCase; -import java.util.Map; - -@UseCase -public interface ApplicantMongoRegisterUseCase { - void execute(Map blocks); -} diff --git a/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/usecase/ApplicantQueryUseCase.java b/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/usecase/ApplicantQueryUseCase.java new file mode 100644 index 00000000..2ef30e18 --- /dev/null +++ b/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/usecase/ApplicantQueryUseCase.java @@ -0,0 +1,29 @@ +package com.econovation.recruit.api.applicant.usecase; + +import com.econovation.recruit.api.applicant.dto.AnswersResponseDto; +import com.econovation.recruitcommon.annotation.UseCase; +import java.util.List; +import java.util.Map; + +@UseCase +public interface ApplicantQueryUseCase { + // clear + Map execute(String applicantId); + + AnswersResponseDto execute(Integer year, Integer page); + // List> execute(List fields, List applicantIds); + + List> execute(); + + // ApplicantPaginationResponseDto execute(Integer page); + + // List> execute(Integer page, String sortType); + + Map execute(String applicantId, List fields); + + List> execute(List fields, Integer page); + + List> execute(List fields, Integer year, Integer page); + + Map> findAllApplicantVo(List fields); +} diff --git a/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/usecase/ApplicantRegisterUseCase.java b/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/usecase/ApplicantRegisterUseCase.java deleted file mode 100644 index 20c73970..00000000 --- a/server/Recruit-Api/src/main/java/com/econovation/recruit/api/applicant/usecase/ApplicantRegisterUseCase.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.econovation.recruit.api.applicant.usecase; - -import com.econovation.recruitcommon.annotation.UseCase; -import com.econovation.recruitdomain.domains.applicant.dto.BlockRequestDto; -import java.util.List; -import java.util.UUID; - -@UseCase -public interface ApplicantRegisterUseCase { - UUID execute(List blocks); -} diff --git a/server/Recruit-Api/src/main/java/com/econovation/recruit/api/card/controller/BoardRestController.java b/server/Recruit-Api/src/main/java/com/econovation/recruit/api/card/controller/BoardRestController.java index 5bef396a..7bcd6366 100644 --- a/server/Recruit-Api/src/main/java/com/econovation/recruit/api/card/controller/BoardRestController.java +++ b/server/Recruit-Api/src/main/java/com/econovation/recruit/api/card/controller/BoardRestController.java @@ -2,7 +2,7 @@ import static com.econovation.recruitcommon.consts.RecruitStatic.*; -import com.econovation.recruit.api.applicant.usecase.AnswerLoadUseCase; +import com.econovation.recruit.api.applicant.usecase.ApplicantQueryUseCase; import com.econovation.recruit.api.card.docs.CreateBoardExceptionDocs; import com.econovation.recruit.api.card.docs.CreateColumnsExceptionDocs; import com.econovation.recruit.api.card.docs.CreateNavigationExceptionDocs; @@ -54,7 +54,7 @@ public class BoardRestController { private final CardRegisterUseCase cardRegisterUseCase; private final CardLoadUseCase cardLoadUseCase; private final NavigationUseCase navigationUseCase; - private final AnswerLoadUseCase answerLoadUseCase; + private final ApplicantQueryUseCase answerQueryUseCase; // ---------- Navigation ---------- @Operation(summary = "네비게이션 바 생성", description = "카드 생성 전에 네비게이션 바를 생성하셔야 합니다.") @ApiErrorExceptionsExample(value = CreateNavigationExceptionDocs.class) @@ -174,10 +174,10 @@ public ResponseEntity> getBoardByNavigationId( @Operation(summary = "지원서 조회(원하는 field) 만 조회", description = "원하는 field만(리스트) 조회합니다.") @ApiErrorExceptionsExample(FindBoardExceptionDocs.class) - @PostMapping("/boards") - public ResponseEntity>> getBoardByNavigationId( - @RequestBody List fields) { - return new ResponseEntity<>(answerLoadUseCase.execute(fields), HttpStatus.OK); + @PostMapping("/page/{page}/boards") + public ResponseEntity>> getBoardByNavigationId( + @PathVariable(name = "page") Integer page, @RequestBody List fields) { + return new ResponseEntity<>(answerQueryUseCase.execute(fields, page), HttpStatus.OK); } @Operation( @@ -185,10 +185,10 @@ public ResponseEntity>> getBoardByNavigationId( description = "특정 지원자에 대하여 원하는 field만(리스트) 조회합니다.") @ApiErrorExceptionsExample(FindBoardExceptionDocs.class) @PostMapping("/boards/{applicant-id}") - public ResponseEntity> getBoardByNavigationId( + public ResponseEntity> getBoardByNavigationId( @PathVariable(name = "applicant-id") String applicantId, @RequestBody List fields) { - return new ResponseEntity<>(answerLoadUseCase.execute(applicantId, fields), HttpStatus.OK); + return new ResponseEntity<>(answerQueryUseCase.execute(applicantId, fields), HttpStatus.OK); } @Operation(summary = "카드 삭제", description = "업무 카드를 삭제합니다(지원서 삭제는 불가합니다.)") diff --git a/server/Recruit-Api/src/main/java/com/econovation/recruit/api/card/service/CardService.java b/server/Recruit-Api/src/main/java/com/econovation/recruit/api/card/service/CardService.java index 9d48fadd..7b22d50a 100644 --- a/server/Recruit-Api/src/main/java/com/econovation/recruit/api/card/service/CardService.java +++ b/server/Recruit-Api/src/main/java/com/econovation/recruit/api/card/service/CardService.java @@ -1,6 +1,6 @@ package com.econovation.recruit.api.card.service; -import com.econovation.recruit.api.applicant.usecase.AnswerLoadUseCase; +import com.econovation.recruit.api.applicant.usecase.ApplicantQueryUseCase; import com.econovation.recruit.api.card.usecase.BoardLoadUseCase; import com.econovation.recruit.api.card.usecase.BoardRegisterUseCase; import com.econovation.recruit.api.card.usecase.CardLoadUseCase; @@ -23,7 +23,6 @@ import com.econovation.recruitdomain.out.CardLoadPort; import com.econovation.recruitdomain.out.CardRecordPort; import com.econovation.recruitdomain.out.LabelLoadPort; -import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -40,7 +39,7 @@ public class CardService implements CardRegisterUseCase, CardLoadUseCase { private final BoardRegisterUseCase boardRegisterUseCase; private final BoardLoadUseCase boardLoadUseCase; private final ColumnsUseCase columnsUseCase; - private final AnswerLoadUseCase answerLoadPort; + private final ApplicantQueryUseCase applicantQueryUseCase; private final LabelLoadPort labelLoadPort; @Override @@ -69,8 +68,8 @@ public List getByNavigationId(Integer navigationId) { List result = new LinkedList<>(); // key : applicantId - Map> answers = - answerLoadPort.findAllApplicantVo(List.of("field1", "field2", "major")); + Map> answers = + applicantQueryUseCase.findAllApplicantVo(List.of("field1", "field2", "major")); List