Skip to content

Conversation

@oxdjww
Copy link
Contributor

@oxdjww oxdjww commented Apr 30, 2025

Resolved Issue #9

Summary by CodeRabbit

  • 신규 기능

    • 프로덕션 및 개발 환경을 위한 새로운 환경설정 파일이 추가되었습니다.
    • CI(테스트 및 빌드)와 CD(배포) 자동화 워크플로우가 도입되었습니다.
  • 버그 수정

    • 백엔드 컨테이너 및 서버의 기본 포트가 8080에서 80으로 변경되었습니다.
    • Swagger 문서의 서버 URL이 최신 주소로 수정되었습니다.
  • 문서

    • Swagger UI 경로 및 OpenAPI 설정이 업데이트되었습니다.
  • 스타일

    • BaseEntity 클래스에 Setter가 자동 생성되도록 변경되었습니다.
  • 기타

    • 불필요한 Redis 설정이 제거되고, JWT 보안 설정이 추가되었습니다.
    • 데이터베이스 및 보안 관련 환경변수 구성이 명확하게 개선되었습니다.

@oxdjww oxdjww added the feature New feature or request label Apr 30, 2025
@oxdjww oxdjww self-assigned this Apr 30, 2025
@oxdjww oxdjww linked an issue Apr 30, 2025 that may be closed by this pull request
@coderabbitai
Copy link

coderabbitai bot commented Apr 30, 2025

Warning

Rate limit exceeded

@oxdjww has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 28 minutes and 40 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between c7c8334 and 2a038b6.

📒 Files selected for processing (10)
  • .github/workflows/cd.yml (1 hunks)
  • .github/workflows/ci.yml (1 hunks)
  • .gitignore (1 hunks)
  • backend/Dockerfile (1 hunks)
  • backend/src/main/java/com/focussu/backend/common/BaseEntity.java (1 hunks)
  • backend/src/main/java/com/focussu/backend/config/SwaggerConfig.java (1 hunks)
  • backend/src/main/java/com/focussu/backend/studyroom/service/StudyRoomQueryService.java (1 hunks)
  • backend/src/main/resources/application-dev.yml (2 hunks)
  • backend/src/main/resources/application-prod.yml (1 hunks)
  • backend/src/main/resources/application.yml (1 hunks)

Walkthrough

이번 변경 사항에서는 CI/CD 자동화와 관련된 GitHub Actions 워크플로우 파일이 새롭게 추가되었고, 백엔드 Dockerfile 및 여러 환경설정 파일(application-*.yml)들이 갱신 및 신설되었습니다. 주요 변경점으로는 서버 포트가 8080에서 80으로 일괄 변경되었으며, Swagger 문서의 서버 주소도 이에 맞춰 수정되었습니다. 또한, 공통 엔터티에 Lombok Setter 어노테이션이 추가되었고, 프로덕션 환경을 위한 application-prod.yml이 새롭게 도입되었습니다. CI와 CD 파이프라인은 각각 PR과 main 브랜치 push 시 동작하도록 설정되었습니다.

Changes

파일/경로 변경 요약
.github/workflows/ci.yml
.github/workflows/cd.yml
CI(테스트/빌드) 및 CD(배포)용 GitHub Actions 워크플로우 신규 추가
backend/Dockerfile 컨테이너 내부 노출 포트 8080 → 80으로 변경
backend/src/main/resources/application-dev.yml
backend/src/main/resources/application.yml
서버 포트 80으로 변경, dev 환경 DB/Redis/JWT 등 설정 변경 및 신규 application.yml(프로필/시크릿 import) 추가
backend/src/main/resources/application-prod.yml 프로덕션 환경용 신규 설정 파일 추가, DB/Kafka/Swagger 등 환경변수 기반 설정
backend/src/main/java/com/focussu/backend/common/BaseEntity.java Lombok @Setter 어노테이션 추가, 필드 setter 자동 생성
backend/src/main/java/com/focussu/backend/config/SwaggerConfig.java Swagger 서버 URL을 포트 80 및 도메인 변경에 맞게 수정
backend/src/main/java/com/focussu/backend/studyroom/service/StudyRoomQueryService.java 예외 처리 커스터마이징 관련 주석 추가

Sequence Diagram(s)

