Skip to content

Conversation

@kyoooooong
Copy link
Contributor

@kyoooooong kyoooooong commented Jan 31, 2025

#️⃣ 요약 설명

📝 작업 내용

  1. 관리자용 컨텐츠를 삭제하는 기능을 구현하였습니다.
  2. 기존의 직무별 추천 컨텐츠 조회 api에서 jobid를 쿼리 파라미터로 받았던 부분을 쿼리파라미터로 받지 않고 로그인한 사용자의 jobid로 설정되도록 수정하였습니다.

코드의 흐름이나 중요한 부분을 작성해주세요.

// 핵심 코드를 붙여넣기 해주세요

코드에 대한 간단한 설명 부탁드립니다.

동작 확인

기능을 실행했을 때 정상 동작하는지 여부를 확인하고 사진을 올려주세요

ex) 테스트 코드 작성후 성공 사진
ex) swagger 사진

작동화면은 아래와 같습니다.

image
image

💬 리뷰 요구사항(선택)

리뷰어가 특별히 봐주었으면 하는 부분이 있다면 작성해주세요

ex) 메서드 XXX의 이름을 더 잘 짓고 싶은데 혹시 좋은 명칭이 있을까요?

Summary by CodeRabbit

  • 새로운 기능

    • 콘텐츠 삭제 엔드포인트 추가
    • 사용자의 직업 ID를 기반으로 콘텐츠 검색 기능 개선
  • 버그 수정

    • 콘텐츠 검색 및 삭제 시 사용자 인증 로직 강화
  • 개선 사항

    • 콘텐츠 관리 API의 사용자 경험 최적화
    • 콘텐츠 검색 메서드의 파라미터 간소화

@kyoooooong kyoooooong added the feat 기능 추가 label Jan 31, 2025
@kyoooooong kyoooooong self-assigned this Jan 31, 2025
@coderabbitai
Copy link

coderabbitai bot commented Jan 31, 2025

Walkthrough

이 변경 사항은 콘텐츠 관리 기능을 개선하기 위한 것입니다. ContentControllerContentService에 새로운 콘텐츠 삭제 엔드포인트가 추가되었습니다. 기존의 콘텐츠 조회 메서드는 로그인된 사용자의 잡 ID를 자동으로 가져오도록 수정되었으며, 콘텐츠 삭제 시 존재 여부를 확인하는 로직이 구현되었습니다.

Changes

파일 변경 요약
src/main/java/UMC/career_mate/domain/content/controller/ContentController.java - 콘텐츠 삭제 엔드포인트 @DeleteMapping 추가
- getContentsByJobId 메서드 시그니처 수정 (jobId 파라미터 제거)
src/main/java/UMC/career_mate/domain/content/service/ContentService.java - deleteContent 메서드 추가 (콘텐츠 삭제 로직)
- getContentsByJobId 메서드 수정 (멤버로부터 jobId 추출)
src/main/resources/application.yml 파일 끝에 개행 문자 추가

Sequence Diagram

sequenceDiagram
    participant Client
    participant ContentController
    participant ContentService
    participant ContentRepository

    Client->>ContentController: DELETE /contents/{contentId}
    ContentController->>ContentService: deleteContent(contentId)
    ContentService->>ContentRepository: findById(contentId)
    alt Content exists
        ContentService->>ContentRepository: delete(content)
        ContentController-->>Client: Success Response
    else Content not found
        ContentService-->>ContentController: Throw GeneralException
        ContentController-->>Client: Error Response
    end
Loading

Poem

🐰 코드의 토끼, 삭제의 춤을 추네
콘텐츠 지우기, 얼마나 쉬운지
로그인한 멤버, 그 직업의 흔적
한 번의 요청으로 사라지는 기록
기술의 마법, 토끼의 손길로! 🔥

✨ Finishing Touches
  • 📝 Generate Docstrings (Beta)

🪧 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. (Beta)
  • @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: 3

🧹 Nitpick comments (3)
src/main/java/UMC/career_mate/domain/content/service/ContentService.java (1)

43-49: 트랜잭션 격리 수준 지정 검토

컨텐츠 삭제 작업은 데이터 일관성을 위해 명시적인 트랜잭션 격리 수준이 필요할 수 있습니다.

