Skip to content

Commit

Permalink
Merge pull request #137 from Team-Going/feature/136
Browse files Browse the repository at this point in the history
[feat] 여행 TODO 생성 API 스펙 및 비즈니스 로직 변경
  • Loading branch information
SunwoongH authored Mar 3, 2024
2 parents 9929558 + 436e0b1 commit a440c2f
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 15 deletions.
10 changes: 8 additions & 2 deletions doorip-api/src/main/java/org/doorip/trip/api/TodoApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@ public interface TodoApi {
content = @Content),
@ApiResponse(
responseCode = "400",
description = "여행 TODO를 생성하기 위해 최소 1명 이상의 배정자가 필요합니다.",
description = "여행 MY TODO의 배정자가 누락되었습니다.",
content = @Content),
@ApiResponse(
responseCode = "400",
description = "여행 MY TODO의 배정자 번호가 잘못되었습니다.",
content = @Content),
@ApiResponse(
responseCode = "401",
Expand Down Expand Up @@ -60,7 +64,9 @@ public interface TodoApi {
responseCode = "500",
description = "서버 내부 오류입니다.",
content = @Content)})
ResponseEntity<BaseResponse<?>> createTripTodo(@PathVariable final Long tripId,
ResponseEntity<BaseResponse<?>> createTripTodo(@Parameter(hidden = true)
@UserId final Long userId,
@PathVariable final Long tripId,
@RequestBody final TodoCreateRequest request);

@Operation(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ public class TodoApiController implements TodoApi {

@PostMapping("/{tripId}/todos")
@Override
public ResponseEntity<BaseResponse<?>> createTripTodo(@PathVariable final Long tripId,
public ResponseEntity<BaseResponse<?>> createTripTodo(@UserId final Long userId,
@PathVariable final Long tripId,
@RequestBody final TodoCreateRequest request) {
todoService.createTripTodo(tripId, request);
todoService.createTripTodo(userId, tripId, request);
return ApiResponseUtil.success(SuccessMessage.CREATED);
}

Expand Down
53 changes: 43 additions & 10 deletions doorip-api/src/main/java/org/doorip/trip/service/TodoService.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import org.doorip.trip.repository.TodoRepository;
import org.doorip.trip.repository.TripRepository;
import org.doorip.user.domain.User;
import org.doorip.user.repository.UserRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

Expand All @@ -30,10 +31,11 @@ public class TodoService {
private final TodoRepository todoRepository;
private final TripRepository tripRepository;
private final ParticipantRepository participantRepository;
private final UserRepository userRepository;

@Transactional
public void createTripTodo(Long tripId, TodoCreateRequest request) {
validateAllocators(request.allocators());
public void createTripTodo(Long userId, Long tripId, TodoCreateRequest request) {
validateAllocators(request.secret(), userId, tripId, request.allocators());
Trip findTrip = getTrip(tripId);
Todo todo = createTodo(request, findTrip);
createAllocators(request.allocators(), todo);
Expand Down Expand Up @@ -68,9 +70,11 @@ public void incompleteTripTodo(Long todoId) {
findTodo.incomplete();
}

private void validateAllocators(List<Long> allocators) {
if (allocators.isEmpty()) {
throw new InvalidValueException(ErrorMessage.INVALID_ALLOCATOR_COUNT);
private void validateAllocators(boolean isSecret, Long userId, Long tripId, List<Long> allocators) {
if (isSecret) {
validateAllocatorCount(allocators);
Long findOwnerParticipantId = getOwnerParticipantId(userId, tripId);
validateAllocatorId(findOwnerParticipantId, allocators);
}
}

Expand Down Expand Up @@ -103,11 +107,6 @@ private List<TodoGetResponse> getTripTodosResponse(Long userId, List<Todo> todos
return response;
}

private Trip getTrip(Long tripId) {
return tripRepository.findById(tripId)
.orElseThrow(() -> new EntityNotFoundException(ErrorMessage.TRIP_NOT_FOUND));
}

private TodoDetailGetResponse getTripTodoResponse(Long userId, Trip findTrip, Todo findTodo) {
List<TodoDetailAllocatorResponse> allocatorResponses = getAndSortAllocatorResponses(userId, findTrip, findTodo);
return TodoDetailGetResponse.of(findTodo, allocatorResponses);
Expand All @@ -118,6 +117,25 @@ private Todo getTodo(Long todoId) {
.orElseThrow(() -> new EntityNotFoundException(ErrorMessage.TODO_NOT_FOUND));
}

private void validateAllocatorCount(List<Long> allocators) {
if (allocators.size() != Constants.MIN_PARTICIPANT_COUNT) {
throw new InvalidValueException(ErrorMessage.INVALID_ALLOCATOR_COUNT);
}
}

private Long getOwnerParticipantId(Long userId, Long tripId) {
User findUser = getUser(userId);
Trip findTrip = getTrip(tripId);
Participant findOwnerParticipant = getOwnerParticipant(findUser, findTrip);
return findOwnerParticipant.getId();
}

private void validateAllocatorId(Long participantId, List<Long> allocators) {
if (!participantId.equals(allocators.get(Constants.TODO_OWNER_POSITION))) {
throw new InvalidValueException(ErrorMessage.INVALID_ALLOCATOR_ID);
}
}

private Participant getParticipant(Long participantId) {
return participantRepository.findById(participantId)
.orElseThrow(() -> new EntityNotFoundException(ErrorMessage.PARTICIPANT_NOT_FOUND));
Expand Down Expand Up @@ -157,6 +175,21 @@ private List<TodoDetailAllocatorResponse> getAndSortAllocatorResponses(Long user
return getAllocatorResponses(ownerParticipant, participants, allocators);
}

private User getUser(Long userId) {
return userRepository.findById(userId)
.orElseThrow(() -> new EntityNotFoundException(ErrorMessage.USER_NOT_FOUND));
}

private Trip getTrip(Long tripId) {
return tripRepository.findById(tripId)
.orElseThrow(() -> new EntityNotFoundException(ErrorMessage.TRIP_NOT_FOUND));
}

private Participant getOwnerParticipant(User findUser, Trip findTrip) {
return participantRepository.findByUserAndTrip(findUser, findTrip)
.orElseThrow(() -> new EntityNotFoundException(ErrorMessage.PARTICIPANT_NOT_FOUND));
}

private List<TodoAllocatorResponse> getAllocatorResponses(Long userId, List<Allocator> allocators) {
return new ArrayList<>(allocators.stream()
.map(allocator -> TodoAllocatorResponse.of(userId, allocator))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@ public enum ErrorMessage {
BAD_REQUEST(HttpStatus.BAD_REQUEST, "e4000", "잘못된 요청입니다."),
INVALID_PLATFORM_TYPE(HttpStatus.BAD_REQUEST, "e4001", "유효하지 않은 플랫폼 타입입니다."),
INVALID_REQUEST_PARAMETER_VALUE(HttpStatus.BAD_REQUEST, "e4002", "유효하지 않은 요청 파라미터 값입니다."),
INVALID_ALLOCATOR_COUNT(HttpStatus.BAD_REQUEST, "e4003", "여행 TODO를 생성하기 위해 최소 1명 이상의 배정자가 필요합니다."),
INVALID_ALLOCATOR_COUNT(HttpStatus.BAD_REQUEST, "e4003", "여행 MY TODO의 배정자가 누락되었습니다."),
INVALID_DATE_TYPE(HttpStatus.BAD_REQUEST, "e4004", "유효하지 않은 날짜 타입입니다."),
INVALID_RESULT_TYPE(HttpStatus.BAD_REQUEST, "e4005", "유효하지 않은 성향 입력 값입니다."),
INVALID_PARTICIPANT_COUNT(HttpStatus.BAD_REQUEST, "e4006", "여행에 입장할 수 있는 최대 인원은 6명입니다."),
INVALID_DISCORD_MESSAGE(HttpStatus.BAD_REQUEST, "e4007", "디스코드 메시지 전달에 실패했습니다."),
INVALID_ALLOCATOR_ID(HttpStatus.BAD_REQUEST, "e4008", "여행 MY TODO의 배정자 번호가 잘못되었습니다."),

/**
* 401 Unauthorized
Expand Down

0 comments on commit a440c2f

Please sign in to comment.