-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: 스터디 수료 처리 및 철회 V2 API 구현 (#891)
* feat: 스터디 수료 처리 v2 api 구현 * feat: 스터디 수료 처리 철회 v2 api 구현 * rename: validator 이름 수정 * fix: 엔드포인트 수정 * refactor: 검증 로직 순서 변경 * docs: description 수정 * feat: 역할 검증 추가
- Loading branch information
1 parent
170deac
commit 48b03e1
Showing
7 changed files
with
200 additions
and
0 deletions.
There are no files selected for viewing
35 changes: 35 additions & 0 deletions
35
src/main/java/com/gdschongik/gdsc/domain/studyv2/api/MentorStudyHistoryControllerV2.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package com.gdschongik.gdsc.domain.studyv2.api; | ||
|
||
import com.gdschongik.gdsc.domain.study.dto.request.StudyCompleteRequest; | ||
import com.gdschongik.gdsc.domain.studyv2.application.MentorStudyHistoryServiceV2; | ||
import io.swagger.v3.oas.annotations.Operation; | ||
import io.swagger.v3.oas.annotations.tags.Tag; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.http.ResponseEntity; | ||
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; | ||
|
||
@Tag(name = "Mentor Study History V2", description = "멘토 스터디 수강 이력 API입니다.") | ||
@RestController | ||
@RequestMapping("/v2/mentor/study-histories") | ||
@RequiredArgsConstructor | ||
public class MentorStudyHistoryControllerV2 { | ||
|
||
private final MentorStudyHistoryServiceV2 mentorStudyHistoryServiceV2; | ||
|
||
@Operation(summary = "스터디 수료 처리", description = "스터디 수료 처리하고 스터디 수료 발급쿠폰을 발급합니다.") | ||
@PostMapping("/complete") | ||
public ResponseEntity<Void> completeStudy(@RequestBody StudyCompleteRequest request) { | ||
mentorStudyHistoryServiceV2.completeStudy(request); | ||
return ResponseEntity.ok().build(); | ||
} | ||
|
||
@Operation(summary = "스터디 수료 철회", description = "스터디 수료 처리를 철회하고 스터디 수료 발급쿠폰을 회수합니다.") | ||
@PostMapping("/withdraw-completion") | ||
public ResponseEntity<Void> withdrawStudyCompletion(@RequestBody StudyCompleteRequest request) { | ||
mentorStudyHistoryServiceV2.withdrawStudyCompletion(request); | ||
return ResponseEntity.ok().build(); | ||
} | ||
} |
84 changes: 84 additions & 0 deletions
84
...main/java/com/gdschongik/gdsc/domain/studyv2/application/MentorStudyHistoryServiceV2.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
package com.gdschongik.gdsc.domain.studyv2.application; | ||
|
||
import com.gdschongik.gdsc.domain.member.domain.Member; | ||
import com.gdschongik.gdsc.domain.study.domain.StudyHistoriesCompletedEvent; | ||
import com.gdschongik.gdsc.domain.study.dto.request.StudyCompleteRequest; | ||
import com.gdschongik.gdsc.domain.studyv2.dao.StudyHistoryV2Repository; | ||
import com.gdschongik.gdsc.domain.studyv2.dao.StudyV2Repository; | ||
import com.gdschongik.gdsc.domain.studyv2.domain.StudyHistoryV2; | ||
import com.gdschongik.gdsc.domain.studyv2.domain.StudyHistoryValidatorV2; | ||
import com.gdschongik.gdsc.domain.studyv2.domain.StudyV2; | ||
import com.gdschongik.gdsc.domain.studyv2.domain.StudyValidatorV2; | ||
import com.gdschongik.gdsc.global.exception.CustomException; | ||
import com.gdschongik.gdsc.global.exception.ErrorCode; | ||
import com.gdschongik.gdsc.global.util.MemberUtil; | ||
import java.util.List; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.context.ApplicationEventPublisher; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
@Slf4j | ||
@Service | ||
@RequiredArgsConstructor | ||
public class MentorStudyHistoryServiceV2 { | ||
|
||
private final ApplicationEventPublisher applicationEventPublisher; | ||
private final MemberUtil memberUtil; | ||
private final StudyValidatorV2 studyValidatorV2; | ||
private final StudyHistoryValidatorV2 studyHistoryValidatorV2; | ||
private final StudyV2Repository studyV2Repository; | ||
private final StudyHistoryV2Repository studyHistoryV2Repository; | ||
|
||
@Transactional | ||
public void completeStudy(StudyCompleteRequest request) { | ||
Member currentMember = memberUtil.getCurrentMember(); | ||
StudyV2 study = studyV2Repository | ||
.findById(request.studyId()) | ||
.orElseThrow(() -> new CustomException(ErrorCode.STUDY_NOT_FOUND)); | ||
|
||
studyValidatorV2.validateStudyMentor(currentMember, study); | ||
|
||
List<StudyHistoryV2> studyHistories = | ||
studyHistoryV2Repository.findAllByStudyIdAndStudentIds(request.studyId(), request.studentIds()); | ||
|
||
studyHistoryValidatorV2.validateAppliedToStudy( | ||
studyHistories.size(), request.studentIds().size()); | ||
|
||
studyHistories.forEach(StudyHistoryV2::complete); | ||
|
||
applicationEventPublisher.publishEvent(new StudyHistoriesCompletedEvent( | ||
studyHistories.stream().map(StudyHistoryV2::getId).toList())); | ||
|
||
log.info( | ||
"[MentorStudyHistoryServiceV2] 스터디 수료 처리: studyId={}, studentIds={}", | ||
request.studyId(), | ||
request.studentIds()); | ||
} | ||
|
||
@Transactional | ||
public void withdrawStudyCompletion(StudyCompleteRequest request) { | ||
Member currentMember = memberUtil.getCurrentMember(); | ||
StudyV2 study = studyV2Repository | ||
.findById(request.studyId()) | ||
.orElseThrow(() -> new CustomException(ErrorCode.STUDY_NOT_FOUND)); | ||
|
||
studyValidatorV2.validateStudyMentor(currentMember, study); | ||
|
||
List<StudyHistoryV2> studyHistories = | ||
studyHistoryV2Repository.findAllByStudyIdAndStudentIds(request.studyId(), request.studentIds()); | ||
|
||
studyHistoryValidatorV2.validateAppliedToStudy( | ||
studyHistories.size(), request.studentIds().size()); | ||
|
||
studyHistories.forEach(StudyHistoryV2::withdrawCompletion); | ||
|
||
studyHistoryV2Repository.saveAll(studyHistories); | ||
|
||
log.info( | ||
"[MentorStudyHistoryServiceV2] 스터디 수료 철회: studyId={}, studentIds={}", | ||
request.studyId(), | ||
request.studentIds()); | ||
} | ||
} |
9 changes: 9 additions & 0 deletions
9
src/main/java/com/gdschongik/gdsc/domain/studyv2/dao/StudyHistoryV2CustomRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package com.gdschongik.gdsc.domain.studyv2.dao; | ||
|
||
import com.gdschongik.gdsc.domain.studyv2.domain.StudyHistoryV2; | ||
import java.util.List; | ||
|
||
public interface StudyHistoryV2CustomRepository { | ||
|
||
List<StudyHistoryV2> findAllByStudyIdAndStudentIds(Long studyId, List<Long> studentIds); | ||
} |
22 changes: 22 additions & 0 deletions
22
src/main/java/com/gdschongik/gdsc/domain/studyv2/dao/StudyHistoryV2CustomRepositoryImpl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package com.gdschongik.gdsc.domain.studyv2.dao; | ||
|
||
import static com.gdschongik.gdsc.domain.studyv2.domain.QStudyHistoryV2.*; | ||
|
||
import com.gdschongik.gdsc.domain.studyv2.domain.StudyHistoryV2; | ||
import com.querydsl.jpa.impl.JPAQueryFactory; | ||
import java.util.List; | ||
import lombok.RequiredArgsConstructor; | ||
|
||
@RequiredArgsConstructor | ||
public class StudyHistoryV2CustomRepositoryImpl implements StudyHistoryV2CustomRepository { | ||
|
||
private final JPAQueryFactory queryFactory; | ||
|
||
@Override | ||
public List<StudyHistoryV2> findAllByStudyIdAndStudentIds(Long studyId, List<Long> studentIds) { | ||
return queryFactory | ||
.selectFrom(studyHistoryV2) | ||
.where(studyHistoryV2.study.id.eq(studyId), studyHistoryV2.student.id.in(studentIds)) | ||
.fetch(); | ||
} | ||
} |
6 changes: 6 additions & 0 deletions
6
src/main/java/com/gdschongik/gdsc/domain/studyv2/dao/StudyHistoryV2Repository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package com.gdschongik.gdsc.domain.studyv2.dao; | ||
|
||
import com.gdschongik.gdsc.domain.studyv2.domain.StudyHistoryV2; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
|
||
public interface StudyHistoryV2Repository extends JpaRepository<StudyHistoryV2, Long>, StudyHistoryV2CustomRepository {} |
16 changes: 16 additions & 0 deletions
16
src/main/java/com/gdschongik/gdsc/domain/studyv2/domain/StudyHistoryValidatorV2.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package com.gdschongik.gdsc.domain.studyv2.domain; | ||
|
||
import static com.gdschongik.gdsc.global.exception.ErrorCode.*; | ||
|
||
import com.gdschongik.gdsc.global.annotation.DomainService; | ||
import com.gdschongik.gdsc.global.exception.CustomException; | ||
|
||
@DomainService | ||
public class StudyHistoryValidatorV2 { | ||
|
||
public void validateAppliedToStudy(long countStudyHistory, int studentCount) { | ||
if (countStudyHistory != studentCount) { | ||
throw new CustomException(STUDY_HISTORY_NOT_APPLIED_STUDENT_EXISTS); | ||
} | ||
} | ||
} |
28 changes: 28 additions & 0 deletions
28
src/main/java/com/gdschongik/gdsc/domain/studyv2/domain/StudyValidatorV2.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package com.gdschongik.gdsc.domain.studyv2.domain; | ||
|
||
import static com.gdschongik.gdsc.global.exception.ErrorCode.*; | ||
|
||
import com.gdschongik.gdsc.domain.member.domain.Member; | ||
import com.gdschongik.gdsc.global.annotation.DomainService; | ||
import com.gdschongik.gdsc.global.exception.CustomException; | ||
|
||
@DomainService | ||
public class StudyValidatorV2 { | ||
|
||
public void validateStudyMentor(Member currentMember, StudyV2 study) { | ||
// 어드민인 경우 검증 통과 | ||
if (currentMember.isAdmin()) { | ||
return; | ||
} | ||
|
||
// 멘토인지 검증 | ||
if (!currentMember.isMentor()) { | ||
throw new CustomException(STUDY_ACCESS_NOT_ALLOWED); | ||
} | ||
|
||
// 해당 스터디의 담당 멘토인지 검증 | ||
if (!currentMember.getId().equals(study.getMentor().getId())) { | ||
throw new CustomException(STUDY_MENTOR_INVALID); | ||
} | ||
} | ||
} |