Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[be/fix] ai 피드백 생성, 조회 수정 #287

Merged
merged 5 commits into from
Feb 27, 2025
Merged

Conversation

Gwanghyeon-k
Copy link
Collaborator

@Gwanghyeon-k Gwanghyeon-k commented Feb 26, 2025

변경 사항

  • ai 피드백 생성 시 오류 수정, 조회도 가능하도록 수정

테스트 결과 (테스트를 했으면)

image

Summary by CodeRabbit

  • New Features

    • Introduced endpoints for retrieving both individual and multiple AI feedback entries.
    • Enhanced integration with external services to improve request handling and error feedback.
  • Refactor

    • Streamlined feedback generation and retrieval processes for improved consistency and performance.
    • Standardized response formats for smoother and more coherent user interactions.
    • Improved logging and error handling for more reliable operations.
  • Documentation

    • Updated API descriptions for clearer guidance toward end-user applications.

@Gwanghyeon-k Gwanghyeon-k self-assigned this Feb 26, 2025
@Gwanghyeon-k Gwanghyeon-k linked an issue Feb 26, 2025 that may be closed by this pull request
Copy link

coderabbitai bot commented Feb 26, 2025

Walkthrough

This pull request introduces significant changes to the AI feedback and feedback modules. The AIFeedbackController has updated method signatures to use a standardized response format (CommonResponse), and new endpoints allow retrieval by feedback ID and resume ID. The repository interfaces now return lists where applicable, and the feedback generation service has been refactored with S3 interactions, logging, and helper methods. The feedback controller now accepts an additional path variable to fetch specific AI feedback, with related adjustments in converters, responses, and service methods.

Changes

File(s) Change Summary
backend/.../aifeedback/controller/AIFeedbackController.java Updated method signatures to return CommonResponse; added methods getFeedbackById and getFeedbacksByResumeId.
backend/.../aifeedback/converter/AIFeedbackConverter.java Introduced AIFeedbackConverter with a static method toResponse to convert AIFeedback to AIFeedbackResponse.
backend/.../aifeedback/repository/AIFeedbackRepository.java Modified findByResumeId to return a list; added findById method to retrieve feedback by ID.
backend/.../aifeedback/service/AIFeedbackService.java Changed return type of generateAIFeedbackFromS3; added methods getFeedbackById and getFeedbacksByResumeId.
backend/.../aifeedback/service/OpenAIService.java Added apiUrl field; updated getAIFeedback method to improve request handling and error management.
backend/.../feedback/controller/FeedbackController.java Updated to include an additional path variable aifeedback_id for retrieving specific AI feedback.
backend/.../feedback/converter/FeedbackConverter.java Removed AI feedback ID from toAllFeedbackResponse method.
backend/.../feedback/dto/response/AllFeedbackResponse.java Removed aiFeedbackId field from the response class.
backend/.../feedback/service/FeedbackService.java Removed getAIFeedbackByResumeId method; introduced getFeedbacksByResumeId.
backend/.../test/java/com/techeer/backend/api/resume/service/FeedbackServiceTest.java Entire content commented out, disabling all test cases.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant AIFeedbackController
    participant AIFeedbackService
    participant AIFeedbackConverter

    Client->>AIFeedbackController: Request createFeedbackFromS3(resumeId)
    AIFeedbackController->>AIFeedbackService: generateAIFeedbackFromS3(resumeId)
    AIFeedbackService-->>AIFeedbackController: AIFeedback entity
    AIFeedbackController->>AIFeedbackConverter: toResponse(feedback)
    AIFeedbackConverter-->>AIFeedbackController: AIFeedbackResponse
    AIFeedbackController-->>Client: CommonResponse(AIFeedbackResponse)
Loading
sequenceDiagram
    participant Client
    participant FeedbackController
    participant AIFeedbackService

    Client->>FeedbackController: Request getFeedbackWithAIFeedback(resumeId, aifeedbackId)
    FeedbackController->>AIFeedbackService: getFeedbackById(aifeedbackId)
    AIFeedbackService-->>FeedbackController: AIFeedback entity
    FeedbackController-->>Client: CommonResponse(AllFeedbackResponse)
Loading

Suggested reviewers

  • dlwldnjs1009
  • YunJuwon0825

Poem

I’m a rabbit with hops so light,
Skipping through code with delight.
New endpoints bloom like spring’s first flower,
Feedback and AI join in dev power.
Carrots and commits make our code shine bright!
Hoppy coding to all this magical night!
(^_−)☆


