Skip to content

Commit

Permalink
Merge pull request #41 from Team-Lecue/feat/#14-book_delete_cascade_api
Browse files Browse the repository at this point in the history
[FEAT] 레큐북 삭제 API 구현
  • Loading branch information
eeddiinn authored Jan 9, 2024
2 parents a770e77 + 629f9ed commit 0bf1d93
Show file tree
Hide file tree
Showing 18 changed files with 105 additions and 106 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/CD.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,4 @@ jobs:
key: ${{ secrets.RELEASE_SERVER_KEY }}
script: |
cd ~
./deploy.sh
docker image prune -f
./deploy.sh
40 changes: 10 additions & 30 deletions src/main/java/org/sopt/lequuServer/InitDb.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,8 @@
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;

import static org.sopt.lequuServer.domain.sticker.model.StickerCategory.*;
import static org.sopt.lequuServer.domain.sticker.model.StickerCategory.ALPHABET;
import static org.sopt.lequuServer.domain.sticker.model.StickerCategory.BIRTHDAY;

@Component
@RequiredArgsConstructor
Expand All @@ -27,15 +25,6 @@ public void init() {
initService.dbInit();
}

private static final List<String> CHARACTER_STICKERS = Arrays.asList(
"https://lequu-server-bucket.s3.ap-northeast-2.amazonaws.com/stickers/8d83b1c1-1e2c-437b-a2f5-e3ce96ce6d35.jpg",
"https://lequu-server-bucket.s3.ap-northeast-2.amazonaws.com/stickers/0215b8a5-d7a1-40c3-b291-5174b1747074.jpg",
"https://lequu-server-bucket.s3.ap-northeast-2.amazonaws.com/stickers/c446705f-d96f-4cef-b490-62979fc52cd9.jpg",
"https://lequu-server-bucket.s3.ap-northeast-2.amazonaws.com/stickers/1d8ac983-4862-4687-b27a-324a4ecb8ae6.jpg",
"https://lequu-server-bucket.s3.ap-northeast-2.amazonaws.com/stickers/ea9a990a-e6e5-4789-9911-a967095d3cdc.jpg",
"https://lequu-server-bucket.s3.ap-northeast-2.amazonaws.com/stickers/38e4509e-61ba-42e7-a823-8b379c1be022.jpg"
);

