Skip to content

Conversation

@minjee2758
Copy link
Collaborator

@minjee2758 minjee2758 commented Jun 27, 2025

작업 내용

  • User 테이블 정규화 -> user, user_github_
  • GitHub 자동 Push를 위한 사용자별 Repository 선택 및 관련 정보 관리 기능 구현
  • 사용자의 GitHub 저장소(Repository) 목록 조회 및 저장소 선택 API 추가

변경 사항

  • UserGithubInfo 엔티티

    • 사용자별 GitHub 정보(owner, repo, branch, accessToken 등) 저장
    • setGithubAccessToken(), setGithubRepo() 메서드 추가
  • UserGithubInfoRepository / UserGithubInfoJpaRepository

    • 사용자별 GitHub 정보 CRUD 및 조회 인터페이스/구현체
  • UserGithubRepoResponse DTO

    • GitHub 저장소 이름 및 기본 브랜치 정보 응답용
  • UserGithubRepoSelectRequest DTO

    • GitHub 저장소 선택 요청용
  • WebClientConfig

    • GitHub API 호출용 WebClient 빈 등록
  • UserGithubService

    • getGithubRepos(): 사용자의 GitHub 저장소 목록 조회 및 변환
    • selectGithubRepo(): 사용자가 선택한 저장소 정보 저장
  • UserGithubController

    • 레포지토리 조회 및 선택 api 추가
    • GET: GitHub 저장소 목록 조회
    • POST: 저장소 선택 및 정보 저장

참고 사항

  • user 테이블 변경되었습니다. drop 후 생성해주세요

코드 리뷰 전 확인 체크리스트

  • 불필요한 콘솔 로그, 주석 제거
  • 커밋 메시지 컨벤션 준수 (type : )
  • 기능 정상 동작 확인

Summary by CodeRabbit

  • 신규 기능

    • 사용자가 자신의 깃허브 저장소 목록을 조회하고, 자동 푸시용 저장소를 선택할 수 있는 API가 추가되었습니다.
    • 깃허브 관련 사용자 정보 관리 기능이 추가되어, 저장소 선택 및 토큰 관리가 분리되었습니다.
    • 깃허브 API 호출을 위한 WebClient가 설정되어 원활한 통신이 가능해졌습니다.
    • 깃허브 자동 푸시 활성화 상태를 나타내는 필드가 사용자 정보에 도입되었습니다.
    • 깃허브 소유자 정보 제공 기능이 OAuth2 응답에 추가되었습니다.
  • 버그 수정

    • 없음
  • 문서화

    • API 문서에 깃허브 저장소 선택 및 조회 관련 설명과 예시가 추가되었습니다.
  • 기타

    • 깃허브 정보가 없는 경우 및 저장소 미존재 시의 예외 코드가 추가되었습니다.

깃허브로 가입하는 순간 바로 깃헙 블로그링크, 아이디, accesstoken가 넘어옴
@minjee2758 minjee2758 self-assigned this Jun 27, 2025
@coderabbitai
Copy link

coderabbitai bot commented Jun 27, 2025

Walkthrough

이 변경 사항은 GitHub 관련 사용자 정보와 저장소 관리를 위한 신규 엔터티, 서비스, 컨트롤러, DTO, 레포지토리 등을 도입합니다. 기존 User 엔터티의 GitHub 액세스 토큰 필드를 분리하여 UserGithubInfo 엔터티로 이동하고, GitHub 저장소 목록 조회 및 저장소 선택 기능을 위한 REST API와 서비스 계층을 추가하였습니다.

Changes

파일/경로 요약 변경 요약
.../UserGithubRepoSelectRequest.java
.../UserGithubRepoResponse.java
GitHub 저장소 선택 및 응답용 신규 DTO 클래스 추가
.../GithubOAuth2Response.java
.../GoogleOAuth2Response.java
.../OAuth2Response.java
OAuth2 응답 인터페이스 및 구현체에 getOwner() 메서드 추가 및 스키마 설명 수정
.../WebClientConfig.java GitHub API 호출을 위한 WebClient 설정용 신규 구성 클래스 추가
.../CustomSuccessHandler.java GitHub 토큰 저장 로직을 UserGithubService로 분리, 관련 의존성 및 필드 추가
.../UserExceptionCode.java NO_GITHUB_INFO, NO_GITHUB_REPO 예외 코드 추가
.../User.java githubAccessToken 필드 제거, gitPushStatus 불리언 필드로 대체 및 관련 생성자/메서드 수정
.../UserFactory.java switch-case 포맷팅만 변경(로직 변화 없음)
.../UserGithubInfo.java User와 1:1 매핑되는 GitHub 정보용 신규 JPA 엔터티 추가
.../UserGithubInfoRepository.java
.../UserGithubInfoJpaRepository.java
.../UserGithubInfoRepositoryImpl.java
UserGithubInfo 엔터티용 레포지토리 인터페이스, JPA, 구현체 추가
.../UserRepository.java
.../UserRepositoryImpl.java
파일 끝 개행 추가 및 UserGithubInfo import(로직 변화 없음)
.../CustomOAuth2UserService.java UserGithubService 의존성 추가, GitHub URL 및 UserGithubInfo 생성 로직 통합 및 예외 처리 추가
.../UserDomainService.java UserGithubInfoRepository 의존성 추가, updateUserGithubAccessToken 메서드 제거
.../UserGithubService.java UserGithubInfo 관리, GitHub 저장소 조회/선택 기능을 제공하는 신규 서비스 클래스 추가
.../UserGithubController.java 인증 사용자 대상 GitHub 저장소 목록 조회 및 저장소 선택 REST API 신규 컨트롤러 추가

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant UserGithubController
    participant UserGithubService
    participant UserGithubInfoRepository
    participant WebClient(GitHub API)

    Client->>UserGithubController: GET /api/users/github
    UserGithubController->>UserGithubService: getGithubRepos(authUser)
    UserGithubService->>UserGithubInfoRepository: getUserGithubInfo(userId)
    UserGithubService->>WebClient(GitHub API): GET /user/repos (with decrypted token)
    WebClient(GitHub API)-->>UserGithubService: List of repos
    UserGithubService-->>UserGithubController: List<UserGithubRepoResponse>
    UserGithubController-->>Client: 200 OK + repo list

    Client->>UserGithubController: POST /api/users/github {repositoryName}
    UserGithubController->>UserGithubService: selectGithubRepo(authUser, request)
    UserGithubService->>UserGithubInfoRepository: getUserGithubInfo(userId)
    UserGithubService->>WebClient(GitHub API): GET /user/repos
    WebClient(GitHub API)-->>UserGithubService: List of repos
    UserGithubService->>UserGithubInfoRepository: updateGithubInfo
    UserGithubService-->>UserGithubController: UserGithubRepoResponse
    UserGithubController-->>Client: 200 OK + selected repo