sequenceDiagram
    participant Developer
    participant GitHub
    participant CI Workflow
    participant CD Workflow
    participant AWS ECR
    participant Deploy Script

    Developer->>GitHub: PR 생성 또는 main 브랜치 push
    alt PR 생성
        GitHub->>CI Workflow: CI 워크플로우 트리거
        CI Workflow->>CI Workflow: 코드 checkout, JDK/Gradle 설정, 빌드 및 테스트
    else main 브랜치 push
        GitHub->>CD Workflow: CD 워크플로우 트리거
        CD Workflow->>CD Workflow: 코드 checkout, Docker Buildx 설정
        CD Workflow->>AWS ECR: 로그인, 이미지 빌드 및 푸시
        CD Workflow->>Deploy Script: 배포 스크립트 실행
    end
Loading

Poem

🐇
새로 온 포트는 이제 여든,
CI/CD로 깡총깡총 흐르는 흐름.
Setter도 추가해, 엔터티는 더 부드럽게,
프로덕션 설정도 야무지게 준비했네.
깃허브 액션 타고 구름 위로 점프!
포커스 백엔드, 오늘도 한 단계 업!

✨ 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.

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.

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

🔭 Outside diff range comments (1)
.github/workflows/cd.yml (1)

32-44: ⚠️ Potential issue

Kafka 연결 설정 누락
CD 워크플로우의 envKAFKA_BOOTSTRAP_SERVERS가 포함되지 않아 프로덕션에서 Kafka 연결이 실패합니다. 워크플로우에 Kafka 시크릿 추가 또는 설정 제거를 검토해주세요.

🧹 Nitpick comments (7)
.github/workflows/ci.yml (1)

1-33: CI 워크플로우 구성이 잘 되어 있습니다만 몇 가지 개선사항을 제안합니다

CI 워크플로우가 기본적인 빌드 및 테스트 단계를 잘 구현하고 있습니다. 다만, 효율성과 가시성을 위해 몇 가지 개선점을 제안합니다.

다음과 같은 개선을 고려해보세요:

  1. Gradle 의존성 캐싱 추가
  2. 테스트 결과를 아티팩트로 저장
  3. 코드 품질 분석(SonarQube 등) 추가
name: CI

on:
  pull_request:
    branches: [ main ]

jobs:
  build-and-test:
    runs-on: ubuntu-latest

    defaults:
      run:
        working-directory: ./backend

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up JDK 17
        uses: actions/setup-java@v4
        with:
          java-version: 17
          distribution: temurin
+         cache: gradle

      - name: Grant execute permission to Gradle wrapper
        run: chmod +x gradlew

      - name: Build with Gradle
        run: ./gradlew build --no-daemon

      - name: Run tests
        run: ./gradlew test
+
+     - name: Save test results
+       uses: actions/upload-artifact@v4
+       if: always()
+       with:
+         name: test-results
+         path: ./backend/build/reports/tests/
backend/Dockerfile (1)

10-14: 비-root 사용자 실행 고려
현재 컨테이너가 root 사용자로 실행되어 포트 80 바인딩이 가능하지만, 보안을 위해 비-root 사용자로 실행하도록 USER 지시어를 추가하는 리팩토링을 제안드립니다.

backend/src/main/resources/application-prod.yml (1)

33-33: 파일 끝 개행 추가
YAMLlint 오류 처리: 파일 마지막에 개행(new line)을 추가해주세요.

🧰 Tools
🪛 YAMLlint (1.35.1)

[error] 33-33: no new line character at the end of file

(new-line-at-end-of-file)

.github/workflows/cd.yml (4)

3-5: CD 워크플로우 트리거 확인
main 브랜치에 대한 push 시 CD가 실행되도록 설정되어 있습니다. 릴리즈 태그나 별도 브랜치에도 배포가 필요하다면 트리거 조건을 확장하세요.


18-20: Amazon ECR 로그인 설정 적절
aws-actions/amazon-ecr-login@v2로 ECR 인증을 처리하는 방식이 안정적입니다. 추가로 OIDC 기반 인증으로 워크플로우 보안을 강화하는 방안도 고려해보세요.


21-25: Docker 빌드 캐시 활용 제안
빌드 속도를 높이기 위해 --cache-from 옵션 사용 또는 actions/cache로 레이어 캐시를 활용하는 구성을 추가하는 것을 권장드립니다.


29-31: 배포 스크립트 실행 권한 확인
./deploy/deploy-prod.sh 스크립트가 실행 권한을 갖추고 있는지 확인하세요. 권한 누락 시 워크플로우가 실패할 수 있습니다.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6b3958f and c7c8334.