📜 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 cfd07b9 and 84891e2.

📒 Files selected for processing (1)
  • backend/src/test/java/com/techeer/backend/api/resume/service/FeedbackServiceTest.java (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • backend/src/test/java/com/techeer/backend/api/resume/service/FeedbackServiceTest.java

🪧 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 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

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Code review by ChatGPT

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 (4)
backend/src/main/java/com/techeer/backend/api/aifeedback/service/OpenAIService.java (2)

43-60: Add try-with-resources for proper resource cleanup.

The current implementation doesn't properly close the HTTP response resources. Use try-with-resources to ensure proper cleanup.

public String getAIFeedback(String resumeText) throws IOException {
    HttpPost httpPost = new HttpPost(apiUrl);
    httpPost.setHeader("Content-Type", "application/json");
    httpPost.setHeader("Authorization", "Bearer " + apiKey);

    String jsonBody = createRequestBody(resumeText);
    StringEntity entity = new StringEntity(jsonBody, ContentType.APPLICATION_JSON);
    httpPost.setEntity(entity);

-    HttpResponse response = httpClient.execute(httpPost);
-    int statusCode = response.getStatusLine().getStatusCode();
-    String responseBody = EntityUtils.toString(response.getEntity());
-
-    if (statusCode != 200) {
-        throw new IOException("OpenAI API 호출 실패: 상태 코드 " + statusCode + ", 응답: " + responseBody);
-    }
-    return responseBody;
+    try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
+        int statusCode = response.getStatusLine().getStatusCode();
+        String responseBody = EntityUtils.toString(response.getEntity());
+
+        if (statusCode != 200) {
+            throw new IOException("OpenAI API 호출 실패: 상태 코드 " + statusCode + ", 응답: " + responseBody);
+        }
+        return responseBody;
+    }
}

78-80: Add actual debug logging as mentioned in the comment.

Line 78 comments about logging for debugging, but no actual logging is implemented. Add proper debug logging using the existing logger.

// JSON 문자열 생성 후 로그 출력 (디버깅용)
String jsonBody = objectMapper.writeValueAsString(requestBody);
+ // Add actual debug logging
+ if (log.isDebugEnabled()) {
+     log.debug("OpenAI API 요청 본문: {}", jsonBody);
+ }
return jsonBody;
backend/src/main/java/com/techeer/backend/api/aifeedback/controller/AIFeedbackController.java (1)

46-54: Consider Pagination for Large Feedback Lists

getFeedbacksByResumeId can potentially return a large list if a resume has extensive AI feedback records. Consider using pagination or filtering to optimize performance and reduce payload size.

backend/src/main/java/com/techeer/backend/api/aifeedback/service/AIFeedbackService.java (1)

99-109: S3 I/O Logging

Adding logs to indicate success/failure of S3 object retrieval is a helpful touch for debugging. Consider also logging the object’s MIME type for clarity if relevant to your domain.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between f640fde and cfd07b9.

📒 Files selected for processing (9)
  • backend/src/main/java/com/techeer/backend/api/aifeedback/controller/AIFeedbackController.java (1 hunks)
  • backend/src/main/java/com/techeer/backend/api/aifeedback/converter/AIFeedbackConverter.java (1 hunks)
  • backend/src/main/java/com/techeer/backend/api/aifeedback/repository/AIFeedbackRepository.java (1 hunks)
  • backend/src/main/java/com/techeer/backend/api/aifeedback/service/AIFeedbackService.java (2 hunks)
  • backend/src/main/java/com/techeer/backend/api/aifeedback/service/OpenAIService.java (1 hunks)
  • backend/src/main/java/com/techeer/backend/api/feedback/controller/FeedbackController.java (3 hunks)
  • backend/src/main/java/com/techeer/backend/api/feedback/converter/FeedbackConverter.java (0 hunks)
  • backend/src/main/java/com/techeer/backend/api/feedback/dto/response/AllFeedbackResponse.java (0 hunks)
  • backend/src/main/java/com/techeer/backend/api/feedback/service/FeedbackService.java (1 hunks)
💤 Files with no reviewable changes (2)
  • backend/src/main/java/com/techeer/backend/api/feedback/dto/response/AllFeedbackResponse.java
  • backend/src/main/java/com/techeer/backend/api/feedback/converter/FeedbackConverter.java