Loading

Suggested labels

enhancement

Suggested reviewers

  • Kimminu7
  • pokerbearkr
  • thezz9

Poem

🐇
깃허브 정보 토끼가 챙겨,
새 엔터티와 서비스로 hop hop hop!
저장소 목록도 척척 보여주고,
자동 푸시 선택까지 한 번에 뚝딱!
코드밭에 변화의 싹,
토끼는 오늘도 행복한 깃허브 꿈을 꾼다.
🌱🐰✨


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bef10d2 and d870b99.

📒 Files selected for processing (1)
  • src/main/java/org/ezcode/codetest/domain/user/service/UserGithubService.java (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/main/java/org/ezcode/codetest/domain/user/service/UserGithubService.java
✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@minjee2758 minjee2758 changed the title Feature/user GitHub Feature : user테이블에서 GitHub 정보 분리, reposiotory 정보 조회 및 저장 Jun 27, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

🧹 Nitpick comments (13)
src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/user/UserRepositoryImpl.java (2)

7-8: 불필요한 import 제거 필요

UserGithubInfo를 사용하지 않으므로 import 문이 컴파일 경고를 유발할 수 있습니다.

-import org.ezcode.codetest.domain.user.model.entity.UserGithubInfo;

56-57: 의미 없는 공백 라인 제거

56~57 라인의 빈 줄은 불필요해 보입니다. 코드 일관성을 위해 삭제를 권장합니다.

src/main/java/org/ezcode/codetest/domain/user/model/entity/UserFactory.java (1)

15-22: 프로바이더 문자열 하드코딩 대신 상수/Enum 사용 고려

"github" 문자열이 여러 곳에서 반복될 경우 오타로 인한 버그 리스크가 있습니다. Enum 또는 상수로 추출하면 컴파일 타임 체크가 가능해집니다.

예시:

public enum OAuthProvider { GITHUB, GOOGLE /* ... */ }

// switch (provider.toLowerCase()) → switch (OAuthProvider.valueOf(provider.toUpperCase()))
src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/GoogleOAuth2Response.java (1)

51-54: 빈 문자열 반환이 의도한 값인지 확인 필요

getOwner()가 항상 ""를 반환하면 이후 로직에서 빈 문자열과 null을 동일시하지 않을 경우 예외적인 동작이 생길 수 있습니다. 불필요한 분기 로직을 막기 위해 null 또는 Optional 사용을 검토해 주세요.

-	return "";
+	return null; // 또는 Optional.ofNullable(...)
src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/GithubOAuth2Response.java (1)

3-3: 사용되지 않는 import를 제거하세요.

java.util.List import가 코드에서 사용되지 않습니다.

-import java.util.List;
src/main/java/org/ezcode/codetest/domain/user/repository/UserGithubInfoRepository.java (2)

8-8: 메서드 명세를 더 명확하게 작성해주세요.

getUserGithubInfo(Long id) 메서드에서 id 파라미터가 UserGithubInfo의 ID인지 User의 ID인지 명확하지 않습니다. 메서드명을 getUserGithubInfoByUserId 또는 getUserGithubInfoById로 변경하거나, JavaDoc을 추가해주세요.


10-12: 메서드 역할의 중복을 검토해주세요.

updateGithubAccessTokenupdateGithubInfo 메서드가 모두 같은 엔티티를 업데이트하는 것 같습니다. 기능적 차이가 있다면 메서드명을 더 구체적으로 하거나, 하나로 통합하는 것을 고려해보세요.

-    void updateGithubAccessToken(UserGithubInfo userGithubInfo);
-
-    void updateGithubInfo(UserGithubInfo userGithub);
+    void updateUserGithubInfo(UserGithubInfo userGithubInfo);
src/main/java/org/ezcode/codetest/common/security/hander/CustomSuccessHandler.java (1)

37-54: 생성자 파라미터 순서를 일관성 있게 유지해주세요.

생성자에서 UserGithubService 파라미터가 중간에 위치해 있습니다. 의존성 주입 순서를 필드 선언 순서와 맞춰서 가독성을 높여주세요.

src/main/java/org/ezcode/codetest/domain/user/model/entity/UserGithubInfo.java (3)

19-19: JPA 엔티티 보안을 위해 생성자 접근 제한을 추가해주세요.

JPA 엔티티의 기본 생성자는 보통 AccessLevel.PROTECTED로 제한하는 것이 좋습니다.

-@NoArgsConstructor
+@NoArgsConstructor(access = AccessLevel.PROTECTED)

30-31: 필수 필드에 대한 검증을 추가해주세요.

owner 필드가 nullable = false로 설정되어 있지만, 추가적인 검증 어노테이션이 없습니다. 비즈니스 로직에서 중요한 필드라면 @NotBlank 등의 검증을 고려해보세요.


49-52: 메서드명을 일관성 있게 작성해주세요.

setGithubRepo 메서드는 실제로 repository와 branch 정보를 모두 설정합니다. 메서드명을 setRepositoryInfo 또는 updateRepositoryInfo로 변경하는 것이 더 명확할 것 같습니다.

src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/user/UserGithubInfoRepositoryImpl.java (1)

15-32: 레포지토리 메서드 중복 제거 검토 필요

updateGithubAccessTokenupdateGithubInfo 메서드가 모두 동일한 save() 작업을 수행하고 있습니다.

다음과 같이 단일 메서드로 통합을 고려해보세요:

-    @Override
-    public void updateGithubAccessToken(UserGithubInfo userGithubInfo) {
-        userGithubInfoJpaRepository.save(userGithubInfo);
-    }
-
-    @Override
-    public void updateGithubInfo(UserGithubInfo userGithub) {
-        userGithubInfoJpaRepository.save(userGithubInfo);
-    }
+    @Override
+    public void updateUserGithubInfo(UserGithubInfo userGithubInfo) {
+        userGithubInfoJpaRepository.save(userGithubInfo);
+    }

다만 현재 구현도 서비스 계층에서 의도를 명확히 표현할 수 있어 유지해도 무방합니다.

src/main/java/org/ezcode/codetest/domain/user/service/UserGithubService.java (1)

31-41: CRUD 메서드 구현 승인

레포지토리 위임 방식의 구현이 적절합니다.

일관성을 위해 @Transactional 어노테이션 추가를 고려해보세요:

+    @Transactional
     public void updateUserGithubAccessToken(UserGithubInfo userGithubInfo) {
+    @Transactional
     public void createUserGithubInfo(UserGithubInfo userGithubInfo) {

단일 레포지토리 호출이므로 필수는 아니지만, 서비스 계층의 일관성을 위해 권장합니다.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b8e6dee and 3673581.

📒 Files selected for processing (20)
  • src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/request/UserGithubRepoSelectRequest.java (1 hunks)
  • src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/GithubOAuth2Response.java (2 hunks)
  • src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/GoogleOAuth2Response.java (1 hunks)
  • src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/OAuth2Response.java (1 hunks)
  • src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/UserGithubRepoResponse.java (1 hunks)
  • src/main/java/org/ezcode/codetest/common/security/config/WebClientConfig.java (1 hunks)
  • src/main/java/org/ezcode/codetest/common/security/hander/CustomSuccessHandler.java (3 hunks)
  • src/main/java/org/ezcode/codetest/domain/user/exception/code/UserExceptionCode.java (1 hunks)
  • src/main/java/org/ezcode/codetest/domain/user/model/entity/User.java (5 hunks)
  • src/main/java/org/ezcode/codetest/domain/user/model/entity/UserFactory.java (1 hunks)
  • src/main/java/org/ezcode/codetest/domain/user/model/entity/UserGithubInfo.java (1 hunks)
  • src/main/java/org/ezcode/codetest/domain/user/repository/UserGithubInfoRepository.java (1 hunks)
  • src/main/java/org/ezcode/codetest/domain/user/repository/UserRepository.java (1 hunks)
  • src/main/java/org/ezcode/codetest/domain/user/service/CustomOAuth2UserService.java (4 hunks)
  • src/main/java/org/ezcode/codetest/domain/user/service/UserDomainService.java (3 hunks)
  • src/main/java/org/ezcode/codetest/domain/user/service/UserGithubService.java (1 hunks)
  • src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/user/UserGithubInfoJpaRepository.java (1 hunks)
  • src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/user/UserGithubInfoRepositoryImpl.java (1 hunks)
  • src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/user/UserRepositoryImpl.java (2 hunks)
  • src/main/java/org/ezcode/codetest/presentation/usermanagement/UserGithubController.java (1 hunks)
🧰 Additional context used
🧠 Learnings (14)
📓 Common learnings
Learnt from: minjee2758
PR: ezcode-my/backend#43
File: src/main/java/org/ezcode/codetest/domain/user/model/entity/User.java:77-89
Timestamp: 2025-06-10T02:13:33.890Z
Learning: 이 프로젝트에서는 입력 검증을 DTO 레벨에서 수행하고 있으며, User 엔티티의 팩토리 메서드에서는 별도의 입력 검증을 하지 않는다.
Learnt from: minjee2758
PR: ezcode-my/backend#105
File: src/main/resources/application.properties:127-127
Timestamp: 2025-06-26T09:43:03.896Z
Learning: GitHub OAuth에서 자동 커밋 기능 구현을 위해서는 `repo` scope가 필요하며, 이는 저장소에 대한 읽기/쓰기 권한을 제공한다. `user` scope는 커밋 작성자 정보 설정을 위해 필요하다.
Learnt from: minjee2758
PR: ezcode-my/backend#105
File: src/main/resources/application.properties:127-127
Timestamp: 2025-06-26T09:43:03.896Z
Learning: GitHub OAuth에서 자동 커밋 기능을 구현하려면 `repo` scope가 필수적이며, 이는 public/private 저장소 모두에 대한 전체 접근 권한을 제공한다. 공개 저장소만 대상으로 한다면 `public_repo` scope 사용 가능하다. 더 세밀한 권한 제어가 필요하다면 OAuth App 대신 GitHub App 사용을 권장한다.
Learnt from: chat26666
PR: ezcode-my/backend#64
File: src/main/java/org/ezcode/codetest/domain/game/repository/EncounterRepository.java:0-0
Timestamp: 2025-06-15T04:36:57.084Z
Learning: 사용자 chat26666은 개발 중인 기능의 경우 향후 개발 예정인 빈 인터페이스를 의도적으로 남겨두는 것을 선호함. EncounterRepository 인터페이스는 현재 미정의 상태이지만 추후 개발 예정으로 의도적으로 빈 상태로 유지됨.
Learnt from: NCookies
PR: ezcode-my/backend#17
File: src/main/java/org/ezcode/codetest/presentation/problemmanagement/ProblemAdminController.java:25-25
Timestamp: 2025-06-02T06:57:37.929Z
Learning: 이 프로젝트에서는 아직 Spring Security가 적용되지 않아서 @PreAuthorize 어노테이션이 주석 처리되어 있음. Spring Security 도입 전까지는 권한 검증 어노테이션들이 비활성화 상태임.
src/main/java/org/ezcode/codetest/domain/user/repository/UserRepository.java (2)
Learnt from: chat26666
PR: ezcode-my/backend#64
File: src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/game/EncounterChoiceRepositoryImpl.java:0-0
Timestamp: 2025-06-15T04:37:29.231Z
Learning: EncounterChoiceRepositoryImpl in src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/game/EncounterChoiceRepositoryImpl.java is intentionally a skeleton implementation that is work-in-progress and will be completed later.
Learnt from: chat26666
PR: ezcode-my/backend#64
File: src/main/java/org/ezcode/codetest/domain/game/repository/EncounterRepository.java:0-0
Timestamp: 2025-06-15T04:36:57.084Z
Learning: 사용자 chat26666은 개발 중인 기능의 경우 향후 개발 예정인 빈 인터페이스를 의도적으로 남겨두는 것을 선호함. EncounterRepository 인터페이스는 현재 미정의 상태이지만 추후 개발 예정으로 의도적으로 빈 상태로 유지됨.
src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/user/UserRepositoryImpl.java (1)
Learnt from: chat26666
PR: ezcode-my/backend#64
File: src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/game/EncounterChoiceRepositoryImpl.java:0-0
Timestamp: 2025-06-15T04:37:29.231Z
Learning: EncounterChoiceRepositoryImpl in src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/game/EncounterChoiceRepositoryImpl.java is intentionally a skeleton implementation that is work-in-progress and will be completed later.
src/main/java/org/ezcode/codetest/domain/user/exception/code/UserExceptionCode.java (1)
Learnt from: thezz9
PR: ezcode-my/backend#98
File: src/main/java/org/ezcode/codetest/application/submission/dto/event/SubmissionErrorEvent.java:17-22
Timestamp: 2025-06-25T01:24:30.754Z
Learning: JudgeClient에서 모든 예외를 SubmissionException으로 래핑해서 넘길 계획이므로, SubmissionErrorEvent.resolveCode() 메서드의 캐스팅은 안전할 예정임.
src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/request/UserGithubRepoSelectRequest.java (1)
Learnt from: minjee2758
PR: ezcode-my/backend#105
File: src/main/resources/application.properties:127-127
Timestamp: 2025-06-26T09:43:03.896Z
Learning: GitHub OAuth에서 자동 커밋 기능 구현을 위해서는 `repo` scope가 필요하며, 이는 저장소에 대한 읽기/쓰기 권한을 제공한다. `user` scope는 커밋 작성자 정보 설정을 위해 필요하다.
src/main/java/org/ezcode/codetest/domain/user/repository/UserGithubInfoRepository.java (1)
Learnt from: chat26666
PR: ezcode-my/backend#64
File: src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/game/EncounterChoiceRepositoryImpl.java:0-0
Timestamp: 2025-06-15T04:37:29.231Z
Learning: EncounterChoiceRepositoryImpl in src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/game/EncounterChoiceRepositoryImpl.java is intentionally a skeleton implementation that is work-in-progress and will be completed later.
src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/UserGithubRepoResponse.java (2)
Learnt from: minjee2758
PR: ezcode-my/backend#105
File: src/main/resources/application.properties:127-127
Timestamp: 2025-06-26T09:43:03.896Z
Learning: GitHub OAuth에서 자동 커밋 기능 구현을 위해서는 `repo` scope가 필요하며, 이는 저장소에 대한 읽기/쓰기 권한을 제공한다. `user` scope는 커밋 작성자 정보 설정을 위해 필요하다.
Learnt from: minjee2758
PR: ezcode-my/backend#105
File: src/main/resources/application.properties:127-127
Timestamp: 2025-06-26T09:43:03.896Z
Learning: GitHub OAuth에서 자동 커밋 기능을 구현하려면 `repo` scope가 필수적이며, 이는 public/private 저장소 모두에 대한 전체 접근 권한을 제공한다. 공개 저장소만 대상으로 한다면 `public_repo` scope 사용 가능하다. 더 세밀한 권한 제어가 필요하다면 OAuth App 대신 GitHub App 사용을 권장한다.
src/main/java/org/ezcode/codetest/domain/user/service/UserDomainService.java (1)
Learnt from: chat26666
PR: ezcode-my/backend#64
File: src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/game/EncounterChoiceRepositoryImpl.java:0-0
Timestamp: 2025-06-15T04:37:29.231Z
Learning: EncounterChoiceRepositoryImpl in src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/game/EncounterChoiceRepositoryImpl.java is intentionally a skeleton implementation that is work-in-progress and will be completed later.
src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/user/UserGithubInfoJpaRepository.java (1)
Learnt from: chat26666
PR: ezcode-my/backend#64
File: src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/game/EncounterChoiceRepositoryImpl.java:0-0
Timestamp: 2025-06-15T04:37:29.231Z
Learning: EncounterChoiceRepositoryImpl in src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/game/EncounterChoiceRepositoryImpl.java is intentionally a skeleton implementation that is work-in-progress and will be completed later.
src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/user/UserGithubInfoRepositoryImpl.java (1)
Learnt from: chat26666
PR: ezcode-my/backend#64
File: src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/game/EncounterChoiceRepositoryImpl.java:0-0
Timestamp: 2025-06-15T04:37:29.231Z
Learning: EncounterChoiceRepositoryImpl in src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/game/EncounterChoiceRepositoryImpl.java is intentionally a skeleton implementation that is work-in-progress and will be completed later.
src/main/java/org/ezcode/codetest/domain/user/model/entity/User.java (2)
Learnt from: NCookies
PR: ezcode-my/backend#17
File: src/main/java/org/ezcode/codetest/presentation/problemmanagement/ProblemAdminController.java:25-25
Timestamp: 2025-06-02T06:57:37.929Z
Learning: 이 프로젝트에서는 아직 Spring Security가 적용되지 않아서 @PreAuthorize 어노테이션이 주석 처리되어 있음. Spring Security 도입 전까지는 권한 검증 어노테이션들이 비활성화 상태임.
Learnt from: minjee2758
PR: ezcode-my/backend#105
File: src/main/resources/application.properties:127-127
Timestamp: 2025-06-26T09:43:03.896Z
Learning: GitHub OAuth에서 자동 커밋 기능을 구현하려면 `repo` scope가 필수적이며, 이는 public/private 저장소 모두에 대한 전체 접근 권한을 제공한다. 공개 저장소만 대상으로 한다면 `public_repo` scope 사용 가능하다. 더 세밀한 권한 제어가 필요하다면 OAuth App 대신 GitHub App 사용을 권장한다.
src/main/java/org/ezcode/codetest/domain/user/service/UserGithubService.java (2)
Learnt from: minjee2758
PR: ezcode-my/backend#105
File: src/main/resources/application.properties:127-127
Timestamp: 2025-06-26T09:43:03.896Z
Learning: GitHub OAuth에서 자동 커밋 기능 구현을 위해서는 `repo` scope가 필요하며, 이는 저장소에 대한 읽기/쓰기 권한을 제공한다. `user` scope는 커밋 작성자 정보 설정을 위해 필요하다.
Learnt from: NCookies
PR: ezcode-my/backend#17
File: src/main/java/org/ezcode/codetest/presentation/problemmanagement/ProblemAdminController.java:25-25
Timestamp: 2025-06-02T06:57:37.929Z
Learning: 이 프로젝트에서는 아직 Spring Security가 적용되지 않아서 @PreAuthorize 어노테이션이 주석 처리되어 있음. Spring Security 도입 전까지는 권한 검증 어노테이션들이 비활성화 상태임.
src/main/java/org/ezcode/codetest/presentation/usermanagement/UserGithubController.java (3)
Learnt from: minjee2758
PR: ezcode-my/backend#105
File: src/main/resources/application.properties:127-127
Timestamp: 2025-06-26T09:43:03.896Z
Learning: GitHub OAuth에서 자동 커밋 기능 구현을 위해서는 `repo` scope가 필요하며, 이는 저장소에 대한 읽기/쓰기 권한을 제공한다. `user` scope는 커밋 작성자 정보 설정을 위해 필요하다.
Learnt from: minjee2758
PR: ezcode-my/backend#105
File: src/main/resources/application.properties:127-127
Timestamp: 2025-06-26T09:43:03.896Z
Learning: GitHub OAuth에서 자동 커밋 기능을 구현하려면 `repo` scope가 필수적이며, 이는 public/private 저장소 모두에 대한 전체 접근 권한을 제공한다. 공개 저장소만 대상으로 한다면 `public_repo` scope 사용 가능하다. 더 세밀한 권한 제어가 필요하다면 OAuth App 대신 GitHub App 사용을 권장한다.
Learnt from: NCookies
PR: ezcode-my/backend#17
File: src/main/java/org/ezcode/codetest/presentation/problemmanagement/ProblemAdminController.java:25-25
Timestamp: 2025-06-02T06:57:37.929Z
Learning: 이 프로젝트에서는 아직 Spring Security가 적용되지 않아서 @PreAuthorize 어노테이션이 주석 처리되어 있음. Spring Security 도입 전까지는 권한 검증 어노테이션들이 비활성화 상태임.
src/main/java/org/ezcode/codetest/domain/user/service/CustomOAuth2UserService.java (1)
Learnt from: chat26666
PR: ezcode-my/backend#64
File: src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/game/EncounterChoiceRepositoryImpl.java:0-0
Timestamp: 2025-06-15T04:37:29.231Z
Learning: EncounterChoiceRepositoryImpl in src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/game/EncounterChoiceRepositoryImpl.java is intentionally a skeleton implementation that is work-in-progress and will be completed later.
🧬 Code Graph Analysis (6)
src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/GithubOAuth2Response.java (1)
src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/GoogleOAuth2Response.java (1)
  • Schema (7-56)
src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/request/UserGithubRepoSelectRequest.java (1)
src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/GithubOAuth2Response.java (1)
  • Schema (8-61)
src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/user/UserGithubInfoJpaRepository.java (1)
src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/user/UserGithubInfoRepositoryImpl.java (1)
  • Repository (9-33)
src/main/java/org/ezcode/codetest/domain/user/model/entity/UserGithubInfo.java (2)
src/main/java/org/ezcode/codetest/domain/user/model/entity/User.java (1)
  • Entity (25-192)
src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/UserGithubRepoResponse.java (1)
  • Getter (7-17)
src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/user/UserGithubInfoRepositoryImpl.java (1)
src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/user/UserRepositoryImpl.java (1)
  • Repository (13-58)
src/main/java/org/ezcode/codetest/domain/user/service/CustomOAuth2UserService.java (1)
src/main/java/org/ezcode/codetest/domain/user/model/entity/UserFactory.java (1)
  • UserFactory (7-31)
🔇 Additional comments (13)
src/main/java/org/ezcode/codetest/domain/user/repository/UserRepository.java (1)

23-24: ```shell
#!/bin/bash
echo "==== UserGithubService.java ===="
rg -n -C3 "updateUserGithubAccessToken" src/main/java/org/ezcode/codetest/domain/user/service/UserGithubService.java
echo "==== UserRepositoryImpl.java ===="
rg -n -C3 "updateUserGithubAccessToken" src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/user/UserRepositoryImpl.java


</details>
<details>
<summary>src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/OAuth2Response.java (1)</summary>

`23-24`: **새 메서드 추가 확인 완료**

`getOwner()` 추가로 GitHub 전용 정보가 명확히 구분되었습니다. 인터페이스 확장은 문제 없어 보입니다.

</details>
<details>
<summary>src/main/java/org/ezcode/codetest/domain/user/exception/code/UserExceptionCode.java (1)</summary>

`14-15`: **새로운 GitHub 정보 관련 예외 코드 추가가 적절합니다.**

GitHub 기능 구현에 필요한 예외 처리를 위한 코드가 올바르게 추가되었습니다. 기존 enum 패턴을 잘 따르고 있고 메시지도 명확합니다.

</details>
<details>
<summary>src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/GithubOAuth2Response.java (1)</summary>

`56-60`: **getOwner() 메서드 구현이 올바릅니다.**

GitHub의 login 속성을 올바르게 반환하고 있으며, 스키마 어노테이션도 적절합니다. OAuth2Response 인터페이스의 새로운 메서드를 잘 구현했습니다.

</details>
<details>
<summary>src/main/java/org/ezcode/codetest/domain/user/service/UserDomainService.java (1)</summary>

`35-35`: **추가된 UserGithubInfoRepository 필드의 사용 여부를 확인하세요.**

UserGithubInfoRepository 필드가 추가되었지만 이 서비스 클래스에서 실제로 사용되지 않는 것으로 보입니다. GitHub 관련 기능이 UserGithubService로 분리되었다면 이 필드가 필요한지 검토해보세요.



다음 스크립트로 이 필드의 사용 여부를 확인해보겠습니다:

```shell
#!/bin/bash
# UserDomainService에서 userGithubInfoRepository 필드 사용 여부 확인
rg -A 5 -B 5 "userGithubInfoRepository" --type java
src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/user/UserGithubInfoJpaRepository.java (1)

8-13: JPA 리포지토리 인터페이스가 올바르게 구현되었습니다.

Spring Data JPA 규칙을 잘 따르고 있으며, 메서드 명명 규칙도 적절합니다. User 엔터티와 User ID로 UserGithubInfo를 조회하는 두 메서드 모두 필요한 기능을 제공합니다.

src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/request/UserGithubRepoSelectRequest.java (1)

5-9: 요청 DTO 레코드가 적절하게 구현되었습니다.

record 문법을 올바르게 사용했고, Swagger 어노테이션도 적절히 설정되어 있습니다. GitHub 리포지토리 선택 기능에 필요한 간단하고 명확한 구조입니다.

src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/UserGithubRepoResponse.java (1)

1-17: 구현이 잘 되어 있습니다.

DTO 구조가 명확하고 Swagger 문서화도 적절합니다. GitHub 저장소 정보를 전달하는 용도로 적합합니다.

src/main/java/org/ezcode/codetest/domain/user/service/CustomOAuth2UserService.java (1)

107-107: OAuth2Response 인터페이스의 메서드 호환성을 확인해주세요.

response.getOwner() 메서드가 모든 OAuth2Response 구현체에서 지원되는지 확인이 필요합니다. GitHub 전용 메서드라면 타입 캐스팅이나 다른 방법을 고려해보세요.

다음 스크립트로 OAuth2Response 인터페이스와 구현체들을 확인해보겠습니다:

#!/bin/bash
# OAuth2Response 인터페이스와 구현체에서 getOwner 메서드 지원 여부 확인
echo "OAuth2Response 인터페이스 확인:"
ast-grep --pattern 'interface OAuth2Response {
  $$$
}'

echo "OAuth2Response 구현체들 확인:"
ast-grep --pattern 'class $_ implements OAuth2Response {
  $$$
}'

echo "getOwner 메서드 사용 확인:"
rg -A 3 -B 3 "getOwner"
src/main/java/org/ezcode/codetest/domain/user/model/entity/User.java (4)

75-75: GitHub 자동 푸시 상태 관리 필드 추가 승인

gitPushStatus 필드 추가는 GitHub 통합 기능의 활성화 상태를 관리하는 명확한 용도로 적절합니다.


94-94: 이메일 사용자의 기본 GitHub 푸시 상태 설정 승인

이메일 가입 사용자의 gitPushStatus를 기본값 false로 설정하여 명시적인 활성화가 필요하도록 한 것이 보안상 적절합니다.


112-112: 소셜/GitHub 사용자의 기본 푸시 상태 설정 승인

모든 사용자 유형에서 gitPushStatus를 일관되게 false로 초기화하여 명시적 활성화를 요구하는 보안 관점이 적절합니다.

Also applies to: 128-128


135-135: 생성자 파라미터 추가 및 필드 할당 승인

gitPushStatus 파라미터를 생성자에 추가하고 필드에 할당하는 구현이 적절합니다.

Also applies to: 146-146

Comment on lines 12 to 15
return WebClient.builder()
.baseUrl("https://api.github.com")
.defaultHeader(HttpHeaders.ACCEPT, "application/vnd.github+json")
.build();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

GitHub API 요청을 위해 User-Agent 헤더 추가 및 URL 하드코딩 제거 제안

GitHub API는 User-Agent 헤더가 없는 요청을 거부합니다. 또한 베이스 URL을 소스에 하드코딩하면 테스트/스테이징 환경 분리가 어려워집니다.
다음과 같이 수정하면 재사용성과 환경 분리가 용이합니다.

     return WebClient.builder()
-            .baseUrl("https://api.github.com")
-            .defaultHeader(HttpHeaders.ACCEPT, "application/vnd.github+json")
+            .baseUrl("${github.api.base-url:https://api.github.com}")
+            .defaultHeader(HttpHeaders.ACCEPT, "application/vnd.github+json")
+            .defaultHeader(HttpHeaders.USER_AGENT, "ezcode-codetest-server")
             .build();

application.yml 예시:

github:
  api:
    base-url: https://api.github.com
🤖 Prompt for AI Agents
In src/main/java/org/ezcode/codetest/common/security/config/WebClientConfig.java
around lines 12 to 15, the WebClient configuration is missing the required
'User-Agent' header for GitHub API requests and has the base URL hardcoded. To
fix this, add a default header for 'User-Agent' with an appropriate value, and
refactor the base URL to be injected from a configuration property (e.g., from
application.yml) instead of hardcoding it, enabling easier environment
separation and reuse.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
src/main/java/org/ezcode/codetest/domain/user/service/UserGithubService.java (1)

69-75: GitHub API 오류 처리가 잘 구현되었습니다.

구체적인 GitHub API 오류 메시지를 포함하는 예외 처리가 유용합니다. 다만 예외 타입을 조정하는 것을 권장합니다.

이전 리뷰에서 논의된 대로, IllegalAccessException 대신 더 적절한 예외 타입 사용을 고려해주세요.

🧹 Nitpick comments (2)
src/main/java/org/ezcode/codetest/domain/user/service/CustomOAuth2UserService.java (1)

107-118: GitHub 정보 생성 로직이 적절히 구현되었습니다.

UserGithubInfo 엔티티 생성과 예외 처리가 잘 되어 있으나, 더 구체적인 예외 처리를 권장합니다.

다음과 같이 더 구체적인 예외 처리를 고려해보세요:

-			try {
-				userGithubService.createUserGithubInfo(userGithubInfo);
-			} catch (Exception e) {
-				throw new UserException(UserExceptionCode.NO_GITHUB_INFO);
-			}
+			try {
+				userGithubService.createUserGithubInfo(userGithubInfo);
+			} catch (DataAccessException e) {
+				log.error("Failed to create UserGithubInfo for user: {}", user.getId(), e);
+				throw new UserException(UserExceptionCode.NO_GITHUB_INFO);
+			}
src/main/java/org/ezcode/codetest/domain/user/service/UserGithubService.java (1)

95-100: Repository 검증 로직에서 성능 최적화가 필요합니다.

매번 GitHub API를 재호출하는 것은 비효율적입니다. 캐시된 데이터 활용을 고려해주세요.

다음과 같은 개선을 권장합니다:

  1. 성능 최적화: API 재호출 대신 이미 조회된 repos 리스트 활용
  2. 일관된 예외 처리: 도메인 예외 사용으로 일관성 유지
-        List<UserGithubRepoResponse> repos = getGithubRepos(authUser);
-
-        UserGithubRepoResponse selectedRepo = repos.stream()
-            .filter(repo -> repo.getRepoName().equals(request.repositoryName()))
-            .findFirst()
-            .orElseThrow(() -> new UserException(UserExceptionCode.NO_GITHUB_REPO));
+        // 이미 호출된 API 결과를 재사용하거나 캐싱 전략 고려
+        UserGithubRepoResponse selectedRepo = repos.stream()
+            .filter(repo -> repo.getRepoName().equals(request.repositoryName()))
+            .findFirst()
+            .orElseThrow(() -> new UserException(UserExceptionCode.NO_GITHUB_REPO));
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3673581 and bef10d2.

📒 Files selected for processing (5)
  • src/main/java/org/ezcode/codetest/common/security/config/WebClientConfig.java (1 hunks)
  • src/main/java/org/ezcode/codetest/domain/user/exception/code/UserExceptionCode.java (1 hunks)
  • src/main/java/org/ezcode/codetest/domain/user/service/CustomOAuth2UserService.java (4 hunks)
  • src/main/java/org/ezcode/codetest/domain/user/service/UserGithubService.java (1 hunks)
  • src/main/java/org/ezcode/codetest/presentation/usermanagement/UserGithubController.java (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/main/java/org/ezcode/codetest/common/security/config/WebClientConfig.java
  • src/main/java/org/ezcode/codetest/presentation/usermanagement/UserGithubController.java
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: minjee2758
PR: ezcode-my/backend#110
File: src/main/java/org/ezcode/codetest/domain/user/service/CustomOAuth2UserService.java:102-112
Timestamp: 2025-06-27T06:03:05.687Z
Learning: `CustomOAuth2UserService`의 `updateGithubUrl` 메서드는 새로운 유저 생성 시나 기존 유저가 새로운 AuthType을 추가할 때만 호출되므로, `UserGithubInfo` 중복 생성 가능성이 없다. 별도의 중복 체크 로직이 불필요하다.
Learnt from: chat26666
PR: ezcode-my/backend#37
File: src/main/java/org/ezcode/codetest/infrastructure/elasticsearch/repository/ProblemElasticsearchRepositoryDsl.java:10-10
Timestamp: 2025-06-06T19:56:27.759Z
Learning: When user chat26666 mentions that code was implemented in a previous PR but explanation was missing, they may submit a follow-up PR just to add documentation/explanation without the actual implementation code.
Learnt from: minjee2758
PR: ezcode-my/backend#43
File: src/main/java/org/ezcode/codetest/domain/user/model/entity/User.java:77-89
Timestamp: 2025-06-10T02:13:33.890Z
Learning: 이 프로젝트에서는 입력 검증을 DTO 레벨에서 수행하고 있으며, User 엔티티의 팩토리 메서드에서는 별도의 입력 검증을 하지 않는다.
Learnt from: minjee2758
PR: ezcode-my/backend#105
File: src/main/resources/application.properties:127-127
Timestamp: 2025-06-26T09:43:03.896Z
Learning: GitHub OAuth에서 자동 커밋 기능 구현을 위해서는 `repo` scope가 필요하며, 이는 저장소에 대한 읽기/쓰기 권한을 제공한다. `user` scope는 커밋 작성자 정보 설정을 위해 필요하다.
Learnt from: minjee2758
PR: ezcode-my/backend#105
File: src/main/resources/application.properties:127-127
Timestamp: 2025-06-26T09:43:03.896Z
Learning: GitHub OAuth에서 자동 커밋 기능을 구현하려면 `repo` scope가 필수적이며, 이는 public/private 저장소 모두에 대한 전체 접근 권한을 제공한다. 공개 저장소만 대상으로 한다면 `public_repo` scope 사용 가능하다. 더 세밀한 권한 제어가 필요하다면 OAuth App 대신 GitHub App 사용을 권장한다.
Learnt from: chat26666
PR: ezcode-my/backend#64
File: src/main/java/org/ezcode/codetest/domain/game/repository/EncounterRepository.java:0-0
Timestamp: 2025-06-15T04:36:57.084Z
Learning: 사용자 chat26666은 개발 중인 기능의 경우 향후 개발 예정인 빈 인터페이스를 의도적으로 남겨두는 것을 선호함. EncounterRepository 인터페이스는 현재 미정의 상태이지만 추후 개발 예정으로 의도적으로 빈 상태로 유지됨.
Learnt from: NCookies
PR: ezcode-my/backend#17
File: src/main/java/org/ezcode/codetest/presentation/problemmanagement/ProblemAdminController.java:25-25
Timestamp: 2025-06-02T06:57:37.929Z
Learning: 이 프로젝트에서는 아직 Spring Security가 적용되지 않아서 @PreAuthorize 어노테이션이 주석 처리되어 있음. Spring Security 도입 전까지는 권한 검증 어노테이션들이 비활성화 상태임.
src/main/java/org/ezcode/codetest/domain/user/service/CustomOAuth2UserService.java (3)
Learnt from: minjee2758
PR: ezcode-my/backend#110
File: src/main/java/org/ezcode/codetest/domain/user/service/CustomOAuth2UserService.java:102-112
Timestamp: 2025-06-27T06:03:05.687Z
Learning: `CustomOAuth2UserService`의 `updateGithubUrl` 메서드는 새로운 유저 생성 시나 기존 유저가 새로운 AuthType을 추가할 때만 호출되므로, `UserGithubInfo` 중복 생성 가능성이 없다. 별도의 중복 체크 로직이 불필요하다.
Learnt from: minjee2758
PR: ezcode-my/backend#105
File: src/main/resources/application.properties:127-127
Timestamp: 2025-06-26T09:43:03.896Z
Learning: GitHub OAuth에서 자동 커밋 기능 구현을 위해서는 `repo` scope가 필요하며, 이는 저장소에 대한 읽기/쓰기 권한을 제공한다. `user` scope는 커밋 작성자 정보 설정을 위해 필요하다.
Learnt from: minjee2758
PR: ezcode-my/backend#105
File: src/main/resources/application.properties:127-127
Timestamp: 2025-06-26T09:43:03.896Z
Learning: GitHub OAuth에서 자동 커밋 기능을 구현하려면 `repo` scope가 필수적이며, 이는 public/private 저장소 모두에 대한 전체 접근 권한을 제공한다. 공개 저장소만 대상으로 한다면 `public_repo` scope 사용 가능하다. 더 세밀한 권한 제어가 필요하다면 OAuth App 대신 GitHub App 사용을 권장한다.
src/main/java/org/ezcode/codetest/domain/user/exception/code/UserExceptionCode.java (2)
Learnt from: minjee2758
PR: ezcode-my/backend#110
File: src/main/java/org/ezcode/codetest/domain/user/service/CustomOAuth2UserService.java:102-112
Timestamp: 2025-06-27T06:03:05.687Z
Learning: `CustomOAuth2UserService`의 `updateGithubUrl` 메서드는 새로운 유저 생성 시나 기존 유저가 새로운 AuthType을 추가할 때만 호출되므로, `UserGithubInfo` 중복 생성 가능성이 없다. 별도의 중복 체크 로직이 불필요하다.
Learnt from: thezz9
PR: ezcode-my/backend#98
File: src/main/java/org/ezcode/codetest/application/submission/dto/event/SubmissionErrorEvent.java:17-22
Timestamp: 2025-06-25T01:24:30.754Z
Learning: JudgeClient에서 모든 예외를 SubmissionException으로 래핑해서 넘길 계획이므로, SubmissionErrorEvent.resolveCode() 메서드의 캐스팅은 안전할 예정임.
src/main/java/org/ezcode/codetest/domain/user/service/UserGithubService.java (5)
Learnt from: minjee2758
PR: ezcode-my/backend#110
File: src/main/java/org/ezcode/codetest/domain/user/service/CustomOAuth2UserService.java:102-112
Timestamp: 2025-06-27T06:03:05.687Z
Learning: `CustomOAuth2UserService`의 `updateGithubUrl` 메서드는 새로운 유저 생성 시나 기존 유저가 새로운 AuthType을 추가할 때만 호출되므로, `UserGithubInfo` 중복 생성 가능성이 없다. 별도의 중복 체크 로직이 불필요하다.
Learnt from: minjee2758
PR: ezcode-my/backend#105
File: src/main/resources/application.properties:127-127
Timestamp: 2025-06-26T09:43:03.896Z
Learning: GitHub OAuth에서 자동 커밋 기능 구현을 위해서는 `repo` scope가 필요하며, 이는 저장소에 대한 읽기/쓰기 권한을 제공한다. `user` scope는 커밋 작성자 정보 설정을 위해 필요하다.
Learnt from: minjee2758
PR: ezcode-my/backend#105
File: src/main/resources/application.properties:127-127
Timestamp: 2025-06-26T09:43:03.896Z
Learning: GitHub OAuth에서 자동 커밋 기능을 구현하려면 `repo` scope가 필수적이며, 이는 public/private 저장소 모두에 대한 전체 접근 권한을 제공한다. 공개 저장소만 대상으로 한다면 `public_repo` scope 사용 가능하다. 더 세밀한 권한 제어가 필요하다면 OAuth App 대신 GitHub App 사용을 권장한다.
Learnt from: thezz9
PR: ezcode-my/backend#73
File: src/main/java/org/ezcode/codetest/infrastructure/openai/OpenAIReviewClient.java:52-64
Timestamp: 2025-06-18T11:42:03.701Z
Learning: OpenAI API 클라이언트에서는 두 가지 재시도 전략을 사용한다: 1) WebClient의 retryWhen은 네트워크/HTTP 에러 및 타임아웃에 대한 재시도, 2) 외부 for 루프는 API 응답 포맷 검증 실패에 대한 재시도. 이는 서로 다른 실패 상황을 처리하는 독립적인 메커니즘이다.
Learnt from: chat26666
PR: ezcode-my/backend#88
File: src/main/java/org/ezcode/codetest/application/game/play/GamePlayUseCase.java:0-0
Timestamp: 2025-06-21T21:29:21.785Z
Learning: JwtUtil.extractClaims() 메서드는 이미 JwtException을 catch하여 ServerException으로 변환하는 예외 처리가 구현되어 있으므로, 호출하는 곳에서 추가적인 try-catch 블록이 필요하지 않습니다.
🔇 Additional comments (4)
src/main/java/org/ezcode/codetest/domain/user/exception/code/UserExceptionCode.java (1)

