diff --git a/src/main/java/com/example/solidconnection/application/domain/Application.java b/src/main/java/com/example/solidconnection/application/domain/Application.java index a8e815d09..9421f6df4 100644 --- a/src/main/java/com/example/solidconnection/application/domain/Application.java +++ b/src/main/java/com/example/solidconnection/application/domain/Application.java @@ -28,13 +28,13 @@ @Entity @Table(indexes = { @Index(name = "idx_app_user_term_delete", - columnList = "site_user_id, term, is_delete"), + columnList = "site_user_id, term_id, is_delete"), @Index(name = "idx_app_first_choice_search", - columnList = "verify_status, term, is_delete, first_choice_university_info_for_apply_id"), + columnList = "verify_status, term_id, is_delete, first_choice_university_info_for_apply_id"), @Index(name = "idx_app_second_choice_search", - columnList = "verify_status, term, is_delete, second_choice_university_info_for_apply_id"), + columnList = "verify_status, term_id, is_delete, second_choice_university_info_for_apply_id"), @Index(name = "idx_app_third_choice_search", - columnList = "verify_status, term, is_delete, third_choice_university_info_for_apply_id") + columnList = "verify_status, term_id, is_delete, third_choice_university_info_for_apply_id") }) public class Application extends BaseEntity { @@ -59,8 +59,8 @@ public class Application extends BaseEntity { @Column(columnDefinition = "int not null default 1", name = "update_count") private Integer updateCount; - @Column(length = 50, nullable = false, name = "term") - private String term; + @Column(nullable = false, name = "term_id") + private long termId; @Column(name = "is_delete") private boolean isDelete = false; @@ -81,11 +81,11 @@ public Application( SiteUser siteUser, Gpa gpa, LanguageTest languageTest, - String term) { + long termId) { this.siteUserId = siteUser.getId(); this.gpa = gpa; this.languageTest = languageTest; - this.term = term; + this.termId = termId; this.updateCount = 1; this.verifyStatus = PENDING; } @@ -94,7 +94,7 @@ public Application( SiteUser siteUser, Gpa gpa, LanguageTest languageTest, - String term, + long termId, Integer updateCount, long firstChoiceUnivApplyInfoId, Long secondChoiceUnivApplyInfoId, @@ -103,7 +103,7 @@ public Application( this.siteUserId = siteUser.getId(); this.gpa = gpa; this.languageTest = languageTest; - this.term = term; + this.termId = termId; this.updateCount = updateCount; this.firstChoiceUnivApplyInfoId = firstChoiceUnivApplyInfoId; this.secondChoiceUnivApplyInfoId = secondChoiceUnivApplyInfoId; @@ -116,7 +116,7 @@ public Application( SiteUser siteUser, Gpa gpa, LanguageTest languageTest, - String term, + long termId, long firstChoiceUnivApplyInfoId, Long secondChoiceUnivApplyInfoId, Long thirdChoiceUnivApplyInfoId, @@ -124,7 +124,7 @@ public Application( this.siteUserId = siteUser.getId(); this.gpa = gpa; this.languageTest = languageTest; - this.term = term; + this.termId = termId; this.updateCount = 1; this.firstChoiceUnivApplyInfoId = firstChoiceUnivApplyInfoId; this.secondChoiceUnivApplyInfoId = secondChoiceUnivApplyInfoId; diff --git a/src/main/java/com/example/solidconnection/application/repository/ApplicationRepository.java b/src/main/java/com/example/solidconnection/application/repository/ApplicationRepository.java index 3916f37db..226e0f2b0 100644 --- a/src/main/java/com/example/solidconnection/application/repository/ApplicationRepository.java +++ b/src/main/java/com/example/solidconnection/application/repository/ApplicationRepository.java @@ -22,22 +22,22 @@ public interface ApplicationRepository extends JpaRepository OR a.secondChoiceUnivApplyInfoId IN :univApplyInfoIds OR a.thirdChoiceUnivApplyInfoId IN :univApplyInfoIds) AND a.verifyStatus = :status - AND a.term = :term + AND a.termId = :termId AND a.isDelete = false """) - List findAllByUnivApplyInfoIds(@Param("univApplyInfoIds") List univApplyInfoIds, @Param("status") VerifyStatus status, @Param("term") String term); + List findAllByUnivApplyInfoIds(@Param("univApplyInfoIds") List univApplyInfoIds, @Param("status") VerifyStatus status, @Param("termId") long termId); @Query(""" SELECT a FROM Application a WHERE a.siteUserId = :siteUserId - AND a.term = :term + AND a.termId = :termId AND a.isDelete = false """) - Optional findBySiteUserIdAndTerm(@Param("siteUserId") long siteUserId, @Param("term") String term); + Optional findBySiteUserIdAndTermId(@Param("siteUserId") long siteUserId, @Param("termId") long termId); - default Application getApplicationBySiteUserIdAndTerm(long siteUserId, String term) { - return findBySiteUserIdAndTerm(siteUserId, term) + default Application getApplicationBySiteUserIdAndTermId(long siteUserId, long termId) { + return findBySiteUserIdAndTermId(siteUserId, termId) .orElseThrow(() -> new CustomException(APPLICATION_NOT_FOUND)); } } diff --git a/src/main/java/com/example/solidconnection/application/service/ApplicationQueryService.java b/src/main/java/com/example/solidconnection/application/service/ApplicationQueryService.java index fef8c3b2b..60a495714 100644 --- a/src/main/java/com/example/solidconnection/application/service/ApplicationQueryService.java +++ b/src/main/java/com/example/solidconnection/application/service/ApplicationQueryService.java @@ -1,6 +1,7 @@ package com.example.solidconnection.application.service; import static com.example.solidconnection.common.exception.ErrorCode.APPLICATION_NOT_APPROVED; +import static com.example.solidconnection.common.exception.ErrorCode.CURRENT_TERM_NOT_FOUND; import static com.example.solidconnection.common.exception.ErrorCode.USER_NOT_FOUND; import com.example.solidconnection.application.domain.Application; @@ -11,6 +12,8 @@ import com.example.solidconnection.common.exception.CustomException; import com.example.solidconnection.siteuser.domain.SiteUser; import com.example.solidconnection.siteuser.repository.SiteUserRepository; +import com.example.solidconnection.term.domain.Term; +import com.example.solidconnection.term.repository.TermRepository; import com.example.solidconnection.university.domain.UnivApplyInfo; import com.example.solidconnection.university.repository.UnivApplyInfoRepository; import com.example.solidconnection.university.repository.custom.UnivApplyInfoFilterRepositoryImpl; @@ -24,7 +27,6 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -36,9 +38,7 @@ public class ApplicationQueryService { private final UnivApplyInfoRepository univApplyInfoRepository; private final UnivApplyInfoFilterRepositoryImpl universityFilterRepository; private final SiteUserRepository siteUserRepository; - - @Value("${university.term}") - public String term; + private final TermRepository termRepository; // todo: 캐싱 정책 변경 시 수정 필요 @Transactional(readOnly = true) @@ -47,15 +47,20 @@ public ApplicationsResponse getApplicants(long siteUserId, String regionCode, St SiteUser siteUser = siteUserRepository.findById(siteUserId) .orElseThrow(() -> new CustomException(USER_NOT_FOUND)); List keywords = StringUtils.isNotBlank(keyword) ? List.of(keyword) : List.of(); - List univApplyInfos = universityFilterRepository.findAllByRegionCodeAndKeywordsAndTerm(regionCode, keywords, term); + + Term term = termRepository.findByIsCurrentTrue() + .orElseThrow(() -> new CustomException(CURRENT_TERM_NOT_FOUND)); + + List univApplyInfos = universityFilterRepository.findAllByRegionCodeAndKeywordsAndTermId(regionCode, keywords, term.getId()); if (univApplyInfos.isEmpty()) { return new ApplicationsResponse(List.of(), List.of(), List.of()); } + // 2. 조건에 맞는 모든 Application 한 번에 조회 List univApplyInfoIds = univApplyInfos.stream() .map(UnivApplyInfo::getId) .toList(); - List applications = applicationRepository.findAllByUnivApplyInfoIds(univApplyInfoIds, VerifyStatus.APPROVED, term); + List applications = applicationRepository.findAllByUnivApplyInfoIds(univApplyInfoIds, VerifyStatus.APPROVED, term.getId()); // 3. 지원서 분류 및 DTO 변환 return classifyApplicationsByChoice(univApplyInfos, applications, siteUser); } @@ -64,7 +69,11 @@ public ApplicationsResponse getApplicants(long siteUserId, String regionCode, St public ApplicationsResponse getApplicantsByUserApplications(long siteUserId) { SiteUser siteUser = siteUserRepository.findById(siteUserId) .orElseThrow(() -> new CustomException(USER_NOT_FOUND)); - Application userLatestApplication = applicationRepository.getApplicationBySiteUserIdAndTerm(siteUser.getId(), term); + + Term term = termRepository.findByIsCurrentTrue() + .orElseThrow(() -> new CustomException(CURRENT_TERM_NOT_FOUND)); + + Application userLatestApplication = applicationRepository.getApplicationBySiteUserIdAndTermId(siteUser.getId(), term.getId()); List univApplyInfoIds = Stream.of( userLatestApplication.getFirstChoiceUnivApplyInfoId(), @@ -78,7 +87,7 @@ public ApplicationsResponse getApplicantsByUserApplications(long siteUserId) { return new ApplicationsResponse(List.of(), List.of(), List.of()); } - List applications = applicationRepository.findAllByUnivApplyInfoIds(univApplyInfoIds, VerifyStatus.APPROVED, term); + List applications = applicationRepository.findAllByUnivApplyInfoIds(univApplyInfoIds, VerifyStatus.APPROVED, term.getId()); List univApplyInfos = univApplyInfoRepository.findAllByIds(univApplyInfoIds); return classifyApplicationsByChoice(univApplyInfos, applications, siteUser); @@ -130,7 +139,11 @@ private List createUniversityApplicantsResponses( public void validateSiteUserCanViewApplicants(long siteUserId) { SiteUser siteUser = siteUserRepository.findById(siteUserId) .orElseThrow(() -> new CustomException(USER_NOT_FOUND)); - VerifyStatus verifyStatus = applicationRepository.getApplicationBySiteUserIdAndTerm(siteUser.getId(), term).getVerifyStatus(); + + Term term = termRepository.findByIsCurrentTrue() + .orElseThrow(() -> new CustomException(CURRENT_TERM_NOT_FOUND)); + + VerifyStatus verifyStatus = applicationRepository.getApplicationBySiteUserIdAndTermId(siteUser.getId(), term.getId()).getVerifyStatus(); if (verifyStatus != VerifyStatus.APPROVED) { throw new CustomException(APPLICATION_NOT_APPROVED); } diff --git a/src/main/java/com/example/solidconnection/application/service/ApplicationSubmissionService.java b/src/main/java/com/example/solidconnection/application/service/ApplicationSubmissionService.java index 4fd403d3a..3f0337aab 100644 --- a/src/main/java/com/example/solidconnection/application/service/ApplicationSubmissionService.java +++ b/src/main/java/com/example/solidconnection/application/service/ApplicationSubmissionService.java @@ -1,6 +1,7 @@ package com.example.solidconnection.application.service; import static com.example.solidconnection.common.exception.ErrorCode.APPLY_UPDATE_LIMIT_EXCEED; +import static com.example.solidconnection.common.exception.ErrorCode.CURRENT_TERM_NOT_FOUND; import static com.example.solidconnection.common.exception.ErrorCode.GPA_SCORE_NOT_FOUND; import static com.example.solidconnection.common.exception.ErrorCode.INVALID_GPA_SCORE_STATUS; import static com.example.solidconnection.common.exception.ErrorCode.INVALID_LANGUAGE_TEST_SCORE; @@ -20,9 +21,10 @@ import com.example.solidconnection.score.repository.LanguageTestScoreRepository; import com.example.solidconnection.siteuser.domain.SiteUser; import com.example.solidconnection.siteuser.repository.SiteUserRepository; +import com.example.solidconnection.term.domain.Term; +import com.example.solidconnection.term.repository.TermRepository; import java.util.Optional; import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -36,9 +38,7 @@ public class ApplicationSubmissionService { private final GpaScoreRepository gpaScoreRepository; private final LanguageTestScoreRepository languageTestScoreRepository; private final SiteUserRepository siteUserRepository; - - @Value("${university.term}") - private String term; + private final TermRepository termRepository; // 학점 및 어학성적이 모두 유효한 경우에만 지원서 등록이 가능하다. // 기존에 있던 status field 우선 APRROVED로 입력시킨다. @@ -49,12 +49,14 @@ public ApplicationSubmissionResponse apply(long siteUserId, ApplyRequest applyRe UnivApplyInfoChoiceRequest univApplyInfoChoiceRequest = applyRequest.univApplyInfoChoiceRequest(); GpaScore gpaScore = getValidGpaScore(siteUser, applyRequest.gpaScoreId()); LanguageTestScore languageTestScore = getValidLanguageTestScore(siteUser, applyRequest.languageTestScoreId()); + Term term = termRepository.findByIsCurrentTrue() + .orElseThrow(() -> new CustomException(CURRENT_TERM_NOT_FOUND)); long firstChoiceUnivApplyInfoId = univApplyInfoChoiceRequest.firstChoiceUnivApplyInfoId(); Long secondChoiceUnivApplyInfoId = univApplyInfoChoiceRequest.secondChoiceUnivApplyInfoId(); Long thirdChoiceUnivApplyInfoId = univApplyInfoChoiceRequest.thirdChoiceUnivApplyInfoId(); - Optional existingApplication = applicationRepository.findBySiteUserIdAndTerm(siteUser.getId(), term); + Optional existingApplication = applicationRepository.findBySiteUserIdAndTermId(siteUser.getId(), term.getId()); int updateCount = existingApplication .map(application -> { validateUpdateLimitNotExceed(application); @@ -67,7 +69,7 @@ public ApplicationSubmissionResponse apply(long siteUserId, ApplyRequest applyRe siteUser, gpaScore.getGpa(), languageTestScore.getLanguageTest(), - term, + term.getId(), updateCount, firstChoiceUnivApplyInfoId, secondChoiceUnivApplyInfoId, diff --git a/src/main/java/com/example/solidconnection/common/exception/ErrorCode.java b/src/main/java/com/example/solidconnection/common/exception/ErrorCode.java index f3de315b1..fae3c4980 100644 --- a/src/main/java/com/example/solidconnection/common/exception/ErrorCode.java +++ b/src/main/java/com/example/solidconnection/common/exception/ErrorCode.java @@ -48,6 +48,8 @@ public enum ErrorCode { CHAT_PARTNER_NOT_FOUND(HttpStatus.BAD_REQUEST.value(), "채팅 상대를 찾을 수 없습니다."), CHAT_PARTICIPANT_NOT_FOUND(HttpStatus.NOT_FOUND.value(), "채팅 참여자를 찾을 수 없습니다."), BLOCK_USER_NOT_FOUND(HttpStatus.NOT_FOUND.value(), "차단 대상 사용자를 찾을 수 없습니다."), + TERM_NOT_FOUND(HttpStatus.NOT_FOUND.value(), "존재하지 않는 학기입니다."), + CURRENT_TERM_NOT_FOUND(HttpStatus.NOT_FOUND.value(), "현재 학기를 찾을 수 없습니다."), // auth USER_ALREADY_SIGN_OUT(HttpStatus.UNAUTHORIZED.value(), "로그아웃 되었습니다."), diff --git a/src/main/java/com/example/solidconnection/mentor/domain/Mentor.java b/src/main/java/com/example/solidconnection/mentor/domain/Mentor.java index f38d083ca..420170236 100644 --- a/src/main/java/com/example/solidconnection/mentor/domain/Mentor.java +++ b/src/main/java/com/example/solidconnection/mentor/domain/Mentor.java @@ -45,8 +45,8 @@ public class Mentor extends BaseEntity { @Column private long universityId; - @Column(length = 50, nullable = false) - private String term; + @Column(nullable = false, name = "term_id") + private long termId; @BatchSize(size = 10) @OrderBy("sequence ASC") diff --git a/src/main/java/com/example/solidconnection/mentor/dto/MatchedMentorResponse.java b/src/main/java/com/example/solidconnection/mentor/dto/MatchedMentorResponse.java index c959ea083..fc3582ff3 100644 --- a/src/main/java/com/example/solidconnection/mentor/dto/MatchedMentorResponse.java +++ b/src/main/java/com/example/solidconnection/mentor/dto/MatchedMentorResponse.java @@ -27,7 +27,9 @@ public record MatchedMentorResponse( ) { public static MatchedMentorResponse of(Mentor mentor, SiteUser mentorUser, - University university, boolean isApplied, Long roomId) { + University university, boolean isApplied, Long roomId, + String termName + ) { return new MatchedMentorResponse( mentor.getId(), roomId, @@ -35,7 +37,7 @@ public static MatchedMentorResponse of(Mentor mentor, SiteUser mentorUser, mentorUser.getProfileImageUrl(), university.getCountry().getKoreanName(), university.getKoreanName(), - mentor.getTerm(), + termName, mentor.getMenteeCount(), mentor.isHasBadge(), mentor.getIntroduction(), diff --git a/src/main/java/com/example/solidconnection/mentor/dto/MentorDetailResponse.java b/src/main/java/com/example/solidconnection/mentor/dto/MentorDetailResponse.java index 6b5f04b0c..a65e784f0 100644 --- a/src/main/java/com/example/solidconnection/mentor/dto/MentorDetailResponse.java +++ b/src/main/java/com/example/solidconnection/mentor/dto/MentorDetailResponse.java @@ -21,14 +21,16 @@ public record MentorDetailResponse( ) { public static MentorDetailResponse of(Mentor mentor, SiteUser mentorUser, - University university, boolean isApplied) { + University university, boolean isApplied, + String termName + ) { return new MentorDetailResponse( mentor.getId(), mentorUser.getNickname(), mentorUser.getProfileImageUrl(), university.getCountry().getKoreanName(), university.getKoreanName(), - mentor.getTerm(), + termName, mentor.getMenteeCount(), mentor.isHasBadge(), mentor.getIntroduction(), diff --git a/src/main/java/com/example/solidconnection/mentor/dto/MentorMyPageResponse.java b/src/main/java/com/example/solidconnection/mentor/dto/MentorMyPageResponse.java index 2ae1acba7..4c5533ebb 100644 --- a/src/main/java/com/example/solidconnection/mentor/dto/MentorMyPageResponse.java +++ b/src/main/java/com/example/solidconnection/mentor/dto/MentorMyPageResponse.java @@ -19,14 +19,14 @@ public record MentorMyPageResponse( List channels ) { - public static MentorMyPageResponse of(Mentor mentor, SiteUser siteUser, University university) { + public static MentorMyPageResponse of(Mentor mentor, SiteUser siteUser, University university, String termName) { return new MentorMyPageResponse( mentor.getId(), siteUser.getProfileImageUrl(), siteUser.getNickname(), university.getCountry().getKoreanName(), university.getKoreanName(), - mentor.getTerm(), + termName, mentor.getMenteeCount(), mentor.isHasBadge(), mentor.getIntroduction(), diff --git a/src/main/java/com/example/solidconnection/mentor/dto/MentorPreviewResponse.java b/src/main/java/com/example/solidconnection/mentor/dto/MentorPreviewResponse.java index c6678fb53..e6a84d2eb 100644 --- a/src/main/java/com/example/solidconnection/mentor/dto/MentorPreviewResponse.java +++ b/src/main/java/com/example/solidconnection/mentor/dto/MentorPreviewResponse.java @@ -20,14 +20,16 @@ public record MentorPreviewResponse( ) { public static MentorPreviewResponse of(Mentor mentor, SiteUser mentorUser, - University university, boolean isApplied) { + University university, boolean isApplied, + String termName + ) { return new MentorPreviewResponse( mentor.getId(), mentorUser.getNickname(), mentorUser.getProfileImageUrl(), university.getCountry().getKoreanName(), university.getKoreanName(), - mentor.getTerm(), + termName, mentor.getMenteeCount(), mentor.isHasBadge(), mentor.getIntroduction(), diff --git a/src/main/java/com/example/solidconnection/mentor/repository/MentorBatchQueryRepository.java b/src/main/java/com/example/solidconnection/mentor/repository/MentorBatchQueryRepository.java index 0b01f3871..27d6a80d3 100644 --- a/src/main/java/com/example/solidconnection/mentor/repository/MentorBatchQueryRepository.java +++ b/src/main/java/com/example/solidconnection/mentor/repository/MentorBatchQueryRepository.java @@ -7,8 +7,11 @@ import com.example.solidconnection.mentor.domain.Mentoring; import com.example.solidconnection.siteuser.domain.SiteUser; import com.example.solidconnection.siteuser.repository.SiteUserRepository; +import com.example.solidconnection.term.domain.Term; +import com.example.solidconnection.term.repository.TermRepository; import com.example.solidconnection.university.domain.University; import com.example.solidconnection.university.repository.UniversityRepository; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; @@ -24,6 +27,7 @@ public class MentorBatchQueryRepository { // 연관관계가 설정되지 않은 private final SiteUserRepository siteUserRepository; private final MentoringRepository mentoringRepository; private final UniversityRepository universityRepository; + private final TermRepository termRepository; public Map getMentorIdToSiteUserMap(List mentors) { List mentorUserIds = mentors.stream().map(Mentor::getSiteUserId).toList(); @@ -73,4 +77,17 @@ public Map getMentorIdToIsApplied(List mentors, long curr mentor -> appliedMentorIds.contains(mentor.getId()) )); } + + public Map getTermIdToNameMap(List mentors) { + if (mentors.isEmpty()) { + return Collections.emptyMap(); + } + + Set termIds = mentors.stream() + .map(Mentor::getTermId) + .collect(Collectors.toSet()); + + return termRepository.findAllById(termIds).stream() + .collect(Collectors.toMap(Term::getId, Term::getName)); + } } diff --git a/src/main/java/com/example/solidconnection/mentor/service/MentorMyPageService.java b/src/main/java/com/example/solidconnection/mentor/service/MentorMyPageService.java index 18e63a6fb..810891b2b 100644 --- a/src/main/java/com/example/solidconnection/mentor/service/MentorMyPageService.java +++ b/src/main/java/com/example/solidconnection/mentor/service/MentorMyPageService.java @@ -2,6 +2,7 @@ import static com.example.solidconnection.common.exception.ErrorCode.CHANNEL_REGISTRATION_LIMIT_EXCEEDED; import static com.example.solidconnection.common.exception.ErrorCode.MENTOR_NOT_FOUND; +import static com.example.solidconnection.common.exception.ErrorCode.TERM_NOT_FOUND; import static com.example.solidconnection.common.exception.ErrorCode.UNIVERSITY_NOT_FOUND; import static com.example.solidconnection.common.exception.ErrorCode.USER_NOT_FOUND; @@ -14,6 +15,8 @@ import com.example.solidconnection.mentor.repository.MentorRepository; import com.example.solidconnection.siteuser.domain.SiteUser; import com.example.solidconnection.siteuser.repository.SiteUserRepository; +import com.example.solidconnection.term.domain.Term; +import com.example.solidconnection.term.repository.TermRepository; import com.example.solidconnection.university.domain.University; import com.example.solidconnection.university.repository.UniversityRepository; import java.util.ArrayList; @@ -32,6 +35,7 @@ public class MentorMyPageService { private final MentorRepository mentorRepository; private final SiteUserRepository siteUserRepository; private final UniversityRepository universityRepository; + private final TermRepository termRepository; @Transactional(readOnly = true) public MentorMyPageResponse getMentorMyPage(long siteUserId) { @@ -39,9 +43,11 @@ public MentorMyPageResponse getMentorMyPage(long siteUserId) { .orElseThrow(() -> new CustomException(USER_NOT_FOUND)); Mentor mentor = mentorRepository.findBySiteUserId(siteUser.getId()) .orElseThrow(() -> new CustomException(MENTOR_NOT_FOUND)); + Term term = termRepository.findById(mentor.getTermId()) + .orElseThrow(() -> new CustomException(TERM_NOT_FOUND)); University university = universityRepository.findById(mentor.getUniversityId()) .orElseThrow(() -> new CustomException(UNIVERSITY_NOT_FOUND)); - return MentorMyPageResponse.of(mentor, siteUser, university); + return MentorMyPageResponse.of(mentor, siteUser, university, term.getName()); } @Transactional diff --git a/src/main/java/com/example/solidconnection/mentor/service/MentorQueryService.java b/src/main/java/com/example/solidconnection/mentor/service/MentorQueryService.java index 16b7172d1..a66b8d45d 100644 --- a/src/main/java/com/example/solidconnection/mentor/service/MentorQueryService.java +++ b/src/main/java/com/example/solidconnection/mentor/service/MentorQueryService.java @@ -1,6 +1,7 @@ package com.example.solidconnection.mentor.service; import static com.example.solidconnection.common.exception.ErrorCode.MENTOR_NOT_FOUND; +import static com.example.solidconnection.common.exception.ErrorCode.TERM_NOT_FOUND; import static com.example.solidconnection.common.exception.ErrorCode.UNIVERSITY_NOT_FOUND; import com.example.solidconnection.common.dto.SliceResponse; @@ -16,6 +17,8 @@ import com.example.solidconnection.mentor.repository.MentoringRepository; import com.example.solidconnection.siteuser.domain.SiteUser; import com.example.solidconnection.siteuser.repository.SiteUserRepository; +import com.example.solidconnection.term.domain.Term; +import com.example.solidconnection.term.repository.TermRepository; import com.example.solidconnection.university.domain.University; import com.example.solidconnection.university.repository.UniversityRepository; import java.util.ArrayList; @@ -37,6 +40,7 @@ public class MentorQueryService { private final MentorBatchQueryRepository mentorBatchQueryRepository; private final UniversityRepository universityRepository; private final RegionRepository regionRepository; + private final TermRepository termRepository; @Transactional(readOnly = true) public MentorDetailResponse getMentorDetails(long mentorId, long currentUserId) { @@ -46,9 +50,11 @@ public MentorDetailResponse getMentorDetails(long mentorId, long currentUserId) .orElseThrow(() -> new CustomException(UNIVERSITY_NOT_FOUND)); SiteUser mentorUser = siteUserRepository.findById(mentor.getSiteUserId()) .orElseThrow(() -> new CustomException(MENTOR_NOT_FOUND)); + Term term = termRepository.findById(mentor.getTermId()) + .orElseThrow(() -> new CustomException(TERM_NOT_FOUND)); boolean isApplied = mentoringRepository.existsByMentorIdAndMenteeId(mentorId, currentUserId); - return MentorDetailResponse.of(mentor, mentorUser, university, isApplied); + return MentorDetailResponse.of(mentor, mentorUser, university, isApplied, term.getName()); } @Transactional(readOnly = true) @@ -73,13 +79,15 @@ private List buildMentorPreviewsWithBatchQuery(List mentorIdToSiteUser = mentorBatchQueryRepository.getMentorIdToSiteUserMap(mentors); Map mentorIdToUniversity = mentorBatchQueryRepository.getMentorIdToUniversityMap(mentors); Map mentorIdToIsApplied = mentorBatchQueryRepository.getMentorIdToIsApplied(mentors, currentUserId); + Map termIdToName = mentorBatchQueryRepository.getTermIdToNameMap(mentors); List mentorPreviews = new ArrayList<>(); for (Mentor mentor : mentors) { SiteUser mentorUser = mentorIdToSiteUser.get(mentor.getId()); University university = mentorIdToUniversity.get(mentor.getId()); boolean isApplied = mentorIdToIsApplied.get(mentor.getId()); - MentorPreviewResponse response = MentorPreviewResponse.of(mentor, mentorUser, university, isApplied); + String termName = termIdToName.get(mentor.getTermId()); + MentorPreviewResponse response = MentorPreviewResponse.of(mentor, mentorUser, university, isApplied, termName); mentorPreviews.add(response); } return mentorPreviews; diff --git a/src/main/java/com/example/solidconnection/mentor/service/MentoringQueryService.java b/src/main/java/com/example/solidconnection/mentor/service/MentoringQueryService.java index 57753f983..ad57d83ad 100644 --- a/src/main/java/com/example/solidconnection/mentor/service/MentoringQueryService.java +++ b/src/main/java/com/example/solidconnection/mentor/service/MentoringQueryService.java @@ -60,6 +60,7 @@ private List buildMatchedMentorsWithBatchQuery(List mentorIdToSiteUser = mentorBatchQueryRepository.getMentorIdToSiteUserMap(mentors); Map mentorIdToUniversity = mentorBatchQueryRepository.getMentorIdToUniversityMap(mentors); Map mentorIdToIsApplied = mentorBatchQueryRepository.getMentorIdToIsApplied(mentors, currentUserId); + Map termIdToName = mentorBatchQueryRepository.getTermIdToNameMap(mentors); Map mentorIdToRoomId = getMentorIdToRoomIdMap(mentors, currentUserId); @@ -69,7 +70,9 @@ private List buildMatchedMentorsWithBatchQuery(List { + + Optional findByIsCurrentTrue(); +} diff --git a/src/main/java/com/example/solidconnection/university/controller/UnivApplyInfoController.java b/src/main/java/com/example/solidconnection/university/controller/UnivApplyInfoController.java index fab050079..0a258ef12 100644 --- a/src/main/java/com/example/solidconnection/university/controller/UnivApplyInfoController.java +++ b/src/main/java/com/example/solidconnection/university/controller/UnivApplyInfoController.java @@ -13,7 +13,6 @@ import jakarta.validation.Valid; import java.util.List; import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Value; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; @@ -33,9 +32,6 @@ public class UnivApplyInfoController { private final LikedUnivApplyInfoService likedUnivApplyInfoService; private final UnivApplyInfoRecommendService univApplyInfoRecommendService; - @Value("${university.term}") - public String term; - @GetMapping("/recommend") public ResponseEntity getUnivApplyInfoRecommends( @AuthorizedUser(required = false) Long siteUserId @@ -95,7 +91,7 @@ public ResponseEntity getUnivApplyInfoDetails( public ResponseEntity searchUnivApplyInfoByFilter( @Valid @ModelAttribute UnivApplyInfoFilterSearchRequest request ) { - UnivApplyInfoPreviewResponses response = univApplyInfoQueryService.searchUnivApplyInfoByFilter(request, term); + UnivApplyInfoPreviewResponses response = univApplyInfoQueryService.searchUnivApplyInfoByFilter(request); return ResponseEntity.ok(response); } @@ -103,7 +99,7 @@ public ResponseEntity searchUnivApplyInfoByFilter public ResponseEntity searchUnivApplyInfoByText( @RequestParam(required = false) String value ) { - UnivApplyInfoPreviewResponses response = univApplyInfoQueryService.searchUnivApplyInfoByText(value, term); + UnivApplyInfoPreviewResponses response = univApplyInfoQueryService.searchUnivApplyInfoByText(value); return ResponseEntity.ok(response); } } diff --git a/src/main/java/com/example/solidconnection/university/domain/UnivApplyInfo.java b/src/main/java/com/example/solidconnection/university/domain/UnivApplyInfo.java index 960a1c32f..7d2fe526d 100644 --- a/src/main/java/com/example/solidconnection/university/domain/UnivApplyInfo.java +++ b/src/main/java/com/example/solidconnection/university/domain/UnivApplyInfo.java @@ -33,8 +33,8 @@ public class UnivApplyInfo extends BaseEntity { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @Column(length = 50, nullable = false) - private String term; + @Column(nullable = false, name = "term_id") + private long termId; @Column(nullable = false, length = 100) private String koreanName; diff --git a/src/main/java/com/example/solidconnection/university/dto/UnivApplyInfoDetailResponse.java b/src/main/java/com/example/solidconnection/university/dto/UnivApplyInfoDetailResponse.java index 481629f24..9d4fa3bbf 100644 --- a/src/main/java/com/example/solidconnection/university/dto/UnivApplyInfoDetailResponse.java +++ b/src/main/java/com/example/solidconnection/university/dto/UnivApplyInfoDetailResponse.java @@ -34,10 +34,12 @@ public record UnivApplyInfoDetailResponse( public static UnivApplyInfoDetailResponse of( University university, - UnivApplyInfo univApplyInfo) { + UnivApplyInfo univApplyInfo, + String termName + ) { return new UnivApplyInfoDetailResponse( univApplyInfo.getId(), - univApplyInfo.getTerm(), + termName, univApplyInfo.getKoreanName(), university.getEnglishName(), university.getFormatName(), diff --git a/src/main/java/com/example/solidconnection/university/dto/UnivApplyInfoPreviewResponse.java b/src/main/java/com/example/solidconnection/university/dto/UnivApplyInfoPreviewResponse.java index 0c6badbfd..37deee8f2 100644 --- a/src/main/java/com/example/solidconnection/university/dto/UnivApplyInfoPreviewResponse.java +++ b/src/main/java/com/example/solidconnection/university/dto/UnivApplyInfoPreviewResponse.java @@ -1,6 +1,7 @@ package com.example.solidconnection.university.dto; import com.example.solidconnection.university.domain.UnivApplyInfo; +import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -15,8 +16,8 @@ public record UnivApplyInfoPreviewResponse( int studentCapacity, List languageRequirements) { - public static UnivApplyInfoPreviewResponse from(UnivApplyInfo univApplyInfo) { - List languageRequirementResponses = new java.util.ArrayList<>( + public static UnivApplyInfoPreviewResponse from(UnivApplyInfo univApplyInfo, String termName) { + List languageRequirementResponses = new ArrayList<>( univApplyInfo.getLanguageRequirements().stream() .map(LanguageRequirementResponse::from) .toList()); @@ -24,7 +25,7 @@ public static UnivApplyInfoPreviewResponse from(UnivApplyInfo univApplyInfo) { return new UnivApplyInfoPreviewResponse( univApplyInfo.getId(), - univApplyInfo.getTerm(), + termName, univApplyInfo.getKoreanName(), univApplyInfo.getUniversity().getRegion().getKoreanName(), univApplyInfo.getUniversity().getCountry().getKoreanName(), diff --git a/src/main/java/com/example/solidconnection/university/repository/UnivApplyInfoRepository.java b/src/main/java/com/example/solidconnection/university/repository/UnivApplyInfoRepository.java index b51ce5a89..5bb56cfc0 100644 --- a/src/main/java/com/example/solidconnection/university/repository/UnivApplyInfoRepository.java +++ b/src/main/java/com/example/solidconnection/university/repository/UnivApplyInfoRepository.java @@ -32,9 +32,9 @@ OR r.code IN ( FROM InterestedRegion ir WHERE ir.siteUserId = :siteUserId )) - AND uai.term = :term + AND uai.termId = :termId """) - List findAllBySiteUsersInterestedCountryOrRegionAndTerm(@Param("siteUserId") Long siteUserId, @Param("term") String term); + List findAllBySiteUsersInterestedCountryOrRegionAndTermId(@Param("siteUserId") Long siteUserId, @Param("termId") long termId); @Query(""" SELECT uai @@ -43,10 +43,10 @@ OR r.code IN ( LEFT JOIN FETCH uai.university u LEFT JOIN FETCH u.country c LEFT JOIN FETCH u.region r - WHERE uai.term = :term + WHERE uai.termId = :termId ORDER BY FUNCTION('RAND') """) - List findRandomByTerm(@Param("term") String term, Pageable pageable); // JPA에서 LIMIT 사용이 불가하므로 Pageable을 통해 0page에서 정해진 개수 만큼 가져오는 방식으로 구현 + List findRandomByTermId(@Param("termId") long termId, Pageable pageable); // JPA에서 LIMIT 사용이 불가하므로 Pageable을 통해 0page에서 정해진 개수 만큼 가져오는 방식으로 구현 default UnivApplyInfo getUnivApplyInfoById(Long id) { return findById(id) diff --git a/src/main/java/com/example/solidconnection/university/repository/custom/UnivApplyInfoFilterRepository.java b/src/main/java/com/example/solidconnection/university/repository/custom/UnivApplyInfoFilterRepository.java index 9efeaee17..5e2a0b906 100644 --- a/src/main/java/com/example/solidconnection/university/repository/custom/UnivApplyInfoFilterRepository.java +++ b/src/main/java/com/example/solidconnection/university/repository/custom/UnivApplyInfoFilterRepository.java @@ -6,9 +6,9 @@ public interface UnivApplyInfoFilterRepository { - List findAllByRegionCodeAndKeywordsAndTerm(String regionCode, List keywords, String term); + List findAllByRegionCodeAndKeywordsAndTermId(String regionCode, List keywords, Long term); - List findAllByFilter(LanguageTestType testType, String testScore, String term, List countryKoreanNames); + List findAllByFilter(LanguageTestType testType, String testScore, Long termId, List countryKoreanNames); - List findAllByText(String text, String term); + List findAllByText(String text, Long termId); } diff --git a/src/main/java/com/example/solidconnection/university/repository/custom/UnivApplyInfoFilterRepositoryImpl.java b/src/main/java/com/example/solidconnection/university/repository/custom/UnivApplyInfoFilterRepositoryImpl.java index 0935933df..7e8da9e40 100644 --- a/src/main/java/com/example/solidconnection/university/repository/custom/UnivApplyInfoFilterRepositoryImpl.java +++ b/src/main/java/com/example/solidconnection/university/repository/custom/UnivApplyInfoFilterRepositoryImpl.java @@ -31,7 +31,7 @@ public UnivApplyInfoFilterRepositoryImpl(EntityManager em) { } @Override - public List findAllByRegionCodeAndKeywordsAndTerm(String regionCode, List keywords, String term) { + public List findAllByRegionCodeAndKeywordsAndTermId(String regionCode, List keywords, Long termId) { QUnivApplyInfo univApplyInfo = QUnivApplyInfo.univApplyInfo; QUniversity university = QUniversity.university; QCountry country = QCountry.country; @@ -45,7 +45,7 @@ public List findAllByRegionCodeAndKeywordsAndTerm(String regionCo .where( regionCodeEq(country, regionCode) .and(countryOrUniversityContainsKeyword(country, university, keywords)) - .and(univApplyInfo.term.eq(term)) + .and(univApplyInfo.termId.eq(termId)) ) .distinct() .fetch(); @@ -76,7 +76,7 @@ private BooleanExpression createKeywordCondition(StringPath namePath, List findAllByFilter( - LanguageTestType testType, String testScore, String term, List countryCodes + LanguageTestType testType, String testScore, Long termId, List countryCodes ) { QUniversity university = QUniversity.university; QUnivApplyInfo univApplyInfo = QUnivApplyInfo.univApplyInfo; @@ -90,7 +90,7 @@ public List findAllByFilter( .fetchJoin() .where( languageTestTypeEq(languageRequirement, testType), - termEq(univApplyInfo, term), + termIdEq(univApplyInfo, termId), countryCodesIn(country, countryCodes) ) .distinct() @@ -119,11 +119,11 @@ private BooleanExpression languageTestTypeEq( return languageRequirement.languageTestType.eq(givenTestType); } - private BooleanExpression termEq(QUnivApplyInfo univApplyInfo, String givenTerm) { - if (givenTerm == null || givenTerm.isBlank()) { + private BooleanExpression termIdEq(QUnivApplyInfo univApplyInfo, Long givenTermId) { + if (givenTermId == null) { return null; } - return univApplyInfo.term.eq(givenTerm); + return univApplyInfo.termId.eq(givenTermId); } private BooleanExpression countryCodesIn(QCountry country, List givenCountryCodes) { @@ -144,7 +144,7 @@ private boolean isGivenScoreOverMinPassScore( } @Override - public List findAllByText(String text, String term) { + public List findAllByText(String text, Long termId) { QUnivApplyInfo univApplyInfo = QUnivApplyInfo.univApplyInfo; QUniversity university = QUniversity.university; QLanguageRequirement languageRequirement = QLanguageRequirement.languageRequirement; @@ -156,7 +156,7 @@ public List findAllByText(String text, String term) { .join(university.country, country).fetchJoin() .join(region).on(country.regionCode.eq(region.code)) .leftJoin(univApplyInfo.languageRequirements, languageRequirement).fetchJoin() - .where(termEq(univApplyInfo, term)); + .where(termIdEq(univApplyInfo, termId)); // text 가 비어있다면 모든 대학 지원 정보를 id 오름차순으로 정렬하여 반환 if (text == null || text.isBlank()) { diff --git a/src/main/java/com/example/solidconnection/university/service/GeneralUnivApplyInfoRecommendService.java b/src/main/java/com/example/solidconnection/university/service/GeneralUnivApplyInfoRecommendService.java index 627e579a3..d115098dd 100644 --- a/src/main/java/com/example/solidconnection/university/service/GeneralUnivApplyInfoRecommendService.java +++ b/src/main/java/com/example/solidconnection/university/service/GeneralUnivApplyInfoRecommendService.java @@ -1,13 +1,16 @@ package com.example.solidconnection.university.service; +import static com.example.solidconnection.common.exception.ErrorCode.CURRENT_TERM_NOT_FOUND; import static com.example.solidconnection.university.service.UnivApplyInfoRecommendService.RECOMMEND_UNIV_APPLY_INFO_NUM; +import com.example.solidconnection.common.exception.CustomException; +import com.example.solidconnection.term.domain.Term; +import com.example.solidconnection.term.repository.TermRepository; import com.example.solidconnection.university.domain.UnivApplyInfo; import com.example.solidconnection.university.repository.UnivApplyInfoRepository; import java.util.List; import lombok.Getter; import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.context.event.EventListener; import org.springframework.data.domain.PageRequest; @@ -22,16 +25,16 @@ public class GeneralUnivApplyInfoRecommendService { * 해당 시기에 열리는 대학교들 중 랜덤으로 선택해서 목록을 구성한다. * */ private final UnivApplyInfoRepository univApplyInfoRepository; + private final TermRepository termRepository; @Getter private List generalRecommends; - @Value("${university.term}") - public String term; - @EventListener(ApplicationReadyEvent.class) public void init() { - Pageable page = PageRequest.of(0, RECOMMEND_UNIV_APPLY_INFO_NUM); - generalRecommends = univApplyInfoRepository.findRandomByTerm(term, page); + termRepository.findByIsCurrentTrue().ifPresent(term -> { + Pageable page = PageRequest.of(0, RECOMMEND_UNIV_APPLY_INFO_NUM); + generalRecommends = univApplyInfoRepository.findRandomByTermId(term.getId(), page); + }); } } diff --git a/src/main/java/com/example/solidconnection/university/service/LikedUnivApplyInfoService.java b/src/main/java/com/example/solidconnection/university/service/LikedUnivApplyInfoService.java index 0c6e06d21..c353edaf0 100644 --- a/src/main/java/com/example/solidconnection/university/service/LikedUnivApplyInfoService.java +++ b/src/main/java/com/example/solidconnection/university/service/LikedUnivApplyInfoService.java @@ -4,6 +4,8 @@ import static com.example.solidconnection.common.exception.ErrorCode.NOT_LIKED_UNIV_APPLY_INFO; import com.example.solidconnection.common.exception.CustomException; +import com.example.solidconnection.term.domain.Term; +import com.example.solidconnection.term.repository.TermRepository; import com.example.solidconnection.university.domain.LikedUnivApplyInfo; import com.example.solidconnection.university.domain.UnivApplyInfo; import com.example.solidconnection.university.dto.IsLikeResponse; @@ -11,7 +13,10 @@ import com.example.solidconnection.university.repository.LikedUnivApplyInfoRepository; import com.example.solidconnection.university.repository.UnivApplyInfoRepository; import java.util.List; +import java.util.Map; import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; @@ -23,9 +28,7 @@ public class LikedUnivApplyInfoService { private final UnivApplyInfoRepository univApplyInfoRepository; private final LikedUnivApplyInfoRepository likedUnivApplyInfoRepository; - - @Value("${university.term}") - public String term; + private final TermRepository termRepository; /* * '좋아요'한 대학교 목록을 조회한다. @@ -33,8 +36,18 @@ public class LikedUnivApplyInfoService { @Transactional(readOnly = true) public List getLikedUnivApplyInfos(long siteUserId) { List univApplyInfos = likedUnivApplyInfoRepository.findUnivApplyInfosBySiteUserId(siteUserId); + Set termIds = univApplyInfos.stream() + .map(UnivApplyInfo::getTermId) + .collect(Collectors.toSet()); + + Map termMap = termRepository.findAllById(termIds).stream() + .collect(Collectors.toMap(Term::getId, Term::getName)); + return univApplyInfos.stream() - .map(UnivApplyInfoPreviewResponse::from) + .map(univApplyInfo -> { + String termName = termMap.getOrDefault(univApplyInfo.getTermId(), "Unknown"); + return UnivApplyInfoPreviewResponse.from(univApplyInfo, termName); + }) .toList(); } diff --git a/src/main/java/com/example/solidconnection/university/service/UnivApplyInfoQueryService.java b/src/main/java/com/example/solidconnection/university/service/UnivApplyInfoQueryService.java index bf6ec089a..c7713fd27 100644 --- a/src/main/java/com/example/solidconnection/university/service/UnivApplyInfoQueryService.java +++ b/src/main/java/com/example/solidconnection/university/service/UnivApplyInfoQueryService.java @@ -1,6 +1,12 @@ package com.example.solidconnection.university.service; +import static com.example.solidconnection.common.exception.ErrorCode.CURRENT_TERM_NOT_FOUND; +import static com.example.solidconnection.common.exception.ErrorCode.TERM_NOT_FOUND; + import com.example.solidconnection.cache.annotation.ThunderingHerdCaching; +import com.example.solidconnection.common.exception.CustomException; +import com.example.solidconnection.term.domain.Term; +import com.example.solidconnection.term.repository.TermRepository; import com.example.solidconnection.university.domain.UnivApplyInfo; import com.example.solidconnection.university.domain.University; import com.example.solidconnection.university.dto.UnivApplyInfoDetailResponse; @@ -18,37 +24,52 @@ public class UnivApplyInfoQueryService { private final UnivApplyInfoRepository univApplyInfoRepository; + private final TermRepository termRepository; /* * 대학교 상세 정보를 불러온다. * - 대학교(University) 정보와 대학 지원 정보(UniversityInfoForApply) 정보를 조합하여 반환한다. * */ @Transactional(readOnly = true) - @ThunderingHerdCaching(key = "univApplyInfo:{0}:{1}", cacheManager = "customCacheManager", ttlSec = 86400) + @ThunderingHerdCaching(key = "univApplyInfo:{0}", cacheManager = "customCacheManager", ttlSec = 86400) public UnivApplyInfoDetailResponse getUnivApplyInfoDetail(Long univApplyInfoId) { UnivApplyInfo univApplyInfo = univApplyInfoRepository.getUnivApplyInfoById(univApplyInfoId); University university = univApplyInfo.getUniversity(); - return UnivApplyInfoDetailResponse.of(university, univApplyInfo); + Term term = termRepository.findById(univApplyInfo.getTermId()) + .orElseThrow(() -> new CustomException(TERM_NOT_FOUND)); + return UnivApplyInfoDetailResponse.of(university, univApplyInfo, term.getName()); } @Transactional(readOnly = true) - public UnivApplyInfoPreviewResponses searchUnivApplyInfoByFilter(UnivApplyInfoFilterSearchRequest request, String term) { + public UnivApplyInfoPreviewResponses searchUnivApplyInfoByFilter(UnivApplyInfoFilterSearchRequest request) { + Term term = termRepository.findByIsCurrentTrue() + .orElseThrow(() -> new CustomException(CURRENT_TERM_NOT_FOUND)); + List responses = univApplyInfoRepository - .findAllByFilter(request.languageTestType(), request.testScore(), term, request.countryCode()) + .findAllByFilter(request.languageTestType(), request.testScore(), term.getId(), request.countryCode()) .stream() - .map(UnivApplyInfoPreviewResponse::from) + .map(univApplyInfo -> UnivApplyInfoPreviewResponse.from( + univApplyInfo, + term.getName() + )) .toList(); return new UnivApplyInfoPreviewResponses(responses); } @Transactional(readOnly = true) - @ThunderingHerdCaching(key = "univApplyInfoTextSearch:{0}:{1}", cacheManager = "customCacheManager", ttlSec = 86400) - public UnivApplyInfoPreviewResponses searchUnivApplyInfoByText(String text, String term) { - List responses = univApplyInfoRepository.findAllByText(text, term) + @ThunderingHerdCaching(key = "univApplyInfoTextSearch:{0}", cacheManager = "customCacheManager", ttlSec = 86400) + public UnivApplyInfoPreviewResponses searchUnivApplyInfoByText(String text) { + Term term = termRepository.findByIsCurrentTrue() + .orElseThrow(() -> new CustomException(CURRENT_TERM_NOT_FOUND)); + + List responses = univApplyInfoRepository.findAllByText(text, term.getId()) .stream() - .map(UnivApplyInfoPreviewResponse::from) + .map(univApplyInfo -> UnivApplyInfoPreviewResponse.from( + univApplyInfo, + term.getName() + )) .toList(); return new UnivApplyInfoPreviewResponses(responses); } diff --git a/src/main/java/com/example/solidconnection/university/service/UnivApplyInfoRecommendService.java b/src/main/java/com/example/solidconnection/university/service/UnivApplyInfoRecommendService.java index 3baeff9f6..a6a2b85fc 100644 --- a/src/main/java/com/example/solidconnection/university/service/UnivApplyInfoRecommendService.java +++ b/src/main/java/com/example/solidconnection/university/service/UnivApplyInfoRecommendService.java @@ -1,6 +1,11 @@ package com.example.solidconnection.university.service; +import static com.example.solidconnection.common.exception.ErrorCode.CURRENT_TERM_NOT_FOUND; + import com.example.solidconnection.cache.annotation.ThunderingHerdCaching; +import com.example.solidconnection.common.exception.CustomException; +import com.example.solidconnection.term.domain.Term; +import com.example.solidconnection.term.repository.TermRepository; import com.example.solidconnection.university.domain.UnivApplyInfo; import com.example.solidconnection.university.dto.UnivApplyInfoPreviewResponse; import com.example.solidconnection.university.dto.UnivApplyInfoRecommendsResponse; @@ -9,7 +14,6 @@ import java.util.Collections; import java.util.List; import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -20,11 +24,9 @@ public class UnivApplyInfoRecommendService { public static final int RECOMMEND_UNIV_APPLY_INFO_NUM = 6; private final UnivApplyInfoRepository univApplyInfoRepository; + private final TermRepository termRepository; private final GeneralUnivApplyInfoRecommendService generalUnivApplyInfoRecommendService; - @Value("${university.term}") - private String term; - /* * 사용자 맞춤 추천 대학교를 불러온다. * - 회원가입 시 선택한 관심 지역과 관심 국가에 해당하는 대학 중, 이번 term 에 열리는 학교들을 불러온다. @@ -33,9 +35,12 @@ public class UnivApplyInfoRecommendService { * */ @Transactional(readOnly = true) public UnivApplyInfoRecommendsResponse getPersonalRecommends(long siteUserId) { + Term term = termRepository.findByIsCurrentTrue() + .orElseThrow(() -> new CustomException(CURRENT_TERM_NOT_FOUND)); + // 맞춤 추천 대학교를 불러온다. List personalRecommends = univApplyInfoRepository - .findAllBySiteUsersInterestedCountryOrRegionAndTerm(siteUserId, term); + .findAllBySiteUsersInterestedCountryOrRegionAndTermId(siteUserId, term.getId()); List trimmedRecommends = personalRecommends.subList(0, Math.min(RECOMMEND_UNIV_APPLY_INFO_NUM, personalRecommends.size())); Collections.shuffle(trimmedRecommends); @@ -46,7 +51,10 @@ public UnivApplyInfoRecommendsResponse getPersonalRecommends(long siteUserId) { } return new UnivApplyInfoRecommendsResponse(trimmedRecommends.stream() - .map(UnivApplyInfoPreviewResponse::from) + .map(univApplyInfo -> UnivApplyInfoPreviewResponse.from( + univApplyInfo, + term.getName() + )) .toList()); } @@ -64,9 +72,15 @@ private List getGeneralRecommendsExcludingSelected(List new CustomException(CURRENT_TERM_NOT_FOUND)); + List generalRecommends = new ArrayList<>(generalUnivApplyInfoRecommendService.getGeneralRecommends()); return new UnivApplyInfoRecommendsResponse(generalRecommends.stream() - .map(UnivApplyInfoPreviewResponse::from) + .map(univApplyInfo -> UnivApplyInfoPreviewResponse.from( + univApplyInfo, + term.getName() + )) .toList()); } } diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql index 433ccb209..3e17fb27c 100644 --- a/src/main/resources/data.sql +++ b/src/main/resources/data.sql @@ -41,6 +41,8 @@ VALUES ('BN', '브루나이', 'ASIA'), ('MY', '말레이시아', 'ASIA'), ('RU', '러시아', 'EUROPE'); +INSERT INTO term (name, is_current) VALUES ('2024-1', true); + INSERT INTO site_user (email, nickname, profile_image_url, exchange_status, role, password, auth_type) VALUES ('test@test.email', 'yonso', 'https://github.com/nayonsoso.png', 'CONSIDERING', 'MENTEE', @@ -144,81 +146,81 @@ VALUES (1, 'US', 'AMERICAS', 'University of Guam', 'university_of_guam', '괌대 'https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/bunkyo_gakuin_university/logo.png', 'https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/bunkyo_gakuin_university/1.png'); -INSERT INTO university_info_for_apply(term, university_id, korean_name, semester_requirement, student_capacity, +INSERT INTO university_info_for_apply(term_id, university_id, korean_name, semester_requirement, student_capacity, semester_available_for_dispatch, tuition_fee_type, details_for_major, details_for_apply, details_for_language, details_for_english_course, details_for_accommodation, details) -VALUES ('2024-1', 1, '괌대학(A형)', 2, 1, 'IRRELEVANT', 'HOME_UNIVERSITY_PAYMENT', '파견대학에 지원하는 전공과 본교 전공이 일치해야함', NULL, +VALUES (1, 1, '괌대학(A형)', 2, 1, 'IRRELEVANT', 'HOME_UNIVERSITY_PAYMENT', '파견대학에 지원하는 전공과 본교 전공이 일치해야함', NULL, '외국어 성적 유효기간이 파견대학의 지원시까지 유효해야함', NULL, NULL, NULL), - ('2024-1', 1, '괌대학(B형)', 2, 2, 'IRRELEVANT', 'OVERSEAS_UNIVERSITY_PAYMENT', '파견대학에 지원하는 전공과 본교 전공이 일치해야함', NULL, + (1, 1, '괌대학(B형)', 2, 2, 'IRRELEVANT', 'OVERSEAS_UNIVERSITY_PAYMENT', '파견대학에 지원하는 전공과 본교 전공이 일치해야함', NULL, '외국어 성적 유효기간이 파견대학의 지원시까지 유효해야함', NULL, NULL, '등록금 관련 정보: https://www.uog.edu/financial-aid/cost-to-attend'), - ('2024-1', 2, '네바다주립대학 라스베이거스(B형)', 2, 5, 'IRRELEVANT', 'OVERSEAS_UNIVERSITY_PAYMENT', + (1, 2, '네바다주립대학 라스베이거스(B형)', 2, 5, 'IRRELEVANT', 'OVERSEAS_UNIVERSITY_PAYMENT', '- 지원가능전공: 공학계열 관련 전공자
- 파견대학에 지원하는 전공과 본교 전공이 일치해야함', NULL, '영어 점수는 다음의 세부영역 점수를 각각 만족해야 함
- IELTS : 모든 영역에서 5.5 이상', NULL, NULL, ' - The Engineering International Programs (EIP) Programs 안의 글로벌 하이브리드 프로그램으로 선발됨
※ 하이브리드 프로그램: 정규 과목 + 비정규 General Education Courses 과목 수강으로 구성, 정규(약 6학점) / 비정규 (약 135시간 이상) 수업 수강 (세부사항 변동 가능)
- 기숙사가 있지만 기숙사 확정이 늦게 발표되고 전원보장이 어려워, 외부숙소로 진행될 수도 있음, 한 학기 기숙사 비용: 약 $4,500~$6,000
- 한 학기 등록금: 약 $7,500
- International Program and Service Fees $2,500'), - ('2024-1', 3, '메모리얼 대학 세인트존스(A형)', 2, 4, 'ONE_SEMESTER', 'HOME_UNIVERSITY_PAYMENT', + (1, 3, '메모리얼 대학 세인트존스(A형)', 2, 4, 'ONE_SEMESTER', 'HOME_UNIVERSITY_PAYMENT', '타전공 지원 및 수강 가능
- 지원불가능전공: Medicine, Pharmacy, Social work, Nursing
- Computer Science, Music 지원 제한적', NULL, '영어 점수는 다음의 세부영역 점수를 각각 만족해야함
- TOEFL iBT : 읽기/쓰기 20점, 듣기/말하기 17점 이상
- IELTS : 모든 영역에서 6.0 이상
- 외국어 성적 유효기간이 파견대학의 학기 시작하는 날까지 유효해야함 ', NULL, NULL, NULL), - ('2024-1', 3, '메모리얼 대학 세인트존스(B형)', 2, 5, 'IRRELEVANT', 'OVERSEAS_UNIVERSITY_PAYMENT', + (1, 3, '메모리얼 대학 세인트존스(B형)', 2, 5, 'IRRELEVANT', 'OVERSEAS_UNIVERSITY_PAYMENT', '타전공 지원 및 수강 가능
- 지원불가능전공: Medicine, Pharmacy, Social work, Nursing
- Computer Science, Music 지원 제한적', NULL, '영어 점수는 다음의 세부영역 점수를 각각 만족해야함
- TOEFL iBT : 읽기/쓰기 20점, 듣기/말하기 17점 이상
- IELTS : 모든 영역에서 6.0 이상
- 외국어 성적 유효기간이 파견대학의 학기 시작하는 날까지 유효해야함 ', NULL, NULL, '국제학생 등록금 적용 (학점당 $2,080)'), - ('2024-1', 4, '서던퀸스랜드대학(B형)', 2, 5, 'ONE_SEMESTER', 'OVERSEAS_UNIVERSITY_PAYMENT', + (1, 4, '서던퀸스랜드대학(B형)', 2, 5, 'ONE_SEMESTER', 'OVERSEAS_UNIVERSITY_PAYMENT', '- 타전공 지원 및 수강 가능
- 미술 계열, 간호학, 약학, 교육학 등 제한 있음
- 학과별 지원 자격요건이 있는 경우 모두 충족해야 하며, 사전 승인 필요', NULL, '영어 점수는 다음의 세부영역 점수를 각각 만족해야 함
- IELTS: 각 영역 최소 5.5 이상
- 외국어 성적 유효기간이 파견대학의 지원시까지 유효해야함 ', NULL, NULL, '서던퀸스랜드대학은 Trimester로 운영되므로 학사일정을 반드시 참고하길 바람
- In-state 등록금 납부
(등록금 관련 정보 : https://www.unisq.edu.au/international/partnerships/study-abroad-exchange/fees-scholarships)'), - ('2024-1', 5, '시드니대학', 2, 5, 'IRRELEVANT', 'OVERSEAS_UNIVERSITY_PAYMENT', + (1, 5, '시드니대학', 2, 5, 'IRRELEVANT', 'OVERSEAS_UNIVERSITY_PAYMENT', '타전공 지원 및 수강 가능
- MECO, CAEL, LAWS unit 수강 여석 제한 있음', NULL, '영어 점수는 다음의 세부영역 점수를 각각 만족해야함
- IELTS: 모든 영역에서 6.0 이상
- TOEFL IBT: 읽기/듣기/말하기 17점, 쓰기 19점 이상
- 어학성적은 파견학기 시작시까지 유효하여야함', NULL, NULL, 'OSHC(Overseas Student Health Cover) 국제학생 보험가입 의무 (2023년 기준 AUD 348/학기, 학기마다 비용 상이)'), - ('2024-1', 6, '커틴대학(A형)', 2, 3, 'ONE_SEMESTER', 'HOME_UNIVERSITY_PAYMENT', + (1, 6, '커틴대학(A형)', 2, 3, 'ONE_SEMESTER', 'HOME_UNIVERSITY_PAYMENT', '타전공 지원 및 수강 가능
지원 불가능 전공: Physiotherapy, Medicine, Nursing, Occupational Therapy ', NULL, '영어 점수는 다음의 세부영역 점수를 각각 만족해야함
- IELTS: 모든 영역에서 6.0 이상
- TOEFL IBT: 읽기 13점, 쓰기 21점, 듣기 13점, 말하기 18점 이상
- 어학성적은 파견학기 시작시까지 유효하여야함', NULL, NULL, '※ 24-1학기에 한하여 ''Destination Australia Cheung Kong Exchange Program Scholarship'' 지급 예정 (신청자 중 가장 총점이 우수한 학생 1명에게 AUD$6000 지급, 상세 내용은 국제처 홈페이지 해외대학정보 공지글 참고)'), - ('2024-1', 7, '서던덴마크대학교', 4, 2, 'IRRELEVANT', 'HOME_UNIVERSITY_PAYMENT', + (1, 7, '서던덴마크대학교', 4, 2, 'IRRELEVANT', 'HOME_UNIVERSITY_PAYMENT', '- 주전공과 지원전공이 반드시 일치할 필요는 없으나 본교에서 기초과목을 이수하여야 함
- 교환학생에게 제공되는 수업만 수강 가능
- Faculty of Engineering 내에서 2/3이상의 수업을 수강하여야 함
- 30 ECTS 수강', '- 어학성적표가 해당 대학 신청서 제출 시 유효하여야 함(~10월 1일)', NULL, NULL, '- 교외 숙소', NULL), - ('2024-1', 8, '코펜하겐 IT대학', 2, 2, 'ONE_SEMESTER', 'HOME_UNIVERSITY_PAYMENT', + (1, 8, '코펜하겐 IT대학', 2, 2, 'ONE_SEMESTER', 'HOME_UNIVERSITY_PAYMENT', '- 본교 기초과목 이수사항에 따라 지원이 제한될 수 있으나 소속전공과 정확하게 일치 하지 않아도 지원은 가능(연관 전공이어야 함)
- 최소 7.5 ECTS, 최대 30ECTS 수강 가능
- 교차 수강 가능(선수과목이 지정되어있는 과목은 사전에 이수하여야 수강이 가능함)', '- 어학성적표가 해당 대학 신청서 제출 시 유효하여야 함(~11월 1일)', NULL, NULL, '- 제공(학교 운영 기숙사 아님)
- 선착순 배정', NULL), - ('2024-1', 9, '노이울름 대학', 2, 3, 'IRRELEVANT', 'HOME_UNIVERSITY_PAYMENT', '타전공 지원 및 수강 가능', NULL, + (1, 9, '노이울름 대학', 2, 3, 'IRRELEVANT', 'HOME_UNIVERSITY_PAYMENT', '타전공 지원 및 수강 가능', NULL, '영어 점수는 다음의 세부영역 점수를 각각 만족해야 함
- TOEFL IBT: 읽기 18점; 듣기 17점, 말하기 20점, 쓰기 17점
- TOEIC: 읽기 385점, 듣기 400점, 말하기 160점, 쓰기 150점
외국어 성적 유효기간이 파견대학의 학기 시작하는 시점까지 유효해야 함', NULL, NULL, NULL), - ('2024-1', 10, '헐대학', 4, 3, 'ONE_SEMESTER', 'HOME_UNIVERSITY_PAYMENT', + (1, 10, '헐대학', 4, 3, 'ONE_SEMESTER', 'HOME_UNIVERSITY_PAYMENT', '제한학과 많음. (Factsheet참조및Factsheet언급된 제한학과 외에도 학기마다 제한학과 발생가능성있음). 지원 전 권역 담당자랑 사전상담 요망. 학기당 30ECTS수강해야 LA승인남. 성적처리 늦은 편이라 8차 학기 수학자는 성적처리 늦은 거 감안하고 추가 이에 따른 불편함이 있음을 인지후 지원요망. ', '지원 전 권역 담당자와 사전상담 요망', '- 영어 점수는 다음의 세부영역 점수를 각각 만족해야 함
- TOEFL iBT : 듣기 및 쓰기 18점, 읽기 18점, 말하기 20점, 쓰기 18점 이상
- IELTS : 모든 영역에서 6.0이상', NULL, NULL, '영국 생활비 및 숙소비용 유럽권 지역 중 상대적으로 매우 높은편. 지원전 반드시 사전고려 요망'), - ('2024-1', 11, '그라츠 대학', 3, 2, 'IRRELEVANT', 'HOME_UNIVERSITY_PAYMENT', '-주전공 혹은 제2전공(혹은 연계전공과) 유관학과여아 함', + (1, 11, '그라츠 대학', 3, 2, 'IRRELEVANT', 'HOME_UNIVERSITY_PAYMENT', '-주전공 혹은 제2전공(혹은 연계전공과) 유관학과여아 함', '선발인원 중 차순위 합격자는 학기제한(1개 학기)이 있을 수 있음', NULL, NULL, '학교인근 외부 숙소는 있지만, 외부업체운영숙소라 대학관할아님', NULL), - ('2024-1', 12, '그라츠공과대학', 2, 2, 'IRRELEVANT', 'HOME_UNIVERSITY_PAYMENT', '-주전공 혹은 제2전공(혹은 연계전공과) 유관학과여아 함', + (1, 12, '그라츠공과대학', 2, 2, 'IRRELEVANT', 'HOME_UNIVERSITY_PAYMENT', '-주전공 혹은 제2전공(혹은 연계전공과) 유관학과여아 함', '선발인원 중 차순위 합격자는 학기제한(1개 학기)이 있을 수 있음', '- 영어 점수는 다음의 세부영역 점수를 각각 만족해야 함
- TOEFL IBT: 읽기 18점 이상, 쓰기 17점 이상, 말하기 20점 이상, 듣기 17점 이상
- IELTS: 쓰기 5.5점 이상, 말하기 6점 이상
''- TOEIC의 경우 S/W 점수 합산 310점 이상 ', NULL, '자체기숙사는 없음. 교환학생이 많이 지원한 학기에는 예약이 어려울 수도 있음(선착순 경우많음). 더블룸 기준약 한달에 € 340 per month (기숙사 종류게 따라 가격 차이 유) 예산잡으면됨.', NULL), - ('2024-1', 13, '린츠 카톨릭 대학교', 3, 2, 'ONE_SEMESTER', 'HOME_UNIVERSITY_PAYMENT', + (1, 13, '린츠 카톨릭 대학교', 3, 2, 'ONE_SEMESTER', 'HOME_UNIVERSITY_PAYMENT', '- 지원가능전공: History, Philosophy, Art History, theology
(영어과목 수가 그리 많지는 않으므로, 사전 확인필요)
''- 학기당 최소 15ECTS 수강신청해야 함', '봄학기에는 영어과목이 극히 제한적으로 열린다고 함. 지원 전 권역 담당자와 사전상담 요망', NULL, NULL, '학교에서 몇가지 기숙사 옵션 합격시 연결예정.', NULL), - ('2024-1', 14, '빈 공과대학교', 3, 2, 'IRRELEVANT', 'HOME_UNIVERSITY_PAYMENT', + (1, 14, '빈 공과대학교', 3, 2, 'IRRELEVANT', 'HOME_UNIVERSITY_PAYMENT', '지원전공과 일치하지 않아도 지원가능하나 유사전공자만 지원가능하며, 본전공과 일치하지않으면 입학 및 수강에 불리할 수 있음
''-학기당 최소 15.ECTS 수강신청해야함', '선발인원 중 차순위 합격자는 학기제한(1개 학기)이 있을 수 있음', NULL, NULL, '기숙사없음', NULL), - ('2024-1', 15, 'IPSA', 4, 3, 'IRRELEVANT', 'HOME_UNIVERSITY_PAYMENT', + (1, 15, 'IPSA', 4, 3, 'IRRELEVANT', 'HOME_UNIVERSITY_PAYMENT', '- 소속전공과 지원전공이 일치 또는 유사하여야 함 : 전공이 제한적이므로 반드시 홈페이지에서 지원 가능 전공을 확인할 것
- 최대 30ECTS 수강', '- 어학성적표가 해당 대학 신청서 제출 시 유효하여야 함(~11월 15일)', NULL, NULL, '- 미제공', NULL), - ('2024-1', 16, '메이지대학', 2, 3, 'IRRELEVANT', 'HOME_UNIVERSITY_PAYMENT', + (1, 16, '메이지대학', 2, 3, 'IRRELEVANT', 'HOME_UNIVERSITY_PAYMENT', 'https://www.meiji.ac.jp/cip/english/admissions/co7mm90000000461-att/co7mm900000004d1.pdf', '*해당 학교 일정 상 10월초까지 서류제출 필요', '학부별로 기준 상이, 관련페이지 참조', NULL, NULL, NULL), - ('2024-1', 17, '바이카여자대학', 2, 1, 'IRRELEVANT', NULL, + (1, 17, '바이카여자대학', 2, 1, 'IRRELEVANT', NULL, '교환학생 지원가능 : Department of Global English, Department of Japanese culture, Department of Media and Information, Department of Psychology.', '여학생만 신청가능', NULL, NULL, '기숙사 없음, 계약된 외부 기숙사 사용-“Maison de Claire Ibaraki” 62,300엔/월, 2식 포함, 계약시 66,000엔 청구 (2023년 6월기준)', NULL), - ('2024-1', 18, '분쿄가쿠인대학', 2, 3, 'ONE_YEAR', 'HOME_UNIVERSITY_PAYMENT', NULL, NULL, NULL, NULL, + (1, 18, '분쿄가쿠인대학', 2, 3, 'ONE_YEAR', 'HOME_UNIVERSITY_PAYMENT', NULL, NULL, NULL, NULL, '기숙사 보유, off campus, 식사 미제공, 45,000~50,000엔/월', NULL); INSERT INTO language_requirement(language_test_type, min_score, university_info_for_apply_id) diff --git a/src/main/resources/db/migration/V36__migrate_term_to_table.sql b/src/main/resources/db/migration/V36__migrate_term_to_table.sql new file mode 100644 index 000000000..93e1b13b0 --- /dev/null +++ b/src/main/resources/db/migration/V36__migrate_term_to_table.sql @@ -0,0 +1,185 @@ +-- 1. Term 테이블 생성 +CREATE TABLE IF NOT EXISTS term ( + id BIGINT AUTO_INCREMENT PRIMARY KEY, + name VARCHAR(20) NOT NULL, + is_current BOOLEAN NOT NULL DEFAULT FALSE, + CONSTRAINT uk_term_name UNIQUE (name) +); + +-- 2. 기존에 사용하던 term 값들을 Term 테이블에 INSERT +INSERT IGNORE INTO term (name, is_current) +SELECT DISTINCT term, FALSE +FROM application +WHERE term NOT IN (SELECT name FROM term); + +INSERT IGNORE INTO term (name, is_current) +SELECT DISTINCT term, FALSE +FROM mentor +WHERE term NOT IN (SELECT name FROM term); + +INSERT IGNORE INTO term (name, is_current) +SELECT DISTINCT term, FALSE +FROM university_info_for_apply +WHERE term NOT IN (SELECT name FROM term); + +-- 3. 현재 학기 설정 +INSERT INTO term (name, is_current) +VALUES ('2026-1', TRUE) + ON DUPLICATE KEY UPDATE is_current = TRUE; + +UPDATE term SET is_current = FALSE WHERE name != '2026-1'; + +-- 4. 각 테이블에 term_id 컬럼 추가 (임시로 nullable) +ALTER TABLE application + ADD COLUMN term_id BIGINT NULL; + +ALTER TABLE mentor + ADD COLUMN term_id BIGINT NULL; + +ALTER TABLE university_info_for_apply + ADD COLUMN term_id BIGINT NULL; + +-- 5. 기존 term(String) 값을 term_id(Long)로 매핑 +UPDATE application a + INNER JOIN term t ON a.term = t.name + SET a.term_id = t.id +WHERE a.term_id IS NULL; + +UPDATE mentor m + INNER JOIN term t ON m.term = t.name + SET m.term_id = t.id +WHERE m.term_id IS NULL; + +UPDATE university_info_for_apply u + INNER JOIN term t ON u.term = t.name + SET u.term_id = t.id +WHERE u.term_id IS NULL; + +-- 6. term_id를 NOT NULL로 변경 +ALTER TABLE application + MODIFY COLUMN term_id BIGINT NOT NULL; + +ALTER TABLE mentor + MODIFY COLUMN term_id BIGINT NOT NULL; + +ALTER TABLE university_info_for_apply + MODIFY COLUMN term_id BIGINT NOT NULL; + +-- 7. term_id에 대해 FK 설정 +ALTER TABLE application + ADD CONSTRAINT fk_application_term_id + FOREIGN KEY (term_id) REFERENCES term(id); + +ALTER TABLE mentor + ADD CONSTRAINT fk_mentor_term_id + FOREIGN KEY (term_id) REFERENCES term(id); + +ALTER TABLE university_info_for_apply + ADD CONSTRAINT fk_university_info_for_apply_term_id + FOREIGN KEY (term_id) REFERENCES term(id); + +-- 8. term_id 기반 새로운 인덱스 생성 +CREATE INDEX idx_app_user_term_id_delete + ON application(site_user_id, term_id, is_delete); + +CREATE INDEX idx_app_first_choice_term_id_search + ON application(verify_status, term_id, is_delete, first_choice_university_info_for_apply_id); + +CREATE INDEX idx_app_second_choice_term_id_search + ON application(verify_status, term_id, is_delete, second_choice_university_info_for_apply_id); + +CREATE INDEX idx_app_third_choice_term_id_search + ON application(verify_status, term_id, is_delete, third_choice_university_info_for_apply_id); + +-- 9. 기존 fk 삭제 +SET @drop_fk1 = ( + SELECT CONCAT('ALTER TABLE `application` DROP FOREIGN KEY `', CONSTRAINT_NAME, '`;') + FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE + WHERE TABLE_SCHEMA = DATABASE() + AND TABLE_NAME = 'application' + AND COLUMN_NAME = 'first_choice_university_info_for_apply_id' + AND REFERENCED_TABLE_NAME = 'university_info_for_apply' + LIMIT 1 +); + +SET @drop_fk1 = IFNULL(@drop_fk1, 'SELECT 1'); +PREPARE stmt1 FROM @drop_fk1; +EXECUTE stmt1; +DEALLOCATE PREPARE stmt1; + +SET @drop_fk2 = ( + SELECT CONCAT('ALTER TABLE `application` DROP FOREIGN KEY `', CONSTRAINT_NAME, '`;') + FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE + WHERE TABLE_SCHEMA = DATABASE() + AND TABLE_NAME = 'application' + AND COLUMN_NAME = 'second_choice_university_info_for_apply_id' + AND REFERENCED_TABLE_NAME = 'university_info_for_apply' + LIMIT 1 +); + +SET @drop_fk2 = IFNULL(@drop_fk2, 'SELECT 1'); +PREPARE stmt2 FROM @drop_fk2; +EXECUTE stmt2; +DEALLOCATE PREPARE stmt2; + +SET @drop_fk3 = ( + SELECT CONCAT('ALTER TABLE `application` DROP FOREIGN KEY `', CONSTRAINT_NAME, '`;') + FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE + WHERE TABLE_SCHEMA = DATABASE() + AND TABLE_NAME = 'application' + AND COLUMN_NAME = 'third_choice_university_info_for_apply_id' + AND REFERENCED_TABLE_NAME = 'university_info_for_apply' + LIMIT 1 +); + +SET @drop_fk3 = IFNULL(@drop_fk3, 'SELECT 1'); +PREPARE stmt3 FROM @drop_fk3; +EXECUTE stmt3; +DEALLOCATE PREPARE stmt3; + +SET @drop_fk4 = ( + SELECT CONCAT('ALTER TABLE `application` DROP FOREIGN KEY `', CONSTRAINT_NAME, '`;') + FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE + WHERE TABLE_SCHEMA = DATABASE() + AND TABLE_NAME = 'application' + AND COLUMN_NAME = 'site_user_id' + AND REFERENCED_TABLE_NAME = 'site_user' + LIMIT 1 +); + +SET @drop_fk4 = IFNULL(@drop_fk4, 'SELECT 1'); +PREPARE stmt4 FROM @drop_fk4; +EXECUTE stmt4; +DEALLOCATE PREPARE stmt4; + +-- 10. 기존 term 관련 인덱스 삭제 +DROP INDEX idx_app_first_choice_search ON application; +DROP INDEX idx_app_second_choice_search ON application; +DROP INDEX idx_app_third_choice_search ON application; +DROP INDEX idx_app_user_term_delete ON application; + +-- 11. term 컬럼 삭제 +ALTER TABLE application DROP COLUMN term; +ALTER TABLE mentor DROP COLUMN term; +ALTER TABLE university_info_for_apply DROP COLUMN term; + +-- 12. FK 재생성 +ALTER TABLE application + ADD CONSTRAINT fk_application_first_choice_university_info_for_apply_id + FOREIGN KEY (first_choice_university_info_for_apply_id) + REFERENCES university_info_for_apply(id); + +ALTER TABLE application + ADD CONSTRAINT fk_application_second_choice_university_info_for_apply_id + FOREIGN KEY (second_choice_university_info_for_apply_id) + REFERENCES university_info_for_apply(id); + +ALTER TABLE application + ADD CONSTRAINT fk_application_third_choice_university_info_for_apply_id + FOREIGN KEY (third_choice_university_info_for_apply_id) + REFERENCES university_info_for_apply(id); + +ALTER TABLE application + ADD CONSTRAINT fk_app_site_user + FOREIGN KEY (site_user_id) + REFERENCES site_user(id); diff --git a/src/test/java/com/example/solidconnection/application/fixture/ApplicationFixture.java b/src/test/java/com/example/solidconnection/application/fixture/ApplicationFixture.java index 9cfc7a805..683f794aa 100644 --- a/src/test/java/com/example/solidconnection/application/fixture/ApplicationFixture.java +++ b/src/test/java/com/example/solidconnection/application/fixture/ApplicationFixture.java @@ -16,7 +16,7 @@ public class ApplicationFixture { public Application 지원서( SiteUser siteUser, String nicknameForApply, - String term, + long termId, Gpa gpa, LanguageTest languageTest, Long firstChoiceUnivApplyInfoId, @@ -28,7 +28,7 @@ public class ApplicationFixture { .gpa(gpa) .languageTest(languageTest) .nicknameForApply(nicknameForApply) - .term(term) + .termId(termId) .firstChoiceUnivApplyInfoId(firstChoiceUnivApplyInfoId) .secondChoiceUnivApplyInfoId(secondChoiceUnivApplyInfoId) .thirdChoiceUnivApplyInfoId(thirdChoiceUnivApplyInfoId) diff --git a/src/test/java/com/example/solidconnection/application/fixture/ApplicationFixtureBuilder.java b/src/test/java/com/example/solidconnection/application/fixture/ApplicationFixtureBuilder.java index 818410938..d8c7fb7e9 100644 --- a/src/test/java/com/example/solidconnection/application/fixture/ApplicationFixtureBuilder.java +++ b/src/test/java/com/example/solidconnection/application/fixture/ApplicationFixtureBuilder.java @@ -22,7 +22,7 @@ public class ApplicationFixtureBuilder { private Long thirdChoiceUnivApplyInfoId; private SiteUser siteUser; private String nicknameForApply; - private String term; + private long termId; public ApplicationFixtureBuilder application() { return new ApplicationFixtureBuilder(applicationRepository); @@ -63,8 +63,8 @@ public ApplicationFixtureBuilder nicknameForApply(String nicknameForApply) { return this; } - public ApplicationFixtureBuilder term(String term) { - this.term = term; + public ApplicationFixtureBuilder termId(long termId) { + this.termId = termId; return this; } @@ -73,7 +73,7 @@ public Application create() { siteUser, gpa, languageTest, - term, + termId, firstChoiceUnivApplyInfoId, secondChoiceUnivApplyInfoId, thirdChoiceUnivApplyInfoId, diff --git a/src/test/java/com/example/solidconnection/application/service/ApplicationQueryServiceTest.java b/src/test/java/com/example/solidconnection/application/service/ApplicationQueryServiceTest.java index 6491b95ac..9025ce6f8 100644 --- a/src/test/java/com/example/solidconnection/application/service/ApplicationQueryServiceTest.java +++ b/src/test/java/com/example/solidconnection/application/service/ApplicationQueryServiceTest.java @@ -17,6 +17,8 @@ import com.example.solidconnection.siteuser.domain.SiteUser; import com.example.solidconnection.siteuser.fixture.SiteUserFixture; import com.example.solidconnection.support.TestContainerSpringBootTest; +import com.example.solidconnection.term.domain.Term; +import com.example.solidconnection.term.fixture.TermFixture; import com.example.solidconnection.university.domain.UnivApplyInfo; import com.example.solidconnection.university.fixture.UnivApplyInfoFixture; import java.util.List; @@ -25,7 +27,6 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; @TestContainerSpringBootTest @DisplayName("지원서 조회 서비스 테스트") @@ -55,8 +56,8 @@ class ApplicationQueryServiceTest { @Autowired private ApplicationFixture applicationFixture; - @Value("${university.term}") - private String term; + @Autowired + private TermFixture termFixture; private SiteUser user1; private SiteUser user2; @@ -74,8 +75,12 @@ class ApplicationQueryServiceTest { private UnivApplyInfo 괌대학_B_지원_정보; private UnivApplyInfo 서던덴마크대학교_지원_정보; + private Term term; + @BeforeEach void setUp() { + term = termFixture.현재_학기("2025-2"); + user1 = siteUserFixture.사용자(1, "test1"); gpaScore1 = gpaScoreFixture.GPA_점수(VerifyStatus.APPROVED, user1); languageTestScore1 = languageTestScoreFixture.어학_점수(VerifyStatus.APPROVED, user1); @@ -88,9 +93,9 @@ void setUp() { gpaScore3 = gpaScoreFixture.GPA_점수(VerifyStatus.APPROVED, user3); languageTestScore3 = languageTestScoreFixture.어학_점수(VerifyStatus.APPROVED, user3); - 괌대학_A_지원_정보 = univApplyInfoFixture.괌대학_A_지원_정보(); - 괌대학_B_지원_정보 = univApplyInfoFixture.괌대학_B_지원_정보(); - 서던덴마크대학교_지원_정보 = univApplyInfoFixture.서던덴마크대학교_지원_정보(); + 괌대학_A_지원_정보 = univApplyInfoFixture.괌대학_A_지원_정보(term.getId()); + 괌대학_B_지원_정보 = univApplyInfoFixture.괌대학_B_지원_정보(term.getId()); + 서던덴마크대학교_지원_정보 = univApplyInfoFixture.서던덴마크대학교_지원_정보(term.getId()); } @Nested @@ -102,7 +107,7 @@ class 지원자_목록_조회_테스트 { Application application1 = applicationFixture.지원서( user1, "nickname1", - term, + term.getId(), gpaScore1.getGpa(), languageTestScore1.getLanguageTest(), 괌대학_A_지원_정보.getId(), @@ -112,7 +117,7 @@ class 지원자_목록_조회_테스트 { Application application2 = applicationFixture.지원서( user2, "nickname2", - term, + term.getId(), gpaScore2.getGpa(), languageTestScore2.getLanguageTest(), 괌대학_B_지원_정보.getId(), @@ -122,7 +127,7 @@ class 지원자_목록_조회_테스트 { Application application3 = applicationFixture.지원서( user3, "nickname3", - term, + term.getId(), gpaScore3.getGpa(), languageTestScore3.getLanguageTest(), 서던덴마크대학교_지원_정보.getId(), @@ -154,7 +159,7 @@ class 지원자_목록_조회_테스트 { Application application1 = applicationFixture.지원서( user1, "nickname1", - term, + term.getId(), gpaScore1.getGpa(), languageTestScore1.getLanguageTest(), 괌대학_A_지원_정보.getId(), @@ -164,7 +169,7 @@ class 지원자_목록_조회_테스트 { Application application2 = applicationFixture.지원서( user2, "nickname2", - term, + term.getId(), gpaScore2.getGpa(), languageTestScore2.getLanguageTest(), 괌대학_B_지원_정보.getId(), @@ -174,7 +179,7 @@ class 지원자_목록_조회_테스트 { applicationFixture.지원서( user3, "nickname3", - term, + term.getId(), gpaScore3.getGpa(), languageTestScore3.getLanguageTest(), 서던덴마크대학교_지원_정보.getId(), @@ -204,7 +209,7 @@ class 지원자_목록_조회_테스트 { Application application1 = applicationFixture.지원서( user1, "nickname1", - term, + term.getId(), gpaScore1.getGpa(), languageTestScore1.getLanguageTest(), 괌대학_A_지원_정보.getId(), @@ -214,7 +219,7 @@ class 지원자_목록_조회_테스트 { Application application2 = applicationFixture.지원서( user2, "nickname2", - term, + term.getId(), gpaScore2.getGpa(), languageTestScore2.getLanguageTest(), 괌대학_B_지원_정보.getId(), @@ -224,7 +229,7 @@ class 지원자_목록_조회_테스트 { applicationFixture.지원서( user3, "nickname3", - term, + term.getId(), gpaScore3.getGpa(), languageTestScore3.getLanguageTest(), 서던덴마크대학교_지원_정보.getId(), @@ -251,10 +256,11 @@ class 지원자_목록_조회_테스트 { @Test void 현재_학기_지원서만_조회되고_이전_학기_지원서는_제외된다() { // given - applicationFixture.지원서( + Term previousTerm = termFixture.이전_학기("2024-2"); + Application application = applicationFixture.지원서( user1, "nickname1_past", - "1988-1", + previousTerm.getId(), gpaScore1.getGpa(), languageTestScore1.getLanguageTest(), 괌대학_A_지원_정보.getId(), @@ -265,7 +271,7 @@ class 지원자_목록_조회_테스트 { Application currentApplication = applicationFixture.지원서( user1, "nickname1", - term, + term.getId(), gpaScore1.getGpa(), languageTestScore1.getLanguageTest(), 괌대학_A_지원_정보.getId(), @@ -294,7 +300,7 @@ class 지원자_목록_조회_테스트 { Application firstApplication = applicationFixture.지원서( user1, "nickname1", - term, + term.getId(), gpaScore1.getGpa(), languageTestScore1.getLanguageTest(), 괌대학_A_지원_정보.getId(), @@ -306,7 +312,7 @@ class 지원자_목록_조회_테스트 { Application secondApplication = applicationFixture.지원서( user1, "nickname2", - term, + term.getId(), gpaScore1.getGpa(), languageTestScore1.getLanguageTest(), 괌대학_B_지원_정보.getId(), @@ -338,7 +344,7 @@ class 경쟁자_목록_조회_테스트 { Application application1 = applicationFixture.지원서( user1, "nickname1", - term, + term.getId(), gpaScore1.getGpa(), languageTestScore1.getLanguageTest(), 괌대학_A_지원_정보.getId(), @@ -348,7 +354,7 @@ class 경쟁자_목록_조회_테스트 { Application application2 = applicationFixture.지원서( user2, "nickname2", - term, + term.getId(), gpaScore2.getGpa(), languageTestScore2.getLanguageTest(), 괌대학_A_지원_정보.getId(), @@ -358,7 +364,7 @@ class 경쟁자_목록_조회_테스트 { applicationFixture.지원서( user3, "nickname3", - term, + term.getId(), gpaScore3.getGpa(), languageTestScore3.getLanguageTest(), 서던덴마크대학교_지원_정보.getId(), @@ -381,7 +387,7 @@ class 경쟁자_목록_조회_테스트 { Application application1 = applicationFixture.지원서( user1, "nickname1", - term, + term.getId(), gpaScore1.getGpa(), languageTestScore1.getLanguageTest(), 괌대학_A_지원_정보.getId(), @@ -391,7 +397,7 @@ class 경쟁자_목록_조회_테스트 { Application application2 = applicationFixture.지원서( user2, "nickname2", - term, + term.getId(), gpaScore2.getGpa(), languageTestScore2.getLanguageTest(), 괌대학_A_지원_정보.getId(), @@ -401,7 +407,7 @@ class 경쟁자_목록_조회_테스트 { Application application3 = applicationFixture.지원서( user3, "nickname3", - term, + term.getId(), gpaScore3.getGpa(), languageTestScore3.getLanguageTest(), 서던덴마크대학교_지원_정보.getId(), diff --git a/src/test/java/com/example/solidconnection/application/service/ApplicationSubmissionServiceTest.java b/src/test/java/com/example/solidconnection/application/service/ApplicationSubmissionServiceTest.java index 5281faa3e..10a72de0b 100644 --- a/src/test/java/com/example/solidconnection/application/service/ApplicationSubmissionServiceTest.java +++ b/src/test/java/com/example/solidconnection/application/service/ApplicationSubmissionServiceTest.java @@ -22,13 +22,14 @@ import com.example.solidconnection.siteuser.domain.SiteUser; import com.example.solidconnection.siteuser.fixture.SiteUserFixture; import com.example.solidconnection.support.TestContainerSpringBootTest; +import com.example.solidconnection.term.domain.Term; +import com.example.solidconnection.term.fixture.TermFixture; import com.example.solidconnection.university.domain.UnivApplyInfo; import com.example.solidconnection.university.fixture.UnivApplyInfoFixture; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; @TestContainerSpringBootTest @DisplayName("지원서 제출 서비스 테스트") @@ -52,20 +53,24 @@ class ApplicationSubmissionServiceTest { @Autowired private LanguageTestScoreFixture languageTestScoreFixture; - @Value("${university.term}") - private String term; + @Autowired + private TermFixture termFixture; private SiteUser user; private UnivApplyInfo 괌대학_A_지원_정보; private UnivApplyInfo 괌대학_B_지원_정보; private UnivApplyInfo 서던덴마크대학교_지원_정보; + private Term term; + @BeforeEach void setUp() { + term = termFixture.현재_학기("2025-2"); + user = siteUserFixture.사용자(); - 괌대학_A_지원_정보 = univApplyInfoFixture.괌대학_A_지원_정보(); - 괌대학_B_지원_정보 = univApplyInfoFixture.괌대학_B_지원_정보(); - 서던덴마크대학교_지원_정보 = univApplyInfoFixture.서던덴마크대학교_지원_정보(); + 괌대학_A_지원_정보 = univApplyInfoFixture.괌대학_A_지원_정보(term.getId()); + 괌대학_B_지원_정보 = univApplyInfoFixture.괌대학_B_지원_정보(term.getId()); + 서던덴마크대학교_지원_정보 = univApplyInfoFixture.서던덴마크대학교_지원_정보(term.getId()); } @Test @@ -84,7 +89,7 @@ void setUp() { ApplicationSubmissionResponse response = applicationSubmissionService.apply(user.getId(), request); // then - Application savedApplication = applicationRepository.findBySiteUserIdAndTerm(user.getId(), term).orElseThrow(); + Application savedApplication = applicationRepository.findBySiteUserIdAndTermId(user.getId(), term.getId()).orElseThrow(); assertAll( () -> assertThat(response.applyCount()) .isEqualTo(savedApplication.getUpdateCount()), diff --git a/src/test/java/com/example/solidconnection/mentor/fixture/MentorFixture.java b/src/test/java/com/example/solidconnection/mentor/fixture/MentorFixture.java index b612a9417..8e47d11d1 100644 --- a/src/test/java/com/example/solidconnection/mentor/fixture/MentorFixture.java +++ b/src/test/java/com/example/solidconnection/mentor/fixture/MentorFixture.java @@ -1,6 +1,7 @@ package com.example.solidconnection.mentor.fixture; import com.example.solidconnection.mentor.domain.Mentor; +import com.example.solidconnection.term.fixture.TermFixture; import lombok.RequiredArgsConstructor; import org.springframework.boot.test.context.TestComponent; @@ -9,6 +10,7 @@ public class MentorFixture { private final MentorFixtureBuilder mentorFixtureBuilder; + private final TermFixture termFixture; public Mentor 멘토(long siteUserId, long universityId) { return mentorFixtureBuilder.mentor() @@ -16,6 +18,7 @@ public class MentorFixture { .universityId(universityId) .introduction("멘토 소개") .passTip("합격 팁") + .termId(termFixture.현재_학기("2025-1").getId()) .create(); } } diff --git a/src/test/java/com/example/solidconnection/mentor/fixture/MentorFixtureBuilder.java b/src/test/java/com/example/solidconnection/mentor/fixture/MentorFixtureBuilder.java index 7eaaefa94..533d29494 100644 --- a/src/test/java/com/example/solidconnection/mentor/fixture/MentorFixtureBuilder.java +++ b/src/test/java/com/example/solidconnection/mentor/fixture/MentorFixtureBuilder.java @@ -17,7 +17,7 @@ public class MentorFixtureBuilder { private String passTip; private long siteUserId; private long universityId; - private String term = "2025-1"; + private long termId; public MentorFixtureBuilder mentor() { return new MentorFixtureBuilder(mentorRepository); @@ -53,8 +53,8 @@ public MentorFixtureBuilder universityId(Long universityId) { return this; } - public MentorFixtureBuilder term(String term) { - this.term = term; + public MentorFixtureBuilder termId(long termId) { + this.termId = termId; return this; } @@ -67,7 +67,7 @@ public Mentor create() { passTip, siteUserId, universityId, - term, + termId, null ); return mentorRepository.save(mentor); diff --git a/src/test/java/com/example/solidconnection/mentor/service/MentorMyPageServiceTest.java b/src/test/java/com/example/solidconnection/mentor/service/MentorMyPageServiceTest.java index f4bc6a0ea..7beb2e4f0 100644 --- a/src/test/java/com/example/solidconnection/mentor/service/MentorMyPageServiceTest.java +++ b/src/test/java/com/example/solidconnection/mentor/service/MentorMyPageServiceTest.java @@ -19,6 +19,7 @@ import com.example.solidconnection.siteuser.domain.SiteUser; import com.example.solidconnection.siteuser.fixture.SiteUserFixture; import com.example.solidconnection.support.TestContainerSpringBootTest; +import com.example.solidconnection.term.fixture.TermFixture; import com.example.solidconnection.university.domain.University; import com.example.solidconnection.university.fixture.UniversityFixture; import java.util.List; @@ -44,6 +45,9 @@ class MentorMyPageServiceTest { @Autowired private ChannelFixture channelFixture; + @Autowired + private TermFixture termFixture; + @Autowired private MentorRepository mentorRepository; @@ -59,6 +63,7 @@ class MentorMyPageServiceTest { @BeforeEach void setUp() { + termFixture.현재_학기("2025-2"); university = universityFixture.메이지_대학(); mentorUser = siteUserFixture.멘토(1, "멘토"); mentor = mentorFixture.멘토(mentorUser.getId(), university.getId()); diff --git a/src/test/java/com/example/solidconnection/mentor/service/MentorQueryServiceTest.java b/src/test/java/com/example/solidconnection/mentor/service/MentorQueryServiceTest.java index d20bc28d7..8a4088845 100644 --- a/src/test/java/com/example/solidconnection/mentor/service/MentorQueryServiceTest.java +++ b/src/test/java/com/example/solidconnection/mentor/service/MentorQueryServiceTest.java @@ -18,6 +18,7 @@ import com.example.solidconnection.siteuser.domain.SiteUser; import com.example.solidconnection.siteuser.fixture.SiteUserFixture; import com.example.solidconnection.support.TestContainerSpringBootTest; +import com.example.solidconnection.term.fixture.TermFixture; import com.example.solidconnection.university.domain.University; import com.example.solidconnection.university.fixture.UniversityFixture; import java.util.Map; @@ -52,10 +53,14 @@ class MentorQueryServiceTest { @Autowired private UniversityFixture universityFixture; + @Autowired + private TermFixture termFixture; + private University university; @BeforeEach void setUp() { + termFixture.현재_학기("2025-2"); university = universityFixture.그라츠_대학(); } diff --git a/src/test/java/com/example/solidconnection/siteuser/service/MyPageServiceTest.java b/src/test/java/com/example/solidconnection/siteuser/service/MyPageServiceTest.java index d8e5c950f..fa83522e7 100644 --- a/src/test/java/com/example/solidconnection/siteuser/service/MyPageServiceTest.java +++ b/src/test/java/com/example/solidconnection/siteuser/service/MyPageServiceTest.java @@ -37,6 +37,8 @@ import com.example.solidconnection.siteuser.fixture.SiteUserFixtureBuilder; import com.example.solidconnection.siteuser.repository.SiteUserRepository; import com.example.solidconnection.support.TestContainerSpringBootTest; +import com.example.solidconnection.term.domain.Term; +import com.example.solidconnection.term.fixture.TermFixture; import com.example.solidconnection.university.domain.LikedUnivApplyInfo; import com.example.solidconnection.university.domain.University; import com.example.solidconnection.university.fixture.UnivApplyInfoFixture; @@ -89,6 +91,9 @@ class MyPageServiceTest { @Autowired private RegionFixture regionFixture; + @Autowired + private TermFixture termFixture; + @Autowired private SiteUserFixtureBuilder siteUserFixtureBuilder; @@ -96,10 +101,12 @@ class MyPageServiceTest { private PasswordEncoder passwordEncoder; private SiteUser user; + private Term term; @BeforeEach void setUp() { user = siteUserFixture.사용자(); + term = termFixture.현재_학기("2025-2"); } @Test @@ -131,7 +138,7 @@ void setUp() { void 멘토의_마이페이지_정보를_조회한다() { // given SiteUser mentorUser = siteUserFixture.멘토(1, "mentor"); - University university = univApplyInfoFixture.괌대학_A_지원_정보().getUniversity(); + University university = univApplyInfoFixture.괌대학_A_지원_정보(term.getId()).getUniversity(); mentorFixture.멘토(mentorUser.getId(), university.getId()); int likedUnivApplyInfoCount = createLikedUnivApplyInfos(mentorUser); @@ -153,9 +160,9 @@ void setUp() { } private int createLikedUnivApplyInfos(SiteUser testUser) { - LikedUnivApplyInfo likedUnivApplyInfo1 = new LikedUnivApplyInfo(null, univApplyInfoFixture.괌대학_A_지원_정보().getId(), testUser.getId()); - LikedUnivApplyInfo likedUnivApplyInfo2 = new LikedUnivApplyInfo(null, univApplyInfoFixture.메이지대학_지원_정보().getId(), testUser.getId()); - LikedUnivApplyInfo likedUnivApplyInfo3 = new LikedUnivApplyInfo(null, univApplyInfoFixture.코펜하겐IT대학_지원_정보().getId(), testUser.getId()); + LikedUnivApplyInfo likedUnivApplyInfo1 = new LikedUnivApplyInfo(null, univApplyInfoFixture.괌대학_A_지원_정보(term.getId()).getId(), testUser.getId()); + LikedUnivApplyInfo likedUnivApplyInfo2 = new LikedUnivApplyInfo(null, univApplyInfoFixture.메이지대학_지원_정보(term.getId()).getId(), testUser.getId()); + LikedUnivApplyInfo likedUnivApplyInfo3 = new LikedUnivApplyInfo(null, univApplyInfoFixture.코펜하겐IT대학_지원_정보(term.getId()).getId(), testUser.getId()); likedUnivApplyInfoRepository.save(likedUnivApplyInfo1); likedUnivApplyInfoRepository.save(likedUnivApplyInfo2); diff --git a/src/test/java/com/example/solidconnection/term/fixture/TermFixture.java b/src/test/java/com/example/solidconnection/term/fixture/TermFixture.java new file mode 100644 index 000000000..085ef75e6 --- /dev/null +++ b/src/test/java/com/example/solidconnection/term/fixture/TermFixture.java @@ -0,0 +1,26 @@ +package com.example.solidconnection.term.fixture; + +import com.example.solidconnection.term.domain.Term; +import lombok.RequiredArgsConstructor; +import org.springframework.boot.test.context.TestComponent; + +@TestComponent +@RequiredArgsConstructor +public class TermFixture { + + private final TermFixtureBuilder termFixtureBuilder; + + public Term 현재_학기(String name) { + return termFixtureBuilder.term() + .name(name) + .isCurrent(true) + .findOrCreate(); + } + + public Term 이전_학기(String name) { + return termFixtureBuilder.term() + .name(name) + .isCurrent(false) + .findOrCreate(); + } +} diff --git a/src/test/java/com/example/solidconnection/term/fixture/TermFixtureBuilder.java b/src/test/java/com/example/solidconnection/term/fixture/TermFixtureBuilder.java new file mode 100644 index 000000000..93933e13e --- /dev/null +++ b/src/test/java/com/example/solidconnection/term/fixture/TermFixtureBuilder.java @@ -0,0 +1,35 @@ +package com.example.solidconnection.term.fixture; + +import com.example.solidconnection.term.domain.Term; +import com.example.solidconnection.term.repository.TermRepositoryForTest; +import lombok.RequiredArgsConstructor; +import org.springframework.boot.test.context.TestComponent; + +@TestComponent +@RequiredArgsConstructor +public class TermFixtureBuilder { + + private final TermRepositoryForTest termRepositoryForTest; + + private String name; + private boolean isCurrent; + + public TermFixtureBuilder term() { + return new TermFixtureBuilder(termRepositoryForTest); + } + + public TermFixtureBuilder name(String name) { + this.name = name; + return this; + } + + public TermFixtureBuilder isCurrent(boolean isCurrent) { + this.isCurrent = isCurrent; + return this; + } + + public Term findOrCreate() { + return termRepositoryForTest.findByName(name) + .orElseGet(() -> termRepositoryForTest.save(new Term(name, isCurrent))); + } +} diff --git a/src/test/java/com/example/solidconnection/term/repository/TermRepositoryForTest.java b/src/test/java/com/example/solidconnection/term/repository/TermRepositoryForTest.java new file mode 100644 index 000000000..f0e0311ee --- /dev/null +++ b/src/test/java/com/example/solidconnection/term/repository/TermRepositoryForTest.java @@ -0,0 +1,10 @@ +package com.example.solidconnection.term.repository; + +import com.example.solidconnection.term.domain.Term; +import java.util.Optional; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface TermRepositoryForTest extends JpaRepository { + + Optional findByName(String name); +} diff --git a/src/test/java/com/example/solidconnection/university/fixture/UnivApplyInfoFixture.java b/src/test/java/com/example/solidconnection/university/fixture/UnivApplyInfoFixture.java index dfd50450f..fdfd11187 100644 --- a/src/test/java/com/example/solidconnection/university/fixture/UnivApplyInfoFixture.java +++ b/src/test/java/com/example/solidconnection/university/fixture/UnivApplyInfoFixture.java @@ -2,7 +2,6 @@ import com.example.solidconnection.university.domain.UnivApplyInfo; import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.context.TestComponent; @TestComponent @@ -12,92 +11,89 @@ public class UnivApplyInfoFixture { private final UnivApplyInfoFixtureBuilder univApplyInfoFixtureBuilder; private final UniversityFixture universityFixture; - @Value("${university.term}") - public String term; - - public UnivApplyInfo 괌대학_A_지원_정보() { + public UnivApplyInfo 괌대학_A_지원_정보(long termId) { return univApplyInfoFixtureBuilder.univApplyInfo() - .term(term) + .termId(termId) .koreanName("괌대학(A형)") .university(universityFixture.괌_대학()) .create(); } - public UnivApplyInfo 괌대학_B_지원_정보() { + public UnivApplyInfo 괌대학_B_지원_정보(long termId) { return univApplyInfoFixtureBuilder.univApplyInfo() - .term(term) + .termId(termId) .koreanName("괌대학(B형)") .university(universityFixture.괌_대학()) .create(); } - public UnivApplyInfo 네바다주립대학_라스베이거스_지원_정보() { + public UnivApplyInfo 네바다주립대학_라스베이거스_지원_정보(long termId) { return univApplyInfoFixtureBuilder.univApplyInfo() - .term(term) + .termId(termId) .koreanName("네바다주립대학 라스베이거스(B형)") .university(universityFixture.네바다주립_대학_라스베이거스()) .create(); } - public UnivApplyInfo 아칸소주립대학_지원_정보() { + public UnivApplyInfo 아칸소주립대학_지원_정보(long termId) { return univApplyInfoFixtureBuilder.univApplyInfo() - .term(term) + .termId(termId) .koreanName("아칸소 주립 대학") .university(universityFixture.아칸소_주립_대학()) .create(); } - public UnivApplyInfo 메모리얼대학_세인트존스_A_지원_정보() { + public UnivApplyInfo 메모리얼대학_세인트존스_A_지원_정보(long termId) { return univApplyInfoFixtureBuilder.univApplyInfo() - .term(term) + .termId(termId) .koreanName("메모리얼 대학 세인트존스(A형)") .university(universityFixture.메모리얼_대학_세인트존스()) .create(); } - public UnivApplyInfo 서던덴마크대학교_지원_정보() { + public UnivApplyInfo 서던덴마크대학교_지원_정보(long termId) { return univApplyInfoFixtureBuilder.univApplyInfo() - .term(term) + .termId(termId) .koreanName("서던덴마크대학교") .university(universityFixture.서던덴마크_대학()) .create(); } - public UnivApplyInfo 코펜하겐IT대학_지원_정보() { + public UnivApplyInfo 코펜하겐IT대학_지원_정보(long termId) { return univApplyInfoFixtureBuilder.univApplyInfo() - .term(term) + .termId(termId) .koreanName("코펜하겐 IT대학") .university(universityFixture.코펜하겐IT_대학()) .create(); } - public UnivApplyInfo 그라츠대학_지원_정보() { + public UnivApplyInfo 그라츠대학_지원_정보(long termId) { return univApplyInfoFixtureBuilder.univApplyInfo() - .term(term) + .termId(termId) .koreanName("그라츠 대학") .university(universityFixture.그라츠_대학()) .create(); } - public UnivApplyInfo 그라츠공과대학_지원_정보() { + public UnivApplyInfo 그라츠공과대학_지원_정보(long termId) { return univApplyInfoFixtureBuilder.univApplyInfo() - .term(term) + .termId(termId) .koreanName("그라츠공과대학") .university(universityFixture.그라츠공과_대학()) .create(); } - public UnivApplyInfo 린츠_카톨릭대학_지원_정보() { + public UnivApplyInfo 린츠_카톨릭대학_지원_정보(long termId) { return univApplyInfoFixtureBuilder.univApplyInfo() - .term(term) + .termId(termId) .koreanName("린츠 카톨릭 대학교") .university(universityFixture.린츠_카톨릭_대학()) .create(); } - public UnivApplyInfo 메이지대학_지원_정보() { + public UnivApplyInfo 메이지대학_지원_정보(long termId) { return univApplyInfoFixtureBuilder.univApplyInfo() - .term(term) + .termId(termId) .koreanName("메이지대학") .university(universityFixture.메이지_대학()) .create(); diff --git a/src/test/java/com/example/solidconnection/university/fixture/UnivApplyInfoFixtureBuilder.java b/src/test/java/com/example/solidconnection/university/fixture/UnivApplyInfoFixtureBuilder.java index 55f81e9eb..6f78d8086 100644 --- a/src/test/java/com/example/solidconnection/university/fixture/UnivApplyInfoFixtureBuilder.java +++ b/src/test/java/com/example/solidconnection/university/fixture/UnivApplyInfoFixtureBuilder.java @@ -16,7 +16,7 @@ public class UnivApplyInfoFixtureBuilder { private final UnivApplyInfoRepository univApplyInfoRepository; - private String term; + private long termId; private String koreanName; private University university; @@ -24,8 +24,8 @@ public UnivApplyInfoFixtureBuilder univApplyInfo() { return new UnivApplyInfoFixtureBuilder(univApplyInfoRepository); } - public UnivApplyInfoFixtureBuilder term(String term) { - this.term = term; + public UnivApplyInfoFixtureBuilder termId(long termId) { + this.termId = termId; return this; } @@ -41,7 +41,7 @@ public UnivApplyInfoFixtureBuilder university(University university) { public UnivApplyInfo create() { UnivApplyInfo univApplyInfo = new UnivApplyInfo( - null, term, koreanName, 1, HOME_UNIVERSITY_PAYMENT, ONE_SEMESTER, + null, termId, koreanName, 1, HOME_UNIVERSITY_PAYMENT, ONE_SEMESTER, "1", "detailsForLanguage", "gpaRequirement", "gpaRequirementCriteria", "detailsForApply", "detailsForMajor", "detailsForAccommodation", "detailsForEnglishCourse", "details", diff --git a/src/test/java/com/example/solidconnection/university/repository/LikedUnivApplyInfoRepositoryTest.java b/src/test/java/com/example/solidconnection/university/repository/LikedUnivApplyInfoRepositoryTest.java index 785b501b5..04696f7a2 100644 --- a/src/test/java/com/example/solidconnection/university/repository/LikedUnivApplyInfoRepositoryTest.java +++ b/src/test/java/com/example/solidconnection/university/repository/LikedUnivApplyInfoRepositoryTest.java @@ -5,9 +5,12 @@ import com.example.solidconnection.siteuser.domain.SiteUser; import com.example.solidconnection.siteuser.fixture.SiteUserFixture; import com.example.solidconnection.support.TestContainerSpringBootTest; +import com.example.solidconnection.term.domain.Term; +import com.example.solidconnection.term.fixture.TermFixture; import com.example.solidconnection.university.domain.LikedUnivApplyInfo; import com.example.solidconnection.university.domain.UnivApplyInfo; import com.example.solidconnection.university.fixture.UnivApplyInfoFixture; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -27,6 +30,16 @@ public class LikedUnivApplyInfoRepositoryTest { @Autowired private UnivApplyInfoFixture univApplyInfoFixture; + @Autowired + private TermFixture termFixture; + + private Term term; + + @BeforeEach + void setUp() { + term = termFixture.현재_학기("2025-2"); + } + @Nested class 사용자와_좋아요한_대학은_복합_유니크_제약조건을_갖는다 { @@ -34,7 +47,7 @@ class 사용자와_좋아요한_대학은_복합_유니크_제약조건을_갖 void 같은_사용자가_같은_대학에_중복으로_좋아요하면_예외가_발생한다() { // given SiteUser user = siteUserFixture.사용자(); - UnivApplyInfo univApplyInfo = univApplyInfoFixture.괌대학_A_지원_정보(); + UnivApplyInfo univApplyInfo = univApplyInfoFixture.괌대학_A_지원_정보(term.getId()); LikedUnivApplyInfo firstLike = createLikedUnivApplyInfo(user, univApplyInfo); likedUnivApplyInfoRepository.save(firstLike); @@ -51,7 +64,7 @@ class 사용자와_좋아요한_대학은_복합_유니크_제약조건을_갖 // given SiteUser user1 = siteUserFixture.사용자(1, "user1"); SiteUser user2 = siteUserFixture.사용자(2, "user2"); - UnivApplyInfo univApplyInfo = univApplyInfoFixture.괌대학_A_지원_정보(); + UnivApplyInfo univApplyInfo = univApplyInfoFixture.괌대학_A_지원_정보(term.getId()); LikedUnivApplyInfo firstLike = createLikedUnivApplyInfo(user1, univApplyInfo); likedUnivApplyInfoRepository.save(firstLike); @@ -66,8 +79,8 @@ class 사용자와_좋아요한_대학은_복합_유니크_제약조건을_갖 void 같은_사용자가_다른_대학에_좋아요하면_정상_저장된다() { // given SiteUser user = siteUserFixture.사용자(); - UnivApplyInfo univApplyInfo1 = univApplyInfoFixture.괌대학_A_지원_정보(); - UnivApplyInfo univApplyInfo2 = univApplyInfoFixture.메이지대학_지원_정보(); + UnivApplyInfo univApplyInfo1 = univApplyInfoFixture.괌대학_A_지원_정보(term.getId()); + UnivApplyInfo univApplyInfo2 = univApplyInfoFixture.메이지대학_지원_정보(term.getId()); LikedUnivApplyInfo firstLike = createLikedUnivApplyInfo(user, univApplyInfo1); likedUnivApplyInfoRepository.save(firstLike); diff --git a/src/test/java/com/example/solidconnection/university/service/GeneralUnivApplyInfoRecommendServiceTest.java b/src/test/java/com/example/solidconnection/university/service/GeneralUnivApplyInfoRecommendServiceTest.java index 4e22897ef..ef6a55bcb 100644 --- a/src/test/java/com/example/solidconnection/university/service/GeneralUnivApplyInfoRecommendServiceTest.java +++ b/src/test/java/com/example/solidconnection/university/service/GeneralUnivApplyInfoRecommendServiceTest.java @@ -5,6 +5,8 @@ import static org.junit.jupiter.api.Assertions.assertAll; import com.example.solidconnection.support.TestContainerSpringBootTest; +import com.example.solidconnection.term.domain.Term; +import com.example.solidconnection.term.fixture.TermFixture; import com.example.solidconnection.university.domain.UnivApplyInfo; import com.example.solidconnection.university.fixture.UnivApplyInfoFixture; import java.util.List; @@ -12,7 +14,6 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; @TestContainerSpringBootTest @DisplayName("대학 지원 정보 공통 추천 서비스 테스트") @@ -24,21 +25,25 @@ class GeneralUnivApplyInfoRecommendServiceTest { @Autowired private UnivApplyInfoFixture univApplyInfoFixture; - @Value("${university.term}") - private String term; + @Autowired + private TermFixture termFixture; + + private Term term; @BeforeEach void setUp() { - univApplyInfoFixture.괌대학_A_지원_정보(); - univApplyInfoFixture.괌대학_B_지원_정보(); - univApplyInfoFixture.네바다주립대학_라스베이거스_지원_정보(); - univApplyInfoFixture.메모리얼대학_세인트존스_A_지원_정보(); - univApplyInfoFixture.서던덴마크대학교_지원_정보(); - univApplyInfoFixture.코펜하겐IT대학_지원_정보(); - univApplyInfoFixture.그라츠대학_지원_정보(); - univApplyInfoFixture.그라츠공과대학_지원_정보(); - univApplyInfoFixture.린츠_카톨릭대학_지원_정보(); - univApplyInfoFixture.메이지대학_지원_정보(); + term = termFixture.현재_학기("2025-2"); + + univApplyInfoFixture.괌대학_A_지원_정보(term.getId()); + univApplyInfoFixture.괌대학_B_지원_정보(term.getId()); + univApplyInfoFixture.네바다주립대학_라스베이거스_지원_정보(term.getId()); + univApplyInfoFixture.메모리얼대학_세인트존스_A_지원_정보(term.getId()); + univApplyInfoFixture.서던덴마크대학교_지원_정보(term.getId()); + univApplyInfoFixture.코펜하겐IT대학_지원_정보(term.getId()); + univApplyInfoFixture.그라츠대학_지원_정보(term.getId()); + univApplyInfoFixture.그라츠공과대학_지원_정보(term.getId()); + univApplyInfoFixture.린츠_카톨릭대학_지원_정보(term.getId()); + univApplyInfoFixture.메이지대학_지원_정보(term.getId()); generalUnivApplyInfoRecommendService.init(); } @@ -50,8 +55,8 @@ void setUp() { // when & then assertAll( () -> assertThat(universities) - .extracting("term") - .allMatch(term::equals), + .extracting("termId") + .allMatch(term.getId()::equals), () -> assertThat(universities).hasSize(RECOMMEND_UNIV_APPLY_INFO_NUM) ); } diff --git a/src/test/java/com/example/solidconnection/university/service/LikedUnivApplyInfoServiceTest.java b/src/test/java/com/example/solidconnection/university/service/LikedUnivApplyInfoServiceTest.java index 2693d4501..bbc2b476b 100644 --- a/src/test/java/com/example/solidconnection/university/service/LikedUnivApplyInfoServiceTest.java +++ b/src/test/java/com/example/solidconnection/university/service/LikedUnivApplyInfoServiceTest.java @@ -10,6 +10,8 @@ import com.example.solidconnection.siteuser.domain.SiteUser; import com.example.solidconnection.siteuser.fixture.SiteUserFixture; import com.example.solidconnection.support.TestContainerSpringBootTest; +import com.example.solidconnection.term.domain.Term; +import com.example.solidconnection.term.fixture.TermFixture; import com.example.solidconnection.university.domain.LikedUnivApplyInfo; import com.example.solidconnection.university.domain.UnivApplyInfo; import com.example.solidconnection.university.dto.IsLikeResponse; @@ -39,20 +41,25 @@ class LikedUnivApplyInfoServiceTest { @Autowired private UnivApplyInfoFixture univApplyInfoFixture; + @Autowired + private TermFixture termFixture; + private SiteUser user; + private Term term; private UnivApplyInfo 괌대학_A_지원_정보; @BeforeEach void setUp() { + term = termFixture.현재_학기("2025-2"); user = siteUserFixture.사용자(); - 괌대학_A_지원_정보 = univApplyInfoFixture.괌대학_A_지원_정보(); + 괌대학_A_지원_정보 = univApplyInfoFixture.괌대학_A_지원_정보(term.getId()); } @Test void 관심_대학_지원_정보_목록을_조회한다() { // given - UnivApplyInfo 메이지대학_지원_정보 = univApplyInfoFixture.메이지대학_지원_정보(); - UnivApplyInfo 그라츠대학_지원_정보 = univApplyInfoFixture.그라츠대학_지원_정보(); + UnivApplyInfo 메이지대학_지원_정보 = univApplyInfoFixture.메이지대학_지원_정보(term.getId()); + UnivApplyInfo 그라츠대학_지원_정보 = univApplyInfoFixture.그라츠대학_지원_정보(term.getId()); saveLikedUnivApplyInfo(user, 메이지대학_지원_정보); saveLikedUnivApplyInfo(user, 그라츠대학_지원_정보); diff --git a/src/test/java/com/example/solidconnection/university/service/UnivApplyInfoQueryServiceTest.java b/src/test/java/com/example/solidconnection/university/service/UnivApplyInfoQueryServiceTest.java index 661294363..cf8a0590d 100644 --- a/src/test/java/com/example/solidconnection/university/service/UnivApplyInfoQueryServiceTest.java +++ b/src/test/java/com/example/solidconnection/university/service/UnivApplyInfoQueryServiceTest.java @@ -11,6 +11,8 @@ import com.example.solidconnection.common.exception.CustomException; import com.example.solidconnection.support.TestContainerSpringBootTest; +import com.example.solidconnection.term.domain.Term; +import com.example.solidconnection.term.fixture.TermFixture; import com.example.solidconnection.university.domain.UnivApplyInfo; import com.example.solidconnection.university.dto.UnivApplyInfoDetailResponse; import com.example.solidconnection.university.dto.UnivApplyInfoFilterSearchRequest; @@ -20,11 +22,11 @@ import com.example.solidconnection.university.fixture.UnivApplyInfoFixture; import com.example.solidconnection.university.repository.UnivApplyInfoRepository; import java.util.List; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.mock.mockito.SpyBean; @TestContainerSpringBootTest @@ -43,8 +45,15 @@ class UnivApplyInfoQueryServiceTest { @Autowired private LanguageRequirementFixture languageRequirementFixture; - @Value("${university.term}") - public String term; + @Autowired + private TermFixture termFixture; + + private Term term; + + @BeforeEach + void setUp() { + term = termFixture.현재_학기("2025-2"); + } @Nested class 대학_지원_정보_상세_조회 { @@ -52,7 +61,7 @@ class 대학_지원_정보_상세_조회 { @Test void 대학_지원_정보를_상세_조회한다() { // given - UnivApplyInfo 괌대학_A_지원_정보 = univApplyInfoFixture.괌대학_A_지원_정보(); + UnivApplyInfo 괌대학_A_지원_정보 = univApplyInfoFixture.괌대학_A_지원_정보(term.getId()); // when UnivApplyInfoDetailResponse response = univApplyInfoQueryService.getUnivApplyInfoDetail(괌대학_A_지원_정보.getId()); @@ -64,7 +73,7 @@ class 대학_지원_정보_상세_조회 { @Test void 대학_지원_정보_상세_조회시_캐시가_적용된다() { // given - UnivApplyInfo 괌대학_A_지원_정보 = univApplyInfoFixture.괌대학_A_지원_정보(); + UnivApplyInfo 괌대학_A_지원_정보 = univApplyInfoFixture.괌대학_A_지원_정보(term.getId()); // when UnivApplyInfoDetailResponse firstResponse = univApplyInfoQueryService.getUnivApplyInfoDetail(괌대학_A_지원_정보.getId()); @@ -96,34 +105,34 @@ class 대학_지원_정보_필터링_검색 { void 어학_시험_종류로_필터링한다() { // given UnivApplyInfoFilterSearchRequest request = new UnivApplyInfoFilterSearchRequest(TOEIC, null, null); - UnivApplyInfo 괌대학_A_지원_정보 = univApplyInfoFixture.괌대학_A_지원_정보(); + UnivApplyInfo 괌대학_A_지원_정보 = univApplyInfoFixture.괌대학_A_지원_정보(term.getId()); languageRequirementFixture.토익_800(괌대학_A_지원_정보); - UnivApplyInfo 괌대학_B_지원_정보 = univApplyInfoFixture.괌대학_B_지원_정보(); + UnivApplyInfo 괌대학_B_지원_정보 = univApplyInfoFixture.괌대학_B_지원_정보(term.getId()); languageRequirementFixture.토플_70(괌대학_B_지원_정보); // when - UnivApplyInfoPreviewResponses response = univApplyInfoQueryService.searchUnivApplyInfoByFilter(request, term); + UnivApplyInfoPreviewResponses response = univApplyInfoQueryService.searchUnivApplyInfoByFilter(request); // then assertThat(response.univApplyInfoPreviews()) - .containsExactly(UnivApplyInfoPreviewResponse.from(괌대학_A_지원_정보)); + .containsExactly(UnivApplyInfoPreviewResponse.from(괌대학_A_지원_정보, term.getName())); } @Test void 어학_시험_점수가_기준치_이상인_곳을_필터링한다() { // given UnivApplyInfoFilterSearchRequest request = new UnivApplyInfoFilterSearchRequest(TOEIC, "800", null); - UnivApplyInfo 괌대학_A_지원_정보 = univApplyInfoFixture.괌대학_A_지원_정보(); + UnivApplyInfo 괌대학_A_지원_정보 = univApplyInfoFixture.괌대학_A_지원_정보(term.getId()); languageRequirementFixture.토익_800(괌대학_A_지원_정보); - UnivApplyInfo 괌대학_B_지원_정보 = univApplyInfoFixture.괌대학_B_지원_정보(); + UnivApplyInfo 괌대학_B_지원_정보 = univApplyInfoFixture.괌대학_B_지원_정보(term.getId()); languageRequirementFixture.토익_900(괌대학_B_지원_정보); // when - UnivApplyInfoPreviewResponses response = univApplyInfoQueryService.searchUnivApplyInfoByFilter(request, term); + UnivApplyInfoPreviewResponses response = univApplyInfoQueryService.searchUnivApplyInfoByFilter(request); // then assertThat(response.univApplyInfoPreviews()) - .containsExactly(UnivApplyInfoPreviewResponse.from(괌대학_A_지원_정보)); + .containsExactly(UnivApplyInfoPreviewResponse.from(괌대학_A_지원_정보, term.getName())); } @Test @@ -131,23 +140,23 @@ class 대학_지원_정보_필터링_검색 { // given UnivApplyInfoFilterSearchRequest request1 = new UnivApplyInfoFilterSearchRequest(TOEIC, null, List.of("US")); UnivApplyInfoFilterSearchRequest request2 = new UnivApplyInfoFilterSearchRequest(TOEIC, null, List.of("US", "CA")); - UnivApplyInfo 괌대학_A_지원_정보 = univApplyInfoFixture.괌대학_A_지원_정보(); + UnivApplyInfo 괌대학_A_지원_정보 = univApplyInfoFixture.괌대학_A_지원_정보(term.getId()); languageRequirementFixture.토익_800(괌대학_A_지원_정보); - UnivApplyInfo 메모리얼대학_세인트존스_A_지원_정보 = univApplyInfoFixture.메모리얼대학_세인트존스_A_지원_정보(); + UnivApplyInfo 메모리얼대학_세인트존스_A_지원_정보 = univApplyInfoFixture.메모리얼대학_세인트존스_A_지원_정보(term.getId()); languageRequirementFixture.토익_800(메모리얼대학_세인트존스_A_지원_정보); // when - UnivApplyInfoPreviewResponses response1 = univApplyInfoQueryService.searchUnivApplyInfoByFilter(request1, term); - UnivApplyInfoPreviewResponses response2 = univApplyInfoQueryService.searchUnivApplyInfoByFilter(request2, term); + UnivApplyInfoPreviewResponses response1 = univApplyInfoQueryService.searchUnivApplyInfoByFilter(request1); + UnivApplyInfoPreviewResponses response2 = univApplyInfoQueryService.searchUnivApplyInfoByFilter(request2); // then assertAll( () -> assertThat(response1.univApplyInfoPreviews()) - .containsExactly(UnivApplyInfoPreviewResponse.from(괌대학_A_지원_정보)), + .containsExactly(UnivApplyInfoPreviewResponse.from(괌대학_A_지원_정보, term.getName())), () -> assertThat(response2.univApplyInfoPreviews()) .containsExactlyInAnyOrder( - UnivApplyInfoPreviewResponse.from(괌대학_A_지원_정보), - UnivApplyInfoPreviewResponse.from(메모리얼대학_세인트존스_A_지원_정보) + UnivApplyInfoPreviewResponse.from(괌대학_A_지원_정보, term.getName()), + UnivApplyInfoPreviewResponse.from(메모리얼대학_세인트존스_A_지원_정보, term.getName()) ) ); } @@ -159,17 +168,17 @@ class 대학_지원_정보_텍스트_검색 { @Test void 텍스트가_없으면_전체_대학을_id_순으로_정렬하여_반환한다() { // given - UnivApplyInfo 괌대학_A_지원_정보 = univApplyInfoFixture.괌대학_A_지원_정보(); - UnivApplyInfo 메이지대학_지원_정보 = univApplyInfoFixture.메이지대학_지원_정보(); + UnivApplyInfo 괌대학_A_지원_정보 = univApplyInfoFixture.괌대학_A_지원_정보(term.getId()); + UnivApplyInfo 메이지대학_지원_정보 = univApplyInfoFixture.메이지대학_지원_정보(term.getId()); // when - UnivApplyInfoPreviewResponses response = univApplyInfoQueryService.searchUnivApplyInfoByText(null, term); + UnivApplyInfoPreviewResponses response = univApplyInfoQueryService.searchUnivApplyInfoByText(null); // then assertThat(response.univApplyInfoPreviews()) .containsExactly( - UnivApplyInfoPreviewResponse.from(괌대학_A_지원_정보), - UnivApplyInfoPreviewResponse.from(메이지대학_지원_정보) + UnivApplyInfoPreviewResponse.from(괌대학_A_지원_정보, term.getName()), + UnivApplyInfoPreviewResponse.from(메이지대학_지원_정보, term.getName()) ); } @@ -180,18 +189,18 @@ class 각각의_검색_대상에_대해_검색한다 { void 국문_대학_지원_정보명() { // given String text = "메"; - UnivApplyInfo 메이지대학_지원_정보 = univApplyInfoFixture.메이지대학_지원_정보(); - UnivApplyInfo 메모리얼대학_세인트존스_A_지원_정보 = univApplyInfoFixture.메모리얼대학_세인트존스_A_지원_정보(); - univApplyInfoFixture.괌대학_A_지원_정보(); + UnivApplyInfo 메이지대학_지원_정보 = univApplyInfoFixture.메이지대학_지원_정보(term.getId()); + UnivApplyInfo 메모리얼대학_세인트존스_A_지원_정보 = univApplyInfoFixture.메모리얼대학_세인트존스_A_지원_정보(term.getId()); + univApplyInfoFixture.괌대학_A_지원_정보(term.getId()); // when - UnivApplyInfoPreviewResponses response = univApplyInfoQueryService.searchUnivApplyInfoByText(text, term); + UnivApplyInfoPreviewResponses response = univApplyInfoQueryService.searchUnivApplyInfoByText(text); // then assertThat(response.univApplyInfoPreviews()) .containsExactly( - UnivApplyInfoPreviewResponse.from(메이지대학_지원_정보), - UnivApplyInfoPreviewResponse.from(메모리얼대학_세인트존스_A_지원_정보) + UnivApplyInfoPreviewResponse.from(메이지대학_지원_정보, term.getName()), + UnivApplyInfoPreviewResponse.from(메모리얼대학_세인트존스_A_지원_정보, term.getName()) ); } @@ -199,18 +208,18 @@ class 각각의_검색_대상에_대해_검색한다 { void 국문_국가명() { // given String text = "미국"; - UnivApplyInfo 괌대학_A_지원_정보 = univApplyInfoFixture.괌대학_A_지원_정보(); - UnivApplyInfo 괌대학_B_지원_정보 = univApplyInfoFixture.괌대학_B_지원_정보(); - univApplyInfoFixture.메이지대학_지원_정보(); + UnivApplyInfo 괌대학_A_지원_정보 = univApplyInfoFixture.괌대학_A_지원_정보(term.getId()); + UnivApplyInfo 괌대학_B_지원_정보 = univApplyInfoFixture.괌대학_B_지원_정보(term.getId()); + univApplyInfoFixture.메이지대학_지원_정보(term.getId()); // when - UnivApplyInfoPreviewResponses response = univApplyInfoQueryService.searchUnivApplyInfoByText(text, term); + UnivApplyInfoPreviewResponses response = univApplyInfoQueryService.searchUnivApplyInfoByText(text); // then assertThat(response.univApplyInfoPreviews()) .containsExactly( - UnivApplyInfoPreviewResponse.from(괌대학_A_지원_정보), - UnivApplyInfoPreviewResponse.from(괌대학_B_지원_정보) + UnivApplyInfoPreviewResponse.from(괌대학_A_지원_정보, term.getName()), + UnivApplyInfoPreviewResponse.from(괌대학_B_지원_정보, term.getName()) ); } @@ -218,18 +227,18 @@ class 각각의_검색_대상에_대해_검색한다 { void 국문_권역명() { // given String text = "유럽"; - UnivApplyInfo 린츠_카톨릭대학_지원_정보 = univApplyInfoFixture.린츠_카톨릭대학_지원_정보(); - UnivApplyInfo 서던덴마크대학교_지원_정보 = univApplyInfoFixture.서던덴마크대학교_지원_정보(); - univApplyInfoFixture.메이지대학_지원_정보(); + UnivApplyInfo 린츠_카톨릭대학_지원_정보 = univApplyInfoFixture.린츠_카톨릭대학_지원_정보(term.getId()); + UnivApplyInfo 서던덴마크대학교_지원_정보 = univApplyInfoFixture.서던덴마크대학교_지원_정보(term.getId()); + univApplyInfoFixture.메이지대학_지원_정보(term.getId()); // when - UnivApplyInfoPreviewResponses response = univApplyInfoQueryService.searchUnivApplyInfoByText(text, term); + UnivApplyInfoPreviewResponses response = univApplyInfoQueryService.searchUnivApplyInfoByText(text); // then assertThat(response.univApplyInfoPreviews()) .containsExactly( - UnivApplyInfoPreviewResponse.from(린츠_카톨릭대학_지원_정보), - UnivApplyInfoPreviewResponse.from(서던덴마크대학교_지원_정보) + UnivApplyInfoPreviewResponse.from(린츠_카톨릭대학_지원_정보, term.getName()), + UnivApplyInfoPreviewResponse.from(서던덴마크대학교_지원_정보, term.getName()) ); } } @@ -238,19 +247,19 @@ class 각각의_검색_대상에_대해_검색한다 { void 대학_국가_권역_일치_순서로_정렬하여_응답한다() { // given String text = "아"; - UnivApplyInfo 권역_아 = univApplyInfoFixture.메이지대학_지원_정보(); - UnivApplyInfo 국가_아 = univApplyInfoFixture.그라츠대학_지원_정보(); - UnivApplyInfo 대학지원정보_아 = univApplyInfoFixture.아칸소주립대학_지원_정보(); + UnivApplyInfo 권역_아 = univApplyInfoFixture.메이지대학_지원_정보(term.getId()); + UnivApplyInfo 국가_아 = univApplyInfoFixture.그라츠대학_지원_정보(term.getId()); + UnivApplyInfo 대학지원정보_아 = univApplyInfoFixture.아칸소주립대학_지원_정보(term.getId()); // when - UnivApplyInfoPreviewResponses response = univApplyInfoQueryService.searchUnivApplyInfoByText(text, term); + UnivApplyInfoPreviewResponses response = univApplyInfoQueryService.searchUnivApplyInfoByText(text); // then assertThat(response.univApplyInfoPreviews()) .containsExactly( - UnivApplyInfoPreviewResponse.from(대학지원정보_아), - UnivApplyInfoPreviewResponse.from(국가_아), - UnivApplyInfoPreviewResponse.from(권역_아) + UnivApplyInfoPreviewResponse.from(대학지원정보_아, term.getName()), + UnivApplyInfoPreviewResponse.from(국가_아, term.getName()), + UnivApplyInfoPreviewResponse.from(권역_아, term.getName()) ); } @@ -258,11 +267,11 @@ class 각각의_검색_대상에_대해_검색한다 { void 캐시가_적용된다() { // given String text = "Guam"; - UnivApplyInfo 괌대학_A_지원_정보 = univApplyInfoFixture.괌대학_A_지원_정보(); + UnivApplyInfo 괌대학_A_지원_정보 = univApplyInfoFixture.괌대학_A_지원_정보(term.getId()); // when - UnivApplyInfoPreviewResponses firstResponse = univApplyInfoQueryService.searchUnivApplyInfoByText(text, term); - UnivApplyInfoPreviewResponses secondResponse = univApplyInfoQueryService.searchUnivApplyInfoByText(text, term); + UnivApplyInfoPreviewResponses firstResponse = univApplyInfoQueryService.searchUnivApplyInfoByText(text); + UnivApplyInfoPreviewResponses secondResponse = univApplyInfoQueryService.searchUnivApplyInfoByText(text); // then assertThatCode(() -> { @@ -270,7 +279,7 @@ class 각각의_검색_대상에_대해_검색한다 { List secondResponseIds = extractIds(secondResponse); assertThat(firstResponseIds).isEqualTo(secondResponseIds); }).doesNotThrowAnyException(); - then(univApplyInfoRepository).should(times(1)).findAllByText(text, term); + then(univApplyInfoRepository).should(times(1)).findAllByText(text, term.getId()); } private List extractIds(UnivApplyInfoPreviewResponses responses) { diff --git a/src/test/java/com/example/solidconnection/university/service/UnivApplyInfoRecommendServiceTest.java b/src/test/java/com/example/solidconnection/university/service/UnivApplyInfoRecommendServiceTest.java index 2c8dd954e..9eeeb2c2b 100644 --- a/src/test/java/com/example/solidconnection/university/service/UnivApplyInfoRecommendServiceTest.java +++ b/src/test/java/com/example/solidconnection/university/service/UnivApplyInfoRecommendServiceTest.java @@ -12,6 +12,8 @@ import com.example.solidconnection.siteuser.domain.SiteUser; import com.example.solidconnection.siteuser.fixture.SiteUserFixture; import com.example.solidconnection.support.TestContainerSpringBootTest; +import com.example.solidconnection.term.domain.Term; +import com.example.solidconnection.term.fixture.TermFixture; import com.example.solidconnection.university.domain.UnivApplyInfo; import com.example.solidconnection.university.dto.UnivApplyInfoPreviewResponse; import com.example.solidconnection.university.dto.UnivApplyInfoRecommendsResponse; @@ -50,7 +52,11 @@ class UnivApplyInfoRecommendServiceTest { @Autowired private UnivApplyInfoFixture univApplyInfoFixture; + @Autowired + private TermFixture termFixture; + private SiteUser user; + private Term term; private UnivApplyInfo 괌대학_A_지원_정보; private UnivApplyInfo 괌대학_B_지원_정보; private UnivApplyInfo 네바다주립대학_라스베이거스_지원_정보; @@ -60,17 +66,18 @@ class UnivApplyInfoRecommendServiceTest { @BeforeEach void setUp() { + term = termFixture.현재_학기("2025-2"); user = siteUserFixture.사용자(); - 괌대학_A_지원_정보 = univApplyInfoFixture.괌대학_A_지원_정보(); - 괌대학_B_지원_정보 = univApplyInfoFixture.괌대학_B_지원_정보(); - 네바다주립대학_라스베이거스_지원_정보 = univApplyInfoFixture.네바다주립대학_라스베이거스_지원_정보(); - 메모리얼대학_세인트존스_A_지원_정보 = univApplyInfoFixture.메모리얼대학_세인트존스_A_지원_정보(); - 서던덴마크대학교_지원_정보 = univApplyInfoFixture.서던덴마크대학교_지원_정보(); - 코펜하겐IT대학_지원_정보 = univApplyInfoFixture.코펜하겐IT대학_지원_정보(); - univApplyInfoFixture.그라츠대학_지원_정보(); - univApplyInfoFixture.그라츠공과대학_지원_정보(); - univApplyInfoFixture.린츠_카톨릭대학_지원_정보(); - univApplyInfoFixture.메이지대학_지원_정보(); + 괌대학_A_지원_정보 = univApplyInfoFixture.괌대학_A_지원_정보(term.getId()); + 괌대학_B_지원_정보 = univApplyInfoFixture.괌대학_B_지원_정보(term.getId()); + 네바다주립대학_라스베이거스_지원_정보 = univApplyInfoFixture.네바다주립대학_라스베이거스_지원_정보(term.getId()); + 메모리얼대학_세인트존스_A_지원_정보 = univApplyInfoFixture.메모리얼대학_세인트존스_A_지원_정보(term.getId()); + 서던덴마크대학교_지원_정보 = univApplyInfoFixture.서던덴마크대학교_지원_정보(term.getId()); + 코펜하겐IT대학_지원_정보 = univApplyInfoFixture.코펜하겐IT대학_지원_정보(term.getId()); + univApplyInfoFixture.그라츠대학_지원_정보(term.getId()); + univApplyInfoFixture.그라츠공과대학_지원_정보(term.getId()); + univApplyInfoFixture.린츠_카톨릭대학_지원_정보(term.getId()); + univApplyInfoFixture.메이지대학_지원_정보(term.getId()); generalUnivApplyInfoRecommendService.init(); } @@ -86,10 +93,10 @@ void setUp() { assertThat(response.recommendedUniversities()) .hasSize(RECOMMEND_UNIV_APPLY_INFO_NUM) .containsAll(List.of( - UnivApplyInfoPreviewResponse.from(괌대학_A_지원_정보), - UnivApplyInfoPreviewResponse.from(괌대학_B_지원_정보), - UnivApplyInfoPreviewResponse.from(메모리얼대학_세인트존스_A_지원_정보), - UnivApplyInfoPreviewResponse.from(네바다주립대학_라스베이거스_지원_정보) + UnivApplyInfoPreviewResponse.from(괌대학_A_지원_정보, term.getName()), + UnivApplyInfoPreviewResponse.from(괌대학_B_지원_정보, term.getName()), + UnivApplyInfoPreviewResponse.from(메모리얼대학_세인트존스_A_지원_정보, term.getName()), + UnivApplyInfoPreviewResponse.from(네바다주립대학_라스베이거스_지원_정보, term.getName()) )); } @@ -105,8 +112,8 @@ void setUp() { assertThat(response.recommendedUniversities()) .hasSize(RECOMMEND_UNIV_APPLY_INFO_NUM) .containsAll(List.of( - UnivApplyInfoPreviewResponse.from(서던덴마크대학교_지원_정보), - UnivApplyInfoPreviewResponse.from(코펜하겐IT대학_지원_정보) + UnivApplyInfoPreviewResponse.from(서던덴마크대학교_지원_정보, term.getName()), + UnivApplyInfoPreviewResponse.from(코펜하겐IT대학_지원_정보, term.getName()) )); } @@ -123,12 +130,12 @@ void setUp() { assertThat(response.recommendedUniversities()) .hasSize(RECOMMEND_UNIV_APPLY_INFO_NUM) .containsExactlyInAnyOrder( - UnivApplyInfoPreviewResponse.from(괌대학_A_지원_정보), - UnivApplyInfoPreviewResponse.from(괌대학_B_지원_정보), - UnivApplyInfoPreviewResponse.from(메모리얼대학_세인트존스_A_지원_정보), - UnivApplyInfoPreviewResponse.from(네바다주립대학_라스베이거스_지원_정보), - UnivApplyInfoPreviewResponse.from(서던덴마크대학교_지원_정보), - UnivApplyInfoPreviewResponse.from(코펜하겐IT대학_지원_정보) + UnivApplyInfoPreviewResponse.from(괌대학_A_지원_정보, term.getName()), + UnivApplyInfoPreviewResponse.from(괌대학_B_지원_정보, term.getName()), + UnivApplyInfoPreviewResponse.from(메모리얼대학_세인트존스_A_지원_정보, term.getName()), + UnivApplyInfoPreviewResponse.from(네바다주립대학_라스베이거스_지원_정보, term.getName()), + UnivApplyInfoPreviewResponse.from(서던덴마크대학교_지원_정보, term.getName()), + UnivApplyInfoPreviewResponse.from(코펜하겐IT대학_지원_정보, term.getName()) ); } @@ -142,7 +149,11 @@ void setUp() { .hasSize(RECOMMEND_UNIV_APPLY_INFO_NUM) .containsExactlyInAnyOrderElementsOf( generalUnivApplyInfoRecommendService.getGeneralRecommends().stream() - .map(UnivApplyInfoPreviewResponse::from).toList() + .map(univApplyInfo -> UnivApplyInfoPreviewResponse.from( + univApplyInfo, + term.getName() + )) + .toList() ); } @@ -156,7 +167,10 @@ void setUp() { .hasSize(RECOMMEND_UNIV_APPLY_INFO_NUM) .containsExactlyInAnyOrderElementsOf( generalUnivApplyInfoRecommendService.getGeneralRecommends().stream() - .map(UnivApplyInfoPreviewResponse::from) + .map(univApplyInfo -> UnivApplyInfoPreviewResponse.from( + univApplyInfo, + term.getName() + )) .toList() ); } diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml index 9d255b46b..ca16a6f01 100644 --- a/src/test/resources/application.yml +++ b/src/test/resources/application.yml @@ -75,8 +75,6 @@ sentry: send-default-pii: true traces-sample-rate: 1.0 exception-resolver-order: -2147483647 -university: - term: 2024-1 jwt: secret: 1234567-1234-1234-1234-12345678901