Skip to content

Conversation

@nahowo
Copy link
Contributor

@nahowo nahowo commented May 1, 2025

Summary

Description

공통

  • 메서드명 좀 더 명확하게 변경
  • 주석 제거
  • 긴 메서드를 분리해서 작은 단위로 수정
  • 필요하지 않은 수준의 접근 제어자 변경(public → private)

controller

  • 실제 로직이 수행되는 부분을 controller → service로 변경
    • controller 추상화 레벨 높임

service

  • SnsService에 공통적으로 사용되는 RestTemplate 요청, HttpResponse 파싱, 오류 검증 로직 추가
  • SlackService, DiscordService가 위 메서드를 사용하도록 변경 → 중복 제거
  • 로직 세부사항을 각 controller로 변경, 각 메서드 크기 축소

Screenshot

Test Checklist

Summary by CodeRabbit

  • Refactor
    • Discord 및 Slack 컨트롤러와 서비스의 로직이 단순화되고 역할이 명확히 분리되어 유지보수가 용이해졌습니다.
    • SNS 정보 생성, 저장, 메시지 전송 과정이 일관성 있게 개선되어 코드 구조가 향상되었습니다.
  • Chores
    • Mac OS에서 생성되는 .DS_Store 파일이 버전 관리에서 제외됩니다.

@nahowo nahowo self-assigned this May 1, 2025
@nahowo nahowo linked an issue May 1, 2025 that may be closed by this pull request
@coderabbitai
Copy link

coderabbitai bot commented May 1, 2025

Walkthrough

이번 변경 사항은 컨트롤러와 서비스 계층에서 SNS(Discord, Slack) 연동 및 메시지 전송 로직을 대폭 리팩토링하여, 컨트롤러의 책임을 단순화하고 서비스 계층에서 외부 API 통신과 SNS 정보 저장을 일원화했습니다. 각 컨트롤러는 더 이상 RestTemplate이나 DTO 변환, 직접적인 SNS 정보 저장을 다루지 않고, 서비스의 고수준 메서드만 호출합니다. 서비스 계층에서는 RestTemplate 호출, 응답 파싱, 예외 처리 등을 SnsService로 위임하여 코드 재사용성과 캡슐화를 높였습니다. 또한, 각종 메서드 시그니처 변경 및 접근제어자 조정이 이뤄졌습니다.

Changes

파일/그룹 변경 요약
.gitignore Mac OS용 .DS_Store 무시 규칙 추가
src/main/java/com/Alchive/backend/controller/BoardController.java SlackService 필드 선언 제거
src/main/java/com/Alchive/backend/controller/DiscordController.java,
src/main/java/com/Alchive/backend/controller/SlackController.java
SNS 연동/메시지 전송 로직을 서비스로 위임, SnsService 관련 코드 및 불필요한 필드/임포트 제거, 메서드 내부 구현 단순화 및 일부 시그니처 변경
src/main/java/com/Alchive/backend/controller/SnsController.java createSns 메서드 파라미터에 @RequestBody 추가, Sns 엔티티 직접 생성 방식 유지
src/main/java/com/Alchive/backend/service/DiscordService.java,
src/main/java/com/Alchive/backend/service/SlackService.java
RestTemplate 직접 사용을 SnsService로 위임, OAuth 및 DM 관련 로직 리팩토링, 메서드 시그니처 및 접근제어자 변경, 주요 흐름을 캡슐화한 신규 메서드 추가
src/main/java/com/Alchive/backend/service/SnsService.java RestTemplate 필드 추가, HTTP 요청 및 응답 파싱/검증용 보호 메서드 3종(sendRestTemplateExchange, parseResponse, checkInvalidGrant) 추가

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Controller
    participant Service
    participant SnsService
    participant ExternalAPI

    User->>Controller: SNS 연동 요청 (코드 등 전달)
    Controller->>Service: initialize[Discord|Slack]ChannelAndSaveSnsInfo(user, code)
    Service->>SnsService: sendRestTemplateExchange(토큰 요청)
    SnsService->>ExternalAPI: OAuth 토큰 요청
    ExternalAPI-->>SnsService: 토큰 응답
    SnsService-->>Service: 파싱된 토큰/유저ID 등
    Service->>SnsService: createSns(Sns)
    SnsService-->>Service: 저장 완료
    Service->>SnsService: sendRestTemplateExchange(DM 전송)
    SnsService->>ExternalAPI: DM 메시지 전송
    ExternalAPI-->>SnsService: 전송 결과
    SnsService-->>Service: 결과 반환
    Service-->>Controller: 완료 응답
    Controller-->>User: 결과 반환
Loading

Possibly related PRs

  • feat: 디스코드, 슬랙 봇 추가 #95: Discord 및 Slack 봇 통합 기능 초기 구현 PR로, 이번 리팩토링과 직접적으로 관련된 SNS 연동 및 메시지 전송 로직을 처음 도입한 PR입니다.