14-16: 새로운 GitHub 관련 예외 코드가 적절히 추가되었습니다.

기존 enum 패턴을 잘 따르고 있으며, 한국어 메시지도 명확합니다. GitHub 기능에 필요한 도메인별 예외 처리가 잘 구성되어 있습니다.

src/main/java/org/ezcode/codetest/domain/user/service/CustomOAuth2UserService.java (1)

8-9: 필요한 의존성과 임포트가 적절히 추가되었습니다.

GitHub 기능 지원을 위한 새로운 서비스 의존성과 엔티티 임포트가 잘 구성되어 있습니다.

Also applies to: 14-14, 36-36

src/main/java/org/ezcode/codetest/domain/user/service/UserGithubService.java (2)

33-43: 기본 CRUD 메서드들이 적절히 구현되었습니다.

UserGithubInfo 엔티티에 대한 생성, 조회, 업데이트 메서드가 잘 구성되어 있습니다.


46-47: 트랜잭션 어노테이션 사용이 적절한지 검토해주세요.

조회 전용 메서드에 @Transactional이 필요한지 확인해주세요.

이 프로젝트의 트랜잭션 관리 패턴을 확인하기 위해 다음 스크립트를 실행하겠습니다:

#!/bin/bash
# 프로젝트의 트랜잭션 관리 패턴 확인
echo "=== UseCase 레벨 트랜잭션 패턴 확인 ==="
rg -A 3 -B 1 "@Transactional" --type java

