Skip to content

Commit

Permalink
Merge pull request #67 from Team-Lecue/fix/#65-apply_unan_feedback
Browse files Browse the repository at this point in the history
[FIX] 윤한이형 피드백 반영
  • Loading branch information
ddongseop authored Jan 17, 2024
2 parents 1ce0f82 + 9576c59 commit 9a07237
Show file tree
Hide file tree
Showing 28 changed files with 362 additions and 401 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package org.sopt.lequuServer.domain.book.controller;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import org.sopt.lequuServer.domain.book.dto.request.BookCreateRequestDto;
import org.sopt.lequuServer.domain.book.dto.response.BookCreateResponseDto;
import org.sopt.lequuServer.domain.book.dto.response.BookDetailResponseDto;
import org.sopt.lequuServer.global.common.dto.ApiResponse;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;

import java.security.Principal;

@Tag(name = "Book", description = "레큐북 API")
public interface BookApi {

@SecurityRequirement(name = "JWT Authorization")
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "201",
description = "레큐북이 성공적으로 생성됐습니다.",
content = @Content(schema = @Schema(implementation = BookCreateResponseDto.class))
)
@Operation(summary = "레큐북 생성")
public ResponseEntity<ApiResponse<BookCreateResponseDto>> createBook(@Valid @RequestBody BookCreateRequestDto request, Principal principal);

@SecurityRequirement(name = "JWT Authorization")
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "204",
description = "레큐북을 성공적으로 삭제했습니다."
)
@Operation(summary = "레큐북 삭제")
public ResponseEntity<?> deleteBook(@Schema(example = "1") @PathVariable Long bookId);

@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "200",
description = "레큐북 상세 조회에 성공했습니다.",
content = @Content(schema = @Schema(implementation = BookDetailResponseDto.class))
)
@Operation(summary = "레큐북 상세 조회")
public ResponseEntity<ApiResponse<BookDetailResponseDto>> getBookDetail(@Schema(example = "ee4f66f9-9cf4-4b28-90f4-f71d0ecba021") @PathVariable String bookUuid);
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
package org.sopt.lequuServer.domain.book.controller;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
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 @@ -15,52 +10,31 @@
import org.sopt.lequuServer.global.common.dto.ApiResponse;
import org.sopt.lequuServer.global.exception.enums.SuccessType;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.security.Principal;

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

private final BookFacade bookFacade;

