Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
d0e15b4
feat: 학기 테이블 추가
Gyuhyeok99 Oct 8, 2025
6721a44
refactor: UnivApplyInfo의 term -> termId로 변경
Gyuhyeok99 Oct 8, 2025
5094455
refactor: UnivApplyInfoRepository의 term -> termId로 변경
Gyuhyeok99 Oct 8, 2025
9ddea89
refactor: UnivApplyInfo 관련 service의 term -> termId로 변경
Gyuhyeok99 Oct 8, 2025
76ea449
refactor: UnivApplyInfo controller term 제거
Gyuhyeok99 Oct 8, 2025
9ffa5fc
feat: Term 관련 fixture 추가
Gyuhyeok99 Oct 8, 2025
ae8b387
refactor: UnivApplyInfoFixture의 term -> termId로 변경
Gyuhyeok99 Oct 8, 2025
78d15f7
test: UnivApplyInfo 관련 테스트 시 Term fixture 추가
Gyuhyeok99 Oct 8, 2025
4e35d2e
refactor: Application의 term -> termId로 변경
Gyuhyeok99 Oct 8, 2025
d31df70
refactor: ApplicationRepository의 term -> termId로 변경
Gyuhyeok99 Oct 8, 2025
6b35b3a
refactor: Application 관련 service의 term -> termId로 변경
Gyuhyeok99 Oct 8, 2025
8422034
refactor: ApplicationFixture의 term -> termId로 변경
Gyuhyeok99 Oct 8, 2025
8385b37
test: Application 관련 테스트 시 Term fixture 추가
Gyuhyeok99 Oct 8, 2025
3fb435d
refactor: Mentor의 term -> termId로 변경
Gyuhyeok99 Oct 8, 2025
4921b0a
refactor: Mentor 관련 service의 term -> termId로 변경
Gyuhyeok99 Oct 8, 2025
8787ede
refactor: MentorFixture의 term -> termId로 변경
Gyuhyeok99 Oct 8, 2025
0a67df5
test: Mentor 관련 테스트 시 Term fixture 추가
Gyuhyeok99 Oct 8, 2025
7a1ac3b
test: term 관련 yml 제거
Gyuhyeok99 Oct 8, 2025
0dcbb5d
refactor: term 관련 data.sql 추가
Gyuhyeok99 Oct 8, 2025
b896dc0
chore: 서브모듈 최신화
Gyuhyeok99 Oct 8, 2025
b5455e9
refactor: 코드래빗 반영
Gyuhyeok99 Oct 8, 2025
1d49a86
feat: flyway 스크립트 작성
Gyuhyeok99 Oct 14, 2025
0ce3b05
feat: flyway 스크립트 수정
Gyuhyeok99 Oct 30, 2025
10ffecc
refactor: 2026-1학기를 제외한 나머지는 is_current를 false로 변경
Gyuhyeok99 Oct 30, 2025
4e508c3
fix: 충돌 해결
Gyuhyeok99 Nov 3, 2025
3f0caf0
refactor: term -> termId 변경
Gyuhyeok99 Nov 3, 2025
8a4719b
refactor: Long type으로 변경
Gyuhyeok99 Nov 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand All @@ -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;
Expand All @@ -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;
}
Expand All @@ -94,7 +94,7 @@ public Application(
SiteUser siteUser,
Gpa gpa,
LanguageTest languageTest,
String term,
long termId,
Integer updateCount,
long firstChoiceUnivApplyInfoId,
Long secondChoiceUnivApplyInfoId,
Expand All @@ -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;
Expand All @@ -116,15 +116,15 @@ public Application(
SiteUser siteUser,
Gpa gpa,
LanguageTest languageTest,
String term,
long termId,
long firstChoiceUnivApplyInfoId,
Long secondChoiceUnivApplyInfoId,
Long thirdChoiceUnivApplyInfoId,
String nicknameForApply) {
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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,22 @@ public interface ApplicationRepository extends JpaRepository<Application, Long>
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<Application> findAllByUnivApplyInfoIds(@Param("univApplyInfoIds") List<Long> univApplyInfoIds, @Param("status") VerifyStatus status, @Param("term") String term);
List<Application> findAllByUnivApplyInfoIds(@Param("univApplyInfoIds") List<Long> 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<Application> findBySiteUserIdAndTerm(@Param("siteUserId") long siteUserId, @Param("term") String term);
Optional<Application> 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));
}
}
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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;
Expand All @@ -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;