@Component
@Transactional
@RequiredArgsConstructor
Expand All @@ -55,7 +44,7 @@ public void dbInit() {
Book book1 = Book.builder()
.uuid("ee4f66f9-9cf4-4b28-90f4-f71d0ecba021")
.favoriteName("LeoJ")
.favoriteImage("https://lequu-server-bucket.s3.ap-northeast-2.amazonaws.com/books/favorite_image/b4006561-382b-479e-ae1d-e841922e883f.jpg")
.favoriteImage("https://lequu-server-bucket.s3.ap-northeast-2.amazonaws.com/b4006561-382b-479e-ae1d-e841922e883f.jpg")
.title("1번째 레큐북")
.description("레큐북의 내용입니다!")
.backgroundColor(1)
Expand All @@ -67,7 +56,7 @@ public void dbInit() {
Book book = Book.builder()
.uuid("ee4f66f9-9cf4-4b28-90f4-f71d0ecba02" + String.valueOf(i + 1))
.favoriteName("LeoJ")
.favoriteImage("https://lequu-server-bucket.s3.ap-northeast-2.amazonaws.com/books/favorite_image/b4006561-382b-479e-ae1d-e841922e883f.jpg")
.favoriteImage("https://lequu-server-bucket.s3.ap-northeast-2.amazonaws.com/b4006561-382b-479e-ae1d-e841922e883f.jpg")
.title(String.valueOf(i + 1) + "번째 레큐북")
.description("레큐북의 내용입니다!")
.backgroundColor(1)
Expand All @@ -80,7 +69,7 @@ public void dbInit() {
for (int i = 0; i < 3; i++) {
Note note = Note.builder()
.content("레큐노트 내용입니다 블라블라블라 블라블라블라 블라블라블라 블라블라블라 블라블라블라 블라블라블라 블라블라블라")
.background("https://lequu-server-bucket.s3.ap-northeast-2.amazonaws.com/notes/background_image/676c2ca3-f868-423f-8000-a0bcb67dc797.jpg")
.background("https://lequu-server-bucket.s3.ap-northeast-2.amazonaws.com/676c2ca3-f868-423f-8000-a0bcb67dc797.jpg")
.textColor(i)
.member(member1)
.book(book1)
Expand All @@ -101,47 +90,38 @@ public void dbInit() {
Sticker sticker1 = Sticker.builder()
.bookId(0L)
.category(ALPHABET)
.stickerImage("https://lequu-server-bucket.s3.ap-northeast-2.amazonaws.com/stickers/8d83b1c1-1e2c-437b-a2f5-e3ce96ce6d35.jpg")
.stickerImage("https://lequu-server-bucket.s3.ap-northeast-2.amazonaws.com/8d83b1c1-1e2c-437b-a2f5-e3ce96ce6d35.jpg")
.build();
em.persist(sticker1);
for (int i = 0; i < 3; i++) {
Sticker sticker = Sticker.builder()
.bookId(0L)
.category(ALPHABET)
.stickerImage("https://lequu-server-bucket.s3.ap-northeast-2.amazonaws.com/stickers/8d83b1c1-1e2c-437b-a2f5-e3ce96ce6d35.jpg")
.stickerImage("https://lequu-server-bucket.s3.ap-northeast-2.amazonaws.com/8d83b1c1-1e2c-437b-a2f5-e3ce96ce6d35.jpg")
.build();
em.persist(sticker);
}
for (int i = 0; i < 6; i++) {
Sticker sticker = Sticker.builder()
.bookId(0L)
.category(BIRTHDAY)
.stickerImage("https://lequu-server-bucket.s3.ap-northeast-2.amazonaws.com/stickers/8d83b1c1-1e2c-437b-a2f5-e3ce96ce6d35.jpg")
.build();
em.persist(sticker);
}
for (String characterSticker : CHARACTER_STICKERS) {
Sticker sticker = Sticker.builder()
.bookId(0L)
.category(CHARACTER)
.stickerImage(characterSticker)
.stickerImage("https://lequu-server-bucket.s3.ap-northeast-2.amazonaws.com/8d83b1c1-1e2c-437b-a2f5-e3ce96ce6d35.jpg")
.build();
em.persist(sticker);
}

for (int i = 0; i < 2; i++) {
Sticker sticker = Sticker.builder()
.bookId(1L)
.category(ALPHABET)
.stickerImage("https://lequu-server-bucket.s3.ap-northeast-2.amazonaws.com/stickers/8d83b1c1-1e2c-437b-a2f5-e3ce96ce6d35.jpg")
.stickerImage("https://lequu-server-bucket.s3.ap-northeast-2.amazonaws.com/8d83b1c1-1e2c-437b-a2f5-e3ce96ce6d35.jpg")
.build();
em.persist(sticker);
}
for (int i = 0; i < 3; i++) {
Sticker sticker = Sticker.builder()
.bookId(1L)
.category(BIRTHDAY)
.stickerImage("https://lequu-server-bucket.s3.ap-northeast-2.amazonaws.com/stickers/8d83b1c1-1e2c-437b-a2f5-e3ce96ce6d35.jpg")
.stickerImage("https://lequu-server-bucket.s3.ap-northeast-2.amazonaws.com/8d83b1c1-1e2c-437b-a2f5-e3ce96ce6d35.jpg")
.build();
em.persist(sticker);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package org.sopt.lequuServer.domain.book.controller;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.sopt.lequuServer.domain.book.dto.request.BookCreateRequestDto;
Expand All @@ -8,22 +11,31 @@
import org.sopt.lequuServer.global.auth.jwt.JwtProvider;
import org.sopt.lequuServer.global.common.dto.ApiResponse;
import org.sopt.lequuServer.global.exception.enums.SuccessType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import java.security.Principal;

@RestController
@RequestMapping("/api/books")
@RequiredArgsConstructor
@Tag(name = "Book", description = "레큐 북 API")
@SecurityRequirement(name = "JWT Auth")
public class BookController {

private final BookFacade bookFacade;

@PostMapping
@ResponseStatus(HttpStatus.CREATED)
@Operation(summary = "레큐 북 생성")
public ApiResponse<BookCreateResponseDto> createBook(@Valid @RequestBody BookCreateRequestDto request, Principal principal) {
return ApiResponse.success(SuccessType.BOOK_CREATE_SUCCESS, bookFacade.createBook(request, JwtProvider.getUserFromPrincial(principal)));
}

@DeleteMapping("/{bookId}")
@Operation(summary = "레큐 북 삭제")
public ApiResponse<?> deleteBook(@PathVariable Long bookId) {
bookFacade.deleteBook(bookId);
return ApiResponse.success(SuccessType.BOOK_DELETE_SUCCESS);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@
public record BookCreateRequestDto(

@NotBlank
@Size(min = 1, max = 12, message = "최애 이름은 1자 이상 12자 이하여야합니다.")
@Size(min = 1, max = 15, message = "최애 이름은 1자 이상 15자 이하여야합니다.")
String favoriteName,

String favoriteImage,

@NotBlank
@Size(min = 1, max = 12, message = "레큐북 제목은 1자 이상 12자 이하여야합니다.")
@Size(min = 1, max = 25, message = "레큐북 제목은 1자 이상 25자 이하여야합니다.")
String title,

@NotBlank
@Size(min = 1, max = 100, message = "레큐북 소개는 1자 이상 100자 이하여야합니다.")
@Size(min = 1, max = 65, message = "레큐북 소개는 1자 이상 65자 이하여야합니다.")
String description,

// TODO 숫자 1 or 2로 제한할 수 있는 것 추가
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,20 @@
import org.sopt.lequuServer.domain.book.dto.request.BookCreateRequestDto;
import org.sopt.lequuServer.domain.book.dto.response.BookCreateResponseDto;
import org.sopt.lequuServer.domain.book.model.Book;
import org.sopt.lequuServer.domain.book.repository.BookRepository;
import org.sopt.lequuServer.domain.book.service.BookService;
import org.sopt.lequuServer.domain.member.model.Member;
import org.sopt.lequuServer.domain.member.repository.MemberRepository;
import org.sopt.lequuServer.domain.note.model.Note;
import org.sopt.lequuServer.domain.note.repository.NoteRepository;
import org.sopt.lequuServer.domain.sticker.model.PostedSticker;
import org.sopt.lequuServer.domain.sticker.repository.PostedStickerRepository;
import org.sopt.lequuServer.domain.sticker.repository.StickerRepository;
import org.sopt.lequuServer.global.s3.service.S3Service;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.UUID;

import static org.sopt.lequuServer.global.s3.enums.ImageFolderName.BOOK_FAVORITE_IMAGE_FOLDER_NAME;
Expand All @@ -23,6 +30,10 @@ public class BookFacade {
private final BookService bookService;
private final MemberRepository memberRepository;
private final S3Service s3Service;
private final NoteRepository noteRepository;
private final PostedStickerRepository postedStickerRepository;
private final BookRepository bookRepository;
private final StickerRepository stickerRepository;

public BookCreateResponseDto createBook(BookCreateRequestDto request, Long memberId) {

Expand Down Expand Up @@ -53,4 +64,30 @@ public BookCreateResponseDto createBook(BookCreateRequestDto request, Long membe

return bookService.createBook(book, member);
}

@Transactional
public void deleteBook(Long bookId) {
// bookId가 올바른건지 검증
Book book = bookRepository.findByIdOrThrow(bookId);

// 레큐북 id에 속하는 레큐노트 삭제
List<Note> notes = book.getNotes();
noteRepository.deleteAllInBatch(notes);

/** 순회 돌면서 삭제할 때 이용
for (Note note : notes) {
note.getId()
}
*/

// 레큐북 id에 속하는 붙여진 스티커 삭제
List<PostedSticker> postedStickers = book.getPostedStickers();
postedStickerRepository.deleteAllInBatch(postedStickers);

// 레큐북 id에 속하는 스티커 삭제
stickerRepository.deleteStickersByBookId(bookId);

// 정상적인 book id가 전송되면
bookRepository.deleteById(bookId);
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
package org.sopt.lequuServer.domain.common.controller;

import java.util.List;
import lombok.RequiredArgsConstructor;
import org.sopt.lequuServer.domain.common.dto.response.PopularBookResponseDto;
import org.sopt.lequuServer.domain.common.dto.response.SplashDto;
import org.sopt.lequuServer.domain.common.facade.CommonFacade;
import org.sopt.lequuServer.global.common.dto.ApiResponse;
import org.sopt.lequuServer.global.exception.enums.SuccessType;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/common")
Expand All @@ -19,11 +22,13 @@ public class CommonController {
private final CommonFacade commonFacade;

@GetMapping("/splash")
@ResponseStatus(HttpStatus.OK)
public ApiResponse<SplashDto> getSplash() {
return ApiResponse.success(SuccessType.GET_SPLASH_SUCCESS, commonFacade.getSplash());
}

@GetMapping("/home")
@ResponseStatus(HttpStatus.OK)
public ApiResponse<List<PopularBookResponseDto>> getHome() {
return ApiResponse.success(SuccessType.GET_HOME_SUCCESS, commonFacade.getHome());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,19 @@
package org.sopt.lequuServer.domain.member.controller;

import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.sopt.lequuServer.domain.member.dto.request.MemberNicknameRequestDto;
import org.sopt.lequuServer.domain.member.dto.request.SocialLoginRequestDto;
import org.sopt.lequuServer.domain.member.dto.response.MemberLoginResponseDto;
import org.sopt.lequuServer.domain.member.dto.response.MemberNicknameResponseDto;
import org.sopt.lequuServer.domain.member.service.MemberService;
import org.sopt.lequuServer.global.auth.fegin.kakao.KakaoLoginService;
import org.sopt.lequuServer.global.auth.jwt.JwtProvider;
import org.sopt.lequuServer.global.auth.jwt.TokenDto;
import org.sopt.lequuServer.global.common.dto.ApiResponse;
import org.sopt.lequuServer.global.exception.enums.SuccessType;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import java.security.Principal;

import static org.sopt.lequuServer.global.exception.enums.SuccessType.*;

@RestController
@RequestMapping("/api")
@RequiredArgsConstructor
Expand All @@ -32,37 +28,30 @@ public ApiResponse<MemberLoginResponseDto> login(
@RequestHeader("Authorization") String socialAccessToken,
@RequestBody SocialLoginRequestDto request) {

return ApiResponse.success(LOGIN_SUCCESS, memberService.login(socialAccessToken, request));
return ApiResponse.success(SuccessType.LOGIN_SUCCESS, memberService.login(socialAccessToken, request));
}

@GetMapping("/reissue")
@ResponseStatus(HttpStatus.OK)
public ApiResponse<TokenDto> reissue(
@RequestHeader("Authorization") String refreshToken) {

return ApiResponse.success(REISSUE_SUCCESS, memberService.reissueToken(refreshToken));
return ApiResponse.success(SuccessType.REISSUE_SUCCESS, memberService.reissueToken(refreshToken));
}

@PatchMapping("/log-out") // Spring Security 자체의 logout과 겹치지 않기 위해 이렇게 설정
@ResponseStatus(HttpStatus.OK)
public ApiResponse<?> logout(Principal principal) {

memberService.logout(JwtProvider.getUserFromPrincial(principal));
return ApiResponse.success(LOGOUT_SUCCESS);
return ApiResponse.success(SuccessType.LOGOUT_SUCCESS);
}

@GetMapping("/kakao")
@ResponseStatus(HttpStatus.OK)
public ApiResponse<?> kakaoAccessToken(
@RequestHeader("Authorization") String code) {

return ApiResponse.success(KAKAO_ACCESS_TOKEN_SUCCESS, kakaoLoginService.getKakaoAccessToken(code));
}

@PatchMapping("/nickname")
@ResponseStatus(HttpStatus.OK)
public ApiResponse<MemberNicknameResponseDto> setMemberNickname(Principal principal, @Valid @RequestBody MemberNicknameRequestDto request) {

return ApiResponse.success(SET_MEMBER_NICKNAME_SUCCESS, memberService.setMemberNickname(JwtProvider.getUserFromPrincial(principal), request));
return ApiResponse.success(SuccessType.KAKAO_ACCESS_TOKEN_SUCCESS, kakaoLoginService.getKakaoAccessToken(code));
}
}
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,6 @@ public class Member extends BaseTimeEntity {

private String nickname;

public void updateNickname(String nickname) {
this.nickname = nickname;
}

/**
* 소셜 로그인 관련
*/
Expand Down
Loading

0 comments on commit 0bf1d93

Please sign in to comment.