🔇 Additional comments (14)
backend/src/main/java/com/techeer/backend/api/aifeedback/converter/AIFeedbackConverter.java (1)

6-17: Clean and well-implemented converter class.

The converter correctly handles null input and uses the builder pattern appropriately. The class has a clear single responsibility of converting entity objects to response DTOs.

backend/src/main/java/com/techeer/backend/api/aifeedback/repository/AIFeedbackRepository.java (1)

11-11: Good change to support multiple feedbacks per resume.

Changing the return type from Optional to List properly reflects that a resume can have multiple AI feedbacks.

backend/src/main/java/com/techeer/backend/api/aifeedback/service/OpenAIService.java (1)

32-41: Good improvement with HTTP client timeout configuration.

Adding timeout configuration for the HTTP client is a valuable improvement that prevents hanging connections or long wait times when the OpenAI API is slow to respond.

backend/src/main/java/com/techeer/backend/api/feedback/controller/FeedbackController.java (2)

4-4: Dependency Import Looks Good

No issues. The import of AIFeedbackService is straightforward and aligns with the usage in this controller.


38-38: Field Injection Looks Good

Introducing private final AIFeedbackService aifeedbackService; is consistent with the constructor-based dependency injection approach used in this class.

backend/src/main/java/com/techeer/backend/api/aifeedback/controller/AIFeedbackController.java (4)

3-17: Imports & Annotations

The newly added imports and annotations (e.g., @Tag, @RestController) are well-structured and align with Spring and Swagger usage. No concerns here.


24-28: Constructor Injection Looks Good

The explicit constructor for AIFeedbackController is consistent with best practices for Spring dependency injection (setter or constructor-based).


30-36: AI Feedback Creation Endpoint

Returning CommonResponse<AIFeedbackResponse> is clear and consistent with the project's standardized response approach. Logging and exception handling appear to be handled within the service.


38-44: Single Feedback Retrieval

The method getFeedbackById is straightforward and well-documented. It aligns with the standard practice of fetching a single record by its numeric ID.

backend/src/main/java/com/techeer/backend/api/aifeedback/service/AIFeedbackService.java (5)

31-31: Logger Initialization

Defining a dedicated logger for this service is a good practice for structured logs, especially when diagnosing S3 file transactions and OpenAI responses.


38-39: Constructor Injection

The constructor injection pattern here maintains consistency and testability across the service. No issues noted.


50-77: Validate Access Control for Resume

While the logic to generate AI feedback from an S3-stored PDF is solid, there's no direct check ensuring the requesting user has access to the resume. Confirm that relevant security/ownership checks are performed in higher layers or implement them here if needed.


79-86: AI Feedback Retrieval Methods

Both getFeedbackById and getFeedbacksByResumeId methods perform as expected, throwing the correct exception if feedback is not found. Implementation is concise.


88-97: Key Extraction Method Works As Intended

This utility method neatly addresses URL decoding and potential path issues. The fallback to BusinessException when decoding fails is suitable for error handling.

Optional<AIFeedback> findByResumeId(Long resumeId);
List<AIFeedback> findByResumeId(Long resumeId);

Optional<AIFeedback> findById(Long feedbackId);
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Remove redundant findById method.

This method is redundant since JpaRepository already provides a findById method with the same signature. The method can be safely removed to reduce code duplication.

-    Optional<AIFeedback> findById(Long feedbackId);
📝 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
Optional<AIFeedback> findById(Long feedbackId);

Comment on lines +72 to 75

