From 4a1494abea438f24b3e65604c96cb194539aaf20 Mon Sep 17 00:00:00 2001 From: junhokim Date: Sun, 1 Mar 2026 17:50:47 +0900 Subject: [PATCH 1/2] =?UTF-8?q?feat.=20Update=20=EA=B0=9C=EB=B0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trip/application/in/TripService.java | 39 ++++++++-- .../in/request/TripUpdateRequest.java | 74 ++++++++++++++++++ .../in/response/TripUpdateResponse.java | 78 +++++++++++++++++++ .../in/usecase/TripManageUseCase.java | 4 + .../com/retrip/trip/domain/entity/Trip.java | 49 ++++++++++-- .../exception/TripUpdateFailedException.java | 12 +++ .../domain/exception/common/ErrorCode.java | 7 +- .../in/presentation/rest/TripController.java | 15 +++- src/main/resources/data.sql | 7 +- 9 files changed, 265 insertions(+), 20 deletions(-) create mode 100644 src/main/java/com/retrip/trip/application/in/request/TripUpdateRequest.java create mode 100644 src/main/java/com/retrip/trip/application/in/response/TripUpdateResponse.java create mode 100644 src/main/java/com/retrip/trip/domain/exception/TripUpdateFailedException.java diff --git a/src/main/java/com/retrip/trip/application/in/TripService.java b/src/main/java/com/retrip/trip/application/in/TripService.java index 093103c..5ff7aa1 100644 --- a/src/main/java/com/retrip/trip/application/in/TripService.java +++ b/src/main/java/com/retrip/trip/application/in/TripService.java @@ -4,17 +4,15 @@ import com.retrip.trip.application.in.response.*; import com.retrip.trip.application.in.usecase.*; import com.retrip.trip.application.out.crypto.TripPasswordEncoder; -import com.retrip.trip.application.out.repository.*; -import com.retrip.trip.domain.entity.Itinerary; -import com.retrip.trip.domain.entity.Trip; -import com.retrip.trip.domain.entity.TripConfirmationDemand; +import com.retrip.trip.application.out.repository.TripConfirmationDemandRepository; +import com.retrip.trip.application.out.repository.TripItineraryQueryRepository; +import com.retrip.trip.application.out.repository.TripQueryRepository; +import com.retrip.trip.application.out.repository.TripRepository; import com.retrip.trip.domain.entity.*; import com.retrip.trip.domain.exception.TripNotFoundException; import com.retrip.trip.domain.exception.common.BusinessException; import com.retrip.trip.domain.exception.common.InvalidValueException; -import com.retrip.trip.domain.vo.TripPassword; -import com.retrip.trip.domain.vo.TripPeriod; -import com.retrip.trip.domain.vo.TripStatus; +import com.retrip.trip.domain.vo.*; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; @@ -56,6 +54,31 @@ public TripCreateResponse createTripWithItineraries(UUID memberId, TripCreateReq return TripCreateResponse.of(savedTrip); } + @Override + public TripUpdateResponse updateTrip(UUID memberId, UUID tripId, TripUpdateRequest request) { + Trip trip = findTrip(tripId); + + TripTitle tripTitle = request.toTripTitle(); + TripDescription tripDescription = request.toTripDescription(); + TripPeriod tripPeriod = request.toTripPeriod(); + TripHashTags tripHashTags = request.toHashTags(trip); + + //List itineraries = tripItineraryQueryRepository.findByIdsWithItineraryDetails(trip.getItinerariesIds()); + trip.update( + memberId, + request.locationId(), + tripTitle, + tripDescription, + tripHashTags, + request.maxParticipants(), + request.imageUrl(), + request.category() + ); + trip.updatePeriod(tripPeriod, memberId); + + return TripUpdateResponse.of(trip); + } + @Override public TripUpdateVisibilityResponse updateTripVisibility(UUID tripId, TripUpdateVisibilityRequest request) { Trip trip = findTrip(tripId); @@ -70,7 +93,7 @@ public Page getTrips(Pageable page) { Page tripsPage = tripQueryRepository.findTrips(page); List trips = tripsPage.getContent(); List hashTags = tripQueryRepository.findHashTags(trips); - + return new PageImpl<>(TripResponse.of(trips, hashTags), page, tripsPage.getTotalElements()); } diff --git a/src/main/java/com/retrip/trip/application/in/request/TripUpdateRequest.java b/src/main/java/com/retrip/trip/application/in/request/TripUpdateRequest.java new file mode 100644 index 0000000..ccbb2f7 --- /dev/null +++ b/src/main/java/com/retrip/trip/application/in/request/TripUpdateRequest.java @@ -0,0 +1,74 @@ +package com.retrip.trip.application.in.request; + +import com.retrip.trip.domain.entity.Trip; +import com.retrip.trip.domain.entity.TripHashTags; +import com.retrip.trip.domain.vo.*; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.FutureOrPresent; +import jakarta.validation.constraints.NotNull; + +import java.time.LocalDate; +import java.util.List; +import java.util.UUID; + +@Schema(description = "여행 수정 Request") +public record TripUpdateRequest( + @Schema(description = "여행 제목", example = "유럽 배낭여행") + @NotNull + String title, + + @Schema(description = "여행 설명", example = "파리, 런던, 로마를 여행하는 일정입니다.") + String description, + + @Schema(description = "여행 위치 ID", example = "550e8400-e29b-41d4-a716-446655440001") + @NotNull + UUID locationId, + + @Schema(description = "여행 시작 날짜", example = "2025-06-15") + @FutureOrPresent + LocalDate start, + + @Schema(description = "여행 종료 날짜", example = "2025-06-25") + @FutureOrPresent + LocalDate end, + + @Schema(description = "여행 최대 참가 인원") + Integer maxParticipants, + + @Schema(description = "HashTag") + List hashTags, + + @Schema(description = "여행 대표 이미지 URL") + String imageUrl, + + @Schema(description = "여행 카테고리") + TripCategory category +) { + public TripTitle toTripTitle() { + if (title != null) { + return new TripTitle(title); + } + return null; + } + + public TripDescription toTripDescription() { + if (description != null) { + return new TripDescription(description); + } + return null; + } + + public TripPeriod toTripPeriod() { + if (start != null && end != null) { + return new TripPeriod(start, end); + } + return null; + } + + public TripHashTags toHashTags(Trip trip) { + if (hashTags != null) { + return new TripHashTags(trip, hashTags); + } + return null; + } +} diff --git a/src/main/java/com/retrip/trip/application/in/response/TripUpdateResponse.java b/src/main/java/com/retrip/trip/application/in/response/TripUpdateResponse.java new file mode 100644 index 0000000..428b375 --- /dev/null +++ b/src/main/java/com/retrip/trip/application/in/response/TripUpdateResponse.java @@ -0,0 +1,78 @@ +package com.retrip.trip.application.in.response; + +import com.retrip.trip.domain.entity.Trip; +import com.retrip.trip.domain.entity.TripHashTag; +import io.swagger.v3.oas.annotations.media.Schema; + +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +@Schema(description = "여행 생성 Response") +public record TripUpdateResponse( + @Schema(description = "여행 ID", example = "550e8400-e29b-41d4-a716-446655440000") + UUID id, + + @Schema(description = "여행 목적지 ID", example = "550e8400-e29b-41d4-a716-446655440001") + UUID destinationId, + + @Schema(description = "여행 제목", example = "파리 여행") + String title, + + @Schema(description = "여행 설명") + String description, + + @Schema(description = "여행 시작 날짜") + LocalDate start, + + @Schema(description = "여행 종료 날짜") + LocalDate end, + + @Schema(description = "여행 최대 참가 인원") + int maxParticipants, + + @Schema(description = "여행 카테고리") + List hashTags, + + @Schema(description = "여행 카테고리") + String category, + + @Schema(description = "여행 대표 이미지 url") + String imageUrl, + + @Schema(description = "여행 일정 리스트") + List itineraries +) { + public static TripUpdateResponse of(Trip trip) { + return new TripUpdateResponse( + trip.getId(), + trip.getDestinationId(), + trip.getTitle().getValue(), + trip.getDescription().getValue(), + trip.getPeriod().getStart(), + trip.getPeriod().getEnd(), + trip.getTripParticipants().getMaxParticipants(), + trip.getHashTags().getValues().stream().map(TripHashTag::getName).toList(), + trip.getCategory().getViewName(), + trip.getImageUrl(), + trip.getItineraries() == null ? new ArrayList<>() : + trip.getItineraries().getValues().stream() + .map(i -> new ItineraryUpdateResponse(i.getId(), i.getName(), i.getDate())) + .toList() + ); + } + + @Schema(description = "여행 일정 Response") + private record ItineraryUpdateResponse( + @Schema(description = "일정 ID") + UUID id, + + @Schema(description = "일정 이름") + String name, + + @Schema(description = "일정 날짜") + LocalDate date + ) { + } +} diff --git a/src/main/java/com/retrip/trip/application/in/usecase/TripManageUseCase.java b/src/main/java/com/retrip/trip/application/in/usecase/TripManageUseCase.java index 5cde42a..530289d 100644 --- a/src/main/java/com/retrip/trip/application/in/usecase/TripManageUseCase.java +++ b/src/main/java/com/retrip/trip/application/in/usecase/TripManageUseCase.java @@ -1,8 +1,10 @@ package com.retrip.trip.application.in.usecase; import com.retrip.trip.application.in.request.TripCreateRequest; +import com.retrip.trip.application.in.request.TripUpdateRequest; import com.retrip.trip.application.in.request.TripUpdateVisibilityRequest; import com.retrip.trip.application.in.response.TripCreateResponse; +import com.retrip.trip.application.in.response.TripUpdateResponse; import com.retrip.trip.application.in.response.TripUpdateVisibilityResponse; import java.util.List; @@ -13,6 +15,8 @@ public interface TripManageUseCase { TripCreateResponse createTripWithItineraries(UUID memberId, TripCreateRequest request); + TripUpdateResponse updateTrip(UUID memberId, UUID tripId, TripUpdateRequest request); + TripUpdateVisibilityResponse updateTripVisibility(UUID tripId, TripUpdateVisibilityRequest request); void banMembers(UUID memberId, UUID tripId, List memberIds); diff --git a/src/main/java/com/retrip/trip/domain/entity/Trip.java b/src/main/java/com/retrip/trip/domain/entity/Trip.java index 812d639..c64bb73 100644 --- a/src/main/java/com/retrip/trip/domain/entity/Trip.java +++ b/src/main/java/com/retrip/trip/domain/entity/Trip.java @@ -1,9 +1,6 @@ package com.retrip.trip.domain.entity; -import com.retrip.trip.domain.exception.LeaderCannotLeaveException; -import com.retrip.trip.domain.exception.NotParticipantException; -import com.retrip.trip.domain.exception.PeriodUpdateFailedException; -import com.retrip.trip.domain.exception.TripNotReadyException; +import com.retrip.trip.domain.exception.*; import com.retrip.trip.domain.exception.common.BusinessException; import com.retrip.trip.domain.vo.*; import jakarta.persistence.*; @@ -205,4 +202,46 @@ public void updateVisibility(boolean isOpen) { public boolean isNotTripRecruitingStatus() { return !TripStatus.RECRUITING.equals(status); } -} \ No newline at end of file + + + public void update( + UUID memberId, + UUID destinationId, + TripTitle tripTitle, + TripDescription tripDescription, + TripHashTags tripHashTags, + Integer maxParticipants, + String imageUrl, + TripCategory category + ) { + if (!tripParticipants.updatableByLeader(memberId)) { + throw new TripUpdateFailedException(); + } + + if (destinationId != null) { + this.destinationId = destinationId; + } + + if (tripTitle != null) { + this.title = tripTitle; + } + if (tripDescription != null) { + this.description = tripDescription; + } + + if (tripHashTags != null) { + this.hashTags.getValues().clear(); + this.hashTags.getValues().addAll(tripHashTags.getValues()); + } + + if (maxParticipants != null) { + this.tripParticipants.updateMaxParticipants(maxParticipants, memberId); + } + if (imageUrl != null) { + this.imageUrl = imageUrl; + } + if (category != null) { + this.category = category; + } + } +} diff --git a/src/main/java/com/retrip/trip/domain/exception/TripUpdateFailedException.java b/src/main/java/com/retrip/trip/domain/exception/TripUpdateFailedException.java new file mode 100644 index 0000000..7b1cdaa --- /dev/null +++ b/src/main/java/com/retrip/trip/domain/exception/TripUpdateFailedException.java @@ -0,0 +1,12 @@ +package com.retrip.trip.domain.exception; + +import com.retrip.trip.domain.exception.common.BusinessException; +import com.retrip.trip.domain.exception.common.ErrorCode; + +public class TripUpdateFailedException extends BusinessException { + private static final ErrorCode errorCode = ErrorCode.TRIP_UPDATE_FAIL; + + public TripUpdateFailedException() { + super(errorCode); + } +} diff --git a/src/main/java/com/retrip/trip/domain/exception/common/ErrorCode.java b/src/main/java/com/retrip/trip/domain/exception/common/ErrorCode.java index 7b2e2d6..50bf8ba 100644 --- a/src/main/java/com/retrip/trip/domain/exception/common/ErrorCode.java +++ b/src/main/java/com/retrip/trip/domain/exception/common/ErrorCode.java @@ -15,7 +15,7 @@ public enum ErrorCode { ILLEGAL_ARGUMENT(BAD_REQUEST, "Common-006", "Illegal argument"), TRIP_NOT_FOUND(BAD_REQUEST, "Trip-001", "트립 엔티티를 찾을 수 없습니다."), - PERIOD_UPDATE_FAIL(INTERNAL_SERVER_ERROR, "Trip-002", "여행 일정을 변경할 수 없습니다."), + PERIOD_UPDATE_FAIL(BAD_REQUEST, "Trip-002", "여행 일정을 변경할 수 없습니다."), NOT_TRIP_LEADER(BAD_REQUEST, "Trip-003", "여행 리더가 아니면 접근할 수 없습니다."), TRIP_INVITATION_DUPLICATE(BAD_REQUEST, "Trip-004", "사용자를 여행에 중복 초대할 수 없습니다."), MEMBER_IS_NOT_LEADER(BAD_REQUEST, "Trip-005", "여행 리더가 아니면 접근할 수 없습니다."), @@ -39,8 +39,8 @@ public enum ErrorCode { TRIP_PASSWORD_INVALID(BAD_REQUEST, "Trip-023", "비공개 여행 비밀번호의 길이가 적절하지 않습니다."), TRIP_DEMAND_NOT_ALLOWED(BAD_REQUEST, "Trip-024", "이미 참여를 요청했거나 참여 중인 여행이므로 참여 요청을 다시 할 수 없습니다."), TRIP_DEMAND_STATUS_NOT_PENDING(BAD_REQUEST, "Trip-025", "현재 참여 요청 상태가 ‘대기’가 아니므로 해당 요청을 수행할 수 없습니다."), - INVALID_MAX_PARTICIPANTS_VALUE(BAD_REQUEST,"Trip-026","최대 참여 인원은 1명 이상이어야 합니다."), - MAX_PARTICIPANTS_LESS_THAN_CURRENT(BAD_REQUEST,"Trip-027","현재 참여 인원보다 적은 수로 변경할 수 없습니다."), + INVALID_MAX_PARTICIPANTS_VALUE(BAD_REQUEST, "Trip-026", "최대 참여 인원은 1명 이상이어야 합니다."), + MAX_PARTICIPANTS_LESS_THAN_CURRENT(BAD_REQUEST, "Trip-027", "현재 참여 인원보다 적은 수로 변경할 수 없습니다."), INVALID_HASHTAG_LENGTH(BAD_REQUEST, "Trip-028", "HashTag는 1~10자 사이여야 합니다."), PRIVATE_TRIP_PASSWORD_REQUIRED(BAD_REQUEST, "Trip-029", "비공개 여행은 비밀번호를 반드시 입력해야 합니다."), TRIP_DAY_MUST_BE_POSITIVE(BAD_REQUEST, "Trip-030", "여행 일차는 1보다 작을 수 없습니다."), @@ -58,6 +58,7 @@ public enum ErrorCode { TRIP_PASSWORD_MISMATCH(BAD_REQUEST, "Trip-042", "여행 비밀번호가 일치하지 않습니다."), VOTE_MODIFY_FORBIDDEN(BAD_REQUEST, "Trip-043", "투표를 만든 사람이 아니면 수정, 종료, 삭제 할 수 없습니다."), EXTENSION_NOT_FOUND(BAD_REQUEST, "Trip-044", "지원하지 않는 이미지 확장자입니다."), + TRIP_UPDATE_FAIL(BAD_REQUEST, "Trip-045", "여행을 수정할 수 없습니다."), ; private final HttpStatus status; diff --git a/src/main/java/com/retrip/trip/infra/adapter/in/presentation/rest/TripController.java b/src/main/java/com/retrip/trip/infra/adapter/in/presentation/rest/TripController.java index 07a170c..2c7370d 100644 --- a/src/main/java/com/retrip/trip/infra/adapter/in/presentation/rest/TripController.java +++ b/src/main/java/com/retrip/trip/infra/adapter/in/presentation/rest/TripController.java @@ -61,6 +61,19 @@ public ApiResponse createTrip( return ApiResponse.created(trip); } + @Operation( + summary = "여행 수정", + description = "여행을 수정하는 API" + ) + @PutMapping("/{tripId}") + public ApiResponse updateTrip( + @WithUserContext UserContext userContext, + @PathVariable UUID tripId, + @RequestBody TripUpdateRequest request) { + TripUpdateResponse trip = tripManageUseCase.updateTrip(userContext.memberId(), tripId, request); + return ApiResponse.ok(trip); + } + @Operation( summary = "일정이 포함된 여행 생성", description = "일정이 포함된 여행을 생성하는 API -> 이거는 사용하는지 확인해봐야함 일정을 별도로 생기는거로 바뀌었던 거 같아서" @@ -79,7 +92,7 @@ public ApiResponse createTripWithItineraries( description = "여행 공개 여부를 변경하는 API" ) @ApiErrorCodeExamples({TRIP_NOT_FOUND, PRIVATE_TRIP_PASSWORD_REQUIRED, TRIP_PASSWORD_INVALID}) - @PutMapping("/{tripId}") + @PutMapping("/open/{tripId}") public ApiResponse updateTripVisibility( @PathVariable UUID tripId, @RequestBody TripUpdateVisibilityRequest request) { TripUpdateVisibilityResponse trip = tripManageUseCase.updateTripVisibility(tripId, request); diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql index b5179de..0764d5c 100644 --- a/src/main/resources/data.sql +++ b/src/main/resources/data.sql @@ -44,13 +44,14 @@ VALUES (random_uuid(), x'11111111111111111111111111111111', x'999999999999999999 -- 방장(HOST) 데이터 INSERT INTO trip_participant (id, trip_id, member_id, status, role, created_at) -VALUES (random_uuid(), x'11111111111111111111111111111111', x'99999999999999999999999999999993', 1, 'HOST', now()); +VALUES (random_uuid(), x'11111111111111111111111111111111', x'99999999999999999999999999999993', 1, 'LEADER', now()); -- 일반 참여자(MEMBER) 데이터 (Member ID를 다르게 설정) INSERT INTO trip_participant (id, trip_id, member_id, status, role, created_at) -VALUES (random_uuid(), x'11111111111111111111111111111112', x'99999999999999999999999999999991', 1, 'HOST', now()); +VALUES (random_uuid(), x'11111111111111111111111111111112', x'99999999999999999999999999999991', 1, 'LEADER', now()); INSERT INTO trip_participant (id, trip_id, member_id, status, role, created_at) -VALUES (random_uuid(), x'11111111111111111111111111111112', x'99999999999999999999999999999992', 1, 'MEMBER', now()); +VALUES (random_uuid(), x'11111111111111111111111111111112', x'99999999999999999999999999999992', 1, 'PARTICIPANT', + now()); -- 7. Vote (투표 생성) INSERT INTO vote (id, trip_id, title, description, status, version, max_selections, anonymous, allow_add_option, From 2faef3fe9b47bc0686fd6d592d6876e05e307c98 Mon Sep 17 00:00:00 2001 From: junhokim Date: Sun, 1 Mar 2026 22:29:31 +0900 Subject: [PATCH 2/2] =?UTF-8?q?feat.=20Update=20=EA=B0=9C=EB=B0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trip/application/in/TripService.java | 7 ++-- .../in/request/TripUpdateRequest.java | 33 ++++++++++++++---- .../in/request/context/UserContext.java | 8 ++++- .../in/response/TripUpdateResponse.java | 34 ++++++++++++++----- .../com/retrip/trip/domain/entity/Trip.java | 9 +++-- .../trip/domain/entity/TripDestinations.java | 7 ++++ .../trip/domain/entity/TripHashTags.java | 7 +++- 7 files changed, 80 insertions(+), 25 deletions(-) diff --git a/src/main/java/com/retrip/trip/application/in/TripService.java b/src/main/java/com/retrip/trip/application/in/TripService.java index 5ff7aa1..d6ada75 100644 --- a/src/main/java/com/retrip/trip/application/in/TripService.java +++ b/src/main/java/com/retrip/trip/application/in/TripService.java @@ -59,17 +59,18 @@ public TripUpdateResponse updateTrip(UUID memberId, UUID tripId, TripUpdateReque Trip trip = findTrip(tripId); TripTitle tripTitle = request.toTripTitle(); + TripDestinations destinations = request.toTripDestinations(trip); TripDescription tripDescription = request.toTripDescription(); TripPeriod tripPeriod = request.toTripPeriod(); - TripHashTags tripHashTags = request.toHashTags(trip); + TripHashTags hashTags = request.toHashTags(trip); //List itineraries = tripItineraryQueryRepository.findByIdsWithItineraryDetails(trip.getItinerariesIds()); trip.update( memberId, - request.locationId(), + destinations, tripTitle, tripDescription, - tripHashTags, + hashTags, request.maxParticipants(), request.imageUrl(), request.category() diff --git a/src/main/java/com/retrip/trip/application/in/request/TripUpdateRequest.java b/src/main/java/com/retrip/trip/application/in/request/TripUpdateRequest.java index ccbb2f7..2cbb97b 100644 --- a/src/main/java/com/retrip/trip/application/in/request/TripUpdateRequest.java +++ b/src/main/java/com/retrip/trip/application/in/request/TripUpdateRequest.java @@ -1,6 +1,7 @@ package com.retrip.trip.application.in.request; import com.retrip.trip.domain.entity.Trip; +import com.retrip.trip.domain.entity.TripDestinations; import com.retrip.trip.domain.entity.TripHashTags; import com.retrip.trip.domain.vo.*; import io.swagger.v3.oas.annotations.media.Schema; @@ -22,7 +23,7 @@ public record TripUpdateRequest( @Schema(description = "여행 위치 ID", example = "550e8400-e29b-41d4-a716-446655440001") @NotNull - UUID locationId, + List destinationIds, @Schema(description = "여행 시작 날짜", example = "2025-06-15") @FutureOrPresent @@ -35,8 +36,8 @@ public record TripUpdateRequest( @Schema(description = "여행 최대 참가 인원") Integer maxParticipants, - @Schema(description = "HashTag") - List hashTags, + @Schema(description = "HashTags") + List hashTags, @Schema(description = "여행 대표 이미지 URL") String imageUrl, @@ -44,6 +45,23 @@ public record TripUpdateRequest( @Schema(description = "여행 카테고리") TripCategory category ) { + @Schema(description = "해시태그 입력") + public record HashTagInput( + @Schema(description = "해시태그 값", example = "10대") + String tag, + + @Schema(description = "정렬 순서", example = "1") + int order + ) { + } + + public TripDestinations toTripDestinations(Trip trip) { + if (destinationIds == null || destinationIds.isEmpty()) { + return null; + } + return new TripDestinations(trip, destinationIds); + } + public TripTitle toTripTitle() { if (title != null) { return new TripTitle(title); @@ -66,9 +84,10 @@ public TripPeriod toTripPeriod() { } public TripHashTags toHashTags(Trip trip) { - if (hashTags != null) { - return new TripHashTags(trip, hashTags); - } - return null; + if (hashTags == null || hashTags.isEmpty()) return null; + return new TripHashTags(trip, hashTags.stream() + .map(h -> new HashTagInfo(h.tag(), h.order())) + .toList()); } + } diff --git a/src/main/java/com/retrip/trip/application/in/request/context/UserContext.java b/src/main/java/com/retrip/trip/application/in/request/context/UserContext.java index 3d71bf5..e817fbb 100644 --- a/src/main/java/com/retrip/trip/application/in/request/context/UserContext.java +++ b/src/main/java/com/retrip/trip/application/in/request/context/UserContext.java @@ -16,8 +16,14 @@ private enum Gender { } public static UserContext mockOf() { + + String hex = "99999999999999999999999999999991"; + +// 바로 변환 + UUID uuid = UUID.fromString(hex.replaceFirst("(\\w{8})(\\w{4})(\\w{4})(\\w{4})(\\w{12})", "$1-$2-$3-$4-$5")); + return new UserContext( - UUID.randomUUID(), + uuid, "Tester", "test@naver.com", "홍길동", diff --git a/src/main/java/com/retrip/trip/application/in/response/TripUpdateResponse.java b/src/main/java/com/retrip/trip/application/in/response/TripUpdateResponse.java index 428b375..bf64912 100644 --- a/src/main/java/com/retrip/trip/application/in/response/TripUpdateResponse.java +++ b/src/main/java/com/retrip/trip/application/in/response/TripUpdateResponse.java @@ -1,21 +1,21 @@ package com.retrip.trip.application.in.response; import com.retrip.trip.domain.entity.Trip; -import com.retrip.trip.domain.entity.TripHashTag; import io.swagger.v3.oas.annotations.media.Schema; import java.time.LocalDate; import java.util.ArrayList; +import java.util.Comparator; import java.util.List; import java.util.UUID; -@Schema(description = "여행 생성 Response") +@Schema(description = "여행 수정 Response") public record TripUpdateResponse( @Schema(description = "여행 ID", example = "550e8400-e29b-41d4-a716-446655440000") UUID id, - @Schema(description = "여행 목적지 ID", example = "550e8400-e29b-41d4-a716-446655440001") - UUID destinationId, + @Schema(description = "여행 목적지 ID 들", example = "550e8400-e29b-41d4-a716-446655440001") + List destinationIds, @Schema(description = "여행 제목", example = "파리 여행") String title, @@ -33,7 +33,7 @@ public record TripUpdateResponse( int maxParticipants, @Schema(description = "여행 카테고리") - List hashTags, + List hashTags, @Schema(description = "여행 카테고리") String category, @@ -44,25 +44,42 @@ public record TripUpdateResponse( @Schema(description = "여행 일정 리스트") List itineraries ) { + public static TripUpdateResponse of(Trip trip) { return new TripUpdateResponse( trip.getId(), - trip.getDestinationId(), + trip.getDestinations().getDestinationIds(), trip.getTitle().getValue(), trip.getDescription().getValue(), trip.getPeriod().getStart(), trip.getPeriod().getEnd(), trip.getTripParticipants().getMaxParticipants(), - trip.getHashTags().getValues().stream().map(TripHashTag::getName).toList(), + trip.getHashTags().getValues().stream() + .map(hashtag -> new HashTagResponse(hashtag.getName(), + hashtag.getTagOrder())) + .sorted(Comparator.comparingInt(HashTagResponse::order)) + .toList(), trip.getCategory().getViewName(), trip.getImageUrl(), trip.getItineraries() == null ? new ArrayList<>() : trip.getItineraries().getValues().stream() - .map(i -> new ItineraryUpdateResponse(i.getId(), i.getName(), i.getDate())) + .map(i -> new ItineraryUpdateResponse(i.getId(), i.getName(), + i.getDate())) .toList() ); } + @Schema(description = "해시태그 Response") + public record HashTagResponse( + @Schema(description = "해시태그") + String tag, + + @Schema(description = "정렬 순서") + int order + ) { + + } + @Schema(description = "여행 일정 Response") private record ItineraryUpdateResponse( @Schema(description = "일정 ID") @@ -74,5 +91,6 @@ private record ItineraryUpdateResponse( @Schema(description = "일정 날짜") LocalDate date ) { + } } diff --git a/src/main/java/com/retrip/trip/domain/entity/Trip.java b/src/main/java/com/retrip/trip/domain/entity/Trip.java index ff49dfb..384525f 100644 --- a/src/main/java/com/retrip/trip/domain/entity/Trip.java +++ b/src/main/java/com/retrip/trip/domain/entity/Trip.java @@ -208,7 +208,7 @@ public boolean isNotTripRecruitingStatus() { public void update( UUID memberId, - UUID destinationId, + TripDestinations destinations, TripTitle tripTitle, TripDescription tripDescription, TripHashTags tripHashTags, @@ -220,8 +220,8 @@ public void update( throw new TripUpdateFailedException(); } - if (destinationId != null) { - this.destinationId = destinationId; + if (destinations != null) { + this.destinations.update(destinations.getValues()); } if (tripTitle != null) { @@ -232,8 +232,7 @@ public void update( } if (tripHashTags != null) { - this.hashTags.getValues().clear(); - this.hashTags.getValues().addAll(tripHashTags.getValues()); + this.hashTags.update(tripHashTags.getValues()); } if (maxParticipants != null) { diff --git a/src/main/java/com/retrip/trip/domain/entity/TripDestinations.java b/src/main/java/com/retrip/trip/domain/entity/TripDestinations.java index a5cd501..ebdf410 100644 --- a/src/main/java/com/retrip/trip/domain/entity/TripDestinations.java +++ b/src/main/java/com/retrip/trip/domain/entity/TripDestinations.java @@ -5,9 +5,11 @@ import jakarta.persistence.CascadeType; import jakarta.persistence.Embeddable; import jakarta.persistence.OneToMany; + import java.util.ArrayList; import java.util.List; import java.util.UUID; + import lombok.Getter; import lombok.NoArgsConstructor; @@ -30,4 +32,9 @@ public List getDestinationIds() { .map(TripDestination::getDestinationId) .toList(); } + + public void update(List tripDestinations) { + this.values.clear(); + this.values.addAll(tripDestinations); + } } diff --git a/src/main/java/com/retrip/trip/domain/entity/TripHashTags.java b/src/main/java/com/retrip/trip/domain/entity/TripHashTags.java index 1dabef4..b81cd3a 100644 --- a/src/main/java/com/retrip/trip/domain/entity/TripHashTags.java +++ b/src/main/java/com/retrip/trip/domain/entity/TripHashTags.java @@ -10,9 +10,9 @@ import jakarta.persistence.OneToMany; import jakarta.persistence.OrderBy; + import java.util.ArrayList; import java.util.Comparator; -import java.util.HashSet; import java.util.List; import java.util.stream.Collectors; @@ -51,4 +51,9 @@ public List getHashTagNames() { .map(TripHashTag::getName) .collect(Collectors.toList()); } + + public void update(List tripHashTags) { + this.values.clear(); + this.values.addAll(tripHashTags); + } }