Skip to content

Commit

Permalink
Feat/#135 내 매칭 기록 조회하기 (#176)
Browse files Browse the repository at this point in the history
* [FEAT] 내 매칭 기록 조회하기 기능 구현

* [FIX] 프로젝트 요청 정렬 누락 오류 해결

* [FIX] Repository 어노테이션 누락 해결

* [FIX] swagger 설명 추가
  • Loading branch information
happyjamy committed Feb 26, 2024
1 parent 5acd6c4 commit 052d038
Show file tree
Hide file tree
Showing 9 changed files with 172 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ public class CursorPaginationInfoReq {
@Nullable
private final Sort.Direction sortOrder;

public CursorPaginationInfoReq(Long cursorId, int pageSize, Direction sortOrder) {
public CursorPaginationInfoReq(@Nullable Long cursorId, int pageSize, Direction sortOrder) {
this.cursorId = cursorId;
this.pageSize = pageSize;
this.sortOrder = Objects.requireNonNullElse(sortOrder, Direction.ASC);
// 최근순 기본
this.sortOrder = Objects.requireNonNullElse(sortOrder, Direction.DESC);
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package io.oeid.mogakgo.common.swagger.template;

import io.oeid.mogakgo.common.base.CursorPaginationInfoReq;
import io.oeid.mogakgo.common.base.CursorPaginationResult;
import io.oeid.mogakgo.core.properties.swagger.error.SwaggerMatchingErrorExamples;
import io.oeid.mogakgo.core.properties.swagger.error.SwaggerProjectErrorExamples;
import io.oeid.mogakgo.core.properties.swagger.error.SwaggerUserErrorExamples;
import io.oeid.mogakgo.domain.matching.presentation.dto.MatchingHistoryRes;
import io.oeid.mogakgo.domain.matching.presentation.dto.MatchingId;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.ExampleObject;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
Expand Down Expand Up @@ -44,4 +48,29 @@ ResponseEntity<MatchingId> cancel(
@Parameter(description = "매칭 ID", required = true) Long matchingId
);

@Operation(summary = "본인의 매칭 기록 가지고 오기", description = "회원이 본인의 매칭 기록을 가지고 올 때 사용하는 API")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "성공"),
@ApiResponse(responseCode = "403", description = "요청을 보낸 사람이 매칭 취소할 권한이 안됨 (매칭 참여자가 아님)",
content = @Content(
mediaType = "application/json",
examples = @ExampleObject(name = "E090201", value = SwaggerMatchingErrorExamples.MATCHING_FORBIDDEN_OPERATION))),
@ApiResponse(responseCode = "404", description = "요청한 데이터가 존재하지 않음",
content = @Content(
mediaType = "application/json",
examples = {
@ExampleObject(name = "E020301", value = SwaggerUserErrorExamples.USER_NOT_FOUND)
})),
})
@Parameters({
@Parameter(name = "cursorId", description = "기준이 되는 커서 ID", example = "1"),
@Parameter(name = "pageSize", description = "요청할 데이터 크기", example = "5", required = true),
@Parameter(name = "sortOrder", description = "정렬 방향", example = "ASC"),
})
ResponseEntity<CursorPaginationResult<MatchingHistoryRes>> getMyMatches(
@Parameter(hidden = true) Long tokenId,
@Parameter(description = "유저 ID", required = true) Long userId,
@Parameter(hidden = true) CursorPaginationInfoReq pageable
);

}
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package io.oeid.mogakgo.domain.matching.application;

import static io.oeid.mogakgo.exception.code.ErrorCode403.MATCHING_FORBIDDEN_OPERATION;
import static io.oeid.mogakgo.exception.code.ErrorCode404.MATCHING_NOT_FOUND;

import io.oeid.mogakgo.common.base.CursorPaginationInfoReq;
import io.oeid.mogakgo.common.base.CursorPaginationResult;
import io.oeid.mogakgo.domain.matching.domain.entity.Matching;
import io.oeid.mogakgo.domain.matching.exception.MatchingException;
import io.oeid.mogakgo.domain.matching.infrastructure.MatchingJpaRepository;
import io.oeid.mogakgo.domain.matching.presentation.dto.MatchingHistoryRes;
import io.oeid.mogakgo.domain.project_join_req.domain.entity.ProjectJoinRequest;
import io.oeid.mogakgo.domain.user.application.UserCommonService;
import io.oeid.mogakgo.domain.user.domain.User;
Expand Down Expand Up @@ -46,6 +50,18 @@ public Long cancel(Long tokenUserId, Long matchingId) {
return matching.getId();
}

public CursorPaginationResult<MatchingHistoryRes> getMyMatches(
Long tokenUserId, Long userId, CursorPaginationInfoReq cursorPaginationInfoReq
) {
User tokenUser = userCommonService.getUserById(tokenUserId);
// 본인만 매칭 기록 조회 가능
if (!tokenUser.getId().equals(userId)) {
throw new MatchingException(MATCHING_FORBIDDEN_OPERATION);
}

return matchingJpaRepository.getMyMatches(tokenUserId, cursorPaginationInfoReq);
}

