Skip to content

Commit

Permalink
Merge pull request #33 from KUSITMS-CORECORD/feat/#31
Browse files Browse the repository at this point in the history
[Feat/#31] 경험 기록 리스트 조회 기능 구현
  • Loading branch information
daeun084 authored Oct 31, 2024
2 parents ec70b7f + a5aa923 commit e10aa6e
Show file tree
Hide file tree
Showing 10 changed files with 237 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public class Ability extends BaseEntity {
@JoinColumn(name = "user_id", nullable = false)
private User user;

@ManyToOne
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "analysis_id", nullable = false)
private Analysis analysis;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.BatchSize;

import java.util.List;

Expand All @@ -29,6 +30,7 @@ public class Analysis extends BaseEntity {
@JoinColumn(name = "record_id", nullable = false)
private Record record;

@BatchSize(size = 3)
@OneToMany(mappedBy = "analysis", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<Ability> abilityList;
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;

@Repository
public interface FolderRepository extends JpaRepository<Folder, Long> {
Expand All @@ -19,5 +20,12 @@ public interface FolderRepository extends JpaRepository<Folder, Long> {
"ORDER BY f.createdAt desc ")
List<FolderResponse.FolderDto> findFolderDtoList(@Param(value = "user") User user);

@Query("SELECT f " +
"FROM Folder f " +
"WHERE f.title = :title AND f.user = :user ")
Optional<Folder> findFolderByTitle(
@Param(value = "title") String title,
@Param(value = "user") User user);

boolean existsByTitle(String title);
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ public enum RecordSuccessStatus implements BaseSuccessStatus {
MEMO_RECORD_CREATE_SUCCESS(HttpStatus.CREATED, "S404", "메모 경험 기록이 성공적으로 완료되었습니다."),
MEMO_RECORD_DETAIL_GET_SUCCESS(HttpStatus.OK, "S401", "메모 경험 기록 세부 조회가 성공적으로 완료되었습니다."),
MEMO_RECORD_TMP_CREATE_SUCCESS(HttpStatus.OK, "S403", "메모 경험 기록 임시 저장이 성공적으로 완료되었습니다."),
MEMO_RECORD_TMP_GET_SUCCESS(HttpStatus.OK, "S402", "메모 경험 기록 임시 저장 내역 조회가 성공적으로 완료되었습니다.")
MEMO_RECORD_TMP_GET_SUCCESS(HttpStatus.OK, "S402", "메모 경험 기록 임시 저장 내역 조회가 성공적으로 완료되었습니다."),
RECORD_LIST_GET_SUCCESS(HttpStatus.OK, "S602", "폴더별 경험 기록 리스트 조회가 성공적으로 완료되었습니다."),
KEYWORD_RECORD_LIST_GET_SUCCESS(HttpStatus.OK, "S503", "역량 키워드별 경험 기록 리스트 조회가 성공적으로 완료되었습니다.")
;

private final HttpStatus httpStatus;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,22 @@ public ResponseEntity<ApiResponse<RecordResponse.TmpMemoRecordDto>> getTmpMemoRe
return ApiResponse.success(RecordSuccessStatus.MEMO_RECORD_TMP_GET_SUCCESS, recordResponse);
}

@GetMapping("")
public ResponseEntity<ApiResponse<RecordResponse.RecordListDto>> getRecordListByFolder(
@UserId Long userId,
@RequestParam(name = "folder", defaultValue = "all") String folder
) {
RecordResponse.RecordListDto recordResponse = recordService.getRecordList(userId, folder);
return ApiResponse.success(RecordSuccessStatus.RECORD_LIST_GET_SUCCESS, recordResponse);
}

@GetMapping("/keyword")
public ResponseEntity<ApiResponse<RecordResponse.KeywordRecordListDto>> getRecordListByKeyword(
@UserId Long userId,
@RequestParam(name = "keyword") String keyword
) {
RecordResponse.KeywordRecordListDto recordResponse = recordService.getKeywordRecordList(userId, keyword);
return ApiResponse.success(RecordSuccessStatus.KEYWORD_RECORD_LIST_GET_SUCCESS, recordResponse);
}

}
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package corecord.dev.domain.record.converter;

import corecord.dev.domain.analysis.constant.Keyword;
import corecord.dev.domain.analysis.entity.Ability;
import corecord.dev.domain.folder.entity.Folder;
import corecord.dev.domain.record.constant.RecordType;
import corecord.dev.domain.record.dto.response.RecordResponse;
import corecord.dev.domain.record.entity.Record;
import corecord.dev.domain.user.entity.User;

import java.util.List;

public class RecordConverter {
public static Record toMemoRecordEntity(String title, String content, User user, Folder folder) {
return Record.builder()
Expand Down Expand Up @@ -42,4 +46,53 @@ public static RecordResponse.TmpMemoRecordDto toNotExistingTmpMemoRecordDto() {
.content(null)
.build();
}

public static RecordResponse.RecordDto toRecordDto(Record record) {
List<String> keywordList = record.getAnalysis().getAbilityList().stream()
.map(Ability::getKeyword)
.map(Keyword::getValue)
.toList();

return RecordResponse.RecordDto.builder()
.analysisId(record.getAnalysis().getAnalysisId())
.folder(record.getFolder().getTitle())
.title(record.getTitle())
.keywordList(keywordList)
.createdAt(record.getCreatedAtFormatted())
.build();
}

public static RecordResponse.RecordListDto toRecordListDto(String folder, List<Record> recordList) {
List<RecordResponse.RecordDto> recordDtoList = recordList.stream()
.map(RecordConverter::toRecordDto)
.toList();

return RecordResponse.RecordListDto.builder()
.folder(folder)
.recordDtoList(recordDtoList)
.build();
}

public static RecordResponse.KeywordRecordDto toKeywordRecordDto(Record record) {
String content = record.getContent();
String truncatedContent = content.length() > 30 ? content.substring(0, 30) : content;

return RecordResponse.KeywordRecordDto.builder()
.analysisId(record.getAnalysis().getAnalysisId())
.folder(record.getFolder().getTitle())
.title(record.getTitle())
.content(truncatedContent)
.createdAt(record.getCreatedAtFormatted())
.build();
}

public static RecordResponse.KeywordRecordListDto toKeywordRecordListDto(List<Record> recordList) {
List<RecordResponse.KeywordRecordDto> keywordRecordDtoList = recordList.stream()
.map(RecordConverter::toKeywordRecordDto)
.toList();

return RecordResponse.KeywordRecordListDto.builder()
.recordDtoList(keywordRecordDtoList)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import lombok.Data;
import lombok.Getter;

import java.util.List;

public class RecordResponse {
@Builder
@Getter
Expand All @@ -27,4 +29,45 @@ public static class TmpMemoRecordDto {
private String title;
private String content;
}

@Builder
@Getter
@AllArgsConstructor
@Data
public static class RecordDto {
private Long analysisId;
private String folder;
private String title;
private List<String> keywordList;
private String createdAt;
}

@Builder
@Getter
@AllArgsConstructor
@Data
public static class RecordListDto {
private String folder;
private List<RecordDto> recordDtoList;
}

@Builder
@Getter
@AllArgsConstructor
@Data
public static class KeywordRecordDto {
private Long analysisId;
private String folder;
private String title;
private String content;
private String createdAt;
}

@Builder
@Getter
@AllArgsConstructor
@Data
public static class KeywordRecordListDto {
private List<KeywordRecordDto> recordDtoList;
}
}
4 changes: 2 additions & 2 deletions src/main/java/corecord/dev/domain/record/entity/Record.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ public class Record extends BaseEntity {
@JoinColumn(name = "chat_room_id", nullable = true)
private ChatRoom chatRoom;

@ManyToOne
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "folder_id", nullable = true)
private Folder folder;

@OneToOne(mappedBy = "record", cascade = CascadeType.ALL, orphanRemoval = true)
@OneToOne(mappedBy = "record", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
private Analysis analysis;

public void updateContent(String content) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,50 @@
package corecord.dev.domain.record.repository;

import corecord.dev.domain.analysis.constant.Keyword;
import corecord.dev.domain.folder.entity.Folder;
import corecord.dev.domain.record.entity.Record;
import corecord.dev.domain.user.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface RecordRepository extends JpaRepository<Record, Long> {

@Query("SELECT r " +
"FROM Record r " +
"JOIN FETCH r.analysis a " +
"JOIN FETCH r.folder f " +
"JOIN FETCH a.abilityList al " +
"WHERE r.user = :user " +
"AND r.folder is not null AND r.folder = :folder "+ // 임시 저장 기록 제외
"ORDER BY r.createdAt desc ") // 최근 생성 순 정렬
List<Record> findRecordsByFolder(
@Param(value = "folder") Folder folder,
@Param(value = "user") User user);

@Query("SELECT r FROM Record r " +
"JOIN FETCH r.analysis a " +
"JOIN FETCH r.folder f " +
"JOIN FETCH a.abilityList al " +
"WHERE r.user = :user " +
"AND r.folder is not null " + // 임시 저장 기록 제외
"ORDER BY r.createdAt DESC") // 최근 생성 순 정렬
List<Record> findRecords(@Param(value = "user") User user);


@Query("SELECT r FROM Ability a " +
"JOIN a.analysis an " +
"JOIN an.record r " +
"JOIN FETCH r.folder f " +
"WHERE a.user = :user " +
"AND a.keyword = :keyword " +
"AND r.folder is not null " + // 임시 저장 기록 제외
"ORDER BY r.createdAt DESC") // 최근 생성 순 정렬
List<Record> findRecordByKeyword(
@Param(value = "keyword")Keyword keyword,
@Param(value = "user") User user);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

import corecord.dev.common.exception.GeneralException;
import corecord.dev.common.status.ErrorStatus;
import corecord.dev.domain.analysis.constant.Keyword;
import corecord.dev.domain.analysis.exception.enums.AnalysisErrorStatus;
import corecord.dev.domain.analysis.exception.model.AnalysisException;
import corecord.dev.domain.analysis.service.AnalysisService;
import corecord.dev.domain.folder.entity.Folder;
import corecord.dev.domain.folder.exception.enums.FolderErrorStatus;
Expand All @@ -21,6 +24,8 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@Slf4j
@RequiredArgsConstructor
Expand Down Expand Up @@ -118,6 +123,43 @@ public RecordResponse.TmpMemoRecordDto getTmpMemoRecord(Long userId) {
return RecordConverter.toExistingTmpMemoRecordDto(tmpMemoRecord);
}

/*
* 폴더별 경험 기록 리스트를 반환합니다. folder의 default value는 'all'입니다.
* @param userId, folderName
* @return
*/
@Transactional(readOnly = true)
public RecordResponse.RecordListDto getRecordList(Long userId, String folderName) {
User user = findUserById(userId);
List<Record> recordList;

// 임시 저장 기록 제외 Record List 최신 생성 순 조회
if (folderName.equals("all")) {
recordList = getRecordList(user);
} else {
Folder folder = findFolderByTitle(user, folderName);
recordList = getRecordListByFolder(user, folder);
}

return RecordConverter.toRecordListDto(folderName, recordList);
}

/*
* keyword를 받아 해당 키워드를 가진 역량 분석 정보와 경험 기록 정보를 반환
* @param userId, keywordValue
* @return
*/
@Transactional(readOnly = true)
public RecordResponse.KeywordRecordListDto getKeywordRecordList(Long userId, String keywordValue) {
User user = findUserById(userId);

// 해당 keyword를 가진 ability 객체 조회 후 맵핑된 Record 객체 리스트 조회
Keyword keyword = getKeyword(keywordValue);
List<Record> recordList = getRecordListByKeyword(user, keyword);

return RecordConverter.toKeywordRecordListDto(recordList);
}

private void validHasUserTmpMemo(User user) {
if (user.getTmpMemo() != null)
throw new RecordException(RecordErrorStatus.ALREADY_TMP_MEMO);
Expand All @@ -143,6 +185,11 @@ private Folder findFolderById(Long folderId) {
.orElseThrow(() -> new FolderException(FolderErrorStatus.FOLDER_NOT_FOUND));
}

private Folder findFolderByTitle(User user, String title) {
return folderRepository.findFolderByTitle(title, user)
.orElseThrow(() -> new FolderException(FolderErrorStatus.FOLDER_NOT_FOUND));
}

private User findUserById(Long userId) {
return userRepository.findById(userId)
.orElseThrow(() -> new GeneralException(ErrorStatus.UNAUTHORIZED));
Expand All @@ -152,4 +199,23 @@ private Record findRecordById(Long recordId) {
return recordRepository.findById(recordId)
.orElseThrow(() -> new RecordException(RecordErrorStatus.RECORD_NOT_FOUND));
}

private List<Record> getRecordListByFolder(User user, Folder folder) {
return recordRepository.findRecordsByFolder(folder, user);
}

private List<Record> getRecordList(User user) {
return recordRepository.findRecords(user);
}

private List<Record> getRecordListByKeyword(User user, Keyword keyword) {
return recordRepository.findRecordByKeyword(keyword, user);
}

private Keyword getKeyword(String keywordValue) {
Keyword keyword = Keyword.getName(keywordValue);
if (keyword == null)
throw new AnalysisException(AnalysisErrorStatus.INVALID_KEYWORD);
return keyword;
}
}

0 comments on commit e10aa6e

Please sign in to comment.