Skip to content

Commit

Permalink
Merge pull request #110 from AdultOfNineteen/refactor/issue-109
Browse files Browse the repository at this point in the history
refactor : ํ…Œ์ด์ŠคํŒ… ๋…ธํŠธ ์กฐํšŒ ์ˆ˜์ •
  • Loading branch information
imenuuu authored Sep 2, 2024
2 parents 618e959 + 036bba6 commit 26aaea4
Show file tree
Hide file tree
Showing 10 changed files with 135 additions and 60 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public OperationCustomizer customize() {
}

private void generateErrorCodeResponseExample(
Operation operation, Class<? extends BaseErrorCode>[] errorCodeList) {
Operation operation, Class<? extends BaseErrorCode>[] errorCodeList) {
ApiResponses responses = operation.getResponses();
Map<Integer, List<ExampleHolder>> statusWithExampleHolders = new HashMap<>();

Expand All @@ -86,31 +86,31 @@ private void generateErrorCodeResponseExample(
// 400, 401, 404 ๋“ฑ ์—๋Ÿฌ์ฝ”๋“œ์˜ ์ƒํƒœ์ฝ”๋“œ๋“ค๋กœ ๋ฆฌ์ŠคํŠธ๋กœ ๋ชจ์๋‹ˆ๋‹ค.
// 400 ๊ฐ™์€ ์ƒํƒœ์ฝ”๋“œ์— ์—ฌ๋Ÿฌ ์—๋Ÿฌ์ฝ”๋“œ๋“ค์ด ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
List<ExampleHolder> exampleHolders =
Arrays.stream(errorCodes)
.map(
baseErrorCode -> {
try {
ErrorReason errorReason = baseErrorCode.getErrorReasonHttpStatus();
ErrorReason errorReasonToView = baseErrorCode.getErrorReason();
return ExampleHolder.builder()
.holder(
getSwaggerExample(
baseErrorCode.getExplainError(), errorReasonToView))
.code(errorReason.getHttpStatus().value())
.name(errorReason.getCode())
.build();
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
}
})
.collect(Collectors.toList());
Arrays.stream(errorCodes)
.map(
baseErrorCode -> {
try {
ErrorReason errorReason = baseErrorCode.getErrorReasonHttpStatus();
ErrorReason errorReasonToView = baseErrorCode.getErrorReason();
return ExampleHolder.builder()
.holder(
getSwaggerExample(
baseErrorCode.getExplainError(), errorReasonToView))
.code(errorReason.getHttpStatus().value())
.name(errorReason.getCode())
.build();
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
}
})
.collect(Collectors.toList());

// statusWithExampleHolders์— ํ˜„์žฌ ๋ฃจํ”„์˜ ๊ฒฐ๊ณผ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
exampleHolders.forEach(
exampleHolder ->
statusWithExampleHolders
.computeIfAbsent(exampleHolder.getCode(), k -> new ArrayList<>())
.add(exampleHolder));
exampleHolder ->
statusWithExampleHolders
.computeIfAbsent(exampleHolder.getCode(), k -> new ArrayList<>())
.add(exampleHolder));
}

addExamplesToResponses(responses, statusWithExampleHolders);
Expand All @@ -124,20 +124,20 @@ private Example getSwaggerExample(String value, ErrorReason errorReason) {
}

