diff --git a/backend/src/main/java/com/cruru/applicant/domain/repository/ApplicantRepository.java b/backend/src/main/java/com/cruru/applicant/domain/repository/ApplicantRepository.java index 784344b42..95279c4fc 100644 --- a/backend/src/main/java/com/cruru/applicant/domain/repository/ApplicantRepository.java +++ b/backend/src/main/java/com/cruru/applicant/domain/repository/ApplicantRepository.java @@ -2,6 +2,7 @@ import com.cruru.applicant.domain.Applicant; import com.cruru.applicant.domain.dto.ApplicantCard; +import com.cruru.dashboard.domain.Dashboard; import com.cruru.process.domain.Process; import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; @@ -35,4 +36,7 @@ a.id, a.name, a.createdDate, a.isRejected, COUNT(e), COALESCE(AVG(e.score), 0.00 GROUP BY a.id, a.name, a.createdDate, a.isRejected """) List findApplicantCardsByProcess(@Param("process") Process process); + + @Query("SELECT a FROM Applicant a JOIN FETCH a.process p JOIN FETCH p.dashboard d WHERE d = :dashboard") + List findAllByDashboard(@Param("dashboard") Dashboard dashboard); } diff --git a/backend/src/main/java/com/cruru/applyform/domain/repository/ApplyFormRepository.java b/backend/src/main/java/com/cruru/applyform/domain/repository/ApplyFormRepository.java index 28144e79a..ec6bfc72d 100644 --- a/backend/src/main/java/com/cruru/applyform/domain/repository/ApplyFormRepository.java +++ b/backend/src/main/java/com/cruru/applyform/domain/repository/ApplyFormRepository.java @@ -2,9 +2,12 @@ import com.cruru.applyform.domain.ApplyForm; import com.cruru.dashboard.domain.Dashboard; +import com.cruru.dashboard.domain.DashboardApplyFormDto; +import java.util.List; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; public interface ApplyFormRepository extends JpaRepository { @@ -16,4 +19,13 @@ public interface ApplyFormRepository extends JpaRepository { WHERE d.id = :dashboardId """) Optional findByDashboardId(long dashboardId); + + @Query(""" + SELECT new com.cruru.dashboard.domain.DashboardApplyFormDto(d, a) + FROM ApplyForm a + JOIN FETCH a.dashboard d + JOIN FETCH d.club c + WHERE c.id = :clubId + """) + List findAllByClub(@Param("clubId") Long clubId); } diff --git a/backend/src/main/java/com/cruru/dashboard/domain/DashboardApplyFormDto.java b/backend/src/main/java/com/cruru/dashboard/domain/DashboardApplyFormDto.java new file mode 100644 index 000000000..adc37ab87 --- /dev/null +++ b/backend/src/main/java/com/cruru/dashboard/domain/DashboardApplyFormDto.java @@ -0,0 +1,7 @@ +package com.cruru.dashboard.domain; + +import com.cruru.applyform.domain.ApplyForm; + +public record DashboardApplyFormDto(Dashboard dashboard, ApplyForm applyForm) { + +} diff --git a/backend/src/main/java/com/cruru/dashboard/domain/repository/DashboardRepository.java b/backend/src/main/java/com/cruru/dashboard/domain/repository/DashboardRepository.java index 42e15f4ae..92b8c02d6 100644 --- a/backend/src/main/java/com/cruru/dashboard/domain/repository/DashboardRepository.java +++ b/backend/src/main/java/com/cruru/dashboard/domain/repository/DashboardRepository.java @@ -1,11 +1,8 @@ package com.cruru.dashboard.domain.repository; -import com.cruru.club.domain.Club; import com.cruru.dashboard.domain.Dashboard; -import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; public interface DashboardRepository extends JpaRepository { - List findAllByClub(Club club); } diff --git a/backend/src/main/java/com/cruru/dashboard/facade/DashboardFacade.java b/backend/src/main/java/com/cruru/dashboard/facade/DashboardFacade.java index 818039668..38301866d 100644 --- a/backend/src/main/java/com/cruru/dashboard/facade/DashboardFacade.java +++ b/backend/src/main/java/com/cruru/dashboard/facade/DashboardFacade.java @@ -1,7 +1,6 @@ package com.cruru.dashboard.facade; import com.cruru.applicant.domain.Applicant; -import com.cruru.applicant.service.ApplicantService; import com.cruru.applyform.controller.request.ApplyFormWriteRequest; import com.cruru.applyform.domain.ApplyForm; import com.cruru.applyform.service.ApplyFormService; @@ -13,10 +12,8 @@ import com.cruru.dashboard.controller.response.DashboardsOfClubResponse; import com.cruru.dashboard.controller.response.StatsResponse; import com.cruru.dashboard.domain.Dashboard; +import com.cruru.dashboard.domain.DashboardApplyFormDto; import com.cruru.dashboard.service.DashboardService; -import com.cruru.member.service.MemberService; -import com.cruru.process.domain.Process; -import com.cruru.process.service.ProcessService; import com.cruru.question.controller.request.QuestionCreateRequest; import com.cruru.question.service.QuestionService; import java.time.Clock; @@ -33,13 +30,10 @@ @RequiredArgsConstructor public class DashboardFacade { - private final MemberService memberService; private final ClubService clubService; private final DashboardService dashboardService; private final ApplyFormService applyFormService; private final QuestionService questionService; - private final ProcessService processService; - private final ApplicantService applicantService; private final Clock clock; @Transactional @@ -64,9 +58,7 @@ private ApplyFormWriteRequest toApplyFormWriteRequest(DashboardCreateRequest req } public DashboardsOfClubResponse findAllDashboardsByClubId(long clubId) { - Club club = clubService.findById(clubId); - - List dashboards = dashboardService.findAllByClub(club); + List dashboards = dashboardService.findAllByClub(clubId); String clubName = clubService.findById(clubId).getName(); LocalDateTime now = LocalDateTime.now(clock); @@ -79,10 +71,12 @@ public DashboardsOfClubResponse findAllDashboardsByClubId(long clubId) { return new DashboardsOfClubResponse(clubName, sortedDashboardPreviews); } - private DashboardPreviewResponse createDashboardPreviewResponse(Dashboard dashboard) { - ApplyForm applyForm = applyFormService.findByDashboard(dashboard); - List allApplicants = getAllApplicantsByDashboardId(dashboard); - StatsResponse stats = calculateStats(allApplicants); + private DashboardPreviewResponse createDashboardPreviewResponse(DashboardApplyFormDto dashboardApplyformDto) { + Dashboard dashboard = dashboardApplyformDto.dashboard(); + ApplyForm applyForm = dashboardApplyformDto.applyForm(); + + List applicants = dashboardService.findAllApplicants(dashboard); + StatsResponse stats = calculateStats(applicants); return new DashboardPreviewResponse( dashboard.getId(), applyForm.getId(), @@ -115,14 +109,6 @@ private List sortDashboardPreviews( return sortedDashboards; } - private List getAllApplicantsByDashboardId(Dashboard dashboard) { - List processes = processService.findAllByDashboard(dashboard); - return processes.stream() - .flatMap(process -> applicantService.findAllByProcess(process) - .stream()) - .toList(); - } - private StatsResponse calculateStats(List allApplicants) { int totalApplicants = allApplicants.size(); int totalFails = (int) allApplicants.stream() diff --git a/backend/src/main/java/com/cruru/dashboard/service/DashboardService.java b/backend/src/main/java/com/cruru/dashboard/service/DashboardService.java index ea9881ff4..65694bc08 100644 --- a/backend/src/main/java/com/cruru/dashboard/service/DashboardService.java +++ b/backend/src/main/java/com/cruru/dashboard/service/DashboardService.java @@ -1,7 +1,11 @@ package com.cruru.dashboard.service; +import com.cruru.applicant.domain.Applicant; +import com.cruru.applicant.domain.repository.ApplicantRepository; +import com.cruru.applyform.domain.repository.ApplyFormRepository; import com.cruru.club.domain.Club; import com.cruru.dashboard.domain.Dashboard; +import com.cruru.dashboard.domain.DashboardApplyFormDto; import com.cruru.dashboard.domain.repository.DashboardRepository; import com.cruru.dashboard.exception.DashboardNotFoundException; import com.cruru.process.domain.Process; @@ -19,6 +23,8 @@ public class DashboardService { private final DashboardRepository dashboardRepository; private final ProcessRepository processRepository; + private final ApplicantRepository applicantRepository; + private final ApplyFormRepository applyFormRepository; @Transactional public Dashboard create(Club club) { @@ -35,7 +41,11 @@ public Dashboard findById(Long id) { .orElseThrow(DashboardNotFoundException::new); } - public List findAllByClub(Club club) { - return dashboardRepository.findAllByClub(club); + public List findAllByClub(long clubId) { + return applyFormRepository.findAllByClub(clubId); + } + + public List findAllApplicants(Dashboard dashboard) { + return applicantRepository.findAllByDashboard(dashboard); } } diff --git a/backend/src/test/java/com/cruru/applicant/domain/repository/ApplicantRepositoryTest.java b/backend/src/test/java/com/cruru/applicant/domain/repository/ApplicantRepositoryTest.java index 5aab485dc..2727ab728 100644 --- a/backend/src/test/java/com/cruru/applicant/domain/repository/ApplicantRepositoryTest.java +++ b/backend/src/test/java/com/cruru/applicant/domain/repository/ApplicantRepositoryTest.java @@ -4,12 +4,19 @@ import static org.junit.jupiter.api.Assertions.assertAll; import com.cruru.applicant.domain.Applicant; +import com.cruru.dashboard.domain.Dashboard; +import com.cruru.dashboard.domain.repository.DashboardRepository; +import com.cruru.process.domain.Process; +import com.cruru.process.domain.repository.ProcessRepository; import com.cruru.applicant.domain.Evaluation; import com.cruru.applicant.domain.dto.ApplicantCard; import com.cruru.process.domain.Process; import com.cruru.process.domain.repository.ProcessRepository; import com.cruru.util.RepositoryTest; import com.cruru.util.fixture.ApplicantFixture; +import com.cruru.util.fixture.DashboardFixture; +import com.cruru.util.fixture.ProcessFixture; +import java.util.List; import com.cruru.util.fixture.EvaluationFixture; import com.cruru.util.fixture.ProcessFixture; import java.util.List; @@ -24,6 +31,9 @@ class ApplicantRepositoryTest extends RepositoryTest { @Autowired private ApplicantRepository applicantRepository; + @Autowired + private DashboardRepository dashboardRepository; + @Autowired private ProcessRepository processRepository; @@ -191,4 +201,25 @@ void findApplicantCardsByProcess_noEvaluations() { () -> assertThat(applicantCard.averageScore()).isZero() ); } + + @DisplayName("특정 대시보드에 해당하는 지원자 목록을 반환한다.") + @Test + void findAllByDashboard() { + // given + Dashboard dashboard = dashboardRepository.save(DashboardFixture.backend()); + + Process process1 = processRepository.save(ProcessFixture.applyType(dashboard)); + Process process2 = processRepository.save(ProcessFixture.approveType(dashboard)); + + Applicant applicant1 = applicantRepository.save(ApplicantFixture.pendingDobby(process1)); + Applicant applicant2 = applicantRepository.save(ApplicantFixture.pendingDobby(process1)); + Applicant applicant3 = applicantRepository.save(ApplicantFixture.pendingDobby(process2)); + + // when + List applicants = applicantRepository.findAllByDashboard(dashboard); + + // then + assertThat(applicants).hasSize(3); + assertThat(applicants).containsExactlyInAnyOrder(applicant1, applicant2, applicant3); + } } diff --git a/backend/src/test/java/com/cruru/applyform/domain/repository/ApplyFormRepositoryTest.java b/backend/src/test/java/com/cruru/applyform/domain/repository/ApplyFormRepositoryTest.java index 0ef2c691f..fe28c6d23 100644 --- a/backend/src/test/java/com/cruru/applyform/domain/repository/ApplyFormRepositoryTest.java +++ b/backend/src/test/java/com/cruru/applyform/domain/repository/ApplyFormRepositoryTest.java @@ -4,13 +4,18 @@ import static org.junit.jupiter.api.Assertions.assertAll; import com.cruru.applyform.domain.ApplyForm; +import com.cruru.club.domain.Club; +import com.cruru.club.domain.repository.ClubRepository; import com.cruru.dashboard.domain.Dashboard; +import com.cruru.dashboard.domain.DashboardApplyFormDto; import com.cruru.dashboard.domain.repository.DashboardRepository; import com.cruru.util.RepositoryTest; import com.cruru.util.fixture.ApplyFormFixture; +import com.cruru.util.fixture.ClubFixture; import com.cruru.util.fixture.DashboardFixture; import com.cruru.util.fixture.LocalDateFixture; import java.time.LocalDateTime; +import java.util.List; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -25,6 +30,9 @@ class ApplyFormRepositoryTest extends RepositoryTest { @Autowired private DashboardRepository dashboardRepository; + @Autowired + private ClubRepository clubRepository; + @BeforeEach void setUp() { applyFormRepository.deleteAllInBatch(); @@ -80,4 +88,32 @@ void save_NotSavedId() { //then assertThat(savedApplyForm1.getId() + 1).isEqualTo(savedApplyForm2.getId()); } + + @DisplayName("특정 동아리에 속하는 DashboardApplyForm 목록을 반환한다.") + @Test + void findAllByClub() { + // given + Club club = clubRepository.save(ClubFixture.create()); + Dashboard dashboard1 = dashboardRepository.save(DashboardFixture.frontend(club)); + Dashboard dashboard2 = dashboardRepository.save(DashboardFixture.backend(club)); + + ApplyForm applyForm1 = applyFormRepository.save(ApplyFormFixture.frontend(dashboard1)); + ApplyForm applyForm2 = applyFormRepository.save(ApplyFormFixture.backend(dashboard2)); + + // when + List dashboardApplyFormDtos = applyFormRepository.findAllByClub(club.getId()); + + // then + assertThat(dashboardApplyFormDtos).hasSize(2); + + DashboardApplyFormDto dto1 = dashboardApplyFormDtos.get(0); + DashboardApplyFormDto dto2 = dashboardApplyFormDtos.get(1); + + assertAll( + () -> assertThat(dto1.dashboard().getId()).isEqualTo(dashboard1.getId()), + () -> assertThat(dto1.applyForm().getId()).isEqualTo(applyForm1.getId()), + () -> assertThat(dto2.dashboard().getId()).isEqualTo(dashboard2.getId()), + () -> assertThat(dto2.applyForm().getId()).isEqualTo(applyForm2.getId()) + ); + } } diff --git a/backend/src/test/java/com/cruru/dashboard/facade/DashboardFacadeTest.java b/backend/src/test/java/com/cruru/dashboard/facade/DashboardFacadeTest.java index 8363e9d38..80176537b 100644 --- a/backend/src/test/java/com/cruru/dashboard/facade/DashboardFacadeTest.java +++ b/backend/src/test/java/com/cruru/dashboard/facade/DashboardFacadeTest.java @@ -93,9 +93,13 @@ void create() { void findAllDashboardsByClubId() { // given Dashboard dashboard = dashboardRepository.save(DashboardFixture.backend(club)); + Dashboard dashboard1 = dashboardRepository.save(DashboardFixture.backend(club)); ApplyForm applyForm = applyFormRepository.save(ApplyFormFixture.backend(dashboard)); + ApplyForm applyForm1 = applyFormRepository.save(ApplyFormFixture.backend(dashboard1)); Process firstProcess = processRepository.save(ProcessFixture.applyType(dashboard)); Process lastProcess = processRepository.save(ProcessFixture.approveType(dashboard)); + Process firstProcess1 = processRepository.save(ProcessFixture.applyType(dashboard1)); + Process lastProcess1 = processRepository.save(ProcessFixture.approveType(dashboard1)); List applicants = List.of( // 마지막 프로세스에 있으면서 불합격 상태인 경우, 불합격 @@ -108,6 +112,16 @@ void findAllDashboardsByClubId() { ); applicantRepository.saveAll(applicants); + List applicants1 = List.of( + ApplicantFixture.rejectedRush(lastProcess1), + ApplicantFixture.rejectedRush(firstProcess1), + ApplicantFixture.pendingDobby(lastProcess1), + ApplicantFixture.pendingDobby(firstProcess1), + ApplicantFixture.pendingDobby(firstProcess1), + ApplicantFixture.pendingDobby(firstProcess1) + ); + applicantRepository.saveAll(applicants1); + // when DashboardsOfClubResponse dashboardsOfClubResponse = dashboardFacade.findAllDashboardsByClubId(club.getId()); diff --git a/backend/src/test/java/com/cruru/dashboard/service/DashboardServiceTest.java b/backend/src/test/java/com/cruru/dashboard/service/DashboardServiceTest.java index 510be7b85..f80aa79bb 100644 --- a/backend/src/test/java/com/cruru/dashboard/service/DashboardServiceTest.java +++ b/backend/src/test/java/com/cruru/dashboard/service/DashboardServiceTest.java @@ -4,13 +4,17 @@ import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import com.cruru.applyform.domain.ApplyForm; +import com.cruru.applyform.domain.repository.ApplyFormRepository; import com.cruru.club.domain.Club; import com.cruru.club.domain.repository.ClubRepository; import com.cruru.dashboard.domain.Dashboard; +import com.cruru.dashboard.domain.DashboardApplyFormDto; import com.cruru.dashboard.domain.repository.DashboardRepository; import com.cruru.process.domain.Process; import com.cruru.process.domain.repository.ProcessRepository; import com.cruru.util.ServiceTest; +import com.cruru.util.fixture.ApplyFormFixture; import com.cruru.util.fixture.ClubFixture; import com.cruru.util.fixture.DashboardFixture; import java.util.Comparator; @@ -34,6 +38,9 @@ class DashboardServiceTest extends ServiceTest { @Autowired private DashboardRepository dashboardRepository; + @Autowired + private ApplyFormRepository applyFormRepository; + @DisplayName("새로운 대시보드를 생성시, 기본 프로세스 2개가 생성된다.") @Test void create_createDefaultProcess() { @@ -75,11 +82,13 @@ void findAllByClub() { Club club = clubRepository.save(ClubFixture.create()); Dashboard backendDashboard = dashboardRepository.save(DashboardFixture.backend(club)); Dashboard frontendDashboard = dashboardRepository.save(DashboardFixture.frontend(club)); + ApplyForm backendApplyform = applyFormRepository.save(ApplyFormFixture.backend(backendDashboard)); + ApplyForm frontendApplyform = applyFormRepository.save(ApplyFormFixture.frontend(frontendDashboard)); - // when & then - assertThat(dashboardService.findAllByClub(club)).containsExactlyInAnyOrder( - backendDashboard, - frontendDashboard + // when&then + assertThat(dashboardService.findAllByClub(club.getId())).containsExactlyInAnyOrder( + new DashboardApplyFormDto(backendDashboard, backendApplyform), + new DashboardApplyFormDto(frontendDashboard, frontendApplyform) ); } }