echo "=== 도메인 서비스의 트랜잭션 사용 패턴 ==="
fd "Service\.java$" src/main/java/org/ezcode/codetest/domain -x rg -l "@Transactional" {}

learned context에 따르면 이 프로젝트는 UseCase 레벨에서 트랜잭션을 관리한다고 되어 있는데, 현재 도메인 서비스에서 직접 트랜잭션을 사용하는 것이 일관된 패턴인지 확인이 필요합니다.

Comment on lines +79 to +82
.map(repo -> new UserGithubRepoResponse(
repo.get("name").toString(),
repo.get("default_branch").toString()
))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

API 응답 파싱에서 null 안전성을 강화해주세요.

GitHub API 응답에서 값 추출 시 null 체크가 필요합니다.

다음과 같이 안전한 파싱을 적용해주세요:

.map(repo -> new UserGithubRepoResponse(
-    repo.get("name").toString(),
-    repo.get("default_branch").toString()
+    Objects.toString(repo.get("name"), ""),
+    Objects.toString(repo.get("default_branch"), "main")
))

추가로 Objects 임포트가 필요합니다:

import java.util.Objects;
🤖 Prompt for AI Agents
In src/main/java/org/ezcode/codetest/domain/user/service/UserGithubService.java
around lines 79 to 82, the code extracts values from the GitHub API response
without null checks, which can cause NullPointerExceptions. Update the mapping
to safely handle potential null values by using Objects.toString() with a
default empty string or similar null-safe methods for both "name" and
"default_branch" fields. Also, add the import statement for java.util.Objects at
the top of the file.

@minjee2758 minjee2758 merged commit 4ab0fd1 into dev Jun 27, 2025
2 checks passed
@minjee2758 minjee2758 deleted the feature/UserGithub branch June 27, 2025 06:19
@coderabbitai coderabbitai bot mentioned this pull request Jul 28, 2025
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants