Skip to content

Commit

Permalink
[refactor] 학원 검증 로직 추가, 연관관계 수정
Browse files Browse the repository at this point in the history
[refactor] 학원 검증 로직 추가, 연관관계 수정
  • Loading branch information
bangyewon authored Jan 14, 2025
2 parents 24292f3 + 63205f9 commit 3e2fe01
Show file tree
Hide file tree
Showing 13 changed files with 137 additions and 89 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package classfit.example.classfit.category.domain;

import classfit.example.classfit.academy.domain.Academy;
import classfit.example.classfit.common.domain.BaseEntity;
import classfit.example.classfit.member.domain.Member;
import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.Getter;
Expand All @@ -27,13 +27,13 @@ public class MainClass extends BaseEntity {
private List<SubClass> subClasses = new ArrayList<>();

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id", nullable = false)
private Member member;
@JoinColumn(name = "academy_id", nullable = false)
private Academy academy;


public MainClass(String mainClassName, Member member) {
public MainClass(String mainClassName, Academy academy) {
this.mainClassName = mainClassName;
this.member = member;
this.academy = academy;
}

// 업데이트 관련 메서드
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,12 @@ public class SubClass extends BaseEntity {
@JoinColumn(name = "main_class_id", nullable = false)
private MainClass mainClass;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id", nullable = false)
private Member member;

@OneToMany(mappedBy = "subClass", cascade = CascadeType.ALL, orphanRemoval = true)
private final List<ClassStudent> classStudents = new ArrayList<>();

public SubClass(String subClassName, Member member, MainClass mainClass) {
public SubClass(String subClassName, MainClass mainClass) {
this.subClassName = subClassName;
this.member = member;
this.mainClass = mainClass;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
public interface MainClassRepository extends JpaRepository<MainClass, Long> {
List<MainClass> findAllByOrderByMainClassNameAsc();

List<MainClass> findByMemberAcademy(Academy academy);
List<MainClass> findByAcademy(Academy academy);

boolean existsByMember_AcademyAndMainClassName(Academy academy, String mainClassName);
boolean existsByAcademyAndMainClassName(Academy academy, String mainClassName);
}

Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
package classfit.example.classfit.category.repository;

import classfit.example.classfit.academy.domain.Academy;
import classfit.example.classfit.category.domain.MainClass;
import classfit.example.classfit.category.domain.SubClass;
import classfit.example.classfit.member.domain.Member;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;

@Repository
public interface SubClassRepository extends JpaRepository<SubClass, Long> {
boolean existsByMemberAndSubClassNameAndMainClass(Member member, String subClassName,
MainClass mainClass);

@Query("SELECT COUNT(s) > 0 FROM SubClass s " +
"WHERE s.mainClass = :mainClass " +
"AND s.subClassName = :subClassName " +
"AND s.mainClass.academy = :academy " +
"AND :member MEMBER OF s.mainClass.academy.members")
boolean existsByMemberAndSubClassNameAndAcademyAndMainClass(
Member member, Academy academy, String subClassName, MainClass mainClass);
}

Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public class MainClassService {
private final MemberRepository memberRepository;

private static void checkMemberRelationMainClass(Member findMember, MainClass findMainClass) {
if (!Objects.equals(findMember.getId(), findMainClass.getMember().getId())) {
if (!Objects.equals(findMember.getId(), findMainClass.getAcademy().getId())) {
throw new ClassfitException("사용자와 클래스가 일치하지 않습니다.", HttpStatus.FORBIDDEN);
}
}
Expand All @@ -37,13 +37,13 @@ public MainClassResponse addMainClass(@AuthMember Member findMember, MainClassRe

Academy academy = findMember.getAcademy();

boolean exists = mainClassRepository.existsByMember_AcademyAndMainClassName(academy,
boolean exists = mainClassRepository.existsByAcademyAndMainClassName(academy,
req.mainClassName());
if (exists) {
throw new ClassfitException("이미 같은 이름의 메인 클래스가 있어요.", HttpStatus.CONFLICT);
}

MainClass mainClass = new MainClass(req.mainClassName(), findMember);
MainClass mainClass = new MainClass(req.mainClassName(), academy);
mainClassRepository.save(mainClass);

return new MainClassResponse(mainClass.getId(), mainClass.getMainClassName());
Expand All @@ -55,7 +55,7 @@ public List<AllMainClassResponse> showMainClass(@AuthMember Member findMember) {

Academy academy = findMember.getAcademy();

List<MainClass> mainClasses = mainClassRepository.findByMemberAcademy(academy);
List<MainClass> mainClasses = mainClassRepository.findByAcademy(academy);

return mainClasses.stream().map(mainClass -> new AllMainClassResponse(mainClass.getId(),
mainClass.getMainClassName())).toList();
Expand All @@ -68,7 +68,7 @@ public void deleteMainClass(@AuthMember Member findMember, Long mainClassId) {
MainClass mainClass = mainClassRepository.findById(mainClassId).orElseThrow(
() -> new ClassfitException("해당 메인 클래스를 찾을 수 없습니다.", HttpStatus.NOT_FOUND));

if (!Objects.equals(findMember.getAcademy(), mainClass.getMember().getAcademy())) {
if (!Objects.equals(findMember.getAcademy(), mainClass.getAcademy())) {
throw new ClassfitException("사용자가 속한 학원 내의 클래스가 아닙니다.", HttpStatus.FORBIDDEN);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package classfit.example.classfit.category.service;

import classfit.example.classfit.academy.domain.Academy;
import classfit.example.classfit.auth.annotation.AuthMember;
import classfit.example.classfit.category.domain.MainClass;
import classfit.example.classfit.category.domain.SubClass;
Expand All @@ -26,34 +27,41 @@ public class SubClassService {
private final MemberRepository memberRepository;

private static void checkMemberRelationMainClass(Member findMember, MainClass findMainClass) {
if (!Objects.equals(findMember.getId(), findMainClass.getMember().getId())) {
if (!Objects.equals(findMember.getId(), findMainClass.getAcademy().getId())) {
throw new ClassfitException("사용자와 클래스가 일치하지 않습니다.", HttpStatus.FORBIDDEN);
}
}

private static void checkMemberRelationSubClass(Member findMember, SubClass findSubClass) {
if (!Objects.equals(findMember.getId(), findSubClass.getMember().getId())) {
throw new ClassfitException("사용자와 클래스가 일치하지 않습니다.", HttpStatus.FORBIDDEN);
Academy academy = findSubClass.getMainClass().getAcademy();

boolean isMemberInAcademy = academy.getMembers().stream()
.anyMatch(member -> member.getId().equals(findMember.getId()));

if (!isMemberInAcademy) {
throw new ClassfitException("사용자가 해당 학원에 속해 있지 않습니다.", HttpStatus.FORBIDDEN);
}
}


@Transactional
// 서브클래스 추가
public SubClassResponse addSubClass(@AuthMember Member findMember, SubClassRequest req) {
Academy findAcademy = findMember.getAcademy();

MainClass findMainClass = mainClassRepository.findById(req.mainClassId())
.orElseThrow(
() -> new ClassfitException("메인 클래스를 찾을 수 없어요.", HttpStatus.NOT_FOUND));

boolean exists = subClassRepository.existsByMemberAndSubClassNameAndMainClass(
findMember, req.subClassName(), findMainClass);
boolean exists = subClassRepository.existsByMemberAndSubClassNameAndAcademyAndMainClass(
findMember, findAcademy, req.subClassName(), findMainClass);
if (exists) {
throw new ClassfitException("해당 메인 클래스 내에 이미 같은 이름의 서브 클래스가 있어요.", HttpStatus.CONFLICT);
}

checkMemberRelationMainClass(findMember, findMainClass);

SubClass subClass = new SubClass(req.subClassName(), findMember, findMainClass);
SubClass subClass = new SubClass(req.subClassName(), findMainClass);

subClassRepository.save(subClass);

Expand Down
16 changes: 0 additions & 16 deletions src/main/java/classfit/example/classfit/member/domain/Member.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@
import classfit.example.classfit.academy.domain.Academy;
import classfit.example.classfit.category.domain.MainClass;
import classfit.example.classfit.common.domain.BaseEntity;
import classfit.example.classfit.member.dto.request.MemberUpdateInfoRequest;
import jakarta.persistence.*;
import lombok.*;

import java.time.LocalDate;
import java.util.List;

@Entity
Expand Down Expand Up @@ -41,15 +39,6 @@ public class Member extends BaseEntity {
@Column(columnDefinition = "VARCHAR(20)", nullable = false)
private MemberStatus status;

@Column(length = 30)
private LocalDate birthDate;

@Column(length = 30)
private String subject;

@OneToMany(mappedBy = "member", cascade = CascadeType.ALL, orphanRemoval = true)
private List<MainClass> mainClasses;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "academy_id")
private Academy academy;
Expand All @@ -65,9 +54,4 @@ public void updateRole(String admin) {
public void updatePassword(String password) {
this.password = password;
}

public void updateInfo(MemberUpdateInfoRequest request) {
this.birthDate = request.birth();
this.subject = request.subject();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,12 @@ public ApiResponse<CreateReportResponse> createReport(@AuthMember Member member,
@GetMapping("/exam-list")
@Operation(summary = "기간 내 시험지 조회", description = "학습 리포트 생성 시 기간 내 시험지 조회 API 입니다.")
public ApiResponse<List<ReportExam>> findExamList(
@AuthMember Member member,
@RequestParam("startDate") LocalDate startDate,
@RequestParam("endDate") LocalDate endDate,
@RequestParam("mainClassId") Long mainClassId,
@RequestParam("subClassId") Long subClassId) {
List<ReportExam> exams = scoreReportService.showReportExam(startDate, endDate, mainClassId,
List<ReportExam> exams = scoreReportService.showReportExam(member,startDate, endDate, mainClassId,
subClassId);
return ApiResponse.success(exams, 200, "FIND-REPORT-EXAM");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,25 +27,20 @@ List<ReportExam> findExamsByCreatedAtBetween(
@Param("subClassId") Long subClassId);

@Query("""
SELECT sr
FROM ScoreReport sr
WHERE sr.mainClass.id = :mainClassId
AND sr.subClass.id = :subClassId
AND sr.id IN (
SELECT MIN(sr2.id)
FROM ScoreReport sr2
WHERE sr2.student.id = sr.student.id
GROUP BY sr2.student.id
)
""")
List<ScoreReport> findFirstReportByStudent(@Param("mainClassId") Long mainClassId,
SELECT sr
FROM ScoreReport sr
WHERE sr.mainClass.id = :mainClassId
AND sr.subClass.id = :subClassId
""")
List<ScoreReport> findAllReportsByMainClassAndSubClass(@Param("mainClassId") Long mainClassId,
@Param("subClassId") Long subClassId);


@Query("SELECT sr FROM ScoreReport sr WHERE sr.id = :studentReportId")
Optional<ScoreReport> findById(@Param("studentReportId") Long studentReportId);
Optional<ScoreReport> findByStudentReportId(@Param("studentReportId") Long studentReportId);

@Query("SELECT r FROM ScoreReport r " +
"WHERE r.mainClass.member.academy = :academy")
"WHERE r.mainClass.academy = :academy")
List<ScoreReport> findAllByAcademy(@Param("academy") Academy academy);

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,9 @@ public CreateReportResponse createReport(@AuthMember Member member,


@Transactional(readOnly = true)
public List<ReportExam> showReportExam(LocalDate startDate, LocalDate endDate, Long mainClassId,
public List<ReportExam> showReportExam(@AuthMember Member member, LocalDate startDate, LocalDate endDate, Long mainClassId,
Long subClassId) {
validateAcademy(member,member.getAcademy().getId());
List<ReportExam> reports = scoreReportRepository.findExamsByCreatedAtBetween(startDate,
endDate, mainClassId, subClassId);
return reports.stream()
Expand All @@ -144,8 +145,8 @@ public List<FindReportResponse> findReport(@AuthMember Member member, Long mainC
SubClass subClass = subClassRepository.findById(subClassId)
.orElseThrow(
() -> new ClassfitException("서브 클래스를 찾을 수 없어요.", HttpStatus.NOT_FOUND));
validateAcademy(member, mainClass.getMember().getAcademy().getId());
List<ScoreReport> studentReports = scoreReportRepository.findFirstReportByStudent(
validateAcademy(member,mainClass.getAcademy().getId());
List<ScoreReport> studentReports = scoreReportRepository.findAllReportsByMainClassAndSubClass(
mainClassId, subClassId);

return studentReports.stream()
Expand Down Expand Up @@ -176,7 +177,7 @@ public List<FindAllReportResponse> findAllReport(@AuthMember Member member) {
report.getStudent().getId(),
report.getStudent().getName(),
report.getReportName(),
report.getMainClass().getMember().getName(),
report.getMainClass().getAcademy().getMembers().getFirst().getName(),
report.getCreatedAt().toLocalDate()
))
.collect(Collectors.toList());
Expand All @@ -185,6 +186,7 @@ public List<FindAllReportResponse> findAllReport(@AuthMember Member member) {

@Transactional
public void deleteReport(@AuthMember Member member, Long studentReportId) {
validateAcademy(member,member.getAcademy().getId());
scoreReportRepository.deleteById(studentReportId);
}

Expand All @@ -198,7 +200,7 @@ public List<FindClassStudent> findClassStudents(@AuthMember Member member, Long
SubClass subClass = subClassRepository.findById(subClassId)
.orElseThrow(
() -> new ClassfitException("서브 클래스를 찾을 수 없어요.", HttpStatus.NOT_FOUND));
validateAcademy(member, mainClass.getMember().getAcademy().getId());
validateAcademy(member, member.getAcademy().getId());

List<FindClassStudent> classStudents = classStudentRepository.findStudentIdsByMainClassIdAndSubClassId(
mainClassId, subClassId);
Expand All @@ -218,7 +220,7 @@ public List<SentStudentOpinionResponse> sentStudentOpinion(@AuthMember Member me
ScoreReport scoreReport = scoreReportRepository.findById(request.reportId())
.orElseThrow(
() -> new ClassfitException("학습리포트를 찾을 수 없어요.", HttpStatus.NOT_FOUND));
validateAcademy(member, scoreReport.getMainClass().getMember().getAcademy().getId());
validateAcademy(member, scoreReport.getMainClass().getAcademy().getId());

scoreReport.updateStudentOpinion(request.studentOpinion());

Expand All @@ -239,7 +241,7 @@ public ShowStudentReportResponse showStudentReport(@AuthMember Member member, Lo
.orElseThrow(
() -> new ClassfitException("학습리포트를 찾을 수 없어요.", HttpStatus.NOT_FOUND));

validateAcademy(member, scoreReport.getMainClass().getMember().getAcademy().getId());
validateAcademy(member, scoreReport.getMainClass().getAcademy().getId());
List<AttendanceInfo> attendanceInfoList = scoreReport.getStudent().getAttendances().stream()
.collect(Collectors.groupingBy(
Attendance::getStatus,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,19 @@
@Repository
public interface ExamRepository extends JpaRepository<Exam, Long> {

List<Exam> findByMainClassMemberName(String name);
@Query("SELECT e FROM Exam e " +
"JOIN e.mainClass mc " +
"JOIN mc.academy a " +
"JOIN a.members m " +
"WHERE a.name = :academyName " +
"AND m.name = :memberName")
List<Exam> findByAcademyAndMemberName(@Param("academyName") String academyName,
@Param("memberName") String memberName);


List<Exam> findByExamName(String examName);

@Query("SELECT e FROM Exam e WHERE e.mainClass.member.academy.id = :academyId ORDER BY e.id ASC")
@Query("SELECT e FROM Exam e WHERE e.mainClass.academy.id = :academyId ORDER BY e.id ASC")
List<Exam> findAllByAcademyId(@Param("academyId") Long academyId);


Expand Down
Loading

0 comments on commit 3e2fe01

Please sign in to comment.