Skip to content

Commit

Permalink
refactor: 리쿠르팅 정규화 (#445)
Browse files Browse the repository at this point in the history
* refactor: 통합테스트 템플릿을 활용하도록 수정

* refactor: 리쿠르팅 테이블 정규화

* fix: 조인 정보 추가

* fix: 불필요한 주석 제거

* fix: 빌더 접근 수준 수정

* remove: 불필요한 주석 제거

* refactor: 리쿠르팅 생성 기능 수정

* refactor: 리쿠르팅 조회 기능 수정

* rename: dto 이름 수정

* rename: 로직과 어울리는 이름으로 변경

recruitment를 recruitmentRound로 수정

* rename: 로직과 어울리는 이름으로 변경

recruitment를 recruitmentRound로 수정

* remove: 멤버십의 학년도와 학기 제거

* docs: summary 수정

* feat: 모집회차 수정 api 추가

* remove: 사용하지 않는 메서드 제거

* refactor: 템플릿 메서드 이용하도록 수정

* refactor: errorCode 수정

* refactor: errorCode 수정

* rename: 메서드명 수정

* rename: ErrorCode 메시지 수정

* rename: 변수명 수정

* remove: 서비스에서 사용하지 않는 리쿠르팅 레포지토리 제거

* feat: 로그 추가

* rename: 변수명 수정

* refactor: final 키워드 추가

* remove: 회비 수정 메서드 제거

* refactor: 모집기간을 VO로 받도록 수정

* chore: pr 분리

* rename: 메서드명 변경

* fix: 경로 수정
  • Loading branch information
Sangwook02 authored Jul 8, 2024
1 parent 6dbd9f5 commit 59b662b
Show file tree
Hide file tree
Showing 33 changed files with 669 additions and 679 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import com.gdschongik.gdsc.domain.membership.application.MembershipService;
import com.gdschongik.gdsc.domain.membership.domain.Membership;
import com.gdschongik.gdsc.domain.recruitment.application.OnboardingRecruitmentService;
import com.gdschongik.gdsc.domain.recruitment.domain.Recruitment;
import com.gdschongik.gdsc.domain.recruitment.domain.RecruitmentRound;
import com.gdschongik.gdsc.global.exception.CustomException;
import com.gdschongik.gdsc.global.util.MemberUtil;
import java.util.Optional;
Expand Down Expand Up @@ -76,9 +76,9 @@ public MemberBasicInfoResponse getMemberBasicInfo() {

public MemberDashboardResponse getDashboard() {
Member currentMember = memberUtil.getCurrentMember();
Recruitment currentRecruitment = onboardingRecruitmentService.findCurrentRecruitment();
Optional<Membership> myMembership = membershipService.findMyMembership(currentMember, currentRecruitment);
RecruitmentRound currentRecruitmentRound = onboardingRecruitmentService.findCurrentRecruitmentRound();
Optional<Membership> myMembership = membershipService.findMyMembership(currentMember, currentRecruitmentRound);

return MemberDashboardResponse.from(currentMember, currentRecruitment, myMembership.orElse(null));
return MemberDashboardResponse.from(currentMember, currentRecruitmentRound, myMembership.orElse(null));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,19 @@
import com.gdschongik.gdsc.domain.member.dto.MemberFullDto;
import com.gdschongik.gdsc.domain.membership.domain.Membership;
import com.gdschongik.gdsc.domain.membership.dto.MembershipFullDto;
import com.gdschongik.gdsc.domain.recruitment.domain.Recruitment;
import com.gdschongik.gdsc.domain.recruitment.dto.RecruitmentFullDto;
import com.gdschongik.gdsc.domain.recruitment.domain.RecruitmentRound;
import com.gdschongik.gdsc.domain.recruitment.dto.RecruitmentRoundFullDto;
import jakarta.annotation.Nullable;

public record MemberDashboardResponse(
MemberFullDto member, RecruitmentFullDto currentRecruitment, @Nullable MembershipFullDto currentMembership) {
MemberFullDto member,
RecruitmentRoundFullDto currentRecruitmentRound,
@Nullable MembershipFullDto currentMembership) {
public static MemberDashboardResponse from(
Member member, Recruitment currentRecruitment, Membership currentMembership) {
Member member, RecruitmentRound currentRecruitmentRound, Membership currentMembership) {
return new MemberDashboardResponse(
MemberFullDto.from(member),
RecruitmentFullDto.from(currentRecruitment),
RecruitmentRoundFullDto.from(currentRecruitmentRound),
currentMembership == null ? null : MembershipFullDto.from(currentMembership));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@ public class MembershipController {

private final MembershipService membershipService;

// todo: 서비스 복구 필요
@Operation(summary = "멤버십 가입 신청 접수", description = "정회원 가입을 위해 멤버십 가입 신청을 접수합니다. 별도의 정회원 가입 조건을 만족해야 가입이 완료됩니다.")
@PostMapping
public ResponseEntity<Void> submitMembership(@RequestParam(name = "recruitmentId") Long recruitmentId) {
membershipService.submitMembership(recruitmentId);
public ResponseEntity<Void> submitMembership(@RequestParam(name = "recruitmentRoundId") Long recruitmentRoundId) {
membershipService.submitMembership(recruitmentRoundId);
return ResponseEntity.ok().build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@

import static com.gdschongik.gdsc.global.exception.ErrorCode.*;

import com.gdschongik.gdsc.domain.common.model.SemesterType;
import com.gdschongik.gdsc.domain.member.domain.Member;
import com.gdschongik.gdsc.domain.membership.dao.MembershipRepository;
import com.gdschongik.gdsc.domain.membership.domain.Membership;
import com.gdschongik.gdsc.domain.recruitment.dao.RecruitmentRepository;
import com.gdschongik.gdsc.domain.recruitment.domain.Recruitment;
import com.gdschongik.gdsc.domain.recruitment.dao.RecruitmentRoundRepository;
import com.gdschongik.gdsc.domain.recruitment.domain.RecruitmentRound;
import com.gdschongik.gdsc.global.exception.CustomException;
import com.gdschongik.gdsc.global.util.MemberUtil;
import java.util.Optional;
Expand All @@ -20,7 +19,7 @@
@Transactional(readOnly = true)
public class MembershipService {
private final MembershipRepository membershipRepository;
private final RecruitmentRepository recruitmentRepository;
private final RecruitmentRoundRepository recruitmentRoundRepository;
private final MemberUtil memberUtil;

@Transactional
Expand All @@ -33,36 +32,28 @@ public void verifyPaymentStatus(Long membershipId) {
}

@Transactional
public void submitMembership(Long recruitmentId) {
Member currentMember = memberUtil.getCurrentMember();
Recruitment recruitment = recruitmentRepository
.findById(recruitmentId)
.orElseThrow(() -> new CustomException(RECRUITMENT_NOT_FOUND));
validateMembershipDuplicate(currentMember, recruitment.getAcademicYear(), recruitment.getSemesterType());
validateRecruitmentOpen(recruitment);

Membership membership = Membership.createMembership(currentMember, recruitment);
membershipRepository.save(membership);
}

private void validateRecruitmentOpen(Recruitment recruitment) {
if (!recruitment.isOpen()) {
throw new CustomException(RECRUITMENT_NOT_OPEN);
}
}

private void validateMembershipDuplicate(Member currentMember, Integer academicYear, SemesterType semesterType) {
membershipRepository
.findByMemberAndAcademicYearAndSemesterType(currentMember, academicYear, semesterType)
.ifPresent(membership -> {
if (membership.isRegularRequirementAllSatisfied()) {
throw new CustomException(MEMBERSHIP_ALREADY_SATISFIED);
}
throw new CustomException(MEMBERSHIP_ALREADY_APPLIED);
});
}

public Optional<Membership> findMyMembership(Member member, Recruitment recruitment) {
return membershipRepository.findByMemberAndRecruitment(member, recruitment);
public void submitMembership(Long recruitmentRoundId) {}

// private void validateRecruitmentRoundOpen(RecruitmentRound recruitmentRound) {
// if (!recruitmentRound.isOpen()) {
// throw new CustomException(RECRUITMENT_ROUND_NOT_OPEN);
// }
// }
//
// private void validateMembershipDuplicate(Member currentMember, Recruitment recruitment) {
// membershipRepository
// .findByMember(currentMember)
// .filter(membership ->
// membership.getRecruitmentRound().getRecruitment().equals(recruitment))
// .ifPresent(membership -> {
// if (membership.isRegularRequirementAllSatisfied()) {
// throw new CustomException(MEMBERSHIP_ALREADY_SATISFIED);
// }
// throw new CustomException(MEMBERSHIP_ALREADY_APPLIED);
// });
// }

public Optional<Membership> findMyMembership(Member member, RecruitmentRound recruitmentRound) {
return membershipRepository.findByMemberAndRecruitmentRound(member, recruitmentRound);
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
package com.gdschongik.gdsc.domain.membership.dao;

import com.gdschongik.gdsc.domain.common.model.SemesterType;
import com.gdschongik.gdsc.domain.member.domain.Member;
import com.gdschongik.gdsc.domain.membership.domain.Membership;
import com.gdschongik.gdsc.domain.recruitment.domain.Recruitment;
import com.gdschongik.gdsc.domain.recruitment.domain.RecruitmentRound;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;

public interface MembershipRepository extends JpaRepository<Membership, Long> {

Optional<Membership> findByMemberAndAcademicYearAndSemesterType(
Member member, Integer academicYear, SemesterType semesterType);
// Optional<Membership> findByMember(Member member);

Optional<Membership> findByMemberAndRecruitment(Member member, Recruitment recruitment);
Optional<Membership> findByMemberAndRecruitmentRound(Member member, RecruitmentRound recruitmentRound);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@
import static com.gdschongik.gdsc.domain.common.model.RequirementStatus.*;
import static com.gdschongik.gdsc.global.exception.ErrorCode.*;

import com.gdschongik.gdsc.domain.common.model.BaseSemesterEntity;
import com.gdschongik.gdsc.domain.common.model.SemesterType;
import com.gdschongik.gdsc.domain.common.model.BaseEntity;
import com.gdschongik.gdsc.domain.member.domain.Member;
import com.gdschongik.gdsc.domain.member.domain.MemberRegularEvent;
import com.gdschongik.gdsc.domain.member.domain.MemberRole;
import com.gdschongik.gdsc.domain.recruitment.domain.Recruitment;
import com.gdschongik.gdsc.domain.recruitment.domain.RecruitmentRound;
import com.gdschongik.gdsc.global.exception.CustomException;
import jakarta.persistence.Column;
import jakarta.persistence.Embedded;
Expand All @@ -27,7 +26,7 @@
@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Membership extends BaseSemesterEntity {
public class Membership extends BaseEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Expand All @@ -39,34 +38,26 @@ public class Membership extends BaseSemesterEntity {
private Member member;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "recruitment_id")
private Recruitment recruitment;
@JoinColumn(name = "recruitment_round_id")
private RecruitmentRound recruitmentRound;

@Embedded
private RegularRequirement regularRequirement;

@Builder(access = AccessLevel.PRIVATE)
private Membership(
Member member,
Recruitment recruitment,
RegularRequirement regularRequirement,
Integer academicYear,
SemesterType semesterType) {
super(academicYear, semesterType);
private Membership(Member member, RecruitmentRound recruitmentRound, RegularRequirement regularRequirement) {
this.member = member;
this.recruitment = recruitment;
this.recruitmentRound = recruitmentRound;
this.regularRequirement = regularRequirement;
}

public static Membership createMembership(Member member, Recruitment recruitment) {
public static Membership createMembership(Member member, RecruitmentRound recruitmentRound) {
validateMembershipApplicable(member);

return Membership.builder()
.member(member)
.recruitment(recruitment)
.recruitmentRound(recruitmentRound)
.regularRequirement(RegularRequirement.createUnsatisfiedRequirement())
.academicYear(recruitment.getAcademicYear())
.semesterType(recruitment.getSemesterType())
.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public static MembershipFullDto from(Membership membership) {
return new MembershipFullDto(
membership.getId(),
membership.getMember().getId(),
membership.getRecruitment().getId(),
membership.getRecruitmentRound().getId(),
membership.getRegularRequirement());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public static Order createPending(
.nanoId(nanoId)
.memberId(membership.getMember().getId())
.membershipId(membership.getId())
.recruitmentId(membership.getRecruitment().getId())
.recruitmentId(membership.getRecruitmentRound().getRecruitment().getId())
.issuedCouponId(issuedCoupon != null ? issuedCoupon.getId() : null)
.moneyInfo(moneyInfo)
.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import com.gdschongik.gdsc.domain.coupon.domain.IssuedCoupon;
import com.gdschongik.gdsc.domain.member.domain.Member;
import com.gdschongik.gdsc.domain.membership.domain.Membership;
import com.gdschongik.gdsc.domain.recruitment.domain.Recruitment;
import com.gdschongik.gdsc.domain.recruitment.domain.RecruitmentRound;
import com.gdschongik.gdsc.global.annotation.DomainService;
import com.gdschongik.gdsc.global.exception.CustomException;
import jakarta.annotation.Nullable;
Expand All @@ -30,9 +30,9 @@ public void validatePendingOrderCreate(

// 리쿠르팅 관련 검증

Recruitment recruitment = membership.getRecruitment();
RecruitmentRound recruitmentRound = membership.getRecruitmentRound();

if (!recruitment.isOpen()) {
if (!recruitmentRound.isOpen()) {
throw new CustomException(ORDER_RECRUITMENT_PERIOD_INVALID);
}

Expand All @@ -48,7 +48,7 @@ public void validatePendingOrderCreate(
Money totalAmount = moneyInfo.getTotalAmount();
Money discountAmount = moneyInfo.getDiscountAmount();

if (!totalAmount.equals(recruitment.getFee())) {
if (!totalAmount.equals(recruitmentRound.getRecruitment().getFee())) {
throw new CustomException(ORDER_TOTAL_AMOUNT_MISMATCH);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package com.gdschongik.gdsc.domain.recruitment.api;

import com.gdschongik.gdsc.domain.recruitment.application.AdminRecruitmentService;
import com.gdschongik.gdsc.domain.recruitment.dto.request.RecruitmentCreateUpdateRequest;
import com.gdschongik.gdsc.domain.recruitment.dto.request.RecruitmentCreateRequest;
import com.gdschongik.gdsc.domain.recruitment.dto.request.RecruitmentRoundUpdateRequest;
import com.gdschongik.gdsc.domain.recruitment.dto.response.AdminRecruitmentResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
Expand All @@ -25,9 +26,10 @@ public class AdminRecruitmentController {

private final AdminRecruitmentService adminRecruitmentService;

@Operation(summary = "리쿠르팅 생성", description = "새로운 리쿠르팅(모집 기간)를 생성합니다.")
// todo: 서비스 복구 필요
@Operation(summary = "리쿠르팅 생성", description = "새로운 리쿠르팅을 생성합니다.")
@PostMapping
public ResponseEntity<Void> createRecruitment(@Valid @RequestBody RecruitmentCreateUpdateRequest request) {
public ResponseEntity<Void> createRecruitment(@Valid @RequestBody RecruitmentCreateRequest request) {
adminRecruitmentService.createRecruitment(request);
return ResponseEntity.ok().build();
}
Expand All @@ -39,11 +41,12 @@ public ResponseEntity<List<AdminRecruitmentResponse>> getAllRecruitments() {
return ResponseEntity.ok().body(response);
}

@Operation(summary = "리쿠르팅 수정", description = "기존 리쿠르팅(모집 기간)를 수정합니다.")
@PutMapping("/{recruitmentId}")
public ResponseEntity<Void> updateRecruitment(
@PathVariable Long recruitmentId, @Valid @RequestBody RecruitmentCreateUpdateRequest request) {
adminRecruitmentService.updateRecruitment(recruitmentId, request);
// todo: 서비스 복구 필요
@Operation(summary = "모집회차 수정", description = "기존 모집회차를 수정합니다.")
@PutMapping("/rounds/{recruitmentRoundId}")
public ResponseEntity<Void> updateRecruitmentRound(
@PathVariable Long recruitmentRoundId, @Valid @RequestBody RecruitmentRoundUpdateRequest request) {
adminRecruitmentService.updateRecruitmentRound(recruitmentRoundId, request);
return ResponseEntity.ok().build();
}
}
Loading

0 comments on commit 59b662b

Please sign in to comment.