Skip to content

Commit b239bc2

Browse files
committed
fix: SSE 호출부 수정 및 이전에 삭제한 레포를 재등록 했을 때 unique 제약 위반하는 오류 수정
1 parent c94787d commit b239bc2

5 files changed

Lines changed: 30 additions & 12 deletions

File tree

backend/src/main/java/com/stackup/stackup/github/application/GithubRepositoryService.java

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,11 @@ public GithubRepositoryResult register(Long userId, RegisterRepositoryCommand co
4242
User user = userRepository.findByIdAndDeletedFalse(userId)
4343
.orElseThrow(() -> new DomainException(ApiErrorCode.USER_NOT_FOUND));
4444

45-
if (repositoryRepository.findByUser_IdAndGithubRepoIdAndDeletedFalse(userId, command.githubRepoId()).isPresent()) {
45+
// soft delete 된 행이 있으면 새 INSERT 대신 그 행을 복구한다
46+
GithubRepository existing = repositoryRepository
47+
.findByUser_IdAndGithubRepoId(userId, command.githubRepoId())
48+
.orElse(null);
49+
if (existing != null && !existing.isDeleted()) {
4650
throw new DomainException(ApiErrorCode.REPO_ALREADY_REGISTERED);
4751
}
4852

@@ -55,14 +59,20 @@ public GithubRepositoryResult register(Long userId, RegisterRepositoryCommand co
5559
throw new DomainException(ApiErrorCode.VALIDATION_ERROR);
5660
}
5761

58-
GithubRepository repo = repositoryRepository.save(GithubRepository.create(
59-
user,
60-
meta.id(),
61-
meta.name(),
62-
meta.fullName(),
63-
meta.htmlUrl(),
64-
meta.defaultBranch()
65-
));
62+
GithubRepository repo;
63+
if (existing != null) {
64+
existing.reactivate(meta.name(), meta.fullName(), meta.htmlUrl(), meta.defaultBranch());
65+
repo = existing;
66+
} else {
67+
repo = repositoryRepository.save(GithubRepository.create(
68+
user,
69+
meta.id(),
70+
meta.name(),
71+
meta.fullName(),
72+
meta.htmlUrl(),
73+
meta.defaultBranch()
74+
));
75+
}
6676

6777
events.publishEvent(new RepositoryRegisteredEvent(userId, repo.getId()));
6878
return GithubRepositoryResult.of(repo);

backend/src/main/java/com/stackup/stackup/github/domain/GithubRepository.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,4 +117,11 @@ public void markFailed() {
117117
public void markDeleted() {
118118
this.deleted = true;
119119
}
120+
121+
// 이전에 soft delete 된 레포를 다시 등록할 때 같은 행을 복구한다.
122+
public void reactivate(String repoName, String repoFullName, String repoUrl, String defaultBranch) {
123+
this.deleted = false;
124+
this.status = RepositoryStatus.PENDING;
125+
updateMetadata(repoName, repoFullName, repoUrl, defaultBranch);
126+
}
120127
}

backend/src/main/java/com/stackup/stackup/github/domain/GithubRepositoryRepository.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,7 @@ public interface GithubRepositoryRepository extends JpaRepository<GithubReposito
1313

1414
Optional<GithubRepository> findByUser_IdAndGithubRepoIdAndDeletedFalse(Long userId, Long githubRepoId);
1515

16+
Optional<GithubRepository> findByUser_IdAndGithubRepoId(Long userId, Long githubRepoId);
17+
1618
List<GithubRepository> findByUser_IdAndGithubRepoIdInAndDeletedFalse(Long userId, Set<Long> githubRepoIds);
1719
}

frontend/src/features/analysis/model/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export type AnalyzedDocument = {
2020
updatedAt: string
2121
}
2222

23-
// /api/stream/me 의 DOC_STATE / REPO_STATE 이벤트 data 의 payload 필드.
23+
// /realtime/stream/me 의 DOC_STATE / REPO_STATE 이벤트 data 의 payload 필드.
2424
export type AnalysisEventPayload = {
2525
targetType: AnalysisSourceType
2626
targetId: number

frontend/src/pages/Workspace/model/useWorkspaceAnalysisStream.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import { repoKeys } from '@/features/repo'
66
import { documentKeys } from '@/features/analysis'
77
import { useEventStream } from '@/shared/hooks'
88

9-
// /api/stream/me 를 구독해 분석 상태(DOC_STATE/REPO_STATE) 가 오면
109
// 이력서·레포·문서 쿼리를 무효화 → 화면이 자동으로 최신 상태로 갱신된다.
1110
export function useWorkspaceAnalysisStream() {
1211
const queryClient = useQueryClient()
@@ -20,7 +19,7 @@ export function useWorkspaceAnalysisStream() {
2019
}, [queryClient])
2120

2221
useEventStream({
23-
path: '/api/stream/me',
22+
path: '/realtime/stream/me',
2423
getToken,
2524
handlers: {
2625
DOC_STATE: invalidateAll,

0 commit comments

Comments
 (0)