Skip to content

Commit

Permalink
[Feature] 게시물 아카이브 대응 및 리팩토링 (#43)
Browse files Browse the repository at this point in the history
* feat: post - archive join (#41)

* feat: 게시물 조회 - 아카이브 id 필터링 추가 (#41)

* refactor: 게시물 목록 response 생성 방법 변경 (#41)

* refactor: 게시물 생성 로직 수정 (#41)

* feat: AI 요약 로직 수정 (#41)

* refactor: post detail 조회 response 로직 수정 (#41)

* feat: 게시물 수정 API 아카이브 추가 (# 41)

* feat: 게시물 재요약 API 수정 (#41)

* feat: 메모 API 수정 (#41)

* feat: url 수정 (#41)

* feat: Swagger server 세팅 (#41)

* feat: 게시물 전체 개수 조회 API (#41)

* refactor: json parsing 관련 메소드 수정 (#41)

* refactor: 네이밍 수정 (#41)

* refactor: 단순 로직 수정 (#41)

* refactor: summary 클래스, 메소드 명 수정 (#41)

* deploy: local로 전환 (#41)
  • Loading branch information
yongbin97 authored Oct 3, 2024
1 parent ad6c882 commit 71c8707
Show file tree
Hide file tree
Showing 27 changed files with 383 additions and 160 deletions.
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ dependencies {
// Swagger
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2'

implementation group: 'org.json', name: 'json', version: '20090211'

compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,12 @@ public class MemoManager {
private final PostRepository postRepository;

public void createUpdateMemo(Post post, String content) {
post.setMemo(content);
post.setMemoCreatedAt(LocalDateTime.now());
post.updatePostMemo(content, LocalDateTime.now());
postRepository.save(post);
}

public void deleteMemo(Post post) {
post.setMemo(null);
post.setMemoCreatedAt(null);
post.updatePostMemo(null, null);
postRepository.save(post);
}
}
55 changes: 33 additions & 22 deletions src/main/java/project/backend/business/post/PostService.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,18 @@
import org.springframework.transaction.annotation.Transactional;
import project.backend.business.post.implement.PostManager;
import project.backend.business.post.implement.PostReader;
import project.backend.business.post.implement.SummaryAIManager;
import project.backend.business.post.implement.SummaryManager;
import project.backend.business.post.request.CreatePostServiceRequest;
import project.backend.business.post.request.PostDetailServiceRequest;
import project.backend.business.post.request.PostListServiceRequest;
import project.backend.business.post.request.UpdatePostServiceRequest;
import project.backend.business.post.response.CreateUpdatePostResponse;
import project.backend.business.post.response.dto.PostDetailDto;
import project.backend.business.post.response.PostCountResponse;
import project.backend.business.post.response.PostDetailResponse;
import project.backend.business.post.response.dto.PostListDto;
import project.backend.business.post.response.PostListResponse;
import project.backend.business.post.response.dto.PostDetailDto;
import project.backend.business.post.response.dto.PostListDto;
import project.backend.business.post.response.dto.SummaryResultDto;
import project.backend.business.user.implement.UserReader;
import project.backend.common.error.CustomException;
import project.backend.common.error.ErrorCode;
Expand All @@ -37,22 +40,29 @@ public class PostService {
private final UserReader userReader;
private final PostReader postReader;
private final PostManager postManager;
private final SummaryAIManager summaryAIManager;
private final SummaryManager summaryManager;

@Transactional(readOnly = true)
public PostListResponse getPosts(Long userId, PostListServiceRequest postListServiceRequest) {
Specification<Post> spec =
Specification.where(PostSpecification.getUser(userId))
.and(PostSpecification.getPublished())
.and(PostSpecification.getArchive(postListServiceRequest.getArchiveId()))
.and(PostSpecification.getSearch(postListServiceRequest.getSearch()))
.and(PostSpecification.getPublished())
.and(PostSpecification.getActivated());

PageRequest pageRequest = PageRequest.of(postListServiceRequest.getPage(), PAGE_SIZE,
Sort.by("id").descending());

List<PostListDto> posts = postReader.readPostsWithTags(spec, pageRequest);
List<PostListDto> postListDtos = postReader.readPostsWithTags(spec, pageRequest);

return new PostListResponse(posts);
return PostListResponse.from(postListDtos);
}

@Transactional(readOnly = true)
public PostCountResponse getTotalPostCount(Long userId) {
int count = postReader.readActivatePostCountByUserId(userId);
return PostCountResponse.from(count);
}

@Transactional(readOnly = true)
Expand All @@ -61,27 +71,27 @@ public PostDetailResponse getPostDetail(Long userId,
PostDetailDto postDetailDto = postReader.readPostDetailWithTags(userId,
postDetailServiceRequest);

return new PostDetailResponse(postDetailDto);
return PostDetailResponse.from(postDetailDto);
}

@Transactional
public CreateUpdatePostResponse createNewPostDetail(Long userId,
public CreateUpdatePostResponse createPostDetail(Long userId,
CreatePostServiceRequest createPostServiceRequest) {
String summary = summaryAIManager.getSummary(createPostServiceRequest);
User user = userReader.readUserById(userId);
Long postId = postManager.createTempPost(user, createPostServiceRequest.getUrl(), summary);
SummaryResultDto summaryResultDto = summaryManager.summarize(createPostServiceRequest);
User user = userReader.readUserByIdOrNull(userId);
Post post = postManager.createPost(user, createPostServiceRequest.getUrl(), summaryResultDto);

return new CreateUpdatePostResponse(postId);
return CreateUpdatePostResponse.from(post);
}

@Transactional
public CreateUpdatePostResponse updatePostDetail(Long userId, Long postId,
PostDetailDto postDetailDto) {
Post post = postReader.readActivatedPost(userId, postId);
postManager.updatePost(post, postDetailDto);
Long id = post.getId();
UpdatePostServiceRequest updatePostServiceRequest) {
User user = userReader.readUserById(userId);
Post post = postReader.readActivatedPostAndWriter(postId);
Post updatedPost = postManager.updatePost(user, post, updatePostServiceRequest);

return new CreateUpdatePostResponse(id);
return CreateUpdatePostResponse.from(updatedPost);
}

@Transactional
Expand All @@ -95,13 +105,14 @@ public CreateUpdatePostResponse updateSummaryPost(Long userId, Long postId,
CreatePostServiceRequest createPostServiceRequest) {
Post post = postReader.readActivatedPostAndWriter(postId);

if (post.getUser() != null && !Objects.equals(post.getUser().getId(), userId)) {
if (!Objects.equals(post.getUser().getId(), userId)) {
throw new CustomException(ErrorCode.BAD_REQUEST);
}

String summary = summaryAIManager.getSummary(createPostServiceRequest);
postManager.updateSummary(post, createPostServiceRequest.getUrl(), summary);
SummaryResultDto summaryResultDto = summaryManager.summarize(createPostServiceRequest);
Post updatedPost = postManager.updateSummary(post, createPostServiceRequest.getUrl(),
summaryResultDto);

return new CreateUpdatePostResponse(post.getId());
return CreateUpdatePostResponse.from(updatedPost);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
import java.time.LocalDateTime;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import project.backend.business.post.response.dto.PostDetailDto;
import project.backend.business.post.util.DateTimeManager;
import project.backend.business.archive.implement.ArchiveReader;
import project.backend.business.post.request.UpdatePostServiceRequest;
import project.backend.business.post.response.dto.SummaryResultDto;
import project.backend.business.tag.implement.TagManager;
import project.backend.entity.archive.Archive;
import project.backend.entity.post.Post;
import project.backend.entity.post.PostStatus;
import project.backend.entity.user.User;
Expand All @@ -17,40 +19,40 @@ public class PostManager {

private final PostRepository postRepository;
private final TagManager tagManager;
private final ArchiveReader archiveReader;

/**
* 임시 Post는 생성 시간으로 시간 세팅
*/
public Long createTempPost(User user, String url, String summary) {
String tmpTitle = DateTimeManager.getCurrentDateTime();
Post newTmpPost = Post.createPost(user, tmpTitle, summary, PostStatus.DRAFT, url);

return postRepository.save(newTmpPost).getId();
public Post createPost(User user, String url, SummaryResultDto summaryResultDto) {
Post newPost = Post.createPost(user, summaryResultDto.getTitle(), summaryResultDto.getContent(),
PostStatus.DRAFT, url);

return postRepository.save(newPost);
}

public void updatePost(Post post, PostDetailDto postDetailDto) {
post.setTitle(postDetailDto.getTitle());
post.setContent(postDetailDto.getContent());
post.setStatus(PostStatus.PUBLISHED);
public Post updatePost(User user, Post post, UpdatePostServiceRequest updatePostServiceRequest) {
Archive archive = archiveReader.readActivatedArchiveById(
updatePostServiceRequest.getArchiveId());

post.updatePost(user, updatePostServiceRequest.getTitle(),
updatePostServiceRequest.getContent(), archive);

// 메모 변경되었을 때만 업데이트
if (post.getMemo() == null || !post.getMemo()
.equals(postDetailDto.getMemoContent())) {
post.setMemo(postDetailDto.getMemoContent());
post.setMemoCreatedAt(LocalDateTime.now());
.equals(updatePostServiceRequest.getMemo())) {
post.updatePostMemo(updatePostServiceRequest.getMemo(), LocalDateTime.now());
}

tagManager.updateTag(post, postDetailDto.getTagList());
postRepository.save(post);
tagManager.updateTag(post, updatePostServiceRequest.getTagList());
return postRepository.save(post);
}

public void deletePost(Post post) {
post.setActivated(Boolean.FALSE);
postRepository.save(post);
}

public void updateSummary(Post post, String url, String summary) {
post.setContent(summary);
post.setUrl(url);
postRepository.save(post);
public Post updateSummary(Post post, String url, SummaryResultDto summaryResultDto) {
post.updatePostSummary(summaryResultDto.getTitle(), summaryResultDto.getContent(), url);
return postRepository.save(post);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,8 @@ public PostDetailDto readPostDetailWithTags(Long userId,
"yy.MM.dd"))
.build();
}

public int readActivatePostCountByUserId(Long userId) {
return postRepository.countPostsByUserIdAndStatusAndActivatedTrue(userId, PostStatus.PUBLISHED);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
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;
import org.springframework.ai.vertexai.gemini.VertexAiGeminiChatOptions;
import org.springframework.stereotype.Component;
import project.backend.business.post.request.CreatePostServiceRequest;
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
@RequiredArgsConstructor
public class SummaryManager {

private final VertexAiGeminiChatModel chatModel;

public SummaryResultDto summarize(CreatePostServiceRequest createPostServiceRequest) {
Prompt prompt = createPrompt(createPostServiceRequest);
ChatResponse response = chatModel.call(prompt);
String responseContent = response.getResult()
.getOutput()
.getContent();

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

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

private Prompt createPrompt(CreatePostServiceRequest createPostServiceRequest) {
SummaryOption options = createPostServiceRequest.getOption();

String promptMessage = "URL: " + createPostServiceRequest.getUrl() + "\n" +
"Summarize the website corresponding to the URL below in a blog style according to the following summary conditions.\n"
+ "Please also recommend the title\n"
+ "The answer is given in json format string with title and content as keys.\n"
+ "Translate the content into the summary language!\n"
+ "Summary conditions: \n"
+ "Summary length: " + options.getLevel().getLines() + "\n"
+ "Summary tone:" + options.getTone().getValue() + "\n"
+ "Summary language: " + options.getLanguage().getValue() + "\n"
+ "Summary keywords: " + options.getKeywords();

return new Prompt(promptMessage,
VertexAiGeminiChatOptions.builder()
.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);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
@Builder
public class PostListServiceRequest {

private Integer page;
private Integer archiveId;
private String search;
private final Integer page;
private final Long archiveId;
private final String search;

public static PostListServiceRequest of(Integer page, Integer archiveId, String search) {
public static PostListServiceRequest of(Integer page, Long archiveId, String search) {
if (page == null) {
page = 0;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package project.backend.business.post.request;

import java.util.List;
import lombok.Builder;
import lombok.Getter;

@Getter
@Builder
public class UpdatePostServiceRequest {

private final String title;
private final String content;
private final String url;
private final List<String> tagList;
private final Long archiveId;
private final String memo;
}
Loading

0 comments on commit 71c8707

Please sign in to comment.