@PostMapping
@SecurityRequirement(name = "JWT Authorization")
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "201",
description = "레큐북이 성공적으로 생성됐습니다.",
content = @Content(schema = @Schema(implementation = BookCreateResponseDto.class))
)
@ResponseStatus(HttpStatus.CREATED)
@Operation(summary = "레큐북 생성")
public ApiResponse<BookCreateResponseDto> createBook(@Valid @RequestBody BookCreateRequestDto request, Principal principal) {
return ApiResponse.success(SuccessType.CREATE_BOOK_SUCCESS, bookFacade.createBook(request, JwtProvider.getUserFromPrincial(principal)));
public ResponseEntity<ApiResponse<BookCreateResponseDto>> createBook(@Valid @RequestBody BookCreateRequestDto request, Principal principal) {
return ResponseEntity.status(HttpStatus.CREATED).body(ApiResponse.success(SuccessType.CREATE_BOOK_SUCCESS, bookFacade.createBook(request, JwtProvider.getUserFromPrincial(principal))));
}

@DeleteMapping("/{bookId}")
@SecurityRequirement(name = "JWT Authorization")
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "204",
description = "레큐북을 성공적으로 삭제했습니다."
)
@Operation(summary = "레큐북 삭제")
public ApiResponse<?> deleteBook(@Schema(example = "1") @PathVariable Long bookId) {
public ResponseEntity<?> deleteBook(@PathVariable Long bookId) {
bookFacade.deleteBook(bookId);
return ApiResponse.success(SuccessType.DELETE_BOOK_SUCCESS);
return ResponseEntity.noContent().build();
}

@GetMapping("/detail/{bookUuid}")
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "200",
description = "레큐북 상세 조회에 성공했습니다.",
content = @Content(schema = @Schema(implementation = BookDetailResponseDto.class))
)
@ResponseStatus(HttpStatus.OK)
@Operation(summary = "레큐북 상세 조회")
public ApiResponse<BookDetailResponseDto> getBookDetail(@Schema(example = "ee4f66f9-9cf4-4b28-90f4-f71d0ecba021") @PathVariable String bookUuid) {
return ApiResponse.success(SuccessType.GET_BOOK_DETAIL_SUCCESS, bookFacade.getBookDetail(bookUuid));
public ResponseEntity<ApiResponse<BookDetailResponseDto>> getBookDetail(@PathVariable String bookUuid) {
return ResponseEntity.ok(ApiResponse.success(SuccessType.GET_BOOK_DETAIL_SUCCESS, bookFacade.getBookDetail(bookUuid)));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ public record BookDetailResponseDto(
@Schema(description = "레큐 노트 개수", example = "100")
int noteNum,

List<NoteDetailResponseDto> noteList,
List<NoteDetailResponseDto> noteDetailDtos,

List<PostedStickerDetailResponseDto> postedStickerList
List<PostedStickerDetailResponseDto> postedStickerDetailDtos
) {
public static BookDetailResponseDto of(Book book) {
String bookDate = formatLocalDate(book);
Expand All @@ -57,22 +57,22 @@ public static BookDetailResponseDto of(Book book) {

// 레큐노트 리스트 가공
int renderTypeCounter = 1;
List<NoteDetailResponseDto> noteList = new ArrayList<>();
List<NoteDetailResponseDto> noteDetailDtos = new ArrayList<>();
for (Note note : sortedNotes) {
noteList.add(NoteDetailResponseDto.of(note, renderTypeCounter));
noteDetailDtos.add(NoteDetailResponseDto.of(note, renderTypeCounter));
renderTypeCounter = (renderTypeCounter % 6 == 0) ? 1 : renderTypeCounter + 1;
}

// 부착된 스티커 리스트 가공
List<PostedSticker> postedStickers = book.getPostedStickers();
List<PostedStickerDetailResponseDto> postedStickerList = new ArrayList<>();
List<PostedStickerDetailResponseDto> postedStickerDetailDtos = new ArrayList<>();
for (PostedSticker postedSticker : postedStickers) {
postedStickerList.add(PostedStickerDetailResponseDto.of(postedSticker));
postedStickerDetailDtos.add(PostedStickerDetailResponseDto.of(postedSticker));
}

return new BookDetailResponseDto(book.getId(), book.getFavoriteImage(), book.getFavoriteName(),
book.getTitle(), book.getDescription(), bookDate, book.getMember().getNickname(),
book.getBackgroundColor(), book.getNotes().size(), noteList, postedStickerList
book.getBackgroundColor(), book.getNotes().size(), noteDetailDtos, postedStickerDetailDtos
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,7 @@ public BookCreateResponseDto createBook(BookCreateRequestDto request, Long membe
String bookUuid = UUID.randomUUID().toString();
// Presigned URL 이미지 업로드하기 위한 이미지 파일명 가져오기
// String imageUrl = s3Service.getURL(BOOK_FAVORITE_IMAGE_FOLDER_NAME.getValue() + request.favoriteImage());
String imageUrl = s3Service.getCloudFrontURL(
BOOK_FAVORITE_IMAGE_FOLDER_NAME.getValue() + request.favoriteImage());
String imageUrl = s3Service.getCloudFrontURL(BOOK_FAVORITE_IMAGE_FOLDER_NAME.getValue() + request.favoriteImage());

Book book = Book.builder()
.uuid(bookUuid)
Expand Down
15 changes: 0 additions & 15 deletions src/main/java/org/sopt/lequuServer/domain/book/model/Book.java
Original file line number Diff line number Diff line change
Expand Up @@ -73,19 +73,4 @@ public Book(String uuid, String favoriteName, String favoriteImage, String title
public static Book of(String uuid, String favoriteName, String favoriteImage, String title, String description, String backgroundColor, Member member, int popularRate) {
return new Book(uuid, favoriteName, favoriteImage, title, description, backgroundColor, member, popularRate);
}

// TODO S3 테스트용, 추후 삭제
public Book(String uuid, String favoriteName, String favoriteImage, String title, String description, String backgroundColor) {
this.uuid = uuid;
this.favoriteName = favoriteName;
this.favoriteImage = favoriteImage;
this.title = title;
this.description = description;
this.backgroundColor = backgroundColor;
}

// TODO S3 테스트용, 추후 삭제
public static Book test(String favoriteImage, String title) {
return new Book("test", "test", favoriteImage, title, "test", "#F5F5F5");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package org.sopt.lequuServer.domain.common.controller;

import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.sopt.lequuServer.domain.common.dto.response.PopularBookResponseDto;
import org.sopt.lequuServer.domain.common.dto.response.SplashDto;
import org.sopt.lequuServer.global.common.dto.ApiResponse;
import org.springframework.http.ResponseEntity;

import java.util.List;

@Tag(name = "Common", description = "홈 & 스플래시 API")
public interface CommonApi {

@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "200",
description = "스플래시 조회에 성공했습니다.",
content = @Content(schema = @Schema(implementation = SplashDto.class))
)
@Operation(summary = "스플래시 조회")
public ResponseEntity<ApiResponse<SplashDto>> getSplash();

@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "200",
description = "홈 화면 조회에 성공했습니다.",
content = @Content(array = @ArraySchema(schema = @Schema(implementation = PopularBookResponseDto.class)))
)
@Operation(summary = "홈 조회")
public ResponseEntity<ApiResponse<List<PopularBookResponseDto>>> getHome();

@Hidden
public ResponseEntity<ApiResponse<?>> test();
}
Original file line number Diff line number Diff line change
@@ -1,62 +1,37 @@
package org.sopt.lequuServer.domain.common.controller;

import io.sentry.Sentry;
import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
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.http.ResponseEntity;
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")
@Tag(name = "Common", description = "홈 & 스플래시 API")
public class CommonController {
public class CommonController implements CommonApi {

private final CommonFacade commonFacade;

@GetMapping("/splash")
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "200",
description = "스플래시 조회에 성공했습니다.",
content = @Content(schema = @Schema(implementation = SplashDto.class))
)
@ResponseStatus(HttpStatus.OK)
@Operation(summary = "스플래시 조회")
public ApiResponse<SplashDto> getSplash() {
return ApiResponse.success(SuccessType.GET_SPLASH_SUCCESS, commonFacade.getSplash());
public ResponseEntity<ApiResponse<SplashDto>> getSplash() {
return ResponseEntity.ok(ApiResponse.success(SuccessType.GET_SPLASH_SUCCESS, commonFacade.getSplash()));
}

@GetMapping("/home")
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "200",
description = "홈 화면 조회에 성공했습니다.",
content = @Content(array = @ArraySchema(schema = @Schema(implementation = PopularBookResponseDto.class)))
)
@ResponseStatus(HttpStatus.OK)
@Operation(summary = "홈 조회")
public ApiResponse<List<PopularBookResponseDto>> getHome() {
return ApiResponse.success(SuccessType.GET_HOME_SUCCESS, commonFacade.getHome());
public ResponseEntity<ApiResponse<List<PopularBookResponseDto>>> getHome() {
return ResponseEntity.ok(ApiResponse.success(SuccessType.GET_HOME_SUCCESS, commonFacade.getHome()));
}

@Hidden
@GetMapping("/test")
@ResponseStatus(HttpStatus.OK)
public ApiResponse<?> test() {
public ResponseEntity<ApiResponse<?>> test() {
throw new RuntimeException("테스트용 에러 발생");
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package org.sopt.lequuServer.domain.member.controller;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
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.dto.response.MypageBookResponseDto;
import org.sopt.lequuServer.domain.member.dto.response.MypageNoteResponseDto;
import org.sopt.lequuServer.global.auth.jwt.TokenDto;
import org.sopt.lequuServer.global.common.dto.ApiResponse;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;

import java.security.Principal;

@Tag(name = "Member", description = "마이페이지 & 로그인 관련 API")
public interface MemberApi {

@SecurityRequirement(name = "KAKAO Token")
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "200",
description = "로그인에 성공했습니다.",
content = @Content(schema = @Schema(implementation = MemberLoginResponseDto.class))
)
@Operation(summary = "로그인 + 회원가입")
public ResponseEntity<ApiResponse<MemberLoginResponseDto>> login(
@Schema(description = "카카오 Access 토큰 (아래 박스에는 아무거나 입력)", example = "ZC57anP1qo58PNNJhKG1MBz9BImWMWih65gKPXKYAAABjQkwKSIh5oEAb4_jFQ")
@RequestHeader("Authorization") String socialAccessToken,
@RequestBody SocialLoginRequestDto request);


@SecurityRequirement(name = "JWT Authorization")
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "200",
description = "Access 토큰 재발급에 성공했습니다.",
content = @Content(schema = @Schema(implementation = TokenDto.class))
)
@Operation(summary = "엑세스 토큰 재발급")
public ResponseEntity<ApiResponse<TokenDto>> reissue(
@Schema(description = "Refresh 토큰 (아래 박스에는 아무거나 입력)", example = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE3MDUyNTc0MDMsImV4cCI6MTc2ODMyOTQwMywibWVtYmVySWQiOjF9.qKP6AZc9EnA_6DLXJGHzURcJXlER8-mvUnPppEVCGfW4iyQGMS0ZT3f09K0khZBtEXHgMuyKy1m4K-GtSKtRAg")
@RequestHeader("Authorization") String refreshToken);

@SecurityRequirement(name = "JWT Authorization")
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "200",
description = "로그아웃에 성공했습니다."
)
@Operation(summary = "로그아웃")
public ResponseEntity<ApiResponse<?>> logout(Principal principal);

@SecurityRequirement(name = "KAKAO Token")
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "200",
description = "카카오 엑세스 토큰을 가져오는데 성공했습니다."
)
@Operation(summary = "카카오 엑세스 토큰 발급")
public ResponseEntity<ApiResponse<?>> kakaoAccessToken(
@Schema(description = "카카오 Authorization 코드 (아래 박스에는 아무거나 입력)", example = "u13t6n_uzDy3VbtRhvmtiOHIVioVMvFPTrrEK_lDgmd7-bY0GMD8FAi8TzUKPXNNAAABjQkwFpiSBpCp5rpDbg")
@RequestHeader("Authorization") String code);

@SecurityRequirement(name = "JWT Authorization")
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "200",
description = "유저 닉네임을 설정하여 회원가입에 성공했습니다.",
content = @Content(schema = @Schema(implementation = MemberNicknameResponseDto.class))
)
@Operation(summary = "유저 닉네임 설정")
public ResponseEntity<ApiResponse<MemberNicknameResponseDto>> setMemberNickname(Principal principal, @Valid @RequestBody MemberNicknameRequestDto request);

@SecurityRequirement(name = "JWT Authorization")
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "200",
description = "마이페이지의 유저 닉네임과 내 레큐북 조회에 성공했습니다.",
content = @Content(schema = @Schema(implementation = MypageBookResponseDto.class))
)
@Operation(summary = "마이페이지 레큐북 조회")
public ResponseEntity<ApiResponse<MypageBookResponseDto>> getMypageBook(Principal principal);

@SecurityRequirement(name = "JWT Authorization")
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "200",
description = "마이페이지의 유저 닉네임과 내 레큐노트 조회에 성공했습니다.",
content = @Content(schema = @Schema(implementation = MypageNoteResponseDto.class))
)
@Operation(summary = "마이페이지 레큐노트 조회")
public ResponseEntity<ApiResponse<MypageNoteResponseDto>> getMypageNote(Principal principal);
}
Loading

0 comments on commit 9a07237

Please sign in to comment.