From 26ae9899bf3056413bd0e4615ec8238ab7ba2a96 Mon Sep 17 00:00:00 2001 From: Yujin1219 Date: Tue, 2 Jun 2026 15:10:43 +0900 Subject: [PATCH 1/3] =?UTF-8?q?fix:=20=EC=BB=A4=EB=B0=8B=20=EB=8F=99?= =?UTF-8?q?=EA=B8=B0=ED=99=94=20=EC=A4=91=EB=B3=B5=20=EC=A0=80=EC=9E=A5=20?= =?UTF-8?q?=EB=B0=A9=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/whylog/server/domain/git/entity/Commit.java | 10 +++++++++- .../domain/git/service/GitCommandServiceImpl.java | 3 +++ 2 files changed, 12 insertions(+), 1 deletion(-) 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/service/GitCommandServiceImpl.java b/src/main/java/com/whylog/server/domain/git/service/GitCommandServiceImpl.java index 0ab8f94..437141d 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(); From 7a52ddf37ce296f41b70d5f596b9d2a091e82039 Mon Sep 17 00:00:00 2001 From: Yujin1219 Date: Tue, 2 Jun 2026 15:23:47 +0900 Subject: [PATCH 2/3] =?UTF-8?q?refactor:=20=EB=AF=B8=EB=B6=84=EC=84=9D=20?= =?UTF-8?q?=EC=BB=A4=EB=B0=8B=20=EC=9E=AC=EB=B6=84=EC=84=9D=20=EC=9A=94?= =?UTF-8?q?=EC=B2=AD=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../git/repository/CommitRepository.java | 10 ++++++++- .../git/service/GitCommandServiceImpl.java | 21 ++++++++++++++++--- 2 files changed, 27 insertions(+), 4 deletions(-) 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 437141d..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 @@ -264,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()); } /** From 618d2e2628a9fc2b205f75e5bac875d0b5ebdcf9 Mon Sep 17 00:00:00 2001 From: Yujin1219 Date: Wed, 3 Jun 2026 20:44:17 +0900 Subject: [PATCH 3/3] =?UTF-8?q?refactor:=20=EC=A0=81=EC=9A=A9=EC=82=AC?= =?UTF-8?q?=ED=95=AD=20=EC=83=81=EC=84=B8=EC=A1=B0=ED=9A=8C=EC=97=90=20mee?= =?UTF-8?q?tingId=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../whylog/server/domain/decision/dto/ApplicationResponse.java | 3 +++ .../domain/decision/service/ApplicationQueryService.java | 1 + 2 files changed, 4 insertions(+) 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))