-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feat: 러닝 결과 저장 V2 API 구현(러닝 경로 추가) (#324)
* Feat: 좌표값이 null Island(0,0,0) 좌표인지 확인하는 함수 추가 * Feat: (러닝 결과 저장 V2) 챌린지, 목표 각각의 모드에서 관련 엔티티 유효성 ErrorType 추가 - 챌린지 모드에서는 챌린지 관련 값이 필수 - 목표 모드에서는 목표 관련 값이 필수 * Feat: 러닝 결과 저장 V2 requestDTO 추가 - requestV2 추가 - 러닝 경로 공통 응답, 요쳥 형식 DTO 추가 * Feat: 러닝 결과 저장 V2(서비스) 리턴 DTO 추가 * Feat: 러닝 결과 저장 V2 서비스단 구현 * Test: 러닝 결과 저장 V2 서비스단 구현 테스트(러닝 경로 확인 테스트) * add-running-new * Feat: 러닝 결과 저장 V2 구현(Controller) * Fix: altitude Nan값으로 저장 애러 수정(현재 고도값은 저장하지 않음으로, 기본 값을 0으로 설정) * Test: 러닝 결과 추가에 대한(V2) request mapping, response 확인 테스트 코드
- Loading branch information
Showing
10 changed files
with
635 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
41 changes: 41 additions & 0 deletions
41
src/main/java/com/dnd/runus/application/running/dto/RunningResultDto.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package com.dnd.runus.application.running.dto; | ||
|
||
|
||
import com.dnd.runus.domain.challenge.achievement.ChallengeAchievement; | ||
import com.dnd.runus.domain.goalAchievement.GoalAchievement; | ||
import com.dnd.runus.domain.running.RunningRecord; | ||
|
||
public record RunningResultDto( | ||
RunningRecord runningRecord, | ||
com.dnd.runus.presentation.v1.running.dto.request.RunningAchievementMode runningAchievementMode, | ||
ChallengeAchievement challengeAchievement, | ||
GoalAchievement goalAchievement | ||
) { | ||
public static RunningResultDto from(RunningRecord runningRecord) { | ||
return new RunningResultDto( | ||
runningRecord, | ||
com.dnd.runus.presentation.v1.running.dto.request.RunningAchievementMode.NORMAL, | ||
null, | ||
null | ||
); | ||
} | ||
|
||
public static RunningResultDto of(RunningRecord runningRecord, | ||
ChallengeAchievement challengeAchievement) { | ||
return new RunningResultDto( | ||
runningRecord, | ||
com.dnd.runus.presentation.v1.running.dto.request.RunningAchievementMode.CHALLENGE, | ||
challengeAchievement, | ||
null | ||
); | ||
} | ||
|
||
public static RunningResultDto of(RunningRecord runningRecord, GoalAchievement goalAchievement) { | ||
return new RunningResultDto( | ||
runningRecord, | ||
com.dnd.runus.presentation.v1.running.dto.request.RunningAchievementMode.GOAL, | ||
null, | ||
goalAchievement | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
20 changes: 20 additions & 0 deletions
20
src/main/java/com/dnd/runus/presentation/v2/running/dto/RouteDtoV2.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package com.dnd.runus.presentation.v2.running.dto; | ||
|
||
|
||
import com.dnd.runus.domain.common.CoordinatePoint; | ||
|
||
/** | ||
* 클라이언트와의 러닝 경로 요청/응답 형식 | ||
* @param start 시작 위치 | ||
* @param end 종료 위치 | ||
*/ | ||
public record RouteDtoV2( | ||
Point start, | ||
Point end | ||
) { | ||
public record Point(double longitude, double latitude) { | ||
public static Point from(CoordinatePoint point) { | ||
return new Point(point.longitude(), point.longitude()); | ||
} | ||
} | ||
} |
98 changes: 98 additions & 0 deletions
98
src/main/java/com/dnd/runus/presentation/v2/running/dto/request/RunningRecordRequestV2.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
package com.dnd.runus.presentation.v2.running.dto.request; | ||
|
||
|
||
import com.dnd.runus.global.constant.RunningEmoji; | ||
import com.dnd.runus.global.exception.BusinessException; | ||
import com.dnd.runus.global.exception.type.ErrorType; | ||
import com.dnd.runus.presentation.v2.running.dto.RouteDtoV2; | ||
import io.swagger.v3.oas.annotations.media.Schema; | ||
import jakarta.validation.constraints.NotBlank; | ||
import jakarta.validation.constraints.NotNull; | ||
import java.time.Duration; | ||
import java.time.LocalDateTime; | ||
import java.util.List; | ||
|
||
public record RunningRecordRequestV2( | ||
@NotNull | ||
LocalDateTime startAt, | ||
@NotNull | ||
LocalDateTime endAt, | ||
@NotBlank | ||
@Schema(description = "시작 위치", example = "서울시 강남구") | ||
String startLocation, | ||
@NotBlank | ||
@Schema(description = "종료 위치", example = "서울시 송파구") | ||
String endLocation, | ||
@NotNull | ||
@Schema(description = "감정 표현, very-good: 최고, good: 좋음, soso: 보통, bad: 나쁨, very-bad: 최악") | ||
RunningEmoji emotion, | ||
@NotNull | ||
@Schema(description = "목표 달성 모드, normal: 목표 설정X, challenge: 챌린지, goal: 개인 목표") | ||
com.dnd.runus.presentation.v1.running.dto.request.RunningAchievementMode achievementMode, | ||
@Schema(description = "챌린지 데이터, 챌린지를 하지 않은 경우 null이나 필드 없이 보내주세요") | ||
ChallengeAchievedDto challengeValues, | ||
@Schema(description = "목표 데이터, 목표를 설정하지 않은 경우 null이나 필드 없이 보내주세요") | ||
GoalAchievedDto goalValues, | ||
@NotNull | ||
RunningRecordMetrics runningData | ||
) { | ||
public RunningRecordRequestV2 { | ||
//request valid check | ||
//시작, 종료 시간 유효값 확인 | ||
if (startAt.isAfter(endAt)) { | ||
throw new BusinessException(ErrorType.START_AFTER_END, startAt + " ~ " + endAt); | ||
} | ||
|
||
// 러닝 모드 유요성 확인 | ||
if (achievementMode == com.dnd.runus.presentation.v1.running.dto.request.RunningAchievementMode.CHALLENGE && challengeValues == null) { | ||
throw new BusinessException(ErrorType.CHALLENGE_VALUES_REQUIRED_IN_CHALLENGE_MODE); | ||
} | ||
|
||
if (achievementMode == com.dnd.runus.presentation.v1.running.dto.request.RunningAchievementMode.GOAL) { | ||
if(goalValues == null) { | ||
throw new BusinessException(ErrorType.GOAL_VALUES_REQUIRED_IN_GOAL_MODE); | ||
} | ||
if (goalValues.goalDistance() == null && goalValues.goalTime() == null) { | ||
throw new BusinessException(ErrorType.GOAL_TIME_AND_DISTANCE_BOTH_EXIST); | ||
} | ||
} | ||
|
||
//러닝 경로 유요성 확인 | ||
if(runningData.route() == null || runningData.route().size() < 2) { | ||
throw new BusinessException(ErrorType.ROUTE_MUST_HAVE_AT_LEAST_TWO_COORDINATES); | ||
} | ||
} | ||
|
||
public record ChallengeAchievedDto( | ||
@Schema(description = "챌린지 ID", example = "1") | ||
long challengeId, | ||
boolean isSuccess | ||
) { | ||
} | ||
|
||
public record GoalAchievedDto( | ||
@Schema(description = "개인 목표 거리 (미터), 거리 목표가 아닌 경우, null이나 필드 없이 보내주세요", example = "5000") | ||
Integer goalDistance, | ||
@Schema(description = "개인 목표 시간 (초), 시간 목표가 아닌 경우, null이나 필드 없이 보내주세요", example = "1800") | ||
Integer goalTime, | ||
boolean isSuccess | ||
) { | ||
} | ||
|
||
@Schema(name = "RunningRecordMetrics for Add V2") | ||
public record RunningRecordMetrics( | ||
@NotNull | ||
@Schema(description = "멈춘 시간을 제외한 실제로 달린 시간", example = "123:45:56", format = "HH:mm:ss") | ||
Duration runningTime, | ||
@Schema(description = "달린 거리(m)", example = "1000") | ||
@NotNull | ||
int distanceMeter, | ||
@Schema(description = "소모 칼로리(kcal)", example = "100") | ||
@NotNull | ||
double calorie, | ||
@NotNull | ||
@Schema(description = "러닝 경로, 최소, 경로는 최소 2개의 좌표를 가져야합니다.") | ||
List<RouteDtoV2> route | ||
) { | ||
} | ||
} |
Oops, something went wrong.