private void addExamplesToResponses(
ApiResponses responses, Map<Integer, List<ExampleHolder>> statusWithExampleHolders) {
ApiResponses responses, Map<Integer, List<ExampleHolder>> statusWithExampleHolders) {
statusWithExampleHolders.forEach(
(status, v) -> {
Content content = new Content();
MediaType mediaType = new MediaType();
ApiResponse apiResponse = new ApiResponse();
v.forEach(
exampleHolder -> {
mediaType.addExamples(
exampleHolder.getName(), exampleHolder.getHolder());
});
content.addMediaType("application/json", mediaType);
apiResponse.setContent(content);
responses.addApiResponse(status.toString(), apiResponse);
});
(status, v) -> {
Content content = new Content();
MediaType mediaType = new MediaType();
ApiResponse apiResponse = new ApiResponse();
v.forEach(
exampleHolder -> {
mediaType.addExamples(
exampleHolder.getName(), exampleHolder.getHolder());
});
content.addMediaType("application/json", mediaType);
apiResponse.setContent(content);
responses.addApiResponse(status.toString(), apiResponse);
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,10 @@ public CommonResponse<PageResponse<List<TastingNoteResponse.TastingNoteListDTO>>
@Parameter(description = "์ตœ์‹ ์ˆœ = 0, ํ‰์ ์ˆœ = 1 ๊ธฐ๋ณธ ์ตœ์‹ ์ˆœ ์ •๋ ฌ์ž…๋‹ˆ๋‹ค.", example = "0") @RequestParam(required = false, defaultValue = "0") Integer order,
@Parameter(description = "์ƒ์‚ฐ์ง€ ๊ตญ๊ฐ€์ž…๋‹ˆ๋‹ค. List<String> ํ˜•์‹์ž…๋‹ˆ๋‹ค.", required = false) @RequestParam(required = false) List<Country> countries,
@Parameter(description = "์™€์ธ ํƒ€์ž…์ž…๋‹ˆ๋‹ค. List<String> ํ˜•์‹์ž…๋‹ˆ๋‹ค.", required = false) @RequestParam(required = false) List<WineType> wineTypes,
@Parameter(description = "์™€์ธ ์žฌ๊ตฌ๋งค ์œ ๋ฌด ์ž…๋‹ˆ๋‹ค.") @RequestParam(required = false) Integer buyAgain
@Parameter(description = "์™€์ธ ์žฌ๊ตฌ๋งค ์œ ๋ฌด ์ž…๋‹ˆ๋‹ค.") @RequestParam(required = false) Integer buyAgain,
@Parameter(description = "ํ…Œ์ด์ŠคํŒ… ๋…ธํŠธ์—์„œ ์™€์ธ ID ๋กœ ๊ฒ€์ƒ‰ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ") @RequestParam(required = false) Long wineId
) {
return CommonResponse.onSuccess(tastingNoteService.getTastingNoteList(user, page, size,order, countries, wineTypes, buyAgain));
return CommonResponse.onSuccess(tastingNoteService.getTastingNoteList(user, page, size,order, countries, wineTypes, buyAgain, wineId));
}

@RequestMapping(value = "", consumes = {"multipart/form-data"}, method = RequestMethod.POST)
Expand All @@ -79,9 +80,10 @@ public CommonResponse<TastingNoteResponse.CreateTastingNoteDTO> createTastingNot
@ApiErrorCodeExample(UserAuthErrorCode.class)
public CommonResponse<TastingNoteResponse.TastingNoteDTO> getTastingNote(
@AuthenticationPrincipal User user,
@PathVariable Long noteId) {

return CommonResponse.onSuccess(tastingNoteService.getTastingNote(user, noteId));
@PathVariable Long noteId,
@RequestParam(defaultValue = "false") boolean isShared
) {
return CommonResponse.onSuccess(tastingNoteService.getTastingNote(user, noteId, isShared));
}

@GetMapping("/filter")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@ private TastingNoteResponse.TastingNoteListDTO toTastingNoteListDTO(TastingNote
.starRating(result.getStarRating())
.buyAgain(result.getBuyAgain())
.wineType(result.getWine().getType())
.isPublic(result.getIsPublic())
.tastingNoteNo(tastingNoteNo.get(result.getId()))
.build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ public static class TastingNoteListDTO {
private boolean buyAgain;
@Schema(description = "์™€์ธ ํƒ€์ž… RED,WHITE ๋“ฑ๋“ฑ")
private WineType wineType;
@Schema(description = "๊ณต๊ฐœ์œ ๋ฌด")
private boolean isPublic;
}

@NoArgsConstructor
Expand Down Expand Up @@ -112,6 +114,9 @@ public static class TastingNoteDTO {
private List<TastingNoteImage> tastingNoteImage;

private String memo;

@Schema(description = "๊ณต๊ฐœ์œ ๋ฌด")
private boolean isPublic;
}

@NoArgsConstructor
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@
public interface TastingNoteService {
TastingNoteResponse.CreateTastingNoteDTO createTastingNote(User user, TastingNoteRequest.CreateTastingNoteDTO request, List<MultipartFile> multipartFiles);

PageResponse<List<TastingNoteResponse.TastingNoteListDTO>> getTastingNoteList(User user, Integer page, Integer size, Integer order, List<Country> countries, List<WineType> wineTypes, Integer isBuyAgain);
PageResponse<List<TastingNoteResponse.TastingNoteListDTO>> getTastingNoteList(User user, Integer page, Integer size, Integer order, List<Country> countries, List<WineType> wineTypes, Integer isBuyAgain,
Long wineId);

TastingNoteResponse.TasteAnalysisDTO tasteAnalysis(User user);

TastingNoteResponse.CheckTastingNote checkTastingNote(User user);

TastingNoteResponse.TastingNoteDTO getTastingNote(User user, Long noteId);
TastingNoteResponse.TastingNoteDTO getTastingNote(User user, Long noteId, boolean isShared);

TastingNoteResponse.NoteFilterDTO getNoteFilter(User user);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
Expand All @@ -35,7 +36,7 @@
import java.util.List;
import java.util.Map;

import static com.example.wineydomain.tastingNote.exception.GetTastingNoteErrorCode.NOT_FOUND_TASTING_NOTE;
import static com.example.wineydomain.tastingNote.exception.GetTastingNoteErrorCode.*;
import static com.example.wineydomain.tastingNote.exception.UploadTastingNoteErrorCode.NOT_FOUNT_WINE;
import static com.example.wineyinfrastructure.amazonS3.enums.Folder.*;

Expand Down Expand Up @@ -69,10 +70,13 @@ public TastingNoteResponse.CheckTastingNote checkTastingNote(User user) {
}

@Override
public TastingNoteResponse.TastingNoteDTO getTastingNote(User user, Long noteId) {
TastingNote tastingNote = tastingNoteRepository.getTastingNote(noteId, false, user);
public TastingNoteResponse.TastingNoteDTO getTastingNote(User user, Long noteId, boolean isShared) {
TastingNote tastingNote = tastingNoteRepository.getTastingNote(noteId, false);
if(tastingNote == null) throw new BadRequestException(NOT_FOUND_TASTING_NOTE);
Map<Long, Integer> tastingNoteNo = getTastingNoteNo(user);
if(tastingNote.getIsPublic().equals(false) && !tastingNote.getUser().getId().equals(user.getId())) throw new BadRequestException(NOT_PUBLIC_TASTING_NOTE);
Map<Long, Integer> tastingNoteNo;
if(!isShared) tastingNoteNo = getTastingNoteNo(tastingNote.getUser());
else tastingNoteNo = getTastingNoteNoByWineId(tastingNote.getWine(), user);
return tastingNoteConvertor.toTastingNote(tastingNote, tastingNoteNo);
}

Expand Down Expand Up @@ -148,7 +152,10 @@ private void deleteImgFile(List<TastingNoteImage> tastingNoteImages) {

@Override
@Transactional
@CacheEvict(value = "tastingNoteNoLists", key = "#user.id")
@Caching(evict = {
@CacheEvict(value = "tastingNoteNoLists", key = "#user.id"),
@CacheEvict(value = "tastingNoteNoByWineId", key = "#request.wineId + '_' + #user.id")
})
public TastingNoteResponse.CreateTastingNoteDTO createTastingNote(User user, TastingNoteRequest.CreateTastingNoteDTO request, List<MultipartFile> multipartFiles) {
Wine wine = wineRepository.findById(request.getWineId()).orElseThrow(() -> new BadRequestException(NOT_FOUNT_WINE));
TastingNote tastingNote = tastingNoteRepository.save(tastingNoteConvertor.CreateTastingNote(request, user, wine));
Expand Down Expand Up @@ -176,11 +183,19 @@ private void tastingNoteImageUpload(TastingNote tastingNote, List<MultipartFile>
}

@Override
public PageResponse<List<TastingNoteResponse.TastingNoteListDTO>> getTastingNoteList(User user, Integer page, Integer size, Integer order, List<Country> countries, List<WineType> wineTypes, Integer buyAgain) {
Map<Long, Integer> tastingNoteNo = getTastingNoteNo(user);

Page<TastingNote> tastingNotes = tastingNoteRepository.findTastingNotes(user, page, size, order, countries, wineTypes, buyAgain);

public PageResponse<List<TastingNoteResponse.TastingNoteListDTO>> getTastingNoteList(User user, Integer page, Integer size, Integer order, List<Country> countries, List<WineType> wineTypes, Integer buyAgain,
Long wineId) {
Map<Long,Integer> tastingNoteNo;
Page<TastingNote> tastingNotes;
if(wineId ==null) {
tastingNoteNo = getTastingNoteNo(user);
tastingNotes = tastingNoteRepository.findTastingNotes(user, page, size, order, countries, wineTypes,
buyAgain);
}
else{
tastingNotes = tastingNoteRepository.findTastingNotesByWine(wineRepository.findById(wineId).orElseThrow(() -> new BadRequestException(NOT_FOUNT_WINE)),user, page, size);
tastingNoteNo = getTastingNoteNoByWineId(wineRepository.findById(wineId).orElseThrow(() -> new BadRequestException(NOT_FOUNT_WINE)), user);
}
return tastingNoteConvertor.toTastingNoteList(tastingNotes, tastingNoteNo);
}

Expand All @@ -194,4 +209,14 @@ public Map<Long, Integer> getTastingNoteNo(User user) {
}
return tastingNoteNo;
}

@Cacheable(value = "tastingNoteNoByWineId", key = "#wine.id + '_' + #user.id")
public Map<Long, Integer> getTastingNoteNoByWineId(Wine wine, User user){
Map<Long, Integer> tastingNoteNo = new HashMap<>();
List<TastingNote> tastingNotes = tastingNoteRepository.findByWineAndIsDeletedAndIsPublicOrderByIdAsc(wine, false, true, user);
for (int i = 0; i < tastingNotes.size(); i++) {
tastingNoteNo.put(tastingNotes.get(i).getId(), i+1);
}
return tastingNoteNo;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ public enum GetTastingNoteErrorCode implements BaseErrorCode {
*/

@ExplainError("ํ•ด๋‹น ์™€์ธ์ด ์—†๋Š” ๊ฒฝ์šฐ")
NOT_FOUND_TASTING_NOTE(BAD_REQUEST,"TASTING_NOTE_001", "ํ•ด๋‹น ํ…Œ์ด์ŠคํŒ… ๋…ธํŠธ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค..");
NOT_FOUND_TASTING_NOTE(BAD_REQUEST,"TASTING_NOTE_001", "ํ•ด๋‹น ํ…Œ์ด์ŠคํŒ… ๋…ธํŠธ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.."),
@ExplainError("ํ•ด๋‹น ํ…Œ์ด์ŠคํŒ… ๋…ธํŠธ๊ฐ€ ๊ณต๊ฐœ๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ")
NOT_PUBLIC_TASTING_NOTE(BAD_REQUEST,"TASTING_NOTE_002", "ํ•ด๋‹น ํ…Œ์ด์ŠคํŒ… ๋…ธํŠธ๊ฐ€ ๊ณต๊ฐœ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.");


private final HttpStatus httpStatus;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@
import com.example.wineydomain.tastingNote.entity.TastingNote;
import com.example.wineydomain.user.entity.User;
import com.example.wineydomain.wine.entity.Country;
import com.example.wineydomain.wine.entity.Wine;
import com.example.wineydomain.wine.entity.WineType;
import org.springframework.data.domain.Page;

import java.util.List;

public interface TastingNoteCustomRepository {
TastingNote getTastingNote(Long noteId, boolean deleted, User user);
TastingNote getTastingNote(Long noteId, boolean deleted);

Page<TastingNote> findTastingNotes(User user, Integer page, Integer size, Integer order, List<Country> countries, List<WineType> wineTypes, Integer buyAgain);

Page<TastingNote> findTastingNotesByWine(Wine wine, User user, Integer page, Integer size);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.example.wineydomain.tastingNote.entity.TastingNote;
import com.example.wineydomain.user.entity.User;
import com.example.wineydomain.wine.entity.Country;
import com.example.wineydomain.wine.entity.Wine;
import com.example.wineydomain.wine.entity.WineSummary;
import com.example.wineydomain.wine.entity.WineType;
import com.example.wineydomain.wine.repository.WineRepository;
Expand Down Expand Up @@ -96,6 +97,14 @@ public interface TastingNoteRepository extends JpaRepository<TastingNote, Long>,

List<TastingNote> findByUserAndIsDeletedOrderByIdAsc(User user, boolean b);

@Query("SELECT t FROM TastingNote t WHERE t.wine = :wine AND t.isDeleted = :isDeleted AND (t.isPublic = :isPublic OR t.user = :user) ORDER BY t.id ASC")
List<TastingNote> findByWineAndIsDeletedAndIsPublicOrderByIdAsc(
@Param("wine") Wine wine,
@Param("isDeleted") boolean isDeleted,
@Param("isPublic") boolean isPublic,
@Param("user") User user
);

interface WineList{
Long getWineId();

Expand Down
Loading

0 comments on commit 26aaea4

Please sign in to comment.