diff --git a/src/main/java/com/whylog/server/domain/decision/dto/DecisionResponse.java b/src/main/java/com/whylog/server/domain/decision/dto/DecisionResponse.java index 68e5f95..212038b 100644 --- a/src/main/java/com/whylog/server/domain/decision/dto/DecisionResponse.java +++ b/src/main/java/com/whylog/server/domain/decision/dto/DecisionResponse.java @@ -9,6 +9,14 @@ public class DecisionResponse { + public record DecisionFlatRow( + Long decisionId, + String meetingName, + Long applicationId, + String applicationName + ) { + } + @Getter @NoArgsConstructor @AllArgsConstructor diff --git a/src/main/java/com/whylog/server/domain/team/repository/TeamRepository.java b/src/main/java/com/whylog/server/domain/team/repository/TeamRepository.java index f8b3912..592219a 100644 --- a/src/main/java/com/whylog/server/domain/team/repository/TeamRepository.java +++ b/src/main/java/com/whylog/server/domain/team/repository/TeamRepository.java @@ -1,6 +1,6 @@ package com.whylog.server.domain.team.repository; -import com.whylog.server.domain.decision.entity.Decision; +import com.whylog.server.domain.decision.dto.DecisionResponse; import com.whylog.server.domain.team.entity.Team; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; @@ -13,12 +13,18 @@ public interface TeamRepository extends JpaRepository { Boolean existsByName(String teamName); @Query(""" - SELECT DISTINCT d + SELECT new com.whylog.server.domain.decision.dto.DecisionResponse$DecisionFlatRow( + d.id, + m.name, + a.id, + a.name + ) FROM Decision d - JOIN FETCH d.meeting m - LEFT JOIN FETCH d.applications + JOIN d.meeting m + LEFT JOIN d.applications a WHERE m.team.id = :teamId + ORDER BY d.id """) - List findDecisions(@Param("teamId") Long teamId); + List findDecisionRows(@Param("teamId") Long teamId); } diff --git a/src/main/java/com/whylog/server/domain/team/service/TeamQueryService.java b/src/main/java/com/whylog/server/domain/team/service/TeamQueryService.java index 304cabd..7601a38 100644 --- a/src/main/java/com/whylog/server/domain/team/service/TeamQueryService.java +++ b/src/main/java/com/whylog/server/domain/team/service/TeamQueryService.java @@ -2,13 +2,15 @@ import com.whylog.server.domain.decision.dto.ApplicationResponse; import com.whylog.server.domain.decision.dto.DecisionResponse; -import com.whylog.server.domain.decision.entity.Decision; import com.whylog.server.domain.team.repository.TeamRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; @Service @RequiredArgsConstructor @@ -19,22 +21,40 @@ public class TeamQueryService { @Transactional(readOnly = true) public List decisions( Long teamId ){ - List decisions = teamRepository.findDecisions(teamId); - - return decisions.stream() - .map(d -> DecisionResponse.DecisionListDTO.builder() - .decisionId(d.getId()) - .name(d.getMeeting().getName()) - .applications( - d.getApplications().stream() - .map(application -> ApplicationResponse.ApplicationDTO.builder() - .applicationId(application.getId()) - .name(application.getName()) - .build()) - .toList() - ) - .build() - ).toList(); + List rows = teamRepository.findDecisionRows(teamId); + Map decisions = new LinkedHashMap<>(); + + for (DecisionResponse.DecisionFlatRow row : rows) { + DecisionAccumulator decision = decisions.computeIfAbsent( + row.decisionId(), + decisionId -> new DecisionAccumulator(decisionId, row.meetingName()) + ); + + if (row.applicationId() != null) { + decision.applications().add(ApplicationResponse.ApplicationDTO.builder() + .applicationId(row.applicationId()) + .name(row.applicationName()) + .build()); + } + } + + return decisions.values().stream() + .map(decision -> DecisionResponse.DecisionListDTO.builder() + .decisionId(decision.decisionId()) + .name(decision.meetingName()) + .applications(decision.applications()) + .build()) + .toList(); + } + + private record DecisionAccumulator( + Long decisionId, + String meetingName, + List applications + ) { + private DecisionAccumulator(Long decisionId, String meetingName) { + this(decisionId, meetingName, new ArrayList<>()); + } } }