다음과 같이 @Transactional 어노테이션에 격리 수준을 지정하는 것을 고려해보세요:

-    public void deleteContent(Long contentId) {
+    @Transactional(isolation = Isolation.READ_COMMITTED)
+    public void deleteContent(Long contentId) {
src/main/java/UMC/career_mate/domain/content/controller/ContentController.java (2)

46-58: 응답 메시지 개선 필요

삭제된 컨텐츠의 ID를 응답에 포함하면 클라이언트 측에서 더 유용하게 활용할 수 있습니다.

다음과 같이 개선하는 것을 추천드립니다:

-    public ApiResponse<String> deleteContent(@PathVariable Long contentId) {
-        contentService.deleteContent(contentId);
-        return ApiResponse.onSuccess("컨텐츠 삭제 완료");
+    public ApiResponse<Map<String, Object>> deleteContent(@PathVariable Long contentId) {
+        contentService.deleteContent(contentId);
+        Map<String, Object> response = new HashMap<>();
+        response.put("message", "컨텐츠 삭제 완료");
+        response.put("deletedContentId", contentId);
+        return ApiResponse.onSuccess(response);

62-64: API 문서 보완 필요

API 문서에 인증 요구사항과 발생 가능한 예외 상황에 대한 설명이 누락되어 있습니다.

다음과 같이 문서를 보완하는 것을 추천드립니다:

     @Operation(
-            summary = "로그인한 사용자의 직무별 컨텐츠 조회 API",
-            description = """
-                로그인한 사용자의 직무 ID에 해당하는 컨텐츠를 조회합니다.
-                이때 사용자가 해당 컨텐츠를 스크랩했는지 여부가 담겨 조회됩니다.
+            summary = "로그인한 사용자의 직무별 컨텐츠 조회 API (인증 필요)",
+            description = """
+                로그인한 사용자의 직무 ID에 해당하는 컨텐츠를 조회합니다.
+                이때 사용자가 해당 컨텐츠를 스크랩했는지 여부가 담겨 조회됩니다.
+                
+                ### 인증 요구사항
+                - 로그인된 사용자만 접근 가능
+                - 유효한 직무가 설정된 사용자만 접근 가능
+                
+                ### 발생 가능한 예외
+                - 401: 인증되지 않은 사용자
+                - 404: 사용자의 직무 정보가 없는 경우
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 77ebef1 and 6674a85.

📒 Files selected for processing (3)
  • src/main/java/UMC/career_mate/domain/content/controller/ContentController.java (1 hunks)
  • src/main/java/UMC/career_mate/domain/content/service/ContentService.java (2 hunks)
  • src/main/resources/application.yml (1 hunks)
🧰 Additional context used
🪛 YAMLlint (1.35.1)
src/main/resources/application.yml

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

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

🔇 Additional comments (2)
src/main/java/UMC/career_mate/domain/content/service/ContentService.java (1)

13-14: LGTM!

예외 처리를 위한 적절한 import문이 추가되었습니다.

src/main/java/UMC/career_mate/domain/content/controller/ContentController.java (1)

75-75: LGTM!

서비스 계층의 변경사항과 일관성 있게 수정되었습니다.

spring:
profiles:
active: dev
active: dev
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

파일 끝에 개행 문자를 추가해주세요.

YAML 파일의 끝에는 항상 개행 문자가 있어야 합니다. 이는 POSIX 표준을 준수하고 다른 도구들과의 호환성을 보장하기 위함입니다.

다음과 같이 수정해주세요:

spring:
  profiles:
-    active: dev
+    active: dev
+
📝 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
active: dev
spring:
profiles:
active: dev
🧰 Tools
🪛 YAMLlint (1.35.1)

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

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


💡 Codebase verification

프로덕션 환경 설정의 심각한 문제점이 확인되었습니다

현재 'dev' 프로필이 여러 위치에 하드코딩되어 있어 프로덕션 환경에서 심각한 문제가 될 수 있습니다:

  • application.ymlactive: dev 하드코딩
  • DockerfileENTRYPOINT 명령어에 -Dspring.profiles.active=dev 하드코딩

권장 수정사항:

  1. application.yml에서 기본 프로필 설정 제거
  2. Dockerfile의 프로필 설정을 환경변수로 대체:
    ENTRYPOINT ["java","-jar","-Dspring.profiles.active=${SPRING_PROFILES_ACTIVE}","/app.jar"]
  3. 환경별 설정 파일 (application-prod.yml, application-dev.yml) 추가
  4. 배포 시 환경변수 SPRING_PROFILES_ACTIVE를 통해 프로필 주입
🔗 Analysis chain

프로덕션 환경 설정 관리 방안을 검토해주세요.

버전 관리 시스템에 'dev' 프로필이 하드코딩되어 있는 것이 확인됩니다. 프로덕션 환경에서는 환경 변수나 외부 설정을 통해 프로필을 주입하는 것이 더 안전한 방법일 수 있습니다.

다음 스크립트를 실행하여 프로필 설정이 다른 설정 파일에서도 하드코딩되어 있는지 확인해보시겠습니까?

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: 프로필 설정이 하드코딩된 YAML 파일 검색

echo "프로필 설정이 하드코딩된 YAML 파일 검색 중..."
rg -l "active:\s*(dev|prod|test)" --type yaml

Length of output: 151


Script:

#!/bin/bash
# Search for profile-specific configuration files and deployment configs
echo "프로필별 설정 파일 및 배포 관련 파일 검색..."

echo -e "\n1. 프로필별 설정 파일 검색:"
fd "application-.*\.yml" "src/"

echo -e "\n2. 도커 및 쿠버네티스 설정 파일 검색:"
fd "(Dockerfile|docker-compose.*\.yml|\.k8s|kubernetes)" .

echo -e "\n3. 배포 스크립트 검색:"
fd "(deploy.*\.sh|\.env.*)" .

Length of output: 382


Script:

#!/bin/bash
# Check Docker files for environment configuration
echo "도커 설정 파일 내용 확인..."

echo -e "\n1. Dockerfile 내용:"
cat Dockerfile

echo -e "\n2. docker-compose.yml 내용:"
cat docker-compose.yml

Length of output: 575

🧰 Tools
🪛 YAMLlint (1.35.1)

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

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

Comment on lines +52 to +58
public PageResponseDTO<List<ContentResponseDTO>> getContentsByJobId(int page, int size, Member member) {

// 로그인한 사용자의 직무 ID 확인
Long jobId = member.getJob().getId();
if (jobId == null) {
throw new GeneralException(CommonErrorCode.NOT_FOUND_JOB);
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

직무 정보 검증 로직 개선 필요

현재 구현은 직무 ID가 null인 경우만 처리하고 있습니다. 사용자의 직무 정보에 대한 더 구체적인 유효성 검사가 필요합니다.

다음과 같이 개선하는 것을 추천드립니다:

-        Long jobId = member.getJob().getId();
-        if (jobId == null) {
+        Job job = member.getJob();
+        if (job == null) {
+            throw new GeneralException(CommonErrorCode.NOT_FOUND_JOB);
+        }
+        Long jobId = job.getId();
+        if (jobId == null || jobId <= 0) {
             throw new GeneralException(CommonErrorCode.NOT_FOUND_JOB);
         }
📝 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 PageResponseDTO<List<ContentResponseDTO>> getContentsByJobId(int page, int size, Member member) {
// 로그인한 사용자의 직무 ID 확인
Long jobId = member.getJob().getId();
if (jobId == null) {
throw new GeneralException(CommonErrorCode.NOT_FOUND_JOB);
}
public PageResponseDTO<List<ContentResponseDTO>> getContentsByJobId(int page, int size, Member member) {
// 로그인한 사용자의 직무 ID 확인
Job job = member.getJob();
if (job == null) {
throw new GeneralException(CommonErrorCode.NOT_FOUND_JOB);
}
Long jobId = job.getId();
if (jobId == null || jobId <= 0) {
throw new GeneralException(CommonErrorCode.NOT_FOUND_JOB);
}

Copy link
Contributor

@jpark0506 jpark0506 left a comment

Choose a reason for hiding this comment

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

LGLGTM~

Copy link
Member

@jjeongdong jjeongdong left a comment

Choose a reason for hiding this comment

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

LGTM~!

@kyoooooong kyoooooong merged commit ba3b624 into develop Feb 2, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat 기능 추가

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants