Skip to content

Commit

Permalink
Merge pull request #15 from inu-appcenter/joonseo
Browse files Browse the repository at this point in the history
[Merge] joonseo - #14
  • Loading branch information
xunxxoie authored Nov 12, 2024
2 parents d90946f + 876524c commit 40bb26b
Show file tree
Hide file tree
Showing 12 changed files with 200 additions and 99 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
@RequestMapping("/api/todos")
public class TodoController {

// TODO dto에서 사용자 아이디 제거하고 RequestParams나 PathVariable로 받는 것으로 수정하기!
private final TodoService todoService;

@Operation(summary = "투두 생성하기")
Expand All @@ -32,48 +31,49 @@ public class TodoController {
@ApiResponse(responseCode = "400", description = "투두 생성 실패")
})
@PostMapping
public ResponseEntity<ResponseDto<Long>> saveTodo(@Valid@RequestBody TodoDto request){
Long todoId = todoService.saveTodo(request);
return ResponseEntity.status(HttpStatus.CREATED).body(ResponseDto.of(todoId, "투두 생성 성공"));
public ResponseEntity<ResponseDto<Long>> saveTodo(@RequestParam Long userId,
@Valid@RequestBody TodoDto request){

return ResponseEntity.status(HttpStatus.CREATED).body(ResponseDto.of(todoService.saveTodo(userId, request), "투두 생성 성공"));
}

@Operation(summary = "투두 삭제하기")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "투두 삭제 성공"),
@ApiResponse(responseCode = "401", description = "투두 삭제 실패 : 권한 없음")
@ApiResponse(responseCode = "403", description = "투두 삭제 실패 : 권한 없음")
})
@DeleteMapping
public ResponseEntity<ResponseDto<Boolean>> deleteTodo(@Valid @RequestBody TodoDeleteRequestDto request){
Boolean isSucceed = todoService.deleteTodo(request);
return ResponseEntity.status(HttpStatus.OK).body(ResponseDto.of(isSucceed, request.getTitle()));
public ResponseEntity<ResponseDto<Boolean>> deleteTodo(@RequestParam Long userId,
@Valid @RequestBody TodoDeleteRequestDto request){
return ResponseEntity.status(HttpStatus.OK).body(ResponseDto.of(todoService.deleteTodo(userId, request), "투두 삭제 성공"));
}

@Operation(summary = "투두 전체 수정하기")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "투두 수정 성공"),
@ApiResponse(responseCode = "401", description = "투두 수정 실패 : 권한 없음")
@ApiResponse(responseCode = "403", description = "투두 수정 실패 : 권한 없음")
})
@PutMapping
public ResponseEntity<ResponseDto<Boolean>> updateTodo(@Valid@RequestBody TodoUpdateRequestDto request){
Boolean isSucceed = todoService.updateTodo(request);
return ResponseEntity.status(HttpStatus.OK).body(ResponseDto.of(isSucceed, request.getTitle()));
public ResponseEntity<ResponseDto<Long>> updateTodo(@RequestParam Long userId,
@Valid@RequestBody TodoUpdateRequestDto request){
return ResponseEntity.status(HttpStatus.OK).body(ResponseDto.of(todoService.updateTodo(userId, request), request.getTitle()));
}

@Operation(summary = "투두 완료여부 수정하기")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "투두 완료여부 수정 성공"),
@ApiResponse(responseCode = "401", description = "투두 완료여부 수정 실패 : 권한 없음")
@ApiResponse(responseCode = "403", description = "투두 완료여부 수정 실패 : 권한 없음")
})
@PutMapping("/complete")
public ResponseEntity<ResponseDto<Boolean>> updateCompletedTodo(@Valid@RequestBody TodoCompletedRequestDto request){
Boolean isSucceed = todoService.updateCompletedTodo(request);
return ResponseEntity.status(HttpStatus.OK).body(ResponseDto.of(isSucceed, request.getTitle()));
public ResponseEntity<ResponseDto<Boolean>> updateCompletedTodo(@RequestParam Long userId,
@Valid@RequestBody TodoCompletedRequestDto request){
return ResponseEntity.status(HttpStatus.OK).body(ResponseDto.of(todoService.updateCompletedTodo(userId, request), request.getTodoId().toString()));
}

@Operation(summary = "전체 투두 불러오기")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "투두 가져오기 성공"),
@ApiResponse(responseCode = "401", description = "투두 가져오기 실패 : 권한 없음")
@ApiResponse(responseCode = "403", description = "투두 가져오기 실패 : 권한 없음")
})
@GetMapping
public ResponseEntity<ResponseDto<List<TodoResponseDto>>> getAllTodo(@RequestParam Long userId){
Expand All @@ -83,10 +83,11 @@ public ResponseEntity<ResponseDto<List<TodoResponseDto>>> getAllTodo(@RequestPar
@Operation(summary = "특정 날짜 투두 불러오기")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "일별 투두 가져오기 성공"),
@ApiResponse(responseCode = "401", description = "일별 투두 가져오기 실패 : 권한 없음")
@ApiResponse(responseCode = "403", description = "일별 투두 가져오기 실패 : 권한 없음")
})
@GetMapping("/date")
public ResponseEntity<ResponseDto<List<TodoResponseDto>>> getDayTodo(@RequestParam Long userId, @Valid @RequestBody DayTodoRequestDto request){
return ResponseEntity.status(HttpStatus.OK).body(ResponseDto.of(todoService.getDayTodo(request), request.getCreatedAt().toString() + "의 투두 조회"));
public ResponseEntity<ResponseDto<List<TodoResponseDto>>> getDayTodo(@RequestParam Long userId,
@Valid @RequestBody DayTodoRequestDto request){
return ResponseEntity.status(HttpStatus.OK).body(ResponseDto.of(todoService.getDayTodo(userId, request), request.getRequestDate().toString() + " 투두 조회"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,7 @@
@Getter
@NoArgsConstructor
public class DayTodoRequestDto {

@Schema(description = "투두 조회를 요청한 유저 아이디", example = "1")
@NotBlank
private Long userId;

// TODO DateTimeFormat 에러 핸들링 추가(Custom Validator)
@DateTimeFormat(pattern = "yyyyMMdd")
private LocalDateTime createdAt;
private LocalDateTime requestDate;
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,7 @@
@Getter
@NoArgsConstructor
public class TodoCompletedRequestDto {
@Schema(description = "완료 상태 업데이트를 요청한 유저 아이디", example = "1")
@NotBlank
private Long userId;

@Schema(description = "제목", example = "지형이랑 카페가서 공부하기")
@NotBlank
private String title;
@Schema(description = "투두 아이디", example = "1")
@NotBlank(message = "투두 ID가 포함되지 않았습니다.")
private Long todoId;
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,7 @@
@Getter
@NoArgsConstructor
public class TodoDeleteRequestDto {
/**
* 여기서 택지가 두개가 있다고 생각하는데, 유저 아이디를 받거나 이메일을 받거나인데,
* 일단 구체적인 인증인가(jwt)를 구현하지 않고 한다고 치면, 로그인 시에 유저의 식별값을 반환해서
* 웹 스토리지에 넣어주고 요청날릴때마다, 포함해서 넣어주는 방식으로 비스무리하게 기능 구현이 가능할 것 같은데
* 여기서 로그인 시에 이메일을 던져주는게 맞는지, 아니면 아이디(long)을 던져주는게 맞는지가 의문입니다.
* 개발 편의상 아이디를 넣어주고 요청에서 아이디 받아오는게 편하긴 한데, 보안적으로... 음.. 이게 맞나 라는 생각이 드네요
* 지금은 보안은 조금 배제한다고 해도 어.. 애매한 부분인거같습니다.
*/

@Schema(description = "삭제를 요청한 유저 아이디", example = "1")
@NotBlank
private Long userId;

// TODO 투두 아이디 넘겨주는거로 변경
@Schema(description = "삭제할 투두 타이틀", example = "이터널 선샤인")
@NotBlank
private String title;
@Schema(description = "투두 아이디", example = "1")
@NotBlank(message = "투두 ID가 포함되지 않았습니다.")
private Long todoId;
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,26 @@

import java.time.LocalDateTime;

@Schema(description = "투두 등록/수정 req dto")
@Schema(description = "투두 등록 req dto")
@Getter
@NoArgsConstructor
public class TodoDto {

@Schema(description = "등록을 요청한 유저 아이디", example = "1")
@NotBlank
private Long userId;

@Schema(description = "제목", example = "지형이랑 카페가서 공부하기")
@NotBlank
@NotBlank(message = "제목이 입력되지 않았습니다.")
private String title;

@Schema(description = "내용", example = "카페 꼼마에서 오전 11시 만남")
@Size(max = 100)
@Size(max = 100, message = "내용의 최대 길이는 100입니다.")
private String description;

@Schema(description = "마감일", example = "YYYY-MM-DD")
@NotBlank
@NotBlank(message = "마감일이 지정되지 않았습니다.")
private LocalDateTime dueDate;

@Schema(description = "우선순위", example = "1")
@NotBlank
@Min(value = 0, message = "최소 = 0(매우매우 중요)")
@Max(value = 4, message = "최대 = 4(매우매우 안중요)")
@NotBlank(message = "우선순위가 입력되지 않았습니다.")
@Min(value = 0, message = "우선순위의 최소값은 0입니다.")
@Max(value = 4, message = "우선순위의 최대값은 4입니다.")
private Integer priority;
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,24 @@

import java.time.LocalDateTime;

@Schema(description = "투두 삭제 req dto")
@Schema(description = "투두 수정 req dto")
@Getter
@NoArgsConstructor
public class TodoUpdateRequestDto {
@NotBlank(message = "투두 ID가 입력되지 않았습니다.")
private Long todoId;

@Schema(description = "삭제를 요청한 유저 아이디", example = "1")
@NotBlank
private Long userId;

@NotBlank
@NotBlank(message = "제목이 입력되지 않았습니다.")
private String title;

@Size(max = 100)
@Size(max = 100, message = "내용의 최대 길이는 100입니다.")
private String description;

@NotBlank
@NotBlank(message = "마감일이 지정되지 않았습니다.")
private LocalDateTime dueDate;

@NotBlank
@Min(value = 0, message = "최소 = 0(매우매우 중요)")
@Max(value = 4, message = "최대 = 4(매우매우 안중요)")
@NotBlank(message = "우선순위가 입력되지 않았습니다.")
@Min(value = 0, message = "우선순위의 최소값은 0입니다.")
@Max(value = 4, message = "우선순위의 최대값은 4입니다.")
private Integer priority;
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import org.todo.todo.domain.user.entity.UserEntity;
import org.todo.todo.domain.user.repository.UserRepository;
import org.todo.todo.domain.todo.dto.res.TodoResponseDto;
import org.todo.todo.global.error.code.CustomErrorCode;
import org.todo.todo.global.error.exception.RestApiException;

import java.util.List;
import java.util.Objects;
Expand All @@ -19,8 +21,8 @@ public class TodoService {
private final TodoRepository todoRepository;
private final UserRepository userRepository;

public Long saveTodo(TodoDto todoDto){
UserEntity user = findUser(todoDto.getUserId());
public Long saveTodo(Long userId, TodoDto todoDto){
UserEntity user = findUser(userId);

TodoEntity todo = TodoEntity.builder()
.title(todoDto.getTitle())
Expand All @@ -33,40 +35,35 @@ public Long saveTodo(TodoDto todoDto){
return todoRepository.save(todo).getId();
}

public Boolean deleteTodo(TodoDeleteRequestDto todoDeleteRequestDto){
// 삭제하려는 유저와 투두 작성자 일치 여부 확인
// TODO 에러핸들링 추가
TodoEntity todo = todoRepository.findByTitle(todoDeleteRequestDto.getTitle())
.orElseThrow(null);
public Boolean deleteTodo(Long userId, TodoDeleteRequestDto todoDeleteRequestDto){

if(checkAuthorization(todo, todoDeleteRequestDto.getUserId())) {
TodoEntity todo = findTodo(todoDeleteRequestDto.getTodoId());

if(checkAuthorization(todo, userId)) {
todoRepository.delete(todo);
return true;
}

return false;
}

public Boolean updateTodo(TodoUpdateRequestDto todoUpdateRequestDto){
// 수정하려는 유저와 투두 작성자 일치 여부 확인
// TODO 에러핸들링 추가
TodoEntity todo = todoRepository.findByTitle(todoUpdateRequestDto.getTitle())
.orElseThrow(null);
public Long updateTodo(Long userId, TodoUpdateRequestDto todoUpdateRequestDto){

TodoEntity todo = findTodo(todoUpdateRequestDto.getTodoId());

if(checkAuthorization(todo, todoUpdateRequestDto.getUserId())){
if(checkAuthorization(todo, userId)){
todo.updateTodo(todoUpdateRequestDto.getTitle(), todoUpdateRequestDto.getDescription(), todoUpdateRequestDto.getDueDate(), todoUpdateRequestDto.getPriority());
return true;
return todo.getId();
}

return false;
return -1L;
}

public Boolean updateCompletedTodo(TodoCompletedRequestDto todoCompletedRequestDto){
// TODO 에러핸들링 추가
TodoEntity todo = todoRepository.findByTitle(todoCompletedRequestDto.getTitle())
.orElseThrow(null);
public Boolean updateCompletedTodo(Long userId, TodoCompletedRequestDto todoCompletedRequestDto){

if(checkAuthorization(todo, todoCompletedRequestDto.getUserId())) {
TodoEntity todo = findTodo(todoCompletedRequestDto.getTodoId());

if(checkAuthorization(todo, userId)) {
todo.updateCompleted();
return true;
}
Expand All @@ -75,23 +72,25 @@ public Boolean updateCompletedTodo(TodoCompletedRequestDto todoCompletedRequestD
}

public List<TodoResponseDto> getAllTodo(Long userId){
// TODO 배열이 비어있는 경우 처리
return todoRepository.findAllByUserId(userId).stream()
.map(TodoResponseDto::from)
.collect(Collectors.toList());
}

public List<TodoResponseDto> getDayTodo(DayTodoRequestDto dayTodoRequestDto){
// TODO 배열이 비어있는 경우 처리
return todoRepository.findAllByCreatedAtAndUserId(dayTodoRequestDto.getCreatedAt(), dayTodoRequestDto.getUserId()).stream()
public List<TodoResponseDto> getDayTodo(Long userId, DayTodoRequestDto dayTodoRequestDto){
return todoRepository.findAllByCreatedAtAndUserId(dayTodoRequestDto.getRequestDate(),userId).stream()
.map(TodoResponseDto::from)
.collect(Collectors.toList());
}

public UserEntity findUser(Long userId){
// TODO 에러핸들링 추가
return userRepository.findById(userId)
.orElseThrow(null);
.orElseThrow(() -> new RestApiException(CustomErrorCode.PERMISSION_DENIED));
}

public TodoEntity findTodo(Long todoId) {
return todoRepository.findById(todoId)
.orElseThrow(() -> new RestApiException(CustomErrorCode.TODO_NOT_FOUND));
}

public Boolean checkAuthorization(TodoEntity todo, Long userId){
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.todo.todo.global.error;

import lombok.Builder;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@Builder
@RequiredArgsConstructor
public class ErrorResponse<T> {
private final Integer error;
private final T message;
}
Loading

0 comments on commit 40bb26b

Please sign in to comment.