Skip to content

Commit

Permalink
merge develop into dding-103
Browse files Browse the repository at this point in the history
  • Loading branch information
KoSeonJe committed Feb 7, 2025
2 parents 3059307 + c899d11 commit 5c5942a
Show file tree
Hide file tree
Showing 20 changed files with 637 additions and 213 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public record FormQuery(

@Builder
public record FormFieldListQuery(
Long id,
String question,
FieldType type,
List<String> options,
Expand All @@ -29,6 +30,7 @@ public record FormFieldListQuery(
) {
public static FormFieldListQuery from(FormField formField) {
return FormFieldListQuery.builder()
.id(formField.getId())
.question(formField.getQuestion())
.type(formField.getFieldType())
.options(formField.getOptions())
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package ddingdong.ddingdongBE.domain.formapplication.api;

import ddingdong.ddingdongBE.auth.PrincipalDetails;
import ddingdong.ddingdongBE.domain.formapplication.controller.dto.response.FormApplicationResponse;
import ddingdong.ddingdongBE.domain.formapplication.controller.dto.request.UpdateFormApplicationStatusRequest;
import ddingdong.ddingdongBE.domain.formapplication.controller.dto.response.FormApplicationResponse;
import ddingdong.ddingdongBE.domain.formapplication.controller.dto.response.MyFormApplicationPageResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
Expand All @@ -9,6 +12,7 @@
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;
Expand All @@ -31,4 +35,26 @@ MyFormApplicationPageResponse getMyFormApplicationPage(
@AuthenticationPrincipal PrincipalDetails principalDetails
);

@Operation(summary = "지원자 상세 조회 API")
@ApiResponse(responseCode = "200", description = "지원자 상세 조회 성공",
content = @Content(schema = @Schema(implementation = FormApplicationResponse.class)))
@ResponseStatus(HttpStatus.OK)
@SecurityRequirement(name = "AccessToken")
@GetMapping("/my/forms/{formId}/applications/{applicationId}")
FormApplicationResponse getFormApplication(
@PathVariable("formId") Long formId,
@PathVariable("applicationId") Long applicationId,
@AuthenticationPrincipal PrincipalDetails principalDetails
);

@Operation(summary = "지원자 상태 수정 API")
@ApiResponse(responseCode = "204", description = "지원자 상태 수정 성공")
@ResponseStatus(HttpStatus.NO_CONTENT)
@SecurityRequirement(name = "AccessToken")
@PatchMapping("/my/forms/{formId}/applications")
void updateFormApplicationStatus(
@PathVariable("formId") Long formId,
@AuthenticationPrincipal PrincipalDetails principalDetails,
@Valid @RequestBody UpdateFormApplicationStatusRequest request
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public interface UserFormApplicationApi {
@ApiResponse(responseCode = "201", description = "지원하기 성공")
@ResponseStatus(HttpStatus.CREATED)
@PostMapping("/forms/{formId}/applications")
void createFormResponse(
void createFormApplication(
@PathVariable Long formId,
@Valid @RequestBody CreateFormApplicationRequest request
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package ddingdong.ddingdongBE.domain.formapplication.controller;

import ddingdong.ddingdongBE.auth.PrincipalDetails;
import ddingdong.ddingdongBE.domain.formapplication.controller.dto.request.UpdateFormApplicationStatusRequest;
import ddingdong.ddingdongBE.domain.formapplication.controller.dto.response.FormApplicationResponse;
import ddingdong.ddingdongBE.domain.formapplication.service.FacadeCentralFormApplicationService;
import ddingdong.ddingdongBE.domain.formapplication.api.CentralFormApplicationApi;
import ddingdong.ddingdongBE.domain.formapplication.controller.dto.response.MyFormApplicationPageResponse;
import ddingdong.ddingdongBE.domain.formapplication.service.dto.query.FormApplicationQuery;
import ddingdong.ddingdongBE.domain.formapplication.service.dto.query.MyFormApplicationPageQuery;
import ddingdong.ddingdongBE.domain.user.entity.User;
import lombok.RequiredArgsConstructor;
Expand All @@ -13,12 +16,25 @@
@RequiredArgsConstructor
public class CentralFormApplicationController implements CentralFormApplicationApi {

private final FacadeCentralFormApplicationService facadeCentralFormService;
private final FacadeCentralFormApplicationService facadeCentralFormApplicationService;

@Override
public MyFormApplicationPageResponse getMyFormApplicationPage(Long formId, int size, Long currentCursorId, PrincipalDetails principalDetails) {
User user = principalDetails.getUser();
MyFormApplicationPageQuery query = facadeCentralFormService.getMyFormApplicationPage(formId, user, size, currentCursorId);
MyFormApplicationPageQuery query = facadeCentralFormApplicationService.getMyFormApplicationPage(formId, user, size, currentCursorId);
return MyFormApplicationPageResponse.from(query);
}

@Override
public FormApplicationResponse getFormApplication(Long formId, Long applicationId, PrincipalDetails principalDetails) {
User user = principalDetails.getUser();
FormApplicationQuery query = facadeCentralFormApplicationService.getFormApplication(formId, applicationId, user);
return FormApplicationResponse.from(query);
}

@Override
public void updateFormApplicationStatus(Long formId, PrincipalDetails principalDetails, UpdateFormApplicationStatusRequest request) {
User user = principalDetails.getUser();
facadeCentralFormApplicationService.updateStatus(request.toCommand(formId, user));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class UserFormApplicationController implements UserFormApplicationApi {
private final FacadeUserFormService facadeUserFormService;

@Override
public void createFormResponse(Long formId, CreateFormApplicationRequest createFormApplicationRequest) {
public void createFormApplication(Long formId, CreateFormApplicationRequest createFormApplicationRequest) {
facadeUserFormService.createFormApplication(createFormApplicationRequest.toCommand(formId));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package ddingdong.ddingdongBE.domain.formapplication.controller.dto.request;

import ddingdong.ddingdongBE.domain.formapplication.entity.FormApplicationStatus;
import ddingdong.ddingdongBE.domain.formapplication.service.dto.command.UpdateFormApplicationStatusCommand;
import ddingdong.ddingdongBE.domain.user.entity.User;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;

import java.util.List;

public record UpdateFormApplicationStatusRequest(
@NotNull(message = "지원자 id 리스트는 필수 입력 사항입니다.")
@Schema(description = "수정할 지원자 id 리스트", example = "[1, 2, 3]")
List<Long> applicationIds,

@NotNull(message = "지원자 상태는 필수 입력 사항입니다.")
@Schema(description = "수정할 지원자 상태", example = "FIRST_PASS")
String status
) {
public UpdateFormApplicationStatusCommand toCommand(Long formId, User user) {
return UpdateFormApplicationStatusCommand.builder()
.formId(formId)
.applicationIds(applicationIds)
.status(FormApplicationStatus.findStatus(status))
.user(user)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package ddingdong.ddingdongBE.domain.formapplication.controller.dto.response;

import ddingdong.ddingdongBE.domain.form.entity.FieldType;
import ddingdong.ddingdongBE.domain.formapplication.entity.FormApplicationStatus;
import ddingdong.ddingdongBE.domain.formapplication.service.dto.query.FormApplicationQuery;
import ddingdong.ddingdongBE.domain.formapplication.service.dto.query.FormApplicationQuery.FormFieldAnswerListQuery;

import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Builder;

import java.time.LocalDateTime;
import java.util.List;

@Builder
public record FormApplicationResponse (
@Schema(description = "제출일시", example = "2025-01-01T00:00")
LocalDateTime submittedAt,
@Schema(description = "지원자 이름", example = "김띵동")
String name,
@Schema(description = "지원자 학번", example = "60201111")
String studentNumber,
@Schema(description = "지원자 학과", example = "융합소프트웨어학부")
String department,
@Schema(description = "status", example = "SUBMITTED")
FormApplicationStatus status,
@ArraySchema(schema = @Schema(implementation = FormFieldAnswerListResponse.class))
List<FormFieldAnswerListResponse> formFieldAnswers
){
@Builder
record FormFieldAnswerListResponse (
@Schema(description = "폼지 질문 ID", example = "1")
Long fieldId,
@Schema(description = "폼지 질문", example = "성별이 무엇입니까??")
String question,
@Schema(description = "폼지 질문 유형", example = "RADIO", allowableValues = {"CHECK_BOX", "RADIO", "TEXT", "LONG_TEXT", "FILE"})
FieldType type,
@Schema(description = "폼지 지문", example = "[\"여성\", \"남성\"]")
List<String> options,
@Schema(description = "필수 여부", example = "true")
Boolean required,
@Schema(description = "질문 순서", example = "1")
Integer order,
@Schema(description = "섹션", example = "공통")
String section,
@Schema(description = "질문 답변 값", example = "[\"지문1\"]")
List<String> value
) {
public static FormFieldAnswerListResponse from(FormFieldAnswerListQuery formFieldAnswerListQuery) {
return FormFieldAnswerListResponse.builder()
.fieldId(formFieldAnswerListQuery.fieldId())
.question(formFieldAnswerListQuery.question())
.type(formFieldAnswerListQuery.type())
.options(formFieldAnswerListQuery.options())
.required(formFieldAnswerListQuery.required())
.order(formFieldAnswerListQuery.order())
.section(formFieldAnswerListQuery.section())
.value(formFieldAnswerListQuery.value())
.build();
}
}
public static FormApplicationResponse from(FormApplicationQuery formApplicationQuery) {
List<FormFieldAnswerListResponse> responses = formApplicationQuery.formFieldAnswers().stream()
.map(FormFieldAnswerListResponse::from)
.toList();

return FormApplicationResponse.builder()
.submittedAt(formApplicationQuery.createdAt())
.name(formApplicationQuery.name())
.studentNumber(formApplicationQuery.studentNumber())
.department(formApplicationQuery.department())
.status(formApplicationQuery.status())
.formFieldAnswers(responses)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,8 @@ private FormApplication(String name, String studentNumber, String department, Fo
this.status = status;
this.form = form;
}

public void updateStatus(FormApplicationStatus status) {
this.status = status;
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
package ddingdong.ddingdongBE.domain.formapplication.entity;

import ddingdong.ddingdongBE.common.exception.InvalidatedMappingException.InvalidatedEnumValue;
import java.util.Arrays;

public enum FormApplicationStatus {
SUBMITTED,
FIRST_PASS,
FINAL_PASS,
FIRST_FAIL,
FINAL_FAIL
FINAL_FAIL;

public static FormApplicationStatus findStatus(String status) {
return Arrays.stream(values())
.filter(findStatus -> findStatus.name().equals(status))
.findFirst()
.orElseThrow(() -> new InvalidatedEnumValue("FormApplicationStatus (status=" + status + ")를 찾을 수 없습니다."));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@

import ddingdong.ddingdongBE.domain.form.entity.FormField;
import ddingdong.ddingdongBE.domain.formapplication.entity.FormAnswer;
import ddingdong.ddingdongBE.domain.formapplication.entity.FormApplication;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface FormAnswerRepository extends JpaRepository<FormAnswer, Long> {

int countByFormField(FormField formField);
List<FormAnswer> findAllByFormApplication(FormApplication formApplication);
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
package ddingdong.ddingdongBE.domain.formapplication.service;

import ddingdong.ddingdongBE.domain.formapplication.service.dto.command.UpdateFormApplicationStatusCommand;
import ddingdong.ddingdongBE.domain.formapplication.service.dto.query.FormApplicationQuery;
import ddingdong.ddingdongBE.domain.formapplication.service.dto.query.MyFormApplicationPageQuery;
import ddingdong.ddingdongBE.domain.user.entity.User;

public interface FacadeCentralFormApplicationService {

MyFormApplicationPageQuery getMyFormApplicationPage(Long formId, User user, int size, Long currentCursorId);

FormApplicationQuery getFormApplication(Long formId, Long applicationId, User user);

void updateStatus(UpdateFormApplicationStatusCommand command);
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
package ddingdong.ddingdongBE.domain.formapplication.service;

import ddingdong.ddingdongBE.domain.club.entity.Club;
import ddingdong.ddingdongBE.domain.club.service.ClubService;
import ddingdong.ddingdongBE.domain.formapplication.entity.FormAnswer;
import ddingdong.ddingdongBE.domain.formapplication.service.dto.command.UpdateFormApplicationStatusCommand;
import ddingdong.ddingdongBE.domain.formapplication.service.dto.query.FormApplicationQuery;
import ddingdong.ddingdongBE.domain.formapplication.service.dto.query.PagingQuery;
import ddingdong.ddingdongBE.domain.form.entity.Form;
import ddingdong.ddingdongBE.domain.form.service.FormService;
import ddingdong.ddingdongBE.domain.formapplication.entity.FormApplication;
import ddingdong.ddingdongBE.domain.formapplication.service.dto.query.MyFormApplicationPageQuery;
import ddingdong.ddingdongBE.domain.formapplication.service.dto.query.MyFormApplicationPageQuery.FormApplicationListQuery;
import ddingdong.ddingdongBE.domain.user.entity.User;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Slice;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

Expand All @@ -22,17 +20,11 @@
@Transactional(readOnly = true)
public class FacadeCentralFormApplicationServiceImpl implements FacadeCentralFormApplicationService {

private final ClubService clubService;
private final FormService formService;
private final FormApplicationService formApplicationService;
private final FormAnswerService formAnswerService;

@Override
public MyFormApplicationPageQuery getMyFormApplicationPage(Long formId, User user, int size, Long currentCursorId) {
Club club = clubService.getByUserId(user.getId());
Form form = formService.getById(formId);
if (!form.getClub().equals(club)) {
throw new AccessDeniedException("권한이 없습니다.");
}
Slice<FormApplication> formApplicationPage = formApplicationService.getFormApplicationPageByFormId(formId, size, currentCursorId);
if (formApplicationPage == null) {
return MyFormApplicationPageQuery.createEmpty();
Expand All @@ -44,6 +36,19 @@ public MyFormApplicationPageQuery getMyFormApplicationPage(Long formId, User use
PagingQuery pagingQuery = PagingQuery.of(currentCursorId, completeFormApplications, formApplicationPage.hasNext());

return MyFormApplicationPageQuery.of(formApplicationListQueries, pagingQuery);
}

@Override
public FormApplicationQuery getFormApplication(Long formId, Long applicationId, User user) {
FormApplication formApplication = formApplicationService.getById(applicationId);
List<FormAnswer> formAnswers = formAnswerService.getAllByApplication(formApplication);
return FormApplicationQuery.of(formApplication, formAnswers);
}

@Transactional
@Override
public void updateStatus(UpdateFormApplicationStatusCommand command) {
List<FormApplication> formApplications = formApplicationService.getAllById(command.applicationIds());
formApplications.forEach(formApplication -> formApplication.updateStatus(command.status()));
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package ddingdong.ddingdongBE.domain.formapplication.service;

import ddingdong.ddingdongBE.domain.formapplication.entity.FormAnswer;
import ddingdong.ddingdongBE.domain.formapplication.entity.FormApplication;

import java.util.List;

public interface FormAnswerService {

void createAll(List<FormAnswer> formAnswers);

List<FormAnswer> getAllByApplication(FormApplication formApplication);

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,15 @@
import ddingdong.ddingdongBE.domain.formapplication.entity.FormApplication;
import org.springframework.data.domain.Slice;

import java.util.List;

public interface FormApplicationService {

FormApplication create(FormApplication formApplication);

Slice<FormApplication> getFormApplicationPageByFormId(Long formId, int size, Long currentCursorId);

FormApplication getById(Long applicationId);

List<FormApplication> getAllById(List<Long> applicationIds);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ddingdong.ddingdongBE.domain.formapplication.service;

import ddingdong.ddingdongBE.domain.formapplication.entity.FormAnswer;
import ddingdong.ddingdongBE.domain.formapplication.entity.FormApplication;
import ddingdong.ddingdongBE.domain.formapplication.repository.FormAnswerRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
Expand All @@ -21,4 +22,8 @@ public void createAll(List<FormAnswer> formAnswers) {
formAnswerRepository.saveAll(formAnswers);
}

@Override
public List<FormAnswer> getAllByApplication(FormApplication formApplication) {
return formAnswerRepository.findAllByFormApplication(formApplication);
}
}
Loading

0 comments on commit 5c5942a

Please sign in to comment.