Skip to content

Commit

Permalink
feature: toast 저장, 삭제, 열람여부 확인 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
sss4920 committed Jan 1, 2024
1 parent 79fead8 commit d142114
Show file tree
Hide file tree
Showing 20 changed files with 232 additions and 28 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
package com.app.toaster.common.advice;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import com.app.toaster.common.dto.ApiResponse;
import com.app.toaster.exception.Error;
import com.app.toaster.exception.model.CustomException;

import jakarta.validation.ConstraintDefinitionException;
import lombok.NoArgsConstructor;

@RestControllerAdvice
Expand All @@ -27,4 +33,10 @@ protected ResponseEntity<ApiResponse> handleCustomException(CustomException e) {
// public ResponseEntity<Void> handleIllegalArgumentException(final IllegalArgumentException e) {
// return ResponseEntity.badRequest().build();
// }
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MethodArgumentNotValidException.class)
protected ResponseEntity<ApiResponse> handleConstraintDefinitionException(final MethodArgumentNotValidException e) {
return ResponseEntity.status(e.getStatusCode())
.body(ApiResponse.error(Error.BAD_REQUEST_VALIDATION, e.getMessage()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.springframework.web.bind.annotation.RestController;

import com.app.toaster.common.dto.ApiResponse;
// import com.app.toaster.config.UserId;
import com.app.toaster.config.UserId;
import com.app.toaster.controller.request.auth.SignInRequestDto;
import com.app.toaster.controller.response.auth.SignInResponseDto;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,33 +1,62 @@
package com.app.toaster.controller;

import org.springframework.http.HttpStatus;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import com.app.toaster.common.dto.ApiResponse;
import com.app.toaster.config.UserId;
// import com.app.toaster.config.UserId;
import com.app.toaster.controller.request.toast.IsReadDto;
import com.app.toaster.controller.request.toast.SaveToastDto;
import com.app.toaster.controller.response.auth.SignInResponseDto;
import com.app.toaster.controller.response.toast.IsReadResponse;
import com.app.toaster.exception.Success;
import com.app.toaster.service.toast.ToastService;

import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;

@RestController
@RequiredArgsConstructor
@RequestMapping("/toast")
@Validated
public class ToastController {
private final ToastService toastService;

@PostMapping
@ResponseStatus(HttpStatus.OK)
@PostMapping("/save")
@ResponseStatus(HttpStatus.CREATED)
public ApiResponse createToast(
@UserId Long userId,
SaveToastDto requestDto
@RequestHeader("userId") Long userId,
@RequestBody @Valid SaveToastDto requestDto
) {
toastService.createToast(userId, requestDto);
return ApiResponse.success(Success.CREATE_TOAST_SUCCESS, Success.CREATE_TOAST_SUCCESS.getMessage());
return ApiResponse.success(Success.CREATE_TOAST_SUCCESS);
}

@PatchMapping("/is-read")
@ResponseStatus(HttpStatus.OK)
public ApiResponse<IsReadResponse> updateIsRead(
@RequestHeader("userId") Long userId,
@RequestBody IsReadDto requestDto
){
return ApiResponse.success(Success.UPDATE_ISREAD_SUCCESS, toastService.readToast(userId,requestDto));
}

@DeleteMapping("/delete")
@ResponseStatus(HttpStatus.OK)
public ApiResponse deleteToast( //나중에 softDelete로 변경
@RequestHeader("userId") Long userId,
@RequestParam Long toastId
) {
toastService.deleteToast(userId, toastId);
return ApiResponse.success(Success.DELETE_TOAST_SUCCESS);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.app.toaster.controller.request.toast;

public record DeleteToastDto(Long toastId) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.app.toaster.controller.request.toast;

public record IsReadDto(Long toastId, Boolean isRead) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,8 @@

import java.util.List;

public record SaveToastDto(String linkUrl, String title, List<Long> categoryIds) {
import com.app.toaster.controller.valid.Severity;
import com.app.toaster.controller.valid.TitleValid;

public record SaveToastDto(String linkUrl, @TitleValid(message = "hi zz", payload = Severity.Error.class) String title, List<Long> categoryIds) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.app.toaster.controller.response.toast;

public record IsReadResponse(Boolean isRead) {
public static IsReadResponse of(Boolean isRead){
return new IsReadResponse(isRead);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.app.toaster.controller.valid;

import jakarta.validation.Payload;

public class Severity {
public static class Info implements Payload {};
public static class Error implements Payload {};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.app.toaster.controller.valid;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.util.ArrayList;

import jakarta.validation.Constraint;
import jakarta.validation.Payload;

@Documented
@Constraint(validatedBy = TitleValidator.class)
@Target({java.lang.annotation.ElementType.FIELD})
@Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
public @interface TitleValid {
String message() default "Invalid title";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
String pattern() default "[가-힣|a-z|A-Z|0-9|]";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.app.toaster.controller.valid;


import com.app.toaster.exception.Error;
import com.app.toaster.exception.model.CustomException;

import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;

public class TitleValidator implements ConstraintValidator<TitleValid, String> {

public String pattern;
@Override
public void initialize(TitleValid constraintAnnotation) {
this.pattern = constraintAnnotation.pattern();
}

@Override
public boolean isValid(String title, ConstraintValidatorContext context) {
System.out.println("여기는 오는건가");
context.disableDefaultConstraintViolation();
// 커스텀 예외를 던집니다.
// null, 공백으로만 이뤄지는 경우, 빈 값인 경우 ''
if (title.isBlank()) {
context.buildConstraintViolationWithTemplate("제목이 공백으로만 차있습니다.")
.addConstraintViolation();
return false;
}
// 길이가 1보다 작거나 10보다 큰 경우
if (title.isEmpty()) {
context.buildConstraintViolationWithTemplate("제목이 비어있습니다. ")
.addConstraintViolation();
return false;
}

// 첫 글자가 공백인 경우
return !(title.charAt(0) == ' ');
}
}
4 changes: 4 additions & 0 deletions linkmind/src/main/java/com/app/toaster/domain/Category.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,8 @@ public class Category {
public Category(String title) {
this.title = title;
}

public void updateCategoryIds(List<CategoryManagement> newCategories){
this.categoryManagements = newCategories; }

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Entity
@NoArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
@Setter
public class CategoryManagement {
Expand Down
5 changes: 2 additions & 3 deletions linkmind/src/main/java/com/app/toaster/domain/Toast.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
@Getter
@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Setter
public class Toast {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Expand All @@ -32,7 +31,7 @@ public class Toast {
@JoinColumn(name = "user_id")
private User user;

@OneToMany(mappedBy = "toast", cascade = CascadeType.ALL)
@OneToMany(mappedBy = "toast", cascade = CascadeType.ALL, orphanRemoval = true)
private List<CategoryManagement> categoryManagements = new ArrayList<>();


Expand All @@ -58,6 +57,6 @@ public void updateIsRead(Boolean isRead) {
this.isRead = isRead;
}

public void updateCategories(List<CategoryManagement> newCategories){
public void updateToastIds(List<CategoryManagement> newCategories){
this.categoryManagements = newCategories; }
}
10 changes: 9 additions & 1 deletion linkmind/src/main/java/com/app/toaster/exception/Error.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,15 @@ public enum Error {
* 404 NOT FOUND
*/
DUMMY_NOT_FOUND(HttpStatus.NOT_FOUND, "더미에 데이터가 덜 들어간 것 같아요"),
RESERVATION_NOT_FOUND(HttpStatus.NOT_FOUND, "예약정보를 찾지 못했어요"),
NOT_FOUND_USER_EXCEPTION(HttpStatus.NOT_FOUND, "찾을 수 없는 유저입니다."),
NOT_FOUND_CATEGORY_EXCEPTION(HttpStatus.NOT_FOUND, "찾을 수 없는 카테고리 입니다."),
NOT_FOUND_TOAST_EXCEPTION(HttpStatus.NOT_FOUND, "찾을 수 없는 토스트 입니다."),

/**
* 400 BAD REQUEST EXCEPTION
*/
BAD_REQUEST_ISREAD(HttpStatus.BAD_REQUEST, "isRead 값이 잘못요청 되었습니다."),
BAD_REQUEST_VALIDATION(HttpStatus.BAD_REQUEST, "유효한 값으로 요청을 다시 보내주세요."),

/**
* 401 UNAUTHORIZED EXCEPTION
Expand All @@ -24,6 +31,7 @@ public enum Error {
INVALID_APPLE_PUBLIC_KEY(HttpStatus.UNAUTHORIZED, "유효하지않은 애플 퍼블릭 키 입니다."),
EXPIRED_APPLE_IDENTITY_TOKEN(HttpStatus.UNAUTHORIZED, "만료된 아이덴티티 토큰입니다."),
INVALID_APPLE_IDENTITY_TOKEN(HttpStatus.UNAUTHORIZED, "잘못된 아이덴티티 토큰입니다."),
INVALID_USER_ACCESS(HttpStatus.UNAUTHORIZED, "접근 권한이 없는 유저입니다."),

UNPROCESSABLE_ENTITY_DELETE_EXCEPTION(HttpStatus.UNPROCESSABLE_ENTITY, "서버에서 요청을 이해해 삭제하려는 도중 문제가 생겼습니다."),
/**
Expand Down
9 changes: 5 additions & 4 deletions linkmind/src/main/java/com/app/toaster/exception/Success.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,16 @@ public enum Success {
/**
* 200 OK
*/
GET_AIR_MINPRICE_SUCESS(HttpStatus.OK, "항공사별 최저가격 조회 성공"),
GET_RESERVATION_SUCCESS(HttpStatus.OK, "항공권 페이지 조회 성공"),
GET_MAIN_SUCCESS(HttpStatus.OK, "메인 페이지 조회 성공"),
GET_TICKET_SUCCESS(HttpStatus.OK, "티켓 선택 페이지 조회 성공"),

LOGIN_SUCCESS(HttpStatus.OK, "로그인 성공"),
LOGIN_SUCCESS(HttpStatus.OK, "로그인 성공"),
RE_ISSUE_TOKEN_SUCCESS(HttpStatus.OK, "토큰 재발급 성공"),
SIGNOUT_SUCCESS(HttpStatus.OK, "로그아웃 성공"),
DELETE_USER_SUCCESS(HttpStatus.OK, "유저 삭제 성공"),
DELETE_TOAST_SUCCESS(HttpStatus.OK, "토스트 삭제 성공"),


UPDATE_ISREAD_SUCCESS(HttpStatus.OK, "열람여부 수정 완료"),


/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.app.toaster.exception.model;

import com.app.toaster.exception.Error;

public class BadRequestException extends CustomException{
public BadRequestException(Error error, String message) {
super(error, message);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import org.springframework.data.jpa.repository.JpaRepository;

import com.app.toaster.domain.CategoryManagement;
import com.app.toaster.domain.Toast;

public interface CategoryManagementRepository extends JpaRepository<CategoryManagement, Long> {

Long deleteAllByToast(Toast toast);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package com.app.toaster.infrastructure;

import java.util.Optional;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

import com.app.toaster.domain.Category;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,4 @@
import com.app.toaster.domain.Toast;

public interface ToastRepository extends JpaRepository<Toast, Long> {
void save();
}
Loading

0 comments on commit d142114

Please sign in to comment.