📒 Files selected for processing (9)
  • .github/workflows/cd.yml (1 hunks)
  • .github/workflows/ci.yml (1 hunks)
  • backend/Dockerfile (1 hunks)
  • backend/src/main/java/com/focussu/backend/common/BaseEntity.java (1 hunks)
  • backend/src/main/java/com/focussu/backend/config/SwaggerConfig.java (1 hunks)
  • backend/src/main/java/com/focussu/backend/studyroom/service/StudyRoomQueryService.java (1 hunks)
  • backend/src/main/resources/application-dev.yml (2 hunks)
  • backend/src/main/resources/application-prod.yml (1 hunks)
  • backend/src/main/resources/application.yml (1 hunks)
🧰 Additional context used
🪛 YAMLlint (1.35.1)
backend/src/main/resources/application-dev.yml

[error] 45-45: no new line character at the end of file

(new-line-at-end-of-file)

backend/src/main/resources/application-prod.yml

[error] 33-33: no new line character at the end of file

(new-line-at-end-of-file)

🔇 Additional comments (5)
backend/src/main/java/com/focussu/backend/config/SwaggerConfig.java (1)

19-21:

Details

✅ Verification successful

로컬 서버 포트 80 사용에 관한 고려사항

로컬 서버 URL이 포트 8080에서 80으로 변경되었습니다. 포트 80은 표준 HTTP 포트로 URL에 별도 포트 지정이 필요없어 편리하지만, 로컬에서 실행할 때 관리자 권한이 필요할 수 있습니다.

개발 환경에서는 일반적으로 비특권 포트(1024 이상)를 사용하는 것이 권장됩니다. 실제로 애플리케이션이 포트 80으로 구성되어 있는지 확인해보세요:


🏁 Script executed:

#!/bin/bash
# application.yml 또는 application-dev.yml에서 서버 포트 설정 확인
echo "로컬 환경 포트 설정 확인:"
find backend/src/main/resources -name "application*.yml" -exec grep -l "port:" {} \; -exec grep "port:" {} \;

Length of output: 412


SwaggerConfig 포트 설정 일치 확인

  • backend/src/main/java/com/focussu/backend/config/SwaggerConfig.java (Lines 19–21)
    · .url("http://localhost:80") 사용
  • backend/src/main/resources/application-dev.yml
    · port: 80
  • backend/src/main/resources/application-prod.yml
    · port: 80

애플리케이션 설정과 SwaggerConfig의 로컬 서버 포트(80)가 일치하므로 별도 수정은 필요하지 않습니다. 다만 포트 80 사용 시 운영체제에 따라 관리자 권한이 요구될 수 있으니, 팀 개발 환경에서 문제가 없다면 현 상태를 유지하시고, 필요 시 비특권 포트(예: 8080) 사용도 검토해 주세요.

backend/Dockerfile (1)

13-13: 컨테이너 노출 포트 일관성 확인
application-*.yml에서 80 포트를 사용하도록 변경한 것과 일치합니다.

backend/src/main/resources/application.yml (1)

3-7: 기본 프로파일 및 시크릿 import 설정 적절
application.yml에서 기본 프로파일을 prod로 활성화하고, application-secret.yml을 optional import 하는 패턴은 비밀 정보 관리 관점에서 안전하며 잘 구성되었습니다.

backend/src/main/resources/application-dev.yml (1)

3-5: 개발 환경 포트 변경 확인 필요
application-dev.ymlserver.port: 80은 로컬 개발 시 root 권한 바인딩 이슈를 발생시킬 수 있습니다. 의도된 설정인지 확인 부탁드립니다.

backend/src/main/resources/application-prod.yml (1)

25-27: 프로덕션 포트 설정 확인
server.port를 80으로 설정하여 Dockerfile 및 CI/CD 배포와 일관성이 있습니다.