private Matching getMatching(Long matchingId) {
return matchingJpaRepository.findById(matchingId)
.orElseThrow(() -> new MatchingException(MATCHING_NOT_FOUND));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;

public interface MatchingJpaRepository extends JpaRepository<Matching, Long> {
@Repository
public interface MatchingJpaRepository extends JpaRepository<Matching, Long>,
MatchingRepositoryCustom {

@Query("select m from Matching m join Project p on m.project.id = p.id "
+ "where (m.sender.id = :userId or p.creator.id = :userId) and m.matchingStatus = 'PROGRESS'")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package io.oeid.mogakgo.domain.matching.infrastructure;

import io.oeid.mogakgo.common.base.CursorPaginationInfoReq;
import io.oeid.mogakgo.common.base.CursorPaginationResult;
import io.oeid.mogakgo.domain.matching.presentation.dto.MatchingHistoryRes;
import java.util.List;

public interface MatchingRepositoryCustom {

CursorPaginationResult<MatchingHistoryRes> getMyMatches(
Long userId, CursorPaginationInfoReq cursorPaginationInfoReq
);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package io.oeid.mogakgo.domain.matching.infrastructure;

import static io.oeid.mogakgo.domain.matching.domain.entity.QMatching.matching;
import static io.oeid.mogakgo.domain.project.domain.entity.QProject.project;

import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.jpa.impl.JPAQueryFactory;
import io.oeid.mogakgo.common.base.CursorPaginationInfoReq;
import io.oeid.mogakgo.common.base.CursorPaginationResult;
import io.oeid.mogakgo.domain.matching.presentation.dto.MatchingHistoryRes;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;

@Repository
@RequiredArgsConstructor
public class MatchingRepositoryCustomImpl implements MatchingRepositoryCustom {

private final JPAQueryFactory jpaQueryFactory;


@Override
public CursorPaginationResult<MatchingHistoryRes> getMyMatches(
Long userId, CursorPaginationInfoReq cursorPaginationInfoReq
) {
List<MatchingHistoryRes> matchingHistoryResList = jpaQueryFactory
.select(
Projections.constructor(
MatchingHistoryRes.class,
matching.id,
matching.matchingStatus,
matching.project.creator.avatarUrl,
matching.project.meetingInfo.meetDetail,
matching.project.meetingInfo.meetStartTime,
matching.project.meetingInfo.meetEndTime
)
)
.from(matching)
.join(matching.project)
.where(
participantInMatching(userId),
cursorIdCondition(cursorPaginationInfoReq.getCursorId())
)
// 최근순
.orderBy(matching.id.desc())
.limit(cursorPaginationInfoReq.getPageSize() + 1)
.fetch();

return CursorPaginationResult.fromDataWithExtraItemForNextCheck(matchingHistoryResList,
cursorPaginationInfoReq.getPageSize());
}

private BooleanExpression cursorIdCondition(Long cursorId) {
return cursorId != null ? matching.id.lt(cursorId) : null;
}

private BooleanExpression participantInMatching(Long userId) {
return userId != null ? (matching.sender.id.eq(userId).or(matching.project.creator.id.eq(
userId))) : null;
}


}
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package io.oeid.mogakgo.domain.matching.presentation;

import io.oeid.mogakgo.common.annotation.UserId;
import io.oeid.mogakgo.common.base.CursorPaginationInfoReq;
import io.oeid.mogakgo.common.base.CursorPaginationResult;
import io.oeid.mogakgo.common.swagger.template.MatchingSwagger;
import io.oeid.mogakgo.domain.matching.application.MatchingService;
import io.oeid.mogakgo.domain.matching.presentation.dto.MatchingHistoryRes;
import io.oeid.mogakgo.domain.matching.presentation.dto.MatchingId;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
Expand All @@ -24,4 +28,13 @@ public ResponseEntity<MatchingId> cancel(@UserId Long userId, @PathVariable Long
return ResponseEntity.ok(new MatchingId(matchingService.cancel(userId, matchingId)));
}

@GetMapping("/my/{userId}")
public ResponseEntity<CursorPaginationResult<MatchingHistoryRes>> getMyMatches(
@UserId Long tokenId, @PathVariable Long userId,
@ModelAttribute CursorPaginationInfoReq pageable
) {
return ResponseEntity.ok(
matchingService.getMyMatches(tokenId, userId, pageable));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package io.oeid.mogakgo.domain.matching.presentation.dto;

import io.oeid.mogakgo.domain.matching.domain.entity.enums.MatchingStatus;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDateTime;
import lombok.AllArgsConstructor;
import lombok.Getter;

@Schema(description = "매칭 이력")
@Getter
@AllArgsConstructor
public class MatchingHistoryRes {

@Schema(description = "매칭 ID")
private final Long matchingId;
@Schema(description = "매칭 상태")
private final MatchingStatus status;
@Schema(description = "상대방 프로필 이미지 URL")
private final String anotherUserAvatarUrl;
@Schema(description = "프로젝트 위치 상세")
private final String projectLocationDetail;
@Schema(description = "프로젝트 시작 시간")
private final LocalDateTime projectStartTime;
@Schema(description = "프로젝트 종료 시간")
private final LocalDateTime projectEndTime;

}
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ public CursorPaginationResult<projectJoinRequestRes> findByConditionWithPaginati
projectIdEq(projectId),
requestStatusEq(requestStatus)
)
// 오래 된 순
.orderBy(projectJoinRequest.id.asc())
.limit(pageable.getPageSize() + 1)
.fetch();

Expand Down

0 comments on commit 052d038

Please sign in to comment.