Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import life.mosu.mosuserver.presentation.inquiry.dto.InquiryCreateRequest;
import life.mosu.mosuserver.presentation.inquiry.dto.InquiryDetailResponse;
import life.mosu.mosuserver.presentation.inquiry.dto.InquiryDetailResponse.InquiryAnswerDetailResponse;
import life.mosu.mosuserver.presentation.inquiry.dto.InquiryListResponse;
import life.mosu.mosuserver.presentation.inquiry.dto.InquiryResponse;
import life.mosu.mosuserver.presentation.inquiry.dto.InquiryUpdateRequest;
import lombok.RequiredArgsConstructor;
Expand Down Expand Up @@ -56,8 +57,9 @@ public InquiryDetailResponse getInquiryDetail(UserJpaEntity user, Long postId) {
}

@Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
public Page<InquiryResponse> getMyInquiry(Long userId, Pageable pageable) {
return inquiryJpaRepository.searchMyInquiry(userId, pageable);
public Page<InquiryListResponse> getMyInquiry(Long userId, Pageable pageable) {
return inquiryJpaRepository.searchMyInquiry(userId,
pageable);
}

@Transactional
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package life.mosu.mosuserver.domain.inquiry.repository;

import life.mosu.mosuserver.domain.inquiry.entity.InquiryStatus;
import life.mosu.mosuserver.presentation.inquiry.dto.InquiryListResponse;
import life.mosu.mosuserver.presentation.inquiry.dto.InquiryResponse;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
Expand All @@ -10,5 +11,5 @@ public interface InquiryQueryRepository {
Page<InquiryResponse> searchInquiries(InquiryStatus status, String sortField, boolean asc,
Pageable pageable);

Page<InquiryResponse> searchMyInquiry(Long userId, Pageable pageable);
Page<InquiryListResponse> searchMyInquiry(Long userId, Pageable pageable);
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
import life.mosu.mosuserver.domain.inquiry.entity.InquiryStatus;
import life.mosu.mosuserver.domain.inquiry.entity.QInquiryJpaEntity;
import life.mosu.mosuserver.domain.inquiry.repository.InquiryQueryRepository;
import life.mosu.mosuserver.domain.inquiryAnswer.entity.QInquiryAnswerJpaEntity;
import life.mosu.mosuserver.presentation.inquiry.dto.InquiryAnswerResponse;
import life.mosu.mosuserver.presentation.inquiry.dto.InquiryListResponse;
import life.mosu.mosuserver.presentation.inquiry.dto.InquiryResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
Expand All @@ -29,6 +32,7 @@ public class InquiryJpaRepositoryImpl implements InquiryQueryRepository {
private final JPAQueryFactory queryFactory;
private final EntityManager entityManager;
private final QInquiryJpaEntity inquiry = QInquiryJpaEntity.inquiryJpaEntity;
private final QInquiryAnswerJpaEntity inquiryAnswer = QInquiryAnswerJpaEntity.inquiryAnswerJpaEntity;

@Override
public Page<InquiryResponse> searchInquiries(
Expand All @@ -38,40 +42,42 @@ public Page<InquiryResponse> searchInquiries(
Pageable pageable
) {

JPAQuery<Tuple> query = baseQuery(inquiry)
.where(buildStatusCondition(inquiry, status))
.orderBy(buildOrderByCondition(sortField, asc))
.offset(pageable.getOffset())
.limit(pageable.getPageSize());
JPAQuery<Tuple> query = baseQuery()
.where(buildStatusCondition(inquiry, status));

long total = getTotalCount(query, inquiry.count());

List<InquiryResponse> content = query.fetch().stream()
.map(this::mapToResponse)
List<InquiryResponse> content = query
.orderBy(buildOrderByCondition(sortField, asc))
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch().stream()
.map(this::mapToInquiryResponse)
.toList();

return new PageImpl<>(content, pageable, total);
}

@Override
public Page<InquiryResponse> searchMyInquiry(Long userId, Pageable pageable) {
JPAQuery<Tuple> query = baseQuery(inquiry)
public Page<InquiryListResponse> searchMyInquiry(Long userId, Pageable pageable) {
JPAQuery<Tuple> query = baseQueryWithAnswer()
.where(inquiry.userId.eq(userId));

long total = getTotalCount(query, inquiry.count());
long total = getTotalCount(query, inquiry.countDistinct());

List<InquiryResponse> content = query
List<InquiryListResponse> content = query
.orderBy(inquiry.createdAt.desc())
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch().stream()
.map(this::mapToResponse)
.map(this::mapToInquiryListResponse)
.toList();
Comment on lines +68 to 74

Choose a reason for hiding this comment

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

medium

The sorting is hardcoded to be descending by createdAt. The Pageable object, which is passed as an argument to this method, can contain sorting information from the client request, but it is being ignored. This prevents clients from sorting the inquiry list according to their needs. It is recommended to use the Sort information from the Pageable object to apply dynamic sorting. You could adapt the existing buildOrderByCondition method or create a new helper to handle this.


return new PageImpl<>(content, pageable, total);
}


private JPAQuery<Tuple> baseQuery(QInquiryJpaEntity inquiry) {
private JPAQuery<Tuple> baseQuery() {
return queryFactory
.select(
inquiry.id,
Expand All @@ -85,6 +91,27 @@ private JPAQuery<Tuple> baseQuery(QInquiryJpaEntity inquiry) {

}

private JPAQuery<Tuple> baseQueryWithAnswer() {
return queryFactory
.select(
inquiry.id,
inquiry.title,
inquiry.content,
inquiry.author,
inquiry.status,
inquiry.createdAt,
inquiryAnswer.id,
inquiryAnswer.title,
inquiryAnswer.content,
inquiryAnswer.author,
inquiryAnswer.createdAt,
inquiryAnswer.updatedAt
)
.from(inquiry)
.leftJoin(inquiryAnswer)
.on(inquiryAnswer.inquiryId.eq(inquiry.id));
}

private BooleanExpression buildStatusCondition(QInquiryJpaEntity inquiry,
InquiryStatus status) {
return status != null ? inquiry.status.eq(status) : null;
Expand All @@ -108,7 +135,7 @@ private <T> long getTotalCount(JPAQuery<T> query, Expression<Long> countExpressi
).orElse(0L);
}

private InquiryResponse mapToResponse(Tuple tuple) {
private InquiryResponse mapToInquiryResponse(Tuple tuple) {
InquiryStatus status = tuple.get(inquiry.status);
return new InquiryResponse(
tuple.get(inquiry.id),
Expand All @@ -119,4 +146,22 @@ private InquiryResponse mapToResponse(Tuple tuple) {
formatDate(tuple.get(inquiry.createdAt))
);
}


private InquiryListResponse mapToInquiryListResponse(Tuple tuple) {
InquiryResponse inquiryDto = mapToInquiryResponse(tuple);
InquiryAnswerResponse answerDto = null;

if (tuple.get(inquiryAnswer.id) != null) {
answerDto = new InquiryAnswerResponse(
tuple.get(inquiryAnswer.title),
tuple.get(inquiryAnswer.content),
tuple.get(inquiryAnswer.author),
formatDate(tuple.get(inquiryAnswer.createdAt)),
formatDate(tuple.get(inquiryAnswer.updatedAt))
);
}

return InquiryListResponse.of(inquiryDto, answerDto);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import life.mosu.mosuserver.global.util.ApiResponseWrapper;
import life.mosu.mosuserver.presentation.inquiry.dto.InquiryCreateRequest;
import life.mosu.mosuserver.presentation.inquiry.dto.InquiryDetailResponse;
import life.mosu.mosuserver.presentation.inquiry.dto.InquiryResponse;
import life.mosu.mosuserver.presentation.inquiry.dto.InquiryListResponse;
import life.mosu.mosuserver.presentation.inquiry.dto.InquiryUpdateRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
Expand Down Expand Up @@ -54,12 +54,13 @@ public ResponseEntity<ApiResponseWrapper<Void>> update(

@GetMapping("/my")
@PreAuthorize("isAuthenticated() and hasRole('USER')")
public ResponseEntity<ApiResponseWrapper<Page<InquiryResponse>>> getMyInquiries(
public ResponseEntity<ApiResponseWrapper<Page<InquiryListResponse>>> getMyInquiries(
@UserId Long userId,
@PageableDefault(size = 10) Pageable pageable
) {
Page<InquiryResponse> inquiries = inquiryService.getMyInquiry(userId, pageable);
return ResponseEntity.ok(ApiResponseWrapper.success(HttpStatus.OK, "내 질문 목록 조회 성공", inquiries));
Page<InquiryListResponse> inquiries = inquiryService.getMyInquiry(userId, pageable);
return ResponseEntity.ok(
ApiResponseWrapper.success(HttpStatus.OK, "내 질문 목록 조회 성공", inquiries));
}

@GetMapping("/{postId}")
Expand All @@ -68,7 +69,8 @@ public ResponseEntity<ApiResponseWrapper<InquiryDetailResponse>> getInquiryDetai
@AuthenticationPrincipal PrincipalDetails principalDetails,
@PathVariable Long postId) {

InquiryDetailResponse inquiry = inquiryService.getInquiryDetail(principalDetails.user(), postId);
InquiryDetailResponse inquiry = inquiryService.getInquiryDetail(principalDetails.user(),
postId);
return ResponseEntity.ok(ApiResponseWrapper.success(HttpStatus.OK, "질문 상세 조회 성공",
inquiry));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import life.mosu.mosuserver.global.util.ApiResponseWrapper;
import life.mosu.mosuserver.presentation.inquiry.dto.InquiryCreateRequest;
import life.mosu.mosuserver.presentation.inquiry.dto.InquiryDetailResponse;
import life.mosu.mosuserver.presentation.inquiry.dto.InquiryResponse;
import life.mosu.mosuserver.presentation.inquiry.dto.InquiryListResponse;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
Expand All @@ -37,7 +37,7 @@ ResponseEntity<ApiResponseWrapper<Void>> create(
@ApiResponse(responseCode = "200", description = "내 문의글 목록 조회 성공",
content = @Content(schema = @Schema(implementation = Page.class)))
})
ResponseEntity<ApiResponseWrapper<Page<InquiryResponse>>> getMyInquiries(
ResponseEntity<ApiResponseWrapper<Page<InquiryListResponse>>> getMyInquiries(
@Parameter(description = "사용자 ID", required = true) Long userId,
@Parameter(description = "페이지 정보") Pageable pageable
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package life.mosu.mosuserver.presentation.inquiry.dto;

public record InquiryAnswerResponse(
String title,
String content,
String author,
String createdAt,
String updatedAt
) {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package life.mosu.mosuserver.presentation.inquiry.dto;

public record InquiryListResponse(
InquiryResponse inquiry,
InquiryAnswerResponse reply
) {

public static InquiryListResponse of(
InquiryResponse inquiry,
InquiryAnswerResponse reply
) {
return new InquiryListResponse(inquiry, reply);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package life.mosu.mosuserver.presentation.inquiry.dto;

import io.swagger.v3.oas.annotations.media.Schema;
import life.mosu.mosuserver.domain.inquiry.entity.InquiryJpaEntity;

@Schema(description = "1:1 문의 응답 DTO")
public record InquiryResponse(
Expand All @@ -24,14 +23,5 @@ public record InquiryResponse(
String createdAt
) {

public static InquiryResponse of(InquiryJpaEntity inquiry) {
return new InquiryResponse(
inquiry.getId(),
inquiry.getTitle(),
inquiry.getContent(),
inquiry.getAuthor(),
inquiry.getStatus().getStatusName(),
inquiry.getCreatedAt()
);
}

}