public List<Feedback> getFeedbacksByResumeId(Long resumeId) {
return feedbackRepository.findAllByResumeId(resumeId);
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Consolidate duplicate feedback retrieval methods.

There are now two nearly identical methods that retrieve feedbacks by resumeId:

  1. getFeedbackByResumeId (singular) - includes resume existence validation
  2. getFeedbacksByResumeId (plural) - skips validation

This creates confusion and a potential bug since the new method bypasses validation. Consider one of these approaches:

  1. Use the existing method and rename it to plural form, or
  2. Add validation to the new method and remove the old one

If keeping both methods, add resume validation to the new method:

public List<Feedback> getFeedbacksByResumeId(Long resumeId) {
+    // Validate resume exists
+    if (!resumeRepository.existsById(resumeId)) {
+        throw new BusinessException(ErrorCode.RESUME_NOT_FOUND);
+    }
    return feedbackRepository.findAllByResumeId(resumeId);
}
📝 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 List<Feedback> getFeedbacksByResumeId(Long resumeId) {
return feedbackRepository.findAllByResumeId(resumeId);
}
public List<Feedback> getFeedbacksByResumeId(Long resumeId) {
// Validate resume exists
if (!resumeRepository.existsById(resumeId)) {
throw new BusinessException(ErrorCode.RESUME_NOT_FOUND);
}
return feedbackRepository.findAllByResumeId(resumeId);
}

Comment on lines +61 to 76
@Operation(summary = "AI 피드백, 일반 피드백 조회", description = "해당 이력서에 대한 일반 피드백과 특정 AI 피드백(aifeedbackId를 이용)을 조회합니다.")
@GetMapping("/{resume_id}/feedbacks/{aifeedback_id}")
public CommonResponse<AllFeedbackResponse> getFeedbackWithAIFeedback(
@PathVariable("resume_id") Long resumeId,
@PathVariable("aifeedback_id") Long aifeedbackId) {

// 엔티티, 리스트 반환
// 일반 피드백 조회 (이력서 ID 기준)
List<Feedback> feedbacks = feedbackService.getFeedbackByResumeId(resumeId);
AIFeedback aiFeedback = feedbackService.getAIFeedbackByResumeId(resumeId);
// 특정 AI 피드백 조회 (AI 피드백 ID 기준)
AIFeedback aiFeedback = aifeedbackService.getFeedbackById(aifeedbackId);

// 두 결과를 하나의 DTO로 변환 (여기서는 원시 도메인 객체를 전달)
AllFeedbackResponse response = FeedbackConverter.toAllFeedbackResponse(feedbacks, aiFeedback);

return CommonResponse.of(SuccessCode.FEEDBACK_FETCH_OK, response);
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Validate AI Feedback Ownership

When fetching AI feedback by ID and general feedback by resume ID, there is no check to ensure that the retrieved AI feedback actually belongs to the specified resume. This could cause a user to retrieve AI feedback that doesn't match the given resume, potentially exposing data that shouldn't be accessible.

Below is a sample diff demonstrating how you might verify the resumeId alignment before returning the combined feedback:

 public CommonResponse<AllFeedbackResponse> getFeedbackWithAIFeedback(
         @PathVariable("resume_id") Long resumeId,
         @PathVariable("aifeedback_id") Long aifeedbackId) {

     List<Feedback> feedbacks = feedbackService.getFeedbackByResumeId(resumeId);
     AIFeedback aiFeedback = aifeedbackService.getFeedbackById(aifeedbackId);

+    // Verify that aiFeedback belongs to the same resume
+    if (!aiFeedback.getResumeId().equals(resumeId)) {
+        throw new BusinessException(ErrorCode.FEEDBACK_NOT_FOUND);
+    }

     AllFeedbackResponse response = FeedbackConverter.toAllFeedbackResponse(feedbacks, aiFeedback);
     return CommonResponse.of(SuccessCode.FEEDBACK_FETCH_OK, response);
 }
📝 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
@Operation(summary = "AI 피드백, 일반 피드백 조회", description = "해당 이력서에 대한 일반 피드백과 특정 AI 피드백(aifeedbackId를 이용)을 조회합니다.")
@GetMapping("/{resume_id}/feedbacks/{aifeedback_id}")
public CommonResponse<AllFeedbackResponse> getFeedbackWithAIFeedback(
@PathVariable("resume_id") Long resumeId,
@PathVariable("aifeedback_id") Long aifeedbackId) {
// 엔티티, 리스트 반환
// 일반 피드백 조회 (이력서 ID 기준)
List<Feedback> feedbacks = feedbackService.getFeedbackByResumeId(resumeId);
AIFeedback aiFeedback = feedbackService.getAIFeedbackByResumeId(resumeId);
// 특정 AI 피드백 조회 (AI 피드백 ID 기준)
AIFeedback aiFeedback = aifeedbackService.getFeedbackById(aifeedbackId);
// 두 결과를 하나의 DTO로 변환 (여기서는 원시 도메인 객체를 전달)
AllFeedbackResponse response = FeedbackConverter.toAllFeedbackResponse(feedbacks, aiFeedback);
return CommonResponse.of(SuccessCode.FEEDBACK_FETCH_OK, response);
}
@Operation(summary = "AI 피드백, 일반 피드백 조회", description = "해당 이력서에 대한 일반 피드백과 특정 AI 피드백(aifeedbackId를 이용)을 조회합니다.")
@GetMapping("/{resume_id}/feedbacks/{aifeedback_id}")
public CommonResponse<AllFeedbackResponse> getFeedbackWithAIFeedback(
@PathVariable("resume_id") Long resumeId,
@PathVariable("aifeedback_id") Long aifeedbackId) {
// 일반 피드백 조회 (이력서 ID 기준)
List<Feedback> feedbacks = feedbackService.getFeedbackByResumeId(resumeId);
// 특정 AI 피드백 조회 (AI 피드백 ID 기준)
AIFeedback aiFeedback = aifeedbackService.getFeedbackById(aifeedbackId);
// Verify that aiFeedback belongs to the same resume
if (!aiFeedback.getResumeId().equals(resumeId)) {
throw new BusinessException(ErrorCode.FEEDBACK_NOT_FOUND);
}
// 두 결과를 하나의 DTO로 변환 (여기서는 원시 도메인 객체를 전달)
AllFeedbackResponse response = FeedbackConverter.toAllFeedbackResponse(feedbacks, aiFeedback);
return CommonResponse.of(SuccessCode.FEEDBACK_FETCH_OK, response);
}

Copy link
Contributor

@dlwldnjs1009 dlwldnjs1009 left a comment

Choose a reason for hiding this comment

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

✅ 확인했습니다.

Map<String, String> message = new HashMap<>();
message.put("role", "user");
// 불필요한 공백이나 개행이 문제를 일으킬 수 있으므로 trim()으로 정리합니다.
message.put("content", ("이 이력서에서 잘 작성된 부분과 개선해야 할 부분을 구체적으로 지적해 주세요. " +
Copy link
Contributor

Choose a reason for hiding this comment

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

여기에 예를들어 gpt한테 너는 IT 빅테크 기업(구글, 페이스북, AWS)면접관이야. 이런식으로 role 부여해주면 대답이 더 좋아져. 이런거 찾아보고 role 추가해도 좋을거 같아.

Comment on lines +61 to +65
@Operation(summary = "AI 피드백, 일반 피드백 조회", description = "해당 이력서에 대한 일반 피드백과 특정 AI 피드백(aifeedbackId를 이용)을 조회합니다.")
@GetMapping("/{resume_id}/feedbacks/{aifeedback_id}")
public CommonResponse<AllFeedbackResponse> getFeedbackWithAIFeedback(
@PathVariable("resume_id") Long resumeId,
@PathVariable("aifeedback_id") Long aifeedbackId) {
Copy link
Member

Choose a reason for hiding this comment

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

url endpoint 이름이 지금 aifeedback_id인데 feedback_id로 가는게 맞을 듯

Comment on lines +67 to 76
// 일반 피드백 조회 (이력서 ID 기준)
List<Feedback> feedbacks = feedbackService.getFeedbackByResumeId(resumeId);
AIFeedback aiFeedback = feedbackService.getAIFeedbackByResumeId(resumeId);
// 특정 AI 피드백 조회 (AI 피드백 ID 기준)
AIFeedback aiFeedback = aifeedbackService.getFeedbackById(aifeedbackId);

// 두 결과를 하나의 DTO로 변환 (여기서는 원시 도메인 객체를 전달)
AllFeedbackResponse response = FeedbackConverter.toAllFeedbackResponse(feedbacks, aiFeedback);

return CommonResponse.of(SuccessCode.FEEDBACK_FETCH_OK, response);
}
Copy link
Member

Choose a reason for hiding this comment

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

특정 feedback 조회에 대한 api인데 toAllFeedbackResponse로 바꿔서 반환하는 로직은 뭔가 부자연스럽다고 느껴짐.
전체 feedback이 아니라 하나의 feedback에 대한 조회라면 좀 수정되어야 할 듯?
이전 로직에서 수정을 하면서 뭔가 이상해진 느낌이 있어

Copy link
Member

Choose a reason for hiding this comment

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

그리고 기왕이면 unit test라도 짜줘. openai service를 mock으로 주입하면 충분히 가능할 듯

@Gwanghyeon-k Gwanghyeon-k merged commit 6bb5ee6 into develop Feb 27, 2025
4 checks passed
@Gwanghyeon-k Gwanghyeon-k deleted the be/fix/#286 branch February 27, 2025 08:50
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.

[fix] aifeedback s3 bucket 오류 수정
3 participants