Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
3c15f37
[SCRUM-212] FEAT: Spot 관련 Entity 생성 (#75)
moonxxpower Jul 31, 2025
446116d
[SCRUM-212] FEAT: 국문 관광정보 API 요청 기능 추가 (#75)
moonxxpower Jul 31, 2025
c323027
[SCRUM-212] FEAT: 위치기반 관광정보 API 호출을 통한 장소 externalId 수집 (#75)
moonxxpower Jul 31, 2025
befd967
[SCRUM-212] FEAT: 공통정보 조회 API에서 Spot 관련 데이터 DB에 저장 (#75)
moonxxpower Jul 31, 2025
624da3f
[SCRUM-212] FEAT: Spot 관련 테이블 생성 DDL 추가 (#75)
moonxxpower Aug 1, 2025
f1ea182
[SCRUM-212] 국문 관광정보 측으로부터 받은 이미지 URL을 AWS S3에 업로드 (#75)
moonxxpower Aug 2, 2025
8274285
[SCRUM-212] TEST: 즐길거리 수정 API 관련 테스트 코드 작성 (#75)
moonxxpower Aug 3, 2025
e26c619
[SCRUM-212] COMMENT: 잘못된 주석 수정 (#75)
moonxxpower Aug 3, 2025
0815991
[SCRUM-212] REFACTOR: Spot 패키지 분리 및 SpotCategory Enum 이름 변경 (#75)
moonxxpower Aug 7, 2025
a58c939
[SCRUM-212] REFACTOR: RoadCondition, CourseImage, Spot 객체 생성 방식을 Buil…
moonxxpower Aug 7, 2025
d60bf53
[SCRUM-212] FEAT: API 응답값 필드 유효성 검사 추가 (#75)
moonxxpower Aug 7, 2025
33ff296
FIX: 두루누비 동기화 API 로직 수정 (#93)
ssggii Aug 9, 2025
3aaa0a8
FEAT: 두루누비 코스 동기화 스케줄러 등록 (#93)
ssggii Aug 9, 2025
0e09bfa
[SCRUM-212] FEAT: API 호출 병렬 처리되게 추가 (#75)
moonxxpower Aug 9, 2025
ccc2852
Merge branch 'develop' into SCRUM-212-국문관광정보-API-연동
moonxxpower Aug 9, 2025
5a41e70
Merge pull request #79 from RunChuck/SCRUM-212-국문관광정보-API-연동
moonxxpower Aug 9, 2025
7c240c4
COMMENT: CourseScheduler의 주석 수정 (#93)
ssggii Aug 10, 2025
2f57812
MERGE: develop 브랜치와의 충돌 해결 (#93)
ssggii Aug 10, 2025
a0d534c
Merge pull request #94 from RunChuck/hotfix/두루누비-동기화-API-스케줄러-등록
ssggii Aug 10, 2025
fb9e8d5
[SCRUM-235] 내 리뷰 조회 API 구현 (#95)
ssggii Aug 10, 2025
016c443
[SCRUM-235] TEST: 내 리뷰 조회 테스트 코드 구현 (#95)
ssggii Aug 10, 2025
f4dda9f
[SCRUM-236] FEAT: 북마크한 코스 조회 API 구현 (#96)
ssggii Aug 10, 2025
3dc59a8
[SCRUM-236] TEST: 북마크한 코스 조회 API 테스트 코드 구현 (#96)
ssggii Aug 11, 2025
01b45af
[SCRUM-228] FEAT: 즐길거리 전체 조회 API 구현 (#80)
moonxxpower Aug 11, 2025
0b3263b
[SCRUM-228] TEST: 즐길거리 전체 조회 API 관련 테스트 코드 작성 (#80)
moonxxpower Aug 11, 2025
8bc5add
[SCRUM-228] FEAT: 코스 요약 조회 API에 즐길거리 정보 추가 (#80)
moonxxpower Aug 11, 2025
597b99e
[SCRUM-228] 코스 요약 조회 API 수정 (#80)
ssggii Aug 12, 2025
5a5ecc9
[SCRUM-228] FIX: 코스 요약 조회의 리뷰 순서 수정 (#80)
ssggii Aug 12, 2025
b39b452
[SCRUM-239] FEAT: 닉네임 중복 조회 API 구현 (#99)
moonxxpower Aug 12, 2025
af40ecd
[SCRUM-239] FEAT: 내 정보 수정 API 구현 (#99)
moonxxpower Aug 12, 2025
103c584
[SCRUM-239] TEST: 닉네임 유효성 검증 메서드 관련 테스트 코드 작성 (#99)
moonxxpower Aug 12, 2025
762802b
[SCRUM-239] TEST: 닉네임 중복 여부 조회 API 관련 테스트 코드 작성 (#99)
moonxxpower Aug 12, 2025
9591c4f
[SCRUM-239] TEST: 내 정보 수정 API 관련 테스트 코드 작성 (#99)
moonxxpower Aug 12, 2025
98309de
[SCRUM-239] REFACTOR: 닉네임 유효성 검증 정규식 패턴 상수화 (#99)
moonxxpower Aug 12, 2025
f14b503
[SCRUM-235] CHORE: 내 리뷰 조회 API 엔드포인트 수정 (#95)
ssggii Aug 13, 2025
c61b165
[SCRUM-235] FIX: 내 리뷰 조회 시 리뷰 정렬 조건 추가 (#95)
ssggii Aug 13, 2025
0e9f581
[SCRUM-236] CHORE: 북마크한 코스 조회 API 엔드포인트 수정 (#96)
ssggii Aug 13, 2025
9c50650
[SCRUM-236] FIX: 북마크한 코스 조회 시 코스 정렬 조건 추가 (#96)
ssggii Aug 13, 2025
f7f042b
Merge pull request #97 from RunChuck/SCRUM-235-내-리뷰-조회-API-구현
ssggii Aug 13, 2025
027afa4
Merge pull request #98 from RunChuck/SCRUM-236-북마크한-코스-조회-API-구현
ssggii Aug 13, 2025
4d28cd8
[SCRUM-240] RENAME: BookmarkCountDto, BookmarkInfoDto 위치 변경 (#101)
ssggii Aug 13, 2025
a1d4598
[SCRUM-228] RENAME: JPA 메서드명 변경 (#88)
moonxxpower Aug 14, 2025
e595ebf
[SCRUM-228] REFACTOR: Course 객체 생성하지 않도록 변경 (#88)
moonxxpower Aug 14, 2025
9c44964
[SCRUM-228] REFACTOR: DTO 생성 로직 서비스로부터 분리 (#88)
moonxxpower Aug 14, 2025
3af7e6f
Merge branch 'develop' into SCRUM-228-즐길거리-전체-조회-API-구현
moonxxpower Aug 14, 2025
9b47fde
Merge pull request #100 from RunChuck/SCRUM-228-즐길거리-전체-조회-API-구현
moonxxpower Aug 14, 2025
e38430d
[SCRUM-239] REFACTOR: 닉네임 최소, 최대 길이 상수 처리 (#99)
moonxxpower Aug 14, 2025
d1d8658
[SCRUM-239] FEAT: @Valid, @Validated 입력값 검증 추가 (#99)
moonxxpower Aug 14, 2025
c3b6982
Merge pull request #102 from RunChuck/SCRUM-239-내-정보-수정-API-구현
moonxxpower Aug 14, 2025
710780c
FIX: AWS S3 저장 시 영문 파일명으로 저장되게 변경 (#105)
moonxxpower Aug 15, 2025
1968829
[SCRUM-240] FEAT: 내 정보 조회에서 기본 정보 조회 구현 (#101)
ssggii Aug 15, 2025
2b8e506
[SCRUM-240] CHORE: 빌드 에러 수정 (#101)
ssggii Aug 15, 2025
b5a9dae
[SCRUM-240] MERGE: develop 브랜치와의 충돌 해결 (#101)
ssggii Aug 15, 2025
1e02e83
Merge pull request #106 from RunChuck/hotfix/aws-s3-filename
ssggii Aug 15, 2025
32d474f
Merge pull request #107 from RunChuck/SCRUM-240-내-정보-조회-API-구현
ssggii Aug 15, 2025
71a9973
FIX: 기존 API 응답의 코스 길이, 고도값을 자연수 형태로 수정 (#103)
ssggii Aug 15, 2025
756bcd5
MERGE: 5차 스프린트 마감
ssggii Aug 15, 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
3 changes: 3 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ MYSQL_ROOT_PASSWORD=
# Durunubi API key
DURUNUBI_SERVICE_KEY=

# Spot API Key
SPOT_SERVICE_KEY=

# OpenAI API Key
OPENAI_API_KEY=

Expand Down
1 change: 1 addition & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ services:
- SPRING_DATASOURCE_USERNAME=${SPRING_DATASOURCE_USERNAME}
- SPRING_DATASOURCE_PASSWORD=${SPRING_DATASOURCE_PASSWORD}
- DURUNUBI_SERVICE_KEY=${DURUNUBI_SERVICE_KEY}
- SPOT_SERVICE_KEY=${SPOT_SERVICE_KEY}
- OPENAI_API_KEY=${OPENAI_API_KEY}
- S3_ACCESS_KEY=${S3_ACCESS_KEY}
- S3_SECRET_KEY=${S3_SECRET_KEY}
Expand Down
43 changes: 41 additions & 2 deletions sql/V1_create_course_related_tables.sql
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,46 @@ create table track_point
foreign key (course_id) references course (course_id)
);

-- 8. review 테이블 생성
-- 8. spot 테이블 생성
create table spot (
spot_id BIGINT AUTO_INCREMENT PRIMARY KEY,
external_id VARCHAR(255) NOT NULL UNIQUE,
name VARCHAR(255) NOT NULL,
address VARCHAR(255) NOT NULL,
description TEXT,
category ENUM('NATURE', 'HISTORY', 'RECREATION', 'EXPERIENCE', 'INDUSTRIAL', 'ARCHITECTURE',
'KOREAN_FOOD', 'WESTERN_FOOD', 'JAPANESE_FOOD', 'CHINESE_FOOD', 'GLOBAL_FOOD',
'CAFE', 'CLUB', 'UNKNOWN') NOT NULL,
lat DOUBLE NOT NULL,
lon DOUBLE NOT NULL,
created_at DATETIME(6) NOT NULL,
updated_at DATETIME(6) NOT NULL
);

-- 9. course_spot 테이블 생성
CREATE TABLE course_spot (
course_spot_id BIGINT AUTO_INCREMENT PRIMARY KEY,
course_id BIGINT NOT NULL,
spot_id BIGINT NOT NULL,
created_at DATETIME(6) NOT NULL,
updated_at DATETIME(6) NOT NULL,
CONSTRAINT course_spot_uk UNIQUE (course_id, spot_id),
CONSTRAINT fk_course FOREIGN KEY (course_id) REFERENCES course(course_id),
CONSTRAINT fk_spot FOREIGN KEY (spot_id) REFERENCES spot(spot_id)
);

-- 10. spot_image 테이블 생성
CREATE TABLE spot_image (
spot_img_id BIGINT AUTO_INCREMENT PRIMARY KEY,
img_url VARCHAR(255) NOT NULL,
original_url VARCHAR(255) NOT NULL,
spot_id BIGINT NOT NULL UNIQUE,
created_at DATETIME(6) NOT NULL,
updated_at DATETIME(6) NOT NULL,
CONSTRAINT fk_spot_image_spot FOREIGN KEY (spot_id) REFERENCES spot(spot_id)
);

-- 11. review 테이블 생성
create table review
(
review_id bigint auto_increment
Expand All @@ -138,4 +177,4 @@ create table review
ALTER TABLE course DROP COLUMN tour_point;

-- course 테이블의 distance 컬럼 타입 변경
ALTER TABLE course MODIFY COLUMN distance DOUBLE NOT NULL;
ALTER TABLE course MODIFY COLUMN distance DOUBLE NOT NULL;
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;

@EnableAsync
@EnableJpaAuditing
@EnableScheduling
@SpringBootApplication
public class RunningHandaiApplication {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.server.running_handai.domain.bookmark.controller;

import com.server.running_handai.domain.bookmark.dto.BookmarkedCourseInfoDto;
import com.server.running_handai.domain.bookmark.service.BookmarkService;
import com.server.running_handai.domain.course.entity.Area;
import com.server.running_handai.global.oauth.CustomOAuth2User;
import com.server.running_handai.global.response.CommonResponse;
import com.server.running_handai.global.response.ResponseCode;
Expand All @@ -9,20 +11,21 @@
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/courses/{courseId}/bookmarks")
@Tag(name = "Bookmark", description = "북마크 관련 API")
public class BookmarkController {

Expand All @@ -35,7 +38,7 @@ public class BookmarkController {
@ApiResponse(responseCode = "400", description = "실패 (이미 북마크한 코스)"),
@ApiResponse(responseCode = "401", description = "실패 (인증 실패)")
})
@PostMapping
@PostMapping("/api/courses/{courseId}/bookmarks")
public ResponseEntity<CommonResponse<?>> registerBookmark(
@Parameter(description = "북마크 대상 코스", required = true) @PathVariable Long courseId,
@AuthenticationPrincipal CustomOAuth2User customOAuth2User
Expand All @@ -54,7 +57,7 @@ public ResponseEntity<CommonResponse<?>> registerBookmark(
@ApiResponse(responseCode = "404", description = "실패 (존재하지 않는 북마크)"),
@ApiResponse(responseCode = "401", description = "실패 (인증 실패)")
})
@DeleteMapping
@DeleteMapping("/api/courses/{courseId}/bookmarks")
public ResponseEntity<CommonResponse<?>> deleteBookmark(
@Parameter(description = "북마크 대상 코스", required = true) @PathVariable Long courseId,
@AuthenticationPrincipal CustomOAuth2User customOAuth2User
Expand All @@ -66,4 +69,25 @@ public ResponseEntity<CommonResponse<?>> deleteBookmark(
return ResponseEntity.ok(CommonResponse.success(ResponseCode.SUCCESS_BOOKMARK_DELETE, null));
}

@Operation(summary = "북마크한 코스 조회", description = "회원이 북마크한 코스를 조회합니다. 코스의 지역으로 조건 검색이 가능합니다.")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "성공"),
@ApiResponse(responseCode = "200", description = "성공 (북마크한 코스 없음)"),
@ApiResponse(responseCode = "400", description = "실패 (요청 파라미터 오류)"),
@ApiResponse(responseCode = "401", description = "실패 (인증 실패)")
})
@GetMapping("/api/members/me/courses/bookmarks")
public ResponseEntity<CommonResponse<?>> getBookmarkedCourses(
@Parameter(description = "지역 조건 (전체 보기인 경우 null)")
@RequestParam(required = false) Area area,
@AuthenticationPrincipal CustomOAuth2User customOAuth2User
) {
Long memberId = customOAuth2User.getMember().getId();
log.info("[북마크한 코스 조회] memberId={}, area={}", memberId, (area != null) ? area.name() : null);
List<BookmarkedCourseInfoDto> responseData = bookmarkService.getBookmarkedCoursesByMemberAndArea(memberId, area);
if (responseData.isEmpty()) {
return ResponseEntity.ok(CommonResponse.success(ResponseCode.SUCCESS_EMPTY_BOOKMARKS, responseData));
}
return ResponseEntity.ok(CommonResponse.success(ResponseCode.SUCCESS, responseData));
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.server.running_handai.domain.course.dto;
package com.server.running_handai.domain.bookmark.dto;

public record BookmarkCountDto(Long courseId, Long bookmarkCount) {
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.server.running_handai.domain.course.dto;
package com.server.running_handai.domain.bookmark.dto;

public record BookmarkInfoDto(int totalCount, boolean isBookmarked) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.server.running_handai.domain.bookmark.dto;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

@JsonPropertyOrder({
"bookmarkId",
"courseId",
"thumbnailUrl",
"distance",
"duration",
"maxElevation",
"isBookmarked",
"bookmarkCount"
})
public interface BookmarkedCourseInfoDto {
long getBookmarkId();
long getCourseId();
String getThumbnailUrl();

@JsonIgnore
double getRawDistance();

default int getDistance() {
return (int) getRawDistance();
}

int getDuration();

@JsonIgnore
double getRawMaxElevation(); // JPA 전용

default int getMaxElevation() { // 클라이언트 전용
return (int) getRawMaxElevation();
}

boolean getIsBookmarked();
int getBookmarkCount();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.server.running_handai.domain.bookmark.dto;

public record MyBookmarkInfoDto(
String courseThumbnailUrl,
int bookmarkCount,
boolean isBookmarked
) {
public static MyBookmarkInfoDto from(String courseThumbnailUrl, int bookmarkCount, boolean isBookmarked) {
return new MyBookmarkInfoDto(courseThumbnailUrl, bookmarkCount, isBookmarked);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.server.running_handai.domain.bookmark.repository;

import com.server.running_handai.domain.bookmark.dto.BookmarkedCourseInfoDto;
import com.server.running_handai.domain.bookmark.entity.Bookmark;
import com.server.running_handai.domain.course.dto.BookmarkCountDto;
import com.server.running_handai.domain.bookmark.dto.BookmarkCountDto;
import com.server.running_handai.domain.course.entity.Area;
import com.server.running_handai.domain.course.entity.Course;
import com.server.running_handai.domain.member.entity.Member;
import java.util.List;
Expand All @@ -23,15 +25,51 @@ public interface BookmarkRepository extends JpaRepository<Bookmark, Long> {
int countByCourseId(Long courseId);

// 코스 ID별 북마크 수 조회
@Query("SELECT new com.server.running_handai.domain.course.dto.BookmarkCountDto(b.course.id, COUNT(b)) "
@Query("SELECT new com.server.running_handai.domain.bookmark.dto.BookmarkCountDto(b.course.id, COUNT(b)) "
+ "FROM Bookmark b "
+ "WHERE b.course.id "
+ "IN :courseIds "
+ "GROUP BY b.course.id")
List<BookmarkCountDto> countByCourseIdIn(@Param("courseIds") List<Long> courseIds);

// 사용자가 북마크한 코스 ID 목록 조회
// 코스 목록 중에서 사용자가 북마크한 코스 조회
@Query("SELECT b.course.id FROM Bookmark b WHERE b.course.id IN :courseIds AND b.member.id = :memberId")
Set<Long> findBookmarkedCourseIdsByMember(@Param("courseIds") List<Long> courseIds, @Param("memberId") Long memberId);

// 사용자가 북마크한 모든 코스 조회
@Query("SELECT "
+ "b.id AS bookmarkId, "
+ "c.id AS courseId, "
+ "ci.imgUrl AS thumbnailUrl, "
+ "c.distance AS rawDistance, "
+ "c.duration AS duration, "
+ "c.maxElevation AS rawMaxElevation, "
+ "true AS isBookmarked, "
+ "(SELECT count(b2.id) FROM Bookmark b2 WHERE b2.course.id = c.id) AS bookmarkCount " // 총 북마크 수 계산
+ "FROM Bookmark b "
+ "LEFT JOIN b.course c "
+ "LEFT JOIN c.courseImage ci "
+ "WHERE b.member.id = :memberId "
+ "ORDER BY b.createdAt DESC "
)
List<BookmarkedCourseInfoDto> findBookmarkedCoursesByMemberId(Long memberId);

// 사용자가 북마크한 코스 중에서 특정 지역의 코스만 조회
@Query("SELECT "
+ "b.id AS bookmarkId, "
+ "c.id AS courseId, "
+ "ci.imgUrl AS thumbnailUrl, "
+ "c.distance AS rawDistance, "
+ "c.duration AS duration, "
+ "c.maxElevation AS rawMaxElevation, "
+ "true AS isBookmarked, "
+ "(SELECT count(b2.id) FROM Bookmark b2 WHERE b2.course.id = c.id) AS bookmarkCount " // 총 북마크 수 계산
+ "FROM Bookmark b "
+ "LEFT JOIN b.course c "
+ "LEFT JOIN c.courseImage ci "
+ "WHERE b.member.id = :memberId "
+ "AND c.area = :area "
+ "ORDER BY b.createdAt DESC "
)
List<BookmarkedCourseInfoDto> findBookmarkedCoursesByMemberIdAndArea(Long memberId, Area area);
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
package com.server.running_handai.domain.bookmark.service;

import com.server.running_handai.domain.bookmark.dto.BookmarkedCourseInfoDto;
import com.server.running_handai.domain.bookmark.entity.Bookmark;
import com.server.running_handai.domain.bookmark.repository.BookmarkRepository;
import com.server.running_handai.domain.course.entity.Area;
import com.server.running_handai.domain.course.entity.Course;
import com.server.running_handai.domain.course.repository.CourseRepository;
import com.server.running_handai.global.response.ResponseCode;
import com.server.running_handai.global.response.exception.BusinessException;
import com.server.running_handai.domain.member.entity.Member;
import com.server.running_handai.domain.member.repository.MemberRepository;
import java.util.Collections;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class BookmarkService {

private final BookmarkRepository bookmarkRepository;
Expand Down Expand Up @@ -53,4 +58,25 @@ public void deleteBookmark(Long memberId, Long courseId) {
// 북마크 삭제
bookmarkRepository.delete(bookmark);
}

/**
* 회원이 북마크한 코스를 조회합니다.
*
* @param memberId 요청한 회원의 ID
* @return 북마크한 코스 정보 DTO
*/
public List<BookmarkedCourseInfoDto> getBookmarkedCoursesByMemberAndArea(Long memberId, Area area) {
List<BookmarkedCourseInfoDto> bookmarkedCourseInfoDtos;
if (area == null) { // 지역 전체인 경우
bookmarkedCourseInfoDtos = bookmarkRepository.findBookmarkedCoursesByMemberId(memberId);
} else { // 특정 지역 필터링한 경우
bookmarkedCourseInfoDtos = bookmarkRepository.findBookmarkedCoursesByMemberIdAndArea(memberId, area);
}

if (bookmarkedCourseInfoDtos.isEmpty()) {
return Collections.emptyList();
}

return bookmarkedCourseInfoDtos;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@ public ResponseEntity<CommonResponse<?>> updateRoadConditions(@PathVariable Long

@PutMapping(value = "/{courseId}/image", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<CommonResponse<?>> updateCourseImage(@PathVariable Long courseId,
@RequestParam MultipartFile courseImageFile) throws IOException {
@RequestParam MultipartFile courseImageFile) {
courseDataService.updateCourseImage(courseId, courseImageFile);
return ResponseEntity.ok().body(CommonResponse.success(ResponseCode.SUCCESS, null));
}

@PostMapping(value = "/gpx", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<CommonResponse<?>> createCourseToGpx(@RequestPart("courseInfo") GpxCourseRequestDto gpxCourseRequestDto,
@RequestParam("courseGpxFile") MultipartFile courseGpxFile) throws IOException {
@RequestParam("courseGpxFile") MultipartFile courseGpxFile) {
courseDataService.createCourseToGpx(gpxCourseRequestDto, courseGpxFile);
return ResponseEntity.ok().body(CommonResponse.success(ResponseCode.SUCCESS, null));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package com.server.running_handai.domain.course.dto;

import com.server.running_handai.domain.bookmark.dto.BookmarkInfoDto;
import com.server.running_handai.domain.course.entity.Course;
import com.server.running_handai.domain.course.entity.RoadCondition;
import java.util.List;

public record CourseDetailDto(
Long courseId,
String courseName,
double distance,
int distance,
int duration,
int minElevation,
int maxElevation,
Expand All @@ -24,7 +25,7 @@ public static CourseDetailDto from(Course course, List<TrackPointDto> trackPoint
return new CourseDetailDto(
course.getId(),
course.getName(),
course.getDistance(),
(int) course.getDistance(),
course.getDuration(),
(int) course.getMinElevation().doubleValue(),
(int) course.getMaxElevation().doubleValue(),
Expand Down
Loading
Loading