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
52 changes: 50 additions & 2 deletions src/docs/asciidoc/grooming-test-api.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ include::{snippetsDir}/submitGroomingTests/2/http-response.adoc[]
include::{snippetsDir}/submitGroomingTests/1/response-fields.adoc[]

==== 실패 Response
실패 3. 유효하지 않은 그루밍 테스트 질문 ID일 경우 (존재하지 않는 질문 ID, 중복된 질문 ID)
실패 1. 유효하지 않은 그루밍 테스트 질문 ID일 경우 (존재하지 않는 질문 ID, 중복된 질문 ID)

include::{snippetsDir}/submitGroomingTests/3/http-response.adoc[]

실패 4. 유효하지 않은 그루밍 테스트 답변 ID일 경우 (존재하지 않는 답변 ID, 질문과 잘못 매핑된 답변 ID, 중복된 답변 ID)
실패 2. 유효하지 않은 그루밍 테스트 답변 ID일 경우 (존재하지 않는 답변 ID, 질문과 잘못 매핑된 답변 ID, 중복된 답변 ID)

include::{snippetsDir}/submitGroomingTests/4/http-response.adoc[]

Expand Down Expand Up @@ -103,3 +103,51 @@ include::{snippetsDir}/saveGroomingTestResult/4/http-response.adoc[]
include::{snippetsDir}/saveGroomingTestResult/5/http-response.adoc[]

---

=== **5. 유저 그루밍 테스트 이력 목록 조회**

유저의 그루밍 테스트 이력 목록을 조회하는 api 입니다. (최신순 5개의 테스트 한 날짜 응답)

==== Request
include::{snippetsDir}/loadGroomingTestHistory/1/http-request.adoc[]

==== 성공 Response
include::{snippetsDir}/loadGroomingTestHistory/1/http-response.adoc[]

==== Response Body Fields
include::{snippetsDir}/loadGroomingTestHistory/1/response-fields.adoc[]

==== 실패 Response
실패 1. 인증된 유저가 아닌 경우

include::{snippetsDir}/loadGroomingTestHistory/2/http-response.adoc[]

---

=== **6. 유저 그루밍 테스트 이력 상세 조회**

유저의 그루밍 테스트 이력 내역을 상세 조회하는 api 입니다. (테스트한 날짜로 요청)

==== Request
include::{snippetsDir}/loadGroomingTestHistoryDetail/1/http-request.adoc[]

==== Request Query Parameters
include::{snippetsDir}/loadGroomingTestHistoryDetail/1/query-parameters.adoc[]

==== 성공 Response
include::{snippetsDir}/loadGroomingTestHistoryDetail/1/http-response.adoc[]

==== Response Body Fields
include::{snippetsDir}/loadGroomingTestHistoryDetail/1/response-fields.adoc[]

==== 실패 Response
실패 1. 인증된 유저가 아닌 경우

include::{snippetsDir}/loadGroomingTestHistoryDetail/2/http-response.adoc[]

실패 2. 잘못된 형식의 날짜 파라미터를 요청할 경우 ("yyyy.MM.dd" or "yyyy-MM-dd" 형식이 아닐 경우)

include::{snippetsDir}/loadGroomingTestHistoryDetail/3/http-response.adoc[]

---

Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.ftm.server.adapter.in.web.grooming.controller;