Comment on lines 15 to 17
public StudyRoomCreateResponse getStudyRoom(Long id) {
// TODO: 예외 커스텀
StudyRoom studyRoom = studyRoomRepository.findById(id)
.orElseThrow(() -> new IllegalArgumentException("존재하지 않는 회원입니다."));
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

예외 처리 개선 계획에 대한 제안

TODO 주석이 추가된 것을 확인했습니다. 현재는 IllegalArgumentException을 사용하고 있지만, REST API에 더 적합한 커스텀 예외 처리로 개선하는 것이 좋을 것 같습니다.

다음과 같은 방식으로 개선할 수 있습니다:

  1. 도메인별 커스텀 예외 클래스 생성 (예: StudyRoomNotFoundException)
  2. @ControllerAdvice를 사용한 글로벌 예외 핸들러 구현
  3. 적절한 HTTP 상태 코드와 응답 형식 표준화
- // TODO: 예외 커스텀
- StudyRoom studyRoom = studyRoomRepository.findById(id)
-         .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 회원입니다."));
+ StudyRoom studyRoom = studyRoomRepository.findById(id)
+         .orElseThrow(() -> new StudyRoomNotFoundException(id));
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public StudyRoomCreateResponse getStudyRoom(Long id) {
// TODO: 예외 커스텀
StudyRoom studyRoom = studyRoomRepository.findById(id)
.orElseThrow(() -> new IllegalArgumentException("존재하지 않는 회원입니다."));
public StudyRoomCreateResponse getStudyRoom(Long id) {
- // TODO: 예외 커스텀
- StudyRoom studyRoom = studyRoomRepository.findById(id)
- .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 회원입니다."));
+ StudyRoom studyRoom = studyRoomRepository.findById(id)
+ .orElseThrow(() -> new StudyRoomNotFoundException(id));

Comment on lines 5 to +14
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;

import java.time.LocalDateTime;

@MappedSuperclass
@Getter
@Setter
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Base 엔터티에 @Setter 추가는 재고해 볼 필요가 있습니다

BaseEntity@Setter 어노테이션을 추가하면 감사(audit) 필드와 같은 중요 필드에 무분별한 접근이 가능해져 데이터 무결성에 위험을 초래할 수 있습니다.

다음과 같은 접근 방식을 고려해보세요:

  1. 감사 필드(createdAt, updatedAt)는 불변으로 유지
  2. isDeleted 필드는 전용 메서드(예: markAsDeleted())를 통해서만 변경 가능하도록 제한
  3. 필요한 경우 특정 필드에 대해서만 개별적으로 setter를 설정
@MappedSuperclass
@Getter
-@Setter
public abstract class BaseEntity {

    @CreationTimestamp
    @Column(name = "created_at", updatable = false)
    private LocalDateTime createdAt;

    @UpdateTimestamp
    @Column(name = "updated_at")
    private LocalDateTime updatedAt;

    @Column(name = "is_deleted")
    private Boolean isDeleted = false;
    
+   public void markAsDeleted() {
+       this.isDeleted = true;
+   }
+   
+   public void restore() {
+       this.isDeleted = false;
+   }
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
import java.time.LocalDateTime;
@MappedSuperclass
@Getter
@Setter
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
import java.time.LocalDateTime;
@MappedSuperclass
@Getter
public abstract class BaseEntity {
@CreationTimestamp
@Column(name = "created_at", updatable = false)
private LocalDateTime createdAt;
@UpdateTimestamp
@Column(name = "updated_at")
private LocalDateTime updatedAt;
@Column(name = "is_deleted")
private Boolean isDeleted = false;
public void markAsDeleted() {
this.isDeleted = true;
}
public void restore() {
this.isDeleted = false;
}
}

Comment on lines +12 to +13
username: admin
password: wlqwndgo1!
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

평문 비밀번호 노출 주의
개발 환경 설정에 DB 비밀번호(wlqwndgo1!)가 하드코딩되어 있습니다. application-secret.yml 또는 환경 변수로 민감 정보를 분리 관리하는 리팩토링이 필요합니다.

Comment on lines +20 to +26
kafka:
bootstrap-servers: ${KAFKA_BOOTSTRAP_SERVERS}
properties:
security.protocol: SSL

Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Kafka 설정 환경 변수 누락
bootstrap-servers: ${KAFKA_BOOTSTRAP_SERVERS} 설정이 있으나, CD 워크플로우에서 해당 변수를 전달하지 않습니다. 배포 시 Kafka 시크릿을 추가하거나 설정을 제거해주세요.

Comment on lines +1 to +5
spring:
config:
import: optional:application-secret.yml
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

시크릿 파일 import 경로 일관성
optional:application-secret.yml 대신 optional:classpath:application-secret.yml로 베이스 설정과 동일하게 classpath 경로를 명시하는 것이 안전합니다.

@oxdjww oxdjww closed this Apr 30, 2025
@oxdjww oxdjww deleted the deploy/#9 branch April 30, 2025 09:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[DEPLOY] 1차 배포

2 participants