Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
301fdd6
[refactor] Feed, Record, Vote에 likeCount, commentCount 필드 추가 (#53)
buzz0331 Jul 11, 2025
f8daee6
[refactor] DateUtil 정적 메서드로 변경 (#53)
buzz0331 Jul 11, 2025
183f5fd
[refactor] isOverview 쿼리파라미터 추가 (#53)
buzz0331 Jul 11, 2025
565cd55
[refactor] dto 이름 수정 및 필요한 메서드 추가 (#53)
buzz0331 Jul 11, 2025
93e4aac
[refactor] RecordSearchQuery 대신 값으로 파라미터 전달 (#53)
buzz0331 Jul 11, 2025
65c4121
[refactor] RoomId로 Book 조회하는 쿼리 추가 (#53)
buzz0331 Jul 11, 2025
f893892
[refactor] Querydsl 로직 수정 필터링 + 정렬 + 페이지네이션 적용 (#53)
buzz0331 Jul 11, 2025
11b8dfa
[refactor] Adapter 로직 간소화 (#53)
buzz0331 Jul 11, 2025
1ee0223
[refactor] 쿼리 파라미터 상수 정의 및 유효성 검증 로직 추가 (#53)
buzz0331 Jul 11, 2025
19e2b5b
[refactor] 서비스 레벨 수정 (#53)
buzz0331 Jul 11, 2025
13dffdf
[refactor] 필요없는 DI 삭제 (#53)
buzz0331 Jul 11, 2025
3b26133
[test] 기록장 조회 api 통합 테스트 (#53)
buzz0331 Jul 11, 2025
09d3027
[refactor] DateUtil 메서드 이름 수정 (#53)
buzz0331 Jul 12, 2025
3278def
[refactor] DateUtil Component 어노테이션 제거 (#53)
buzz0331 Jul 12, 2025
34fb5cc
[refactor] pageNum이 null인 경우 검증 로직 수정 (#53)
buzz0331 Jul 12, 2025
256661d
[test] RecordSearchService 단위 테스트 (#53)
buzz0331 Jul 12, 2025
4d93575
[test] RecordQueryController 통합 테스트 (#63)
buzz0331 Jul 12, 2025
d0317c3
[refactor] 필요없는 정적 메서드 제거 (#63)
buzz0331 Jul 12, 2025
7bcd7b3
[chore] VoteItem percentage 계산 알고리즘 todo 추가 (#63)
buzz0331 Jul 12, 2025
66bc8ee
[chore] 필요없는 주석 제거 (#63)
buzz0331 Jul 12, 2025
68cdb0e
[refactor] 가독성을 위해 builder 패턴 적용 (#63)
buzz0331 Jul 12, 2025
6af0a96
[refactor] Querydsl 로직 테스트 (정렬, 필터링, 페이징) (#63)
buzz0331 Jul 12, 2025
23f49e2
[refactor] count builder 초기값 설정 (#63)
buzz0331 Jul 12, 2025
631f0a0
[fix] conflict 해결 (#63)
buzz0331 Jul 12, 2025
cf958bf
[test] DataJpaTest는 자동 롤백되므로 AfterEach 제거 (#63)
buzz0331 Jul 12, 2025
96fee95
[refactor] count 쿼리 로직 수정 (#63)
buzz0331 Jul 12, 2025
2b825e7
[test] 정렬 테스트 추가 (#63)
buzz0331 Jul 12, 2025
a9edaf4
[refactor] 잘못된 예외 클래스 import 제거 (#63)
buzz0331 Jul 12, 2025
4dcff14
[refactor] 잘못된 예외 클래스 import 제거 (#63)
buzz0331 Jul 12, 2025
eb31143
[refactor] count 변수 NPE 방지 (#63)
buzz0331 Jul 12, 2025
f6b8e43
[refactor] 필터링 논리 오류 수정 및 메서드 추출 (#63)
buzz0331 Jul 12, 2025
88f021c
[refactor] recordCount 0으로 초기화 (#63)
buzz0331 Jul 13, 2025
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
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,18 @@
import konkuk.thip.book.application.port.out.BookCommandPort;
import konkuk.thip.book.domain.Book;
import konkuk.thip.common.exception.EntityNotFoundException;
import konkuk.thip.room.adapter.out.persistence.RoomJpaRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;

import static konkuk.thip.common.exception.code.ErrorCode.BOOK_NOT_FOUND;
import static konkuk.thip.common.exception.code.ErrorCode.ROOM_NOT_FOUND;

@Repository
@RequiredArgsConstructor
public class BookCommandPersistenceAdapter implements BookCommandPort {

private final RoomJpaRepository roomJpaRepository;
private final BookJpaRepository bookJpaRepository;
private final BookMapper bookMapper;

Expand Down Expand Up @@ -49,4 +52,12 @@ public void updateForPageCount(Book book) {
bookJpaEntity.changePageCount(book.getPageCount());
bookJpaRepository.save(bookJpaEntity);
}

@Override
public Book findBookByRoomId(Long roomId) {
BookJpaEntity bookJpaEntity = roomJpaRepository.findById(roomId).orElseThrow(
() -> new EntityNotFoundException(ROOM_NOT_FOUND)
).getBookJpaEntity();
return bookMapper.toDomainEntity(bookJpaEntity);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@ public interface BookCommandPort {
Book findById(Long id);

void updateForPageCount(Book book);

Book findBookByRoomId(Long roomId);
}
5 changes: 1 addition & 4 deletions src/main/java/konkuk/thip/common/util/DateUtil.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
package konkuk.thip.common.util;

import org.springframework.stereotype.Component;

import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;

@Component
public class DateUtil {

//마지막 활동 시간 포맷팅 -> ex. 1분 전, 1시간 전, 1일 전
public String formatLastActivityTime(LocalDateTime createdAt) {
public static String formatBeforeTime(LocalDateTime createdAt) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM

long minutes = Duration.between(createdAt, LocalDateTime.now()).toMinutes();
if (minutes < 1) return "방금 전";
if (minutes < 60) return minutes + "분 전";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ public class FeedJpaEntity extends PostJpaEntity {
private BookJpaEntity bookJpaEntity;

@Builder
public FeedJpaEntity(String content, UserJpaEntity userJpaEntity, Boolean isPublic, int reportCount, BookJpaEntity bookJpaEntity) {
super(content, userJpaEntity);
public FeedJpaEntity(String content, Integer likeCount, Integer commentCount, UserJpaEntity userJpaEntity, Boolean isPublic, int reportCount, BookJpaEntity bookJpaEntity) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

👍🏻👍🏻

super(content, likeCount, commentCount, userJpaEntity);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM

this.isPublic = isPublic;
this.reportCount = reportCount;
this.bookJpaEntity = bookJpaEntity;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ public FeedJpaEntity toJpaEntity(Feed feed, UserJpaEntity userJpaEntity, BookJpa
.userJpaEntity(userJpaEntity)
.isPublic(feed.getIsPublic())
.reportCount(feed.getReportCount())
.likeCount(feed.getLikeCount())
.commentCount(feed.getCommentCount())
.bookJpaEntity(bookJpaEntity)
.build();
}
Expand All @@ -30,6 +32,8 @@ public Feed toDomainEntity(FeedJpaEntity feedJpaEntity, List<TagJpaEntity> tagJp
.creatorId(feedJpaEntity.getUserJpaEntity().getUserId())
.isPublic(feedJpaEntity.getIsPublic())
.reportCount(feedJpaEntity.getReportCount())
.likeCount(feedJpaEntity.getLikeCount())
.commentCount(feedJpaEntity.getCommentCount())
.targetBookId(feedJpaEntity.getBookJpaEntity().getBookId())
.tagList(tagJpaEntityList.stream()
.map(TagJpaEntity::getValue)
Expand Down
16 changes: 13 additions & 3 deletions src/main/java/konkuk/thip/feed/domain/Feed.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package konkuk.thip.feed.domain;

import konkuk.thip.common.entity.BaseDomainEntity;
import lombok.Builder;
import lombok.Getter;
import lombok.experimental.SuperBuilder;

Expand All @@ -18,19 +19,28 @@ public class Feed extends BaseDomainEntity {

private Boolean isPublic;

private int reportCount;
@Builder.Default
private Integer reportCount = 0;

@Builder.Default
private Integer likeCount = 0;

@Builder.Default
private Integer commentCount = 0;

private Long targetBookId;

private List<Tag> tagList;

public static Feed withoutId(String content, Long creatorId, Boolean isPublic, int reportCount, Long targetBookId, List<Tag> tagList) {
public static Feed withoutId(String content, Long creatorId, Boolean isPublic, Long targetBookId, List<Tag> tagList) {
return Feed.builder()
.id(null)
.content(content)
.creatorId(creatorId)
.isPublic(isPublic)
.reportCount(reportCount)
.reportCount(0)
.likeCount(0)
.commentCount(0)
.targetBookId(targetBookId)
.tagList(tagList)
.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,18 @@ public abstract class PostJpaEntity extends BaseJpaEntity {
@Column(length = 6100, nullable = false)
private String content;

private Integer likeCount = 0;

private Integer commentCount = 0;
Comment on lines +26 to +28
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

좋습니다! 이제 저희가 관련 C,U,D 할때 해당 데이터를 잘 업데이트 해줘야 하니 이 점 유의하면서 개발 진행해야할 것 같네요


@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", nullable = false)
private UserJpaEntity userJpaEntity;

public PostJpaEntity(String content, UserJpaEntity userJpaEntity) {
public PostJpaEntity(String content, Integer likeCount, Integer commentCount, UserJpaEntity userJpaEntity) {
this.content = content;
this.likeCount = likeCount;
this.commentCount = commentCount;
this.userJpaEntity = userJpaEntity;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import konkuk.thip.common.dto.BaseResponse;
import konkuk.thip.common.security.annotation.UserId;
import konkuk.thip.record.adapter.in.web.response.RecordSearchResponse;
import konkuk.thip.record.application.port.in.dto.RecordSearchQuery;
import konkuk.thip.record.application.port.in.dto.RecordSearchUseCase;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
Expand All @@ -20,24 +19,15 @@ public class RecordQueryController {
@GetMapping("/rooms/{roomId}/posts")
public BaseResponse<RecordSearchResponse> viewRecordList(
@PathVariable final Long roomId,
@RequestParam final String type,
@RequestParam final String sort,
@RequestParam(required = false) final String type,
@RequestParam(required = false) final String sort,
@RequestParam(required = false) final Integer pageStart,
@RequestParam(required = false) final Integer pageEnd,
@RequestParam final Boolean isOverview,
@RequestParam final Integer pageNum,
@UserId final Long userId
) {
return BaseResponse.ok(recordSearchUseCase.search(
RecordSearchQuery.builder()
.roomId(roomId)
.type(type)
.sort(sort)
.pageStart(pageStart)
.pageEnd(pageEnd)
.pageNum(pageNum)
.userId(userId)
.build()
));
return BaseResponse.ok(recordSearchUseCase.search(roomId, type, sort, pageStart, pageEnd, isOverview, pageNum, userId));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

옷 RecordSearchQuery는 왜 빼신거에요?? 단순궁금

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

현재 pageNum과 같은 변수에서 유효성 검증 후 값을 직접 조정하는 로직이 있어서, 굳이 불변객체로 DTO를 하나 더 두지 않아도 된다고 판단했습니다!

}

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package konkuk.thip.record.adapter.in.web.response;

import konkuk.thip.record.domain.Record;
import konkuk.thip.user.domain.User;
import lombok.Builder;

@Builder
Expand All @@ -17,25 +15,25 @@ public record RecordDto(
boolean isLiked,
boolean isWriter,
Long recordId
) implements RecordSearchResponse.PostDto {
) implements RecordSearchResponse.RecordSearchResult {
@Override
public String type() {
return "RECORD";
}

public static RecordDto of(Record record, String postDate, User user, int likeCount, int commentCount, boolean isLiked, boolean isWriter) {
return RecordDto.builder()
.postDate(postDate)
.page(record.getPage())
.userId(record.getCreatorId())
.nickName(user.getNickname())
.profileImageUrl(user.getAlias().getImageUrl())
.content(record.getContent())
.likeCount(likeCount)
.commentCount(commentCount)
.isLiked(isLiked)
.isWriter(isWriter)
.recordId(record.getId())
.build();
public RecordDto withIsLiked(boolean isLiked) {
return new RecordDto(
postDate,
page,
userId,
nickName,
profileImageUrl,
content,
likeCount,
commentCount,
isLiked,
isWriter,
recordId
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@
import java.util.List;

public record RecordSearchResponse(
List<PostDto> recordList,
List<RecordSearchResult> recordList,
Integer page,
Integer size,
Boolean first,
Boolean last
){

public static RecordSearchResponse of(List<PostDto> recordList,
public static RecordSearchResponse of(List<RecordSearchResult> recordList,
Integer page,
Integer size,
Boolean first,
Expand All @@ -26,7 +26,7 @@ public static RecordSearchResponse of(List<PostDto> recordList,
@JsonSubTypes.Type(value = RecordDto.class, name = "RECORD"),
@JsonSubTypes.Type(value = VoteDto.class, name = "VOTE")
})
public sealed interface PostDto permits RecordDto, VoteDto {
public sealed interface RecordSearchResult permits RecordDto, VoteDto {
String type();
String postDate();
int page();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package konkuk.thip.record.adapter.in.web.response;

import konkuk.thip.user.domain.User;
import konkuk.thip.vote.domain.Vote;
import konkuk.thip.vote.domain.VoteItem;
import lombok.Builder;

Expand All @@ -21,30 +19,27 @@ public record VoteDto(
boolean isWriter,
Long voteId,
List<VoteItemDto> voteItems
) implements RecordSearchResponse.PostDto {
) implements RecordSearchResponse.RecordSearchResult {
@Override
public String type() {
return "VOTE";
}

public static VoteDto of(
Vote vote, String postDate, User user, int likeCount, int commentCount, boolean isLiked, boolean isWriter,
List<VoteItemDto> voteItems
) {
return VoteDto.builder()
.postDate(postDate)
.page(vote.getPage())
.userId(vote.getCreatorId())
.nickName(user.getNickname())
.profileImageUrl(user.getAlias().getImageUrl())
.content(vote.getContent())
.likeCount(likeCount)
.commentCount(commentCount)
.isLiked(isLiked)
.isWriter(isWriter)
.voteId(vote.getId())
.voteItems(voteItems)
.build();
public VoteDto withIsLikedAndVoteItems(boolean isLiked, List<VoteItemDto> voteItems) {
return new VoteDto(
postDate,
page,
userId,
nickName,
profileImageUrl,
content,
likeCount,
commentCount,
isLiked,
isWriter,
voteId,
voteItems
);
}

public record VoteItemDto(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ public class RecordJpaEntity extends PostJpaEntity {
private RoomJpaEntity roomJpaEntity;

@Builder
public RecordJpaEntity(String content, UserJpaEntity userJpaEntity, Integer page, boolean isOverview, RoomJpaEntity roomJpaEntity) {
super(content, userJpaEntity);
public RecordJpaEntity(String content, Integer likeCount, Integer commentCount, UserJpaEntity userJpaEntity, Integer page, boolean isOverview, RoomJpaEntity roomJpaEntity) {
super(content, likeCount, commentCount, userJpaEntity);
this.page = page;
this.isOverview = isOverview;
this.roomJpaEntity = roomJpaEntity;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ public class RecordMapper {
public RecordJpaEntity toJpaEntity(Record record, UserJpaEntity userJpaEntity, RoomJpaEntity roomJpaEntity) {
return RecordJpaEntity.builder()
.content(record.getContent())
.likeCount(record.getLikeCount())
.commentCount(record.getCommentCount())
.userJpaEntity(userJpaEntity)
.page(record.getPage())
.isOverview(record.isOverview())
Expand All @@ -27,6 +29,8 @@ public Record toDomainEntity(RecordJpaEntity recordJpaEntity) {
.page(recordJpaEntity.getPage())
.isOverview(recordJpaEntity.isOverview())
.roomId(recordJpaEntity.getRoomJpaEntity().getRoomId())
.likeCount(recordJpaEntity.getLikeCount())
.commentCount(recordJpaEntity.getCommentCount())
.createdAt(recordJpaEntity.getCreatedAt())
.modifiedAt(recordJpaEntity.getModifiedAt())
.status(recordJpaEntity.getStatus())
Expand Down
Original file line number Diff line number Diff line change
@@ -1,39 +1,21 @@
package konkuk.thip.record.adapter.out.persistence;

import konkuk.thip.record.adapter.out.mapper.RecordMapper;
import konkuk.thip.record.application.port.in.dto.RecordSearchResult;
import konkuk.thip.record.adapter.in.web.response.RecordSearchResponse;
import konkuk.thip.record.application.port.out.RecordQueryPort;
import konkuk.thip.record.domain.Record;
import konkuk.thip.vote.adapter.out.mapper.VoteMapper;
import konkuk.thip.vote.adapter.out.persistence.VoteJpaRepository;
import konkuk.thip.vote.domain.Vote;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
@RequiredArgsConstructor
public class RecordQueryPersistenceAdapter implements RecordQueryPort {

private final RecordJpaRepository recordJpaRepository;
private final VoteJpaRepository voteJpaRepository;
private final RecordMapper recordMapper;
private final VoteMapper voteMapper;

private static final Integer PAGE_SIZE = 10;

@Override
public RecordSearchResult findRecordsByRoom(Long roomId, String type, Integer pageStart, Integer pageEnd, Long userId, Integer pageNum) {
List<Record> records = recordJpaRepository.findRecordsByRoom(roomId, type, pageStart, pageEnd, userId).stream()
.map(recordMapper::toDomainEntity)
.toList();

List<Vote> votes = voteJpaRepository.findVotesByRoom(roomId, type, pageStart, pageEnd, userId).stream()
.map(voteMapper::toDomainEntity)
.toList();

return RecordSearchResult.of(records, votes);
public Page<RecordSearchResponse.RecordSearchResult> findRecordsByRoom(Long roomId, String type, Integer pageStart, Integer pageEnd, Boolean isOverview, Long userId, Pageable pageable) {
return recordJpaRepository.findRecordsByRoom(roomId, type, pageStart, pageEnd, isOverview, userId, pageable);
}
}

Loading