Skip to content

Commit

Permalink
Merge pull request #45 from MOONSHOT-Team/feature/#42
Browse files Browse the repository at this point in the history
[Add] #42 - Task, KeyResult 순서 변경 API
  • Loading branch information
its-sky authored Jan 9, 2024
2 parents a91005a + 2b13d41 commit 7a10df9
Show file tree
Hide file tree
Showing 20 changed files with 202 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public record KeyResultCreateRequestDto(
LocalDateTime expireAt,
@NotNull(message = "KR의 순서를 입력해주세요.")
@Range(min = 0, max = 2, message = "KeyResult의 순서는 0부터 2까지로 설정할 수 있습니다.")
Short idx,
Integer idx,
@NotNull(message = "KR 목표 수치를 입력해주세요.")
@ValidTargetNumber
@ValidLimitValue
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public record KeyResultCreateRequestInfoDto(
LocalDateTime expireAt,
@NotNull(message = "KR의 순서를 입력해주세요.")
@Range(min = 0, max = 2, message = "KeyResult의 순서는 0부터 2까지로 설정할 수 있습니다.")
Short idx,
Integer idx,
@NotNull(message = "KR 목표 수치를 입력해주세요.")
@ValidTargetNumber
@ValidLimitValue
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public class KeyResult {
private Long target;

@Column(nullable = false)
private Short idx;
private Integer idx;

@Column(nullable = false)
private String metric;
Expand All @@ -52,6 +52,10 @@ public void incrementIdx() {
++this.idx;
}

public void decreaseIdx() {
--this.idx;
}

public void modifyTitle(String title) {
this.title = title;
}
Expand All @@ -60,7 +64,7 @@ public void modifyPeriod(Period period) {
this.period = period;
}

public void modifyIdx(Short idx) {
public void modifyIdx(Integer idx) {
this.idx = idx;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import org.moonshot.server.domain.keyresult.model.KeyResult;
import org.moonshot.server.domain.objective.model.Objective;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

Expand All @@ -13,8 +14,15 @@ public interface KeyResultRepository extends JpaRepository<KeyResult, Long> {
Long countAllByObjective(Objective objective);
List<KeyResult> findByIdIn(List<Long> ids);
List<KeyResult> findAllByObjective(Objective objective);
List<KeyResult> findAllByObjectiveOrderByIdx(Objective objective);
List<KeyResult> findAllByObjectiveId(Long objectiveId);
@Query("select kr from KeyResult kr join fetch kr.objective join fetch kr.objective.user where kr.id = :keyResultId")
Optional<KeyResult> findKeyResultAndObjective(@Param("keyResultId") Long keyResultId);
@Modifying(clearAutomatically = true)
@Query("UPDATE KeyResult kr SET kr.idx = kr.idx + 1 WHERE kr.idx >= :lBound AND kr.idx < :uBound AND kr.objective.id = :objectiveId AND kr.id != :targetId")
void bulkUpdateIdxIncrease(@Param("lBound") int lowerBound, @Param("uBound") int upperBound, @Param("objectiveId") Long objectiveId, @Param("targetId") Long targetId);
@Modifying(clearAutomatically = true)
@Query("UPDATE KeyResult kr SET kr.idx = kr.idx - 1 WHERE kr.idx >= :lBound AND kr.idx <= :uBound AND kr.objective.id = :objectiveId AND kr.id != :targetId")
void bulkUpdateIdxDecrease(@Param("lBound") int lowerBound, @Param("uBound") int upperBound, @Param("objectiveId") Long objectiveId, @Param("targetId") Long targetId);

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@
import org.moonshot.server.domain.keyresult.exception.KeyResultNumberExceededException;
import org.moonshot.server.domain.keyresult.model.KeyResult;
import org.moonshot.server.domain.keyresult.repository.KeyResultRepository;
import org.moonshot.server.domain.objective.dto.request.ModifyIndexRequestDto;
import org.moonshot.server.domain.log.repository.LogRepository;
import org.moonshot.server.domain.log.service.LogService;
import org.moonshot.server.domain.objective.exception.ObjectiveNotFoundException;
import org.moonshot.server.domain.objective.model.IndexService;
import org.moonshot.server.domain.objective.model.Objective;
import org.moonshot.server.domain.objective.repository.ObjectiveRepository;
import org.moonshot.server.domain.task.dto.request.TaskCreateRequestDto;
Expand All @@ -28,7 +30,7 @@
@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class KeyResultService {
public class KeyResultService implements IndexService {

private static final int ACTIVE_KEY_RESULT_NUMBER = 3;

Expand Down Expand Up @@ -85,7 +87,7 @@ public void createKeyResult(KeyResultCreateRequestDto request, Long userId) {
throw new KeyResultInvalidPositionException();
}

for (short i = request.idx(); i < krList.size(); i++) {
for (int i = request.idx(); i < krList.size(); i++) {
krList.get(i).incrementIdx();
}
KeyResult keyResult = keyResultRepository.save(KeyResult.builder()
Expand Down Expand Up @@ -144,7 +146,25 @@ public void modifyKeyResult(KeyResultModifyRequestDto request, Long userId) {
if (request.state() != null) {
keyResult.modifyState(request.state());
}
}

@Override
@Transactional
public void modifyIdx(ModifyIndexRequestDto request, Long userId) {
KeyResult keyResult = keyResultRepository.findKeyResultAndObjective(request.id())
.orElseThrow(KeyResultNotFoundException::new);
userService.validateUserAuthorization(keyResult.getObjective().getUser(), userId);
Integer prevIdx = keyResult.getIdx();
if (prevIdx.equals(request.idx())) {
return;
}

keyResult.modifyIdx(request.idx());
if (prevIdx < request.idx()) {
keyResultRepository.bulkUpdateIdxDecrease(prevIdx + 1, request.idx(), keyResult.getObjective().getId(), keyResult.getId());
} else {
keyResultRepository.bulkUpdateIdxIncrease(request.idx(), prevIdx, keyResult.getObjective().getId(), keyResult.getId());
}
}

}
3 changes: 0 additions & 3 deletions src/main/java/org/moonshot/server/domain/log/model/Log.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,8 @@

import jakarta.persistence.*;
import lombok.*;
import org.hibernate.annotations.ColumnDefault;
import org.hibernate.annotations.DynamicInsert;
import org.moonshot.server.domain.keyresult.model.KeyResult;
import org.moonshot.server.domain.user.model.SocialPlatform;
import org.moonshot.server.domain.user.model.User;

import java.time.LocalDateTime;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.moonshot.server.domain.objective.controller;

import jakarta.validation.Valid;
import java.security.Principal;
import lombok.RequiredArgsConstructor;
import org.moonshot.server.domain.objective.dto.request.ModifyIndexRequestDto;
import org.moonshot.server.domain.objective.model.IndexService;
import org.moonshot.server.domain.objective.service.IndexTargetProvider;
import org.moonshot.server.global.auth.jwt.JwtTokenProvider;
import org.moonshot.server.global.common.response.ApiResponse;
import org.moonshot.server.global.common.response.SuccessType;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
@RequestMapping("/v1/index")
public class IndexController {

private final IndexTargetProvider indexTargetProvider;

@PatchMapping
public ApiResponse<?> modifyIdx(Principal principal, @RequestBody @Valid ModifyIndexRequestDto request) {
IndexService indexService = indexTargetProvider.getIndexService(request.target());
indexService.modifyIdx(request, JwtTokenProvider.getUserIdFromPrincipal(principal));
return ApiResponse.success(SuccessType.PATCH_TARGET_INDEX_SUCCESS);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.moonshot.server.domain.objective.dto.request;

import jakarta.validation.constraints.NotNull;
import org.hibernate.validator.constraints.Range;
import org.moonshot.server.domain.objective.model.IndexTarget;

public record ModifyIndexRequestDto(
@NotNull(message = "대상의 ID를 입력해주세요.")
Long id,
@NotNull(message = "대상을 지정해주세요.")
IndexTarget target,
@NotNull(message = "대상의 이동할 위치 값을 입력하세요.")
@Range(min = 0, max = 2, message = "순서는 0부터 2까지로 설정할 수 있습니다.")
Integer idx
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.moonshot.server.domain.objective.model;

import org.moonshot.server.domain.objective.dto.request.ModifyIndexRequestDto;

public interface IndexService {

void modifyIdx(ModifyIndexRequestDto request, Long userId);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.moonshot.server.domain.objective.model;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public enum IndexTarget {

KEY_RESULT("keyResult"),
TASK("task");

private final String value;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.moonshot.server.domain.objective.service;

import jakarta.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import org.moonshot.server.domain.keyresult.service.KeyResultService;
import org.moonshot.server.domain.objective.model.IndexService;
import org.moonshot.server.domain.objective.model.IndexTarget;
import org.moonshot.server.domain.task.service.TaskService;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
public class IndexTargetProvider {

private static final Map<IndexTarget, IndexService> indexServiceMap = new HashMap<>();
private final KeyResultService keyResultService;
private final TaskService taskService;

@PostConstruct
void initIndexServiceMap() {
indexServiceMap.put(IndexTarget.KEY_RESULT, keyResultService);
indexServiceMap.put(IndexTarget.TASK, taskService);
}

public IndexService getIndexService(IndexTarget indexTarget) {
return indexServiceMap.get(indexTarget);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ public record TaskCreateRequestDto(
String title,
@NotNull(message = "KR 순서를 입력해주세요")
@Range(min = 0, max = 2, message = "Task의 순서는 0부터 2까지로 설정할 수 있습니다.")
Short idx
Integer idx
) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ public record TaskSingleCreateRequestDto(
String title,
@NotNull(message = "KR 순서를 입력해주세요")
@Range(min = 0, max = 2, message = "KeyResult의 순서는 0부터 2까지로 설정할 수 있습니다.")
Short idx
Integer idx
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.moonshot.server.domain.task.exception;

import org.moonshot.server.global.common.exception.MoonshotException;
import org.moonshot.server.global.common.response.ErrorType;

public class TaskNotFoundException extends MoonshotException {

public TaskNotFoundException() {
super(ErrorType.NOT_FOUND_TASK_ERROR);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public class Task {
private String title;

@Column(nullable = false)
private short idx;
private Integer idx;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "key_result_id")
Expand All @@ -29,4 +29,9 @@ public class Task {
public void incrementIdx() {
++this.idx;
}

public void modifyIdx(Integer idx) {
this.idx = idx;
}

}
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
package org.moonshot.server.domain.task.repository;

import java.util.List;
import java.util.Optional;
import org.moonshot.server.domain.keyresult.model.KeyResult;
import org.moonshot.server.domain.task.model.Task;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

public interface TaskRepository extends JpaRepository<Task, Long> {

List<Task> findAllByKeyResult(KeyResult keyResult);
List<Task> findAllByKeyResultOrderByIdx(KeyResult keyResult);
@Query("select t from Task t join fetch t.keyResult kr join fetch kr.objective obj join fetch obj.user u where t.id = :taskId")
Optional<Task> findTaskWithFetchJoin(@Param("taskId") Long taskId);
@Modifying(clearAutomatically = true)
@Query(value = "UPDATE Task t SET t.idx = t.idx + 1 WHERE t.idx >= :lBound AND t.idx < :uBound AND t.keyResult.id = :keyResultId AND t.id != :targetId")
void bulkUpdateTaskIdxIncrease(@Param("lBound") int lowerBound, @Param("uBound") int upperBound, @Param("keyResultId") Long keyResultId, @Param("targetId") Long targetId);
@Modifying(clearAutomatically = true)
@Query(value = "UPDATE Task t SET t.idx = t.idx - 1 WHERE t.idx >= :lBound AND t.idx <= :uBound AND t.keyResult.id = :keyResultId AND t.id != :targetId")
void bulkUpdateTaskIdxDecrease(@Param("lBound") int lowerBound, @Param("uBound") int upperBound, @Param("keyResultId") Long keyResultId, @Param("targetId") Long targetId);

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,29 @@
import org.moonshot.server.domain.keyresult.exception.KeyResultInvalidPositionException;
import org.moonshot.server.domain.keyresult.model.KeyResult;
import org.moonshot.server.domain.keyresult.repository.KeyResultRepository;
import org.moonshot.server.domain.objective.dto.request.ModifyIndexRequestDto;
import org.moonshot.server.domain.objective.model.IndexService;
import org.moonshot.server.domain.task.dto.request.TaskCreateRequestDto;
import org.moonshot.server.domain.task.dto.request.TaskSingleCreateRequestDto;
import org.moonshot.server.domain.task.exception.TaskNotFoundException;
import org.moonshot.server.domain.task.exception.TaskNumberExceededException;
import org.moonshot.server.domain.task.model.Task;
import org.moonshot.server.domain.task.repository.TaskRepository;
import org.moonshot.server.domain.user.service.UserService;
import org.moonshot.server.global.auth.exception.AccessDeniedException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class TaskService {
public class TaskService implements IndexService {

private static final int ACTIVE_TASK_NUMBER = 3;

private final KeyResultRepository keyResultRepository;
private final TaskRepository taskRepository;
private final UserService userService;

@Transactional
public void createTask(TaskSingleCreateRequestDto request, Long userId) {
Expand All @@ -40,7 +45,7 @@ public void createTask(TaskSingleCreateRequestDto request, Long userId) {
throw new KeyResultInvalidPositionException();
}

for (short i = request.idx(); i < taskList.size(); i++) {
for (int i = request.idx(); i < taskList.size(); i++) {
taskList.get(i).incrementIdx();
}

Expand All @@ -63,4 +68,24 @@ public void saveTask(KeyResult keyResult, TaskCreateRequestDto request) {
.build());
}

@Override
@Transactional
public void modifyIdx(ModifyIndexRequestDto request, Long userId) {
Task task = taskRepository.findTaskWithFetchJoin(request.id())
.orElseThrow(TaskNotFoundException::new);
userService.validateUserAuthorization(task.getKeyResult().getObjective().getUser(), userId);
Integer prevIdx = task.getIdx();
if (prevIdx.equals(request.idx())) {
return;
}
List<Task> taskList = taskRepository.findAllByKeyResult(task.getKeyResult());

task.modifyIdx(request.idx());
if (prevIdx < request.idx()) {
taskRepository.bulkUpdateTaskIdxDecrease(prevIdx + 1, request.idx(), task.getKeyResult().getId(), task.getId());
} else {
taskRepository.bulkUpdateTaskIdxIncrease(request.idx(), prevIdx, task.getKeyResult().getId(), task.getId());
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import lombok.extern.slf4j.Slf4j;

public class TargetNumberValidator implements ConstraintValidator<ValidTargetNumber, Long> {

Expand Down
Loading

0 comments on commit 7a10df9

Please sign in to comment.