diff --git a/src/main/java/com/whylog/server/domain/decision/dto/ApplicationResponse.java b/src/main/java/com/whylog/server/domain/decision/dto/ApplicationResponse.java index 0f54ca8..9f0dd8f 100644 --- a/src/main/java/com/whylog/server/domain/decision/dto/ApplicationResponse.java +++ b/src/main/java/com/whylog/server/domain/decision/dto/ApplicationResponse.java @@ -36,6 +36,9 @@ public static class ApplicationDetailDTO { @Schema(description = "적용사항 ID", example = "1") private Long applicationId; + @Schema(description = "회의 ID", example = "1") + private Long meetingId; + @Schema(description = "적용사항 명", example = "Redis키 정책 변경") private String name; diff --git a/src/main/java/com/whylog/server/domain/decision/service/ApplicationQueryService.java b/src/main/java/com/whylog/server/domain/decision/service/ApplicationQueryService.java index d4efb46..a138b26 100644 --- a/src/main/java/com/whylog/server/domain/decision/service/ApplicationQueryService.java +++ b/src/main/java/com/whylog/server/domain/decision/service/ApplicationQueryService.java @@ -51,6 +51,7 @@ public ApplicationResponse.ApplicationDetailDTO getApplicationDetail(Long applic return ApplicationResponse.ApplicationDetailDTO.builder() .applicationId(application.getId()) + .meetingId(application.getDecision().getMeeting().getId()) .name(application.getName()) .decisionReasons(toDecisionReasonItems(applicationBases)) .decisionTimelines(toDecisionTimelineItems(applicationTimelines)) diff --git a/src/main/java/com/whylog/server/domain/git/entity/Commit.java b/src/main/java/com/whylog/server/domain/git/entity/Commit.java index b00c5d7..71ffe37 100644 --- a/src/main/java/com/whylog/server/domain/git/entity/Commit.java +++ b/src/main/java/com/whylog/server/domain/git/entity/Commit.java @@ -13,7 +13,15 @@ @Entity @Getter -@Table(name = "Commits") +@Table( + name = "Commits", + uniqueConstraints = { + @UniqueConstraint( + name = "uk_commits_repository_hash", + columnNames = {"repository_id", "hash"} + ) + } +) @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Commit extends BaseEntity { diff --git a/src/main/java/com/whylog/server/domain/git/repository/CommitRepository.java b/src/main/java/com/whylog/server/domain/git/repository/CommitRepository.java index 07990a7..3519e88 100644 --- a/src/main/java/com/whylog/server/domain/git/repository/CommitRepository.java +++ b/src/main/java/com/whylog/server/domain/git/repository/CommitRepository.java @@ -37,6 +37,15 @@ Set findExistingHashes( """) List findAllWithRepositoryByIdIn(@Param("commitIds") List commitIds); + @Query(""" + SELECT c + FROM Commit c + LEFT JOIN c.commitAnalysis ca + WHERE c.repository.id = :repositoryId + AND ca.id IS NULL + """) + List findUnanalyzedCommitsByRepositoryId(@Param("repositoryId") Long repositoryId); + @Query(""" SELECT c.id FROM Commit c @@ -68,4 +77,3 @@ Slice findCommitsWithCursor( Pageable pageable ); } - diff --git a/src/main/java/com/whylog/server/domain/git/service/GitCommandServiceImpl.java b/src/main/java/com/whylog/server/domain/git/service/GitCommandServiceImpl.java index 0ab8f94..ca8909e 100644 --- a/src/main/java/com/whylog/server/domain/git/service/GitCommandServiceImpl.java +++ b/src/main/java/com/whylog/server/domain/git/service/GitCommandServiceImpl.java @@ -220,14 +220,17 @@ private void syncCommits(GHRepository ghRepository, Repository repository, Local List allHashes = allGitHubCommits.stream() .map(GHCommit::getSHA1) + .distinct() .toList(); Set existingHashes = allHashes.isEmpty() ? Collections.emptySet() : commitRepository.findExistingHashes(repository.getId(), allHashes); + Set syncTargetHashes = new HashSet<>(); List newCommits = allGitHubCommits.stream() .filter(ghCommit -> !existingHashes.contains(ghCommit.getSHA1())) + .filter(ghCommit -> syncTargetHashes.add(ghCommit.getSHA1())) .map(ghCommit -> { try { var shortInfo = ghCommit.getCommitShortInfo(); @@ -261,13 +264,28 @@ private void syncCommits(GHRepository ghRepository, Repository repository, Local .filter(Objects::nonNull) .toList(); + List savedCommits = new ArrayList<>(); if (!newCommits.isEmpty()) { - List savedCommits = commitRepository.saveAllAndFlush(newCommits); - triggerCommitAnalyzeRunsAfterCommit(ghRepository, repository, savedCommits); - log.info("새로운 커밋 {}개 동기화 완료: {}", newCommits.size(), ghRepository.getFullName()); + savedCommits = commitRepository.saveAllAndFlush(newCommits); + log.info("새로운 커밋 {}개 동기화 완료: {}", savedCommits.size(), ghRepository.getFullName()); } else { log.info("새로 동기화할 커밋이 없습니다: {}", ghRepository.getFullName()); } + + List unanalyzedCommits = commitRepository.findUnanalyzedCommitsByRepositoryId(repository.getId()); + List analyzeTargets = mergeAnalyzeTargets(savedCommits, unanalyzedCommits); + + if (!analyzeTargets.isEmpty()) { + triggerCommitAnalyzeRunsAfterCommit(ghRepository, repository, analyzeTargets); + log.info("커밋 분석 요청 대상 {}개 확인: {}", analyzeTargets.size(), ghRepository.getFullName()); + } + } + + private List mergeAnalyzeTargets(List savedCommits, List unanalyzedCommits) { + Map analyzeTargets = new LinkedHashMap<>(); + savedCommits.forEach(commit -> analyzeTargets.put(commit.getId(), commit)); + unanalyzedCommits.forEach(commit -> analyzeTargets.putIfAbsent(commit.getId(), commit)); + return new ArrayList<>(analyzeTargets.values()); } /**