Expand All @@ -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)
Expand All @@ -47,15 +47,20 @@ public ApplicationsResponse getApplicants(long siteUserId, String regionCode, St
SiteUser siteUser = siteUserRepository.findById(siteUserId)
.orElseThrow(() -> new CustomException(USER_NOT_FOUND));
List<String> keywords = StringUtils.isNotBlank(keyword) ? List.of(keyword) : List.of();
List<UnivApplyInfo> univApplyInfos = universityFilterRepository.findAllByRegionCodeAndKeywordsAndTerm(regionCode, keywords, term);

Term term = termRepository.findByIsCurrentTrue()
.orElseThrow(() -> new CustomException(CURRENT_TERM_NOT_FOUND));

List<UnivApplyInfo> univApplyInfos = universityFilterRepository.findAllByRegionCodeAndKeywordsAndTermId(regionCode, keywords, term.getId());
if (univApplyInfos.isEmpty()) {
return new ApplicationsResponse(List.of(), List.of(), List.of());
}

// 2. 조건에 맞는 모든 Application 한 번에 조회
List<Long> univApplyInfoIds = univApplyInfos.stream()
.map(UnivApplyInfo::getId)
.toList();
List<Application> applications = applicationRepository.findAllByUnivApplyInfoIds(univApplyInfoIds, VerifyStatus.APPROVED, term);
List<Application> applications = applicationRepository.findAllByUnivApplyInfoIds(univApplyInfoIds, VerifyStatus.APPROVED, term.getId());
// 3. 지원서 분류 및 DTO 변환
return classifyApplicationsByChoice(univApplyInfos, applications, siteUser);
}
Expand All @@ -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<Long> univApplyInfoIds = Stream.of(
userLatestApplication.getFirstChoiceUnivApplyInfoId(),
Expand All @@ -78,7 +87,7 @@ public ApplicationsResponse getApplicantsByUserApplications(long siteUserId) {
return new ApplicationsResponse(List.of(), List.of(), List.of());
}

List<Application> applications = applicationRepository.findAllByUnivApplyInfoIds(univApplyInfoIds, VerifyStatus.APPROVED, term);
List<Application> applications = applicationRepository.findAllByUnivApplyInfoIds(univApplyInfoIds, VerifyStatus.APPROVED, term.getId());
List<UnivApplyInfo> univApplyInfos = univApplyInfoRepository.findAllByIds(univApplyInfoIds);

return classifyApplicationsByChoice(univApplyInfos, applications, siteUser);
Expand Down Expand Up @@ -130,7 +139,11 @@ private List<ApplicantsResponse> 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);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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;

Expand All @@ -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로 입력시킨다.
Expand All @@ -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<Application> existingApplication = applicationRepository.findBySiteUserIdAndTerm(siteUser.getId(), term);
Optional<Application> existingApplication = applicationRepository.findBySiteUserIdAndTermId(siteUser.getId(), term.getId());
int updateCount = existingApplication
.map(application -> {
validateUpdateLimitNotExceed(application);
Expand All @@ -67,7 +69,7 @@ public ApplicationSubmissionResponse apply(long siteUserId, ApplyRequest applyRe
siteUser,
gpaScore.getGpa(),
languageTestScore.getLanguageTest(),
term,
term.getId(),
updateCount,
firstChoiceUnivApplyInfoId,
secondChoiceUnivApplyInfoId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(), "로그아웃 되었습니다."),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,17 @@ 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,
mentorUser.getNickname(),
mentorUser.getProfileImageUrl(),
university.getCountry().getKoreanName(),
university.getKoreanName(),
mentor.getTerm(),
termName,
mentor.getMenteeCount(),
mentor.isHasBadge(),
mentor.getIntroduction(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ public record MentorMyPageResponse(
List<ChannelResponse> 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(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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<Long, SiteUser> getMentorIdToSiteUserMap(List<Mentor> mentors) {
List<Long> mentorUserIds = mentors.stream().map(Mentor::getSiteUserId).toList();
Expand Down Expand Up @@ -73,4 +77,17 @@ public Map<Long, Boolean> getMentorIdToIsApplied(List<Mentor> mentors, long curr
mentor -> appliedMentorIds.contains(mentor.getId())
));
}

public Map<Long, String> getTermIdToNameMap(List<Mentor> mentors) {
if (mentors.isEmpty()) {
return Collections.emptyMap();
}

Set<Long> termIds = mentors.stream()
.map(Mentor::getTermId)
.collect(Collectors.toSet());

return termRepository.findAllById(termIds).stream()
.collect(Collectors.toMap(Term::getId, Term::getName));
}
}
Loading
Loading