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

[Feature] 게시물 아카이브 대응 및 리팩토링 #43

Merged
merged 17 commits into from
Oct 3, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Copy link
Collaborator

Choose a reason for hiding this comment

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

SummaryAIManager → PostSummaryManager

  • 이 클래스는 AI를 사용하여 게시물의 요약을 관리하고 있어요. AI를 명시하는 것 보다, 게시물과 요약이 주도적인 초점이기 때문에 이렇게 변경하면 같은 패키지 안에 다른 클래스와 통일성과, 해당 클래스가 어떤 기능을하는지 더욱 명시할 수 있다고 생각해요.

getSummary → summarizePost

  • getSummary라는 메서드명은 정보를 단순히 가져오는 것으로 보이지만, 실제로 기능은 요약을 생성하는 작업이죠. 요약을 생성한다는 작업을 더 명확히 하기 위해 가져온다 보다는 요약 작업을 더 명시하는 것이 좋다고 생각해요.

getPrompt → createSummaryPrompt

  • 비슷하게 이 메서드는 요약을 생성하기 위한 프롬포트를 '작성'하는 역할을 하고 있어요. 프롬포트를 가져오는 것 보다는 생성하는 것이 주된 작업이기 때문에 더 명시하는 것이 좋다 생각해요.

requestMessage → promptMessage

  • 요청 메시지를 의미하는데, 실제로는 프롬포트 메시지 역할을 하고 있으므로 promptMessage로 이름을 바꿔 명시하면 더 일관성 있고 좋아진다 생각해요.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

3, 4번은 좋은 것 같습니다~
1, 2번은 저희 게시물을 요약하는 느낌이 강해서 UrlSummaryManager, summarizeUrl이 어떨까요?

Copy link
Collaborator

Choose a reason for hiding this comment

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

그렇다면 SummaryManager,
summarize로 변경하는 게 좋을 거 같네요
URL을 강조하거나 명시할 이유는 없는 거 같아요.
클래스 이름에서 URL만이 강조되는데, 요약 기능이 강조돼야 하기 때문에 요약에 더 직관적으로 바꾸는 게 좋다 생각합니다.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

좋습니다!

Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package project.backend.business.post.implement;

import java.util.HashMap;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.vertexai.gemini.VertexAiGeminiChatModel;
Expand All @@ -12,6 +15,8 @@
import project.backend.business.post.request.summary.SummaryOption;
import project.backend.business.post.response.dto.SummaryResultDto;
import project.backend.business.post.util.JsonParser;
import project.backend.common.error.CustomException;
import project.backend.common.error.ErrorCode;

@Slf4j
@Component
Expand All @@ -27,11 +32,12 @@ public SummaryResultDto getSummary(CreatePostServiceRequest createPostServiceReq
.getOutput()
.getContent();

Map<String, String> result = JsonParser.convertString2Json(responseContent);
JSONObject jsonObject = JsonParser.parseJsonFromText(responseContent);
Map<String, String> summaryResult = extractSummaryDataFromJson(jsonObject);

return SummaryResultDto.builder()
.title(result.get("title"))
.content(result.get("content"))
.title(summaryResult.get("title"))
.content(summaryResult.get("content"))
.build();
}

Expand All @@ -54,4 +60,21 @@ private Prompt getPrompt(CreatePostServiceRequest createPostServiceRequest) {
.withModel(VertexAiGeminiChatModel.ChatModel.GEMINI_1_5_FLASH)
.build());
}