Poem

🐰
새싹처럼 자라는 코드,
컨트롤러는 가벼워지고
서비스는 똑똑해졌네!
슬랙과 디스코드,
모두 한 곳에서 척척—
토끼는 오늘도 깡총깡총
리팩토링 춤을 춥니다!
🌱✨


📜 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 f8ae840 and 55f5034.

📒 Files selected for processing (5)
  • src/main/java/com/Alchive/backend/controller/DiscordController.java (1 hunks)
  • src/main/java/com/Alchive/backend/controller/SnsController.java (2 hunks)
  • src/main/java/com/Alchive/backend/service/DiscordService.java (3 hunks)
  • src/main/java/com/Alchive/backend/service/SlackService.java (4 hunks)
  • src/main/java/com/Alchive/backend/service/SnsService.java (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
  • src/main/java/com/Alchive/backend/controller/SnsController.java
  • src/main/java/com/Alchive/backend/service/SnsService.java
  • src/main/java/com/Alchive/backend/service/SlackService.java
  • src/main/java/com/Alchive/backend/controller/DiscordController.java
  • src/main/java/com/Alchive/backend/service/DiscordService.java
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build
✨ 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.
    • Generate unit testing code for this file.
    • 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 generate unit testing code for this file.
    • @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 generate unit testing code.
    • @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.

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: 5

🧹 Nitpick comments (12)
.gitignore (1)

39-41: 추가 macOS 아티팩트 무시 고려 제안
.DS_Store 외에도 .AppleDouble, .LSOverride 같은 macOS 관련 임시 파일을 무시 목록에 포함하면 더 완벽한 무시 설정이 될 수 있습니다.

src/main/java/com/Alchive/backend/controller/SlackController.java (1)

3-7: 사용되지 않는 SnsService import 제거

SnsService를 더 이상 사용하지 않으므로 import 를 남겨두면 컴파일 경고가 발생합니다.

-import com.Alchive.backend.service.SnsService;
src/main/java/com/Alchive/backend/controller/DiscordController.java (1)

3-7: 불필요한 SnsService import 제거

SlackController와 동일하게 SnsService import 가 사용되지 않습니다.

-import com.Alchive.backend.service.SnsService;
src/main/java/com/Alchive/backend/service/SnsService.java (1)

36-40: RestTemplate 직접 생성 대신 Bean 주입 권장

new RestTemplate()를 필드에 직접 생성하면 커스텀 타임아웃, 인터셉터, 로깅 등을 설정하기 어렵고 테스트 시 Mock 주입도 힘듭니다.

- private RestTemplate restTemplate = new RestTemplate();
+ private final RestTemplate restTemplate;
+
+ public SnsService(SnsReporitory snsReporitory, RestTemplateBuilder builder) {
+     this.snsReporitory = snsReporitory;
+     this.restTemplate  = builder.build();
+ }

스프링 빈으로 주입받으면 공통 설정을 중앙에서 관리할 수 있습니다.

src/main/java/com/Alchive/backend/service/SlackService.java (4)

27-31: 중복 애너테이션 제거 권장

@Service@Configuration을 동시에 선언할 필요가 없습니다.
@Service만으로 빈 등록이 충분하며, @Configuration은 오히려 의미상 혼동을 줄 수 있습니다.
불필요한 애너테이션을 제거하여 의도를 명확히 해 주세요.


44-46: 사용되지 않는 필드 정리

slackBotToken 필드는 선언만 되고 실제로 사용되지 않습니다.
불필요한 필드는 삭제하거나 사용 목적이 있다면 코드에 반영해 주세요.


69-82: 제네릭 타입 명시 및 타입 세이프티 개선

ResponseEntity<Map> 은 raw Map 사용으로 인해 캐스팅 오류 가능성이 있습니다.
Jackson ObjectNode 또는 Map<String, Object>로 명시하여 타입 안정성을 높여 주세요.


85-88: 변수명-로직 불일치

threeDaysAgo라는 변수명이 실제로는 minusDays(1)을 사용합니다.
의도한 기간(1일 vs 3일)을 확인한 뒤 변수명 또는 로직을 맞춰 주세요.

src/main/java/com/Alchive/backend/service/DiscordService.java (4)

50-54: 메서드명 오타

initializeDiscordChannleAndSaveSnsInfoinitializeDiscordChannelAndSaveSnsInfo
철자 오류는 IDE 자동 검색·호출에 영향을 주므로 조속히 수정해 주세요.


81-88: HttpEntity 제네릭 타입 부적절

HttpEntity<String> request = new HttpEntity<>(accessTokenHeaders); 는 body가 없으므로
HttpEntity<Void> 또는 HttpEntity<Object>가 의미상 더 명확합니다.
작동에는 문제 없지만 가독성 차원에서 타입 수정을 권장합니다.


103-106: 변수명-로직 불일치

threeDaysAgo 변수는 실제로 minusDays(1)을 사용합니다.
SlackService와 동일한 문제로, 기간 값과 변수명을 일치시켜 주세요.


147-153: JDA 블로킹 호출 주의

retrieveUserById(...).complete() 는 REST 요청을 동기 블로킹으로 수행합니다.
대량 호출 시 스레드 점유 및 지연이 발생할 수 있으므로
queue() 콜백 사용이나 별도 스케줄러로 비동기 처리를 검토해 주세요.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 5a7d6f4 and f8ae840.

⛔ Files ignored due to path filters (1)
  • .DS_Store is excluded by !**/.DS_Store
📒 Files selected for processing (8)
  • .gitignore (1 hunks)
  • src/main/java/com/Alchive/backend/controller/BoardController.java (0 hunks)
  • src/main/java/com/Alchive/backend/controller/DiscordController.java (1 hunks)
  • src/main/java/com/Alchive/backend/controller/SlackController.java (1 hunks)
  • src/main/java/com/Alchive/backend/controller/SnsController.java (2 hunks)
  • src/main/java/com/Alchive/backend/service/DiscordService.java (3 hunks)
  • src/main/java/com/Alchive/backend/service/SlackService.java (4 hunks)
  • src/main/java/com/Alchive/backend/service/SnsService.java (2 hunks)
💤 Files with no reviewable changes (1)
  • src/main/java/com/Alchive/backend/controller/BoardController.java
🧰 Additional context used
🧬 Code Graph Analysis (2)
src/main/java/com/Alchive/backend/service/SlackService.java (1)
src/main/java/com/Alchive/backend/config/error/exception/sns/NoSuchSnsIdException.java (1)
  • NoSuchSnsIdException (6-8)
src/main/java/com/Alchive/backend/service/DiscordService.java (1)
src/main/java/com/Alchive/backend/config/error/exception/sns/NoSuchSnsIdException.java (1)
  • NoSuchSnsIdException (6-8)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build
🔇 Additional comments (3)
.gitignore (1)

39-41: Mac OS 메타데이터 파일 무시 추가 – 적절합니다
.DS_Store 항목을 추가하여 macOS에서 자동 생성되는 디렉터리 메타데이터 파일을 Git 관리 대상에서 제외한 것은 좋은 관행입니다.

src/main/java/com/Alchive/backend/controller/SlackController.java (1)

28-30:

Details

✅ Verification successful

모든 예외 상황에서 성공 코드 반환 위험

initializeSlackChannelAndSaveSnsInfosendSlackDm 과정에서 예외가 발생해도 컨트롤러는 무조건 200 OKSLACK_DM_SEND_SUCCESS 코드를 반환합니다. 서비스가 런타임 예외를 던지도록 설계됐다면 @ExceptionHandler 또는 글로벌 예외 처리기를 통해 HTTP 상태를 전달하도록 하거나, 메서드 내부에서 실패 여부를 체크한 뒤 적절한 응답 코드를 리턴해 주세요.

Also applies to: 36-36


예외 처리 핸들러 존재 여부와 SlackService 호출 방식 확인을 위해 아래 스크립트를 실행하겠습니다.


🏁 Script executed:

#!/bin/bash
# 글로벌 예외 처리 핸들러 확인
rg "@ControllerAdvice" -A3
rg "@ExceptionHandler" -A3

# SlackController 클래스 확인
rg "class SlackController" -A3 src/main/java/com/Alchive/backend/controller/SlackController.java

# SlackService 메서드 구현 위치 확인
rg "initializeSlackChannelAndSaveSnsInfo" -A2 src/main/java
rg "sendSlackDm" -A2 src/main/java

Length of output: 3926


글로벌 예외 처리기로 SlackController 예외가 처리됨 확인됨
SlackService 호출 중 발생하는 RuntimeExceptionBusinessExceptionGlobalExceptionHandler(@ControllerAdvice)에 정의된 @ExceptionHandler가 적절한 HTTP 상태 코드(500 또는 비즈니스 에러 코드)로 변환하여 응답합니다.
따라서 컨트롤러 내부에 별도의 예외 처리 로직을 추가할 필요가 없습니다.

src/main/java/com/Alchive/backend/service/SlackService.java (1)

102-116: DM 전송 방식 검토 필요

Slack chat.postMessage API에서 channel 파라미터에는 DM 채널 ID가 필요합니다.
현재 저장 중인 값이 User ID라면 메시지 전송이 실패할 수 있습니다.
Slack DM용 채널 ID(conversations.open API로 획득)를 저장·사용하는지 확인해 주세요.

@nahowo nahowo merged commit 7b28b11 into develop May 1, 2025
2 checks passed
@nahowo nahowo deleted the refactor/#101 branch May 1, 2025 07:35
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.

[refactor] SNS 로직 리팩토링

2 participants