import com.ftm.server.adapter.in.web.grooming.dto.response.GroomingTestHistoryResponse;
import com.ftm.server.application.port.in.grooming.LoadGroomingTestHistoryUseCase;
import com.ftm.server.application.query.FindByUserIdQuery;
import com.ftm.server.application.vo.grooming.GroomingTestHistoryVo;
import com.ftm.server.common.response.ApiResponse;
import com.ftm.server.common.response.enums.SuccessResponseCode;
import com.ftm.server.infrastructure.security.UserPrincipal;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
public class LoadGroomingTestHistoryController {

private final LoadGroomingTestHistoryUseCase loadGroomingTestsHistoryUseCase;

@GetMapping("/api/grooming/tests/histories")
public ResponseEntity<ApiResponse<GroomingTestHistoryResponse>> loadHistories(
@AuthenticationPrincipal UserPrincipal userPrincipal) {
GroomingTestHistoryVo vo =
loadGroomingTestsHistoryUseCase.execute(
FindByUserIdQuery.of(userPrincipal.getId()));

return ResponseEntity.status(HttpStatus.OK)
.body(
ApiResponse.success(
SuccessResponseCode.OK, GroomingTestHistoryResponse.of(vo)));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.ftm.server.adapter.in.web.grooming.controller;

import com.ftm.server.adapter.in.web.grooming.dto.response.GroomingTestHistoryDetailResponse;
import com.ftm.server.application.port.in.grooming.LoadGroomingTestHistoryDetailUseCase;
import com.ftm.server.application.query.FindGroomingTestResultByUserIdAndTestedAtQuery;
import com.ftm.server.application.vo.grooming.GroomingTestHistoryDetailVo;
import com.ftm.server.common.response.ApiResponse;
import com.ftm.server.common.response.enums.SuccessResponseCode;
import com.ftm.server.infrastructure.security.UserPrincipal;
import java.time.LocalDate;
import lombok.RequiredArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
public class LoadGroomingTestHistoryDetailController {

private final LoadGroomingTestHistoryDetailUseCase loadGroomingTestHistoryDetailUseCase;

@GetMapping("/api/grooming/tests/histories/detail")
public ResponseEntity<ApiResponse<GroomingTestHistoryDetailResponse>> loadHistoryDetail(
@RequestParam("date") @DateTimeFormat(pattern = "yyyy.MM.dd") LocalDate date,
@AuthenticationPrincipal UserPrincipal userPrincipal) {
GroomingTestHistoryDetailVo vo =
loadGroomingTestHistoryDetailUseCase.execute(
FindGroomingTestResultByUserIdAndTestedAtQuery.of(
userPrincipal.getId(), date));
return ResponseEntity.status(HttpStatus.OK)
.body(
ApiResponse.success(
SuccessResponseCode.OK,
GroomingTestHistoryDetailResponse.from(vo)));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.ftm.server.adapter.in.web.grooming.dto.response;

import com.ftm.server.application.vo.grooming.*;
import lombok.Getter;

@Getter
public class GroomingTestHistoryDetailResponse {

private final String testedAt;
private final GroomingTestResultScoresVo scores;
private final GroomingTestResultGradesVo grades;
private final GroomingLevelVo level;

private GroomingTestHistoryDetailResponse(
GroomingTestHistoryDetailVo groomingTestHistoryDetailVo) {
this.testedAt = groomingTestHistoryDetailVo.getTestedAt();
this.scores = groomingTestHistoryDetailVo.getScores();
this.grades = groomingTestHistoryDetailVo.getGrades();
this.level = groomingTestHistoryDetailVo.getLevel();
}

public static GroomingTestHistoryDetailResponse from(
GroomingTestHistoryDetailVo groomingTestHistoryDetailVo) {
return new GroomingTestHistoryDetailResponse(groomingTestHistoryDetailVo);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.ftm.server.adapter.in.web.grooming.dto.response;

import com.ftm.server.application.vo.grooming.GroomingTestHistoryVo;
import java.util.List;
import lombok.Getter;

@Getter
public class GroomingTestHistoryResponse {

private final List<String> historyDates;

private GroomingTestHistoryResponse(GroomingTestHistoryVo groomingTestHistoryVo) {
this.historyDates = groomingTestHistoryVo.getHistoryDates();
}

public static GroomingTestHistoryResponse of(GroomingTestHistoryVo groomingTestHistoryVo) {
return new GroomingTestHistoryResponse(groomingTestHistoryVo);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.ftm.server.application.query.FIndGroomingLevelByScoreQuery;
import com.ftm.server.application.query.FindByIdQuery;
import com.ftm.server.application.query.FindByUserIdQuery;
import com.ftm.server.application.query.FindGroomingTestResultByUserIdAndTestedAtQuery;
import com.ftm.server.common.annotation.Adapter;
import com.ftm.server.common.exception.CustomException;
import com.ftm.server.common.response.enums.ErrorResponseCode;
Expand Down Expand Up @@ -121,4 +122,18 @@ public void updateUserGroomingStatus(User user) {
public LocalDateTime loadLatestTestedAtByUserId(FindByUserIdQuery query) {
return groomingTestResultRepository.fetchLatestTestedAtByUserId(query);
}

@Override
public List<LocalDateTime> loadRecentTestedAtListByUserId(FindByUserIdQuery query) {
return groomingTestResultRepository.fetchRecentTestedAtListByUserId(query);
}

@Override
public List<GroomingTestResult> loadByUserIdAndTestedAt(
FindGroomingTestResultByUserIdAndTestedAtQuery query) {
List<GroomingTestResultJpaEntity> results =
groomingTestResultRepository.loadByUserIdAndTestedAt(query);

return results.stream().map(groomingTestResultMapper::toDomainEntity).toList();
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
package com.ftm.server.adapter.out.persistence.repository;

import com.ftm.server.adapter.out.persistence.model.GroomingTestResultJpaEntity;
import com.ftm.server.application.query.FindByUserIdQuery;
import com.ftm.server.application.query.FindGroomingTestResultByUserIdAndTestedAtQuery;
import java.time.LocalDateTime;
import java.util.List;

public interface GroomingTestResultCustomRepository {

LocalDateTime fetchLatestTestedAtByUserId(FindByUserIdQuery query);

List<LocalDateTime> fetchRecentTestedAtListByUserId(FindByUserIdQuery query);

List<GroomingTestResultJpaEntity> loadByUserIdAndTestedAt(
FindGroomingTestResultByUserIdAndTestedAtQuery query);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@

import static com.ftm.server.adapter.out.persistence.model.QGroomingTestResultJpaEntity.groomingTestResultJpaEntity;

import com.ftm.server.adapter.out.persistence.model.GroomingTestResultJpaEntity;
import com.ftm.server.application.query.FindByUserIdQuery;
import com.ftm.server.application.query.FindGroomingTestResultByUserIdAndTestedAtQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;

Expand All @@ -22,4 +26,33 @@ public LocalDateTime fetchLatestTestedAtByUserId(FindByUserIdQuery query) {
.where(groomingTestResultJpaEntity.user.id.eq(query.getUserId()))
.fetchOne();
}

@Override
public List<LocalDateTime> fetchRecentTestedAtListByUserId(FindByUserIdQuery query) {
return queryFactory
.select(groomingTestResultJpaEntity.testedAt)
.distinct()
.from(groomingTestResultJpaEntity)
.where(groomingTestResultJpaEntity.user.id.eq(query.getUserId()))
.orderBy(groomingTestResultJpaEntity.testedAt.desc())
.limit(5)
.fetch();
}

@Override
public List<GroomingTestResultJpaEntity> loadByUserIdAndTestedAt(
FindGroomingTestResultByUserIdAndTestedAtQuery query) {
LocalDateTime start = query.getTestedAt().atStartOfDay();
LocalDateTime end = query.getTestedAt().atTime(LocalTime.MAX);

return queryFactory
.selectFrom(groomingTestResultJpaEntity)
.where(
groomingTestResultJpaEntity
.user
.id
.eq(query.getUserId())
.and(groomingTestResultJpaEntity.testedAt.between(start, end)))
.fetch();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.ftm.server.application.port.in.grooming;

import com.ftm.server.application.query.FindGroomingTestResultByUserIdAndTestedAtQuery;
import com.ftm.server.application.vo.grooming.GroomingTestHistoryDetailVo;
import com.ftm.server.common.annotation.UseCase;

@UseCase
public interface LoadGroomingTestHistoryDetailUseCase {

GroomingTestHistoryDetailVo execute(FindGroomingTestResultByUserIdAndTestedAtQuery query);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.ftm.server.application.port.in.grooming;

import com.ftm.server.application.query.FindByUserIdQuery;
import com.ftm.server.application.vo.grooming.GroomingTestHistoryVo;
import com.ftm.server.common.annotation.UseCase;

@UseCase
public interface LoadGroomingTestHistoryUseCase {

GroomingTestHistoryVo execute(FindByUserIdQuery query);
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
package com.ftm.server.application.port.out.persistence.grooming;

import com.ftm.server.application.query.FindByUserIdQuery;
import com.ftm.server.application.query.FindGroomingTestResultByUserIdAndTestedAtQuery;
import com.ftm.server.common.annotation.Port;
import com.ftm.server.domain.entity.GroomingTestResult;
import java.time.LocalDateTime;
import java.util.List;

@Port
public interface LoadGroomingTestResultPort {

LocalDateTime loadLatestTestedAtByUserId(FindByUserIdQuery query);

List<LocalDateTime> loadRecentTestedAtListByUserId(FindByUserIdQuery query);

List<GroomingTestResult> loadByUserIdAndTestedAt(
FindGroomingTestResultByUserIdAndTestedAtQuery query);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.ftm.server.application.query;

import java.time.LocalDate;
import lombok.Getter;

@Getter
public class FindGroomingTestResultByUserIdAndTestedAtQuery {

private final Long userId;
private final LocalDate testedAt;

private FindGroomingTestResultByUserIdAndTestedAtQuery(Long userId, LocalDate testedAt) {
this.userId = userId;
this.testedAt = testedAt;
}

public static FindGroomingTestResultByUserIdAndTestedAtQuery of(
Long userId, LocalDate testedAt) {
return new FindGroomingTestResultByUserIdAndTestedAtQuery(userId, testedAt);
}
}
Loading