private Map<String, String> extractSummaryDataFromJson(JSONObject jsonObject) {
try {
String title = jsonObject.getString("title");
String content = jsonObject.getString("content");

Map<String, String> summaryDataMap = new HashMap<>();

summaryDataMap.put("title", title);
summaryDataMap.put("content", content);

return summaryDataMap;

} catch (JSONException e) {
throw new CustomException(ErrorCode.INVALID_SUMMARY);
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

👍

}
22 changes: 6 additions & 16 deletions src/main/java/project/backend/business/post/util/JsonParser.java
Copy link
Collaborator

Choose a reason for hiding this comment

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

convertString2Json → parseJsonFromText

  • 이 메서드는 주어진 텍스트에서 JSON 형식을 추출하는 거 같아요. convert 보다는 parse 가 적합하다 생각합니다. JSON 형식을 파싱하는 것을 강조하면 더 명확하고 직관적으로 바뀔 거 같습니다.

stripJsonMarkdown → extractJsonContent

  • 이 메서드의 역할은 주어진 텍스트에서 JSON 마크다운을 제거하고 JSON 콘텐츠를 추출하는 것이므로 strip 보다는 extract가 더 명확하지 않을까요? 이미 다른 클래스에서 extract 네이밍을 차용하고 있기도하여 통일성도 있습니다.

result → jsonMap

  • 이 Map 이 JSON 데이터를 저장하는 것임을 명확하게 보일 수 있을 거 같아요

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

2번은 좋은 것 같습니다.

1, 3번의 경우 개발하면서도 애매하다 생각했는데, 좋은 의견 감사합니다.
다만, 준섭님 의견도 약간은 애매하다는 느낌이 듭니다.

준섭님 의견 참고하여 명확하게 분리해보았으니 확인 부탁드립니다!

Copy link
Collaborator

@junseoplee junseoplee Oct 3, 2024

Choose a reason for hiding this comment

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

JSONObject 좋네요!

Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package project.backend.business.post.util;

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.json.JSONException;
Expand All @@ -11,29 +9,21 @@

public class JsonParser {

public static Map<String, String> convertString2Json(String text) {
public static JSONObject parseJsonFromText(String text) {
try {
text = stripJsonMarkdown(text);
JSONObject jsonObject = new JSONObject(text);

String title = jsonObject.getString("title");
String content = jsonObject.getString("content");

Map<String, String> result = new HashMap<>();
result.put("title", title);
result.put("content", content);
return result;
text = extractJsonContent(text);
return new JSONObject(text);
} catch (JSONException e) {
throw new CustomException(ErrorCode.BAD_REQUEST);
throw new CustomException(ErrorCode.INVALID_SUMMARY);
}
}

private static String stripJsonMarkdown(String text) {
private static String extractJsonContent(String text) {
String jsonPattern = "(?s)```json\\s*(.*?)\\s*```";
Pattern pattern = Pattern.compile(jsonPattern);
Matcher matcher = pattern.matcher(text);
if (!matcher.find()) {
throw new CustomException(ErrorCode.BAD_REQUEST);
throw new CustomException(ErrorCode.INVALID_SUMMARY);
}
return matcher.group(1);
}
Expand Down
11 changes: 9 additions & 2 deletions src/main/java/project/backend/common/error/ErrorCode.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,22 @@

@Getter
public enum ErrorCode {
// auth
NONE_AUTHENTICATED("인증 정보가 없습니다.", HttpStatus.UNAUTHORIZED),
NOT_AUTHENTICATED("유효하지 않는 인증 정보입니다.", HttpStatus.UNAUTHORIZED),
USER_NOT_FOUND("존재하지 않는 유저입니다.", HttpStatus.UNAUTHORIZED),
BAD_REQUEST("잘못된 요청입니다.", HttpStatus.BAD_REQUEST),
INVALID_REFRESH_TOKEN("유효하지 않은 리프레시 토큰입니다.", HttpStatus.UNAUTHORIZED),
INVALID_ACCESS_TOKEN("유효하지 않은 엑세스 토큰입니다.", HttpStatus.UNAUTHORIZED),
TOKEN_INVALID("유효하지 않은 토큰입니다.", HttpStatus.UNAUTHORIZED),
ACCESS_DENIED("접근 권한이 없습니다.", HttpStatus.FORBIDDEN),
NOT_EXIST_REFRESH_TOKEN("존재하지 않는 리프레시 토큰입니다.", HttpStatus.BAD_REQUEST);
NOT_EXIST_REFRESH_TOKEN("존재하지 않는 리프레시 토큰입니다.", HttpStatus.BAD_REQUEST),

// 400
BAD_REQUEST("잘못된 요청입니다.", HttpStatus.BAD_REQUEST),

// 500
INVALID_SUMMARY("웹 사이트 요약 중 문제가 발생하였습니다.", HttpStatus.INTERNAL_SERVER_ERROR);


private final String message;
private final HttpStatus httpStatus;
Expand Down
Loading