Skip to content

Commit

Permalink
기수 테이블 추가 / 지원서 기수별 구분 기능 추가 (#150)
Browse files Browse the repository at this point in the history
* Fix: 다른 기수 중복 지원을 위해 unique 제약 조건 제거

* Feat: 기수 저장을 위한 엔티티 생성

* Feat: 기수와 지원서 간 연관관계 작성

* Feat: 기수 레포지토리 작성

* Feat: 기수 DTO 작성

* Feat: 기수 서비스 작성

* Feat: 기수 컨트롤러 작성

* Feat: 기수 ErrorCode 작성

* Fix: 중복 제출 오류 코드를 좀더 명확하게 수정

* Feat: 지원서 403 에러코드 추가

* Feat: ClassYear 업데이트 편의 메서드 추가

* Refac: 에러코드를 명확하게 변경

* Feat: 지원서 작성 시 기수 정보도 요청

* Fix: 누락된 갱신 로직 적용

* Feat: 기수 정보를 포함해 지원서를 조회

* Fix: 기수 정보 단건 조회 방식 수정

* Fix: 잘못된 응답코드 수정

* Feat: 기수 - 지원서 간 연관관계 설정

* Feat: 조건별 서류 조회(필터링)에 기수 id 추가

* Fix: LocalDateTime 통신 형태 지정

* Fix: 잘못된 초기 지원 중복 체크 로직 수정

* Fix: 지원서 auto auditing 제거

* Fix: 지원서 - 프레젠테이션 계층 간 의존성 제거

* Feat: 예외 상황 추가 및 에러메시지 자세하게 수정

* Feat: 기수 예외처리 추가

* Test: 지원서 테스트에 기수 관련 로직 추가 및 수정

* Docs: 조건별 지원 서류 조회 스웨거 설명 추가

* Rename: ApplicationRequestDTO -> ApplicationModel

* Fix: 고유 code로 수정

* Refac: 기수 관련 코드 분리

* Fix: 일관된 ErrorCode 사용

* Fix: 의미 없는 save 제거

* Fix: 객체 생성 방식 통일

* Fix: 테스트용 출력, 주석 삭제

* Docs: 분리한 기수 컨트롤러 스웨거 태그 추가
  • Loading branch information
chaejm55 authored Dec 26, 2024
1 parent d0578c9 commit 832167d
Show file tree
Hide file tree
Showing 22 changed files with 449 additions and 72 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,12 @@ public class ApplicationController {
최종제출 상태의 지원서는 조회가 불가능합니다.
""")
public ResponseEntity<ApplicationResponse> getApplication(@TokenMember JwtMemberDetail jwtMemberDetail, @RequestParam String name, @RequestParam String studentNumber) {
public ResponseEntity<ApplicationResponse> getApplication(@TokenMember JwtMemberDetail jwtMemberDetail,
@RequestParam String name,
@RequestParam String studentNumber,
@RequestParam Long classYearId) {
return ResponseEntity.ok()
.body(applicationService.getApplication(jwtMemberDetail.getEmail(), name, studentNumber));
.body(applicationService.getApplication(jwtMemberDetail.getEmail(), name, studentNumber, classYearId));
}

@PostMapping
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,16 @@ public ResponseEntity<Map<String, Integer>> getTrackStatistic() {
마크된것만 조회하려면 isMarked=true로 설정하세요.
isMarked를 비워두거나 false로 설정하면 전체가 조회됩니다.(track도 마찬가지로 비워두면 전체)""")
isMarked를 비워두거나 false로 설정하면 전체가 조회됩니다.(track, classYearId도 마찬가지로 비워두면 전체)""")
public ResponseEntity<PagingResponse<AdminApplicationResponse.Overview>> getApplicationListByOption(
@RequestParam(value = "track", required = false) Track track,
@RequestParam(value = "isMarked", required = false, defaultValue = "false") Boolean isMarked,
@RequestParam(value = "page", defaultValue = "0") int page,
@RequestParam(value = "size", defaultValue = "10") int size)
@RequestParam(value = "size", defaultValue = "10") int size,
@RequestParam(value = "classYearId", required = false) Long classYearId)

{
return ResponseEntity.ok().body(applicationService.getApplicationsByOption(page, size, track, isMarked));
return ResponseEntity.ok().body(applicationService.getApplicationsByOption(page, size, track, isMarked, classYearId));
}


Expand Down Expand Up @@ -112,7 +113,4 @@ public ResponseEntity<Void> noteApplication(@RequestParam("id") Long id,
applicationService.noteApplication(id, request.getNote(), request.getVersion());
return new ResponseEntity<>(HttpStatus.OK);
}



}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.gdsc_knu.official_homepage.controller.admin;

import com.gdsc_knu.official_homepage.dto.admin.application.AdminApplicationRequest;
import com.gdsc_knu.official_homepage.dto.admin.application.AdminApplicationResponse;
import com.gdsc_knu.official_homepage.service.admin.AdminClassYearService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@Tag(name = "Admin ClassYear", description = "기수 관리 관련 API")
@RestController
@RequiredArgsConstructor
@RequestMapping("api/admin/class-year")
public class AdminClassYearController {
private final AdminClassYearService classYearService;

@GetMapping()
@Operation(summary="기수 목록 조회 API", description = "기수 목록을 조회합니다.")
public ResponseEntity<List<AdminApplicationResponse.ClassYearResponse>> getClassYearList() {
return ResponseEntity.ok(classYearService.getClassYearList());
}

@GetMapping("/{id}")
@Operation(summary="기수 단건 조회 API", description = "기수를 단건 조회합니다.")
public ResponseEntity<AdminApplicationResponse.ClassYearResponse> getClassYear(@PathVariable("id") Long id) {
return ResponseEntity.ok(classYearService.getClassYear(id));
}

@PostMapping()
@Operation(summary="기수 추가 API", description = "기수를 추가합니다.")
public ResponseEntity<Void> addClassYear(@RequestBody AdminApplicationRequest.ClassYearRequest classYearRequest) {
classYearService.addClassYear(classYearRequest);
return new ResponseEntity<>(HttpStatus.CREATED);
}

@PutMapping()
@Operation(summary="기수 수정 API", description = "기수의 정보를 수정합니다.")
public ResponseEntity<Void> updateClassYear(@RequestParam("id") Long id,
@RequestBody AdminApplicationRequest.ClassYearRequest classYearRequest) {
classYearService.updateClassYear(id, classYearRequest);
return new ResponseEntity<>(HttpStatus.OK);
}

@DeleteMapping()
@Operation(summary="기수 삭제 API", description = "기수를 삭제 합니다.")
public ResponseEntity<Void> deleteClassYear(@RequestParam("id") Long id) {
classYearService.deleteClassYear(id);
return new ResponseEntity<>(HttpStatus.OK);
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
package com.gdsc_knu.official_homepage.dto.admin.application;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.gdsc_knu.official_homepage.entity.ClassYear;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;

public class AdminApplicationRequest {
@Getter
@AllArgsConstructor
Expand All @@ -12,4 +20,28 @@ public static class Append {
private String note;
private Integer version;
}
}

@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public static class ClassYearRequest {
private String name;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
private LocalDateTime applyStartDateTime;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
private LocalDateTime applyEndDateTime;

public ClassYear toEntity() {
return ClassYear.builder()
.name(name)
.applicationStartDateTime(applyStartDateTime)
.applicationEndDateTime(applyEndDateTime)
.build();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.gdsc_knu.official_homepage.entity.ClassYear;
import com.gdsc_knu.official_homepage.entity.application.Application;
import com.gdsc_knu.official_homepage.entity.application.ApplicationAnswer;
import lombok.AllArgsConstructor;
Expand Down Expand Up @@ -60,7 +61,7 @@ public static Overview from(Application application){
return Overview.builder()
.id(application.getId())
.name(application.getName())
.submittedAt(application.getModifiedAt())
.submittedAt(application.getSubmittedAt())
.studentNumber(application.getStudentNumber())
.major(application.getMajor())
.track(application.getTrack().name())
Expand Down Expand Up @@ -104,7 +105,7 @@ public static Detail from(Application application){
.phoneNumber(application.getPhoneNumber())
.email(application.getEmail())
.track(application.getTrack().name())
.submittedAt(application.getModifiedAt())
.submittedAt(application.getSubmittedAt())
.techStack(application.getTechStack())
.link(application.getLinks())
.isMarked(application.isMarked())
Expand Down Expand Up @@ -147,4 +148,30 @@ public static Result from(HttpStatus status, String message) {
.build();
}
}

@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public static class ClassYearResponse {
private Long id;
private String name;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
private LocalDateTime applyStartDateTime;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
private LocalDateTime applyEndDateTime;

public static AdminApplicationResponse.ClassYearResponse from(ClassYear classYear) {
return AdminApplicationResponse.ClassYearResponse.builder()
.id(classYear.getId())
.name(classYear.getName())
.applyStartDateTime(classYear.getApplicationStartDateTime())
.applyEndDateTime(classYear.getApplicationEndDateTime())
.build();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.gdsc_knu.official_homepage.dto.application;

import com.gdsc_knu.official_homepage.entity.enumeration.ApplicationStatus;
import com.gdsc_knu.official_homepage.entity.enumeration.Track;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.List;

@Getter
@AllArgsConstructor
@Builder
@NoArgsConstructor
public class ApplicationModel {
private String techStack;
private String links;
private ApplicationStatus applicationStatus;
private Track track;
private List<ApplicationAnswerDTO> answers;

public ApplicationModel(ApplicationRequest applicationRequest) {
this.techStack = applicationRequest.getTechStack();
this.links = applicationRequest.getLinks();
this.applicationStatus = applicationRequest.getApplicationStatus();
this.track = applicationRequest.getTrack();
this.answers = applicationRequest.getAnswers();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
@Builder
@Getter
public class ApplicationRequest {
@NotNull(message = "기수 정보는 필수입니다.")
private Long classYearId;

@NotNull(message = "잘못된 입력 형식입니다.")
private String techStack;

Expand Down
34 changes: 34 additions & 0 deletions src/main/java/com/gdsc_knu/official_homepage/entity/ClassYear.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.gdsc_knu.official_homepage.entity;

import com.gdsc_knu.official_homepage.entity.application.Application;
import jakarta.persistence.*;
import lombok.*;

import java.time.LocalDate;
import java.time.LocalDateTime;

@Entity
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class ClassYear {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(nullable = false, unique = true)
private String name;

@Column(nullable = false)
private LocalDateTime applicationStartDateTime;

@Column(nullable = false)
private LocalDateTime applicationEndDateTime;

public void update(String name, LocalDateTime applicationStartDateTime, LocalDateTime applicationEndDateTime) {
this.name = name;
this.applicationStartDateTime = applicationStartDateTime;
this.applicationEndDateTime = applicationEndDateTime;
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.gdsc_knu.official_homepage.entity.application;

import com.gdsc_knu.official_homepage.dto.application.ApplicationAnswerDTO;
import com.gdsc_knu.official_homepage.dto.application.ApplicationRequest;
import com.gdsc_knu.official_homepage.entity.BaseTimeEntity;
import com.gdsc_knu.official_homepage.dto.application.ApplicationModel;
import com.gdsc_knu.official_homepage.entity.ClassYear;
import com.gdsc_knu.official_homepage.entity.Member;
import com.gdsc_knu.official_homepage.entity.enumeration.ApplicationStatus;
import com.gdsc_knu.official_homepage.entity.enumeration.Track;
Expand All @@ -11,6 +11,7 @@
import jakarta.persistence.*;
import lombok.*;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
Expand All @@ -21,7 +22,7 @@
@Builder
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Application extends BaseTimeEntity {
public class Application {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
Expand All @@ -31,21 +32,24 @@ public class Application extends BaseTimeEntity {

private String name;

@Column(unique = true)
private String studentNumber;

private String major;

@Column(unique = true)
private String email;

@Column(unique = true)
private String phoneNumber;

private String techStack;

private String links;

private LocalDateTime submittedAt;

@ManyToOne
@JoinColumn(name = "class_year_id")
private ClassYear classYear;

@Enumerated(EnumType.STRING)
private ApplicationStatus applicationStatus;

Expand All @@ -65,35 +69,36 @@ public class Application extends BaseTimeEntity {
@OneToMany(mappedBy = "application", cascade = CascadeType.ALL, orphanRemoval = true)
private List<ApplicationAnswer> answers = new ArrayList<>();

// TODO : presentation 계층과 의존 제거
public Application(Member member, ApplicationRequest applicationRequest) {
public Application(Member member, ApplicationModel applicationModel) {
this.name = member.getName();
this.studentNumber = member.getStudentNumber();
this.major = member.getMajor();
this.email = member.getEmail();
this.phoneNumber = member.getPhoneNumber();
this.techStack = applicationRequest.getTechStack();
this.links = applicationRequest.getLinks();
this.applicationStatus = applicationRequest.getApplicationStatus();
this.track = applicationRequest.getTrack();
this.answers = applicationRequest.getAnswers().stream()
this.techStack = applicationModel.getTechStack();
this.links = applicationModel.getLinks();
this.applicationStatus = applicationModel.getApplicationStatus();
this.track = applicationModel.getTrack();
this.answers = applicationModel.getAnswers().stream()
.map(answers -> ApplicationAnswer.builder()
.questionNumber(answers.getQuestionNumber())
.answer(answers.getAnswer())
.build()).toList();
this.submittedAt = LocalDateTime.now();
}

public void updateApplication(Member member, ApplicationRequest applicationRequest) {
public void updateApplication(Member member, ApplicationModel applicationModel) {
this.name = member.getName();
this.studentNumber = member.getStudentNumber();
this.major = member.getMajor();
this.email = member.getEmail();
this.phoneNumber = member.getPhoneNumber();
this.techStack = applicationRequest.getTechStack();
this.links = applicationRequest.getLinks();
this.applicationStatus = applicationRequest.getApplicationStatus();
this.track = applicationRequest.getTrack();
updateNewAnswers(applicationRequest.getAnswers());
this.techStack = applicationModel.getTechStack();
this.links = applicationModel.getLinks();
this.applicationStatus = applicationModel.getApplicationStatus();
this.track = applicationModel.getTrack();
updateNewAnswers(applicationModel.getAnswers());
this.submittedAt = LocalDateTime.now();
}

private void updateNewAnswers(List<ApplicationAnswerDTO> newAnswersDTO) {
Expand Down Expand Up @@ -131,4 +136,8 @@ public void saveNote(String note, Integer version) {
throw new CustomException(ErrorCode.CONCURRENT_FAILED);
this.note = note;
}

public void updateClassYear(ClassYear classYear) {
this.classYear = classYear;
}
}
Loading

0 comments on commit 832167d

Please sign in to comment.