Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโ€™ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

๐Ÿ”ง ํ”„๋ก ํŠธ ์ธก ์š”๊ตฌ์‚ฌํ•ญ ๋ฐ ์ผ๋ถ€ ๋ฒ„๊ทธ ํ”ฝ์Šค #98

Merged
merged 4 commits into from
Feb 4, 2024
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@
- [ํ”„๋ก ํŠธ์—”๋“œ](https://github.com/KCY-Fit-a-Pet/fit-a-pet-client): [์ตœํฌ์ง„](https://github.com/heejinnn)
- ๋ฐฑ์—”๋“œ: [์–‘์žฌ์„œ](https://github.com/psychology50)

## [๊ฐœ๋ฐœ ๊ธฐ๋ก]
- [Side Project: Kakao Chat CI](https://jaeseo0519.tistory.com/323)
- [NCP Cloud Function & Object Storage presigned URL ๋ฐœ๊ธ‰](https://jaeseo0519.tistory.com/331)
- [Service Layer ๋ถ„๋ฆฌ์— ๋Œ€ํ•˜์—ฌ](https://jaeseo0519.tistory.com/314)
- [API ์„ธ๋ถ„ํ™”์— ๋Œ€ํ•˜์—ฌ](https://jaeseo0519.tistory.com/341)
- [OIDC OAuth2 ์ธ์ฆ](https://jaeseo0519.tistory.com/349)
- [Nginx ๊ตฌ์„ฑ๊ณผ HTTPS ์„ค์ •](https://jaeseo0519.tistory.com/354)
- [GitHub Action & NCP CD pipeline ๊ตฌ์ถ•](https://jaeseo0519.tistory.com/354)

## [ Contents ]
- [Project Summary](#project-summary)
- [Version Control](#version-control)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
import com.kcy.fitapet.domain.care.dto.CareInfoRes;
import com.kcy.fitapet.domain.care.dto.CareSaveReq;
import com.kcy.fitapet.domain.care.exception.CareErrorCode;
import com.kcy.fitapet.domain.care.service.module.CareSaveService;
import com.kcy.fitapet.domain.care.service.module.CareUpdateService;
import com.kcy.fitapet.domain.care.service.module.CareSearchService;
import com.kcy.fitapet.domain.care.type.WeekType;
import com.kcy.fitapet.domain.log.domain.CareLog;
import com.kcy.fitapet.domain.log.dto.CareLogInfo;
import com.kcy.fitapet.domain.log.service.CareLogSaveService;
import com.kcy.fitapet.domain.log.service.CareLogUpdateService;
import com.kcy.fitapet.domain.log.service.CareLogSearchService;
import com.kcy.fitapet.domain.member.service.module.MemberSearchService;
import com.kcy.fitapet.domain.pet.domain.Pet;
Expand All @@ -32,13 +32,13 @@
@RequiredArgsConstructor
@Slf4j
public class CareManageService {
private final CareSaveService careSaveService;
private final CareUpdateService careUpdateService;

private final MemberSearchService memberSearchService;
private final PetSearchService petSearchService;
private final CareSearchService careSearchService;
private final CareLogSearchService careLogSearchService;
private final CareLogSaveService careLogSaveService;
private final CareLogUpdateService careLogUpdateService;

@Transactional
public List<?> findCareCategoryNamesByPetId(Long petId) {
Expand Down Expand Up @@ -84,14 +84,13 @@ public CareLogInfo doCare(Long careDateId, Long userId) {
}

// TODO: ์ผ€์–ด ๋“ฑ๋ก ์‹œ๊ฐ„ 10๋ถ„ ์ „๋ถ€ํ„ฐ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ์กฐ๊ฑด ์ถ”๊ฐ€?

LocalDateTime today = LocalDateTime.now();
if (careLogSearchService.existsByCareDateIdOnLogDate(careDateId, today)) {
log.warn("์ด๋ฏธ ์ผ€์–ด๋ฅผ ์ˆ˜ํ–‰ํ•œ ๊ธฐ๋ก์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.");
throw new GlobalErrorException(CareErrorCode.ALREADY_CARED);
}

CareLog careLog = careLogSaveService.save(CareLog.of(careDate));
CareLog careLog = careLogUpdateService.save(CareLog.of(careDate));
log.info("careLog: {}", careLog);
return CareLogInfo.of(careLog.getLogDate(), memberSearchService.findById(userId).getUid());
}
Expand Down Expand Up @@ -120,13 +119,13 @@ private void persistAboutCare(
List<CareSaveReq.AdditionalPetDto> additionalPetDtos
) {
List<CareCategory> categories = findOrCreateCategories(categoryDto, additionalPetDtos);
careSaveService.saveCareCategories(categories);
careUpdateService.saveCareCategories(categories);

List<Care> cares = createCares(categoryDto, careInfoDto, categories);
careSaveService.saveCares(cares);
careUpdateService.saveCares(cares);

List<CareDate> dates = createCareDates(careInfoDto, cares);
careSaveService.saveCareDates(dates);
careUpdateService.saveCareDates(dates);
}

private List<CareCategory> findOrCreateCategories(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
@Service
@RequiredArgsConstructor
@Slf4j
public class CareSaveService {
public class CareUpdateService {
private final CareRepository careRepository;
private final CareDateRepository careDateRepository;
private final CareCategoryRepository careCategoryRepository;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package com.kcy.fitapet.domain.log.service;

import com.kcy.fitapet.domain.care.domain.Care;
import com.kcy.fitapet.domain.log.dao.CareLogRepository;
import com.kcy.fitapet.domain.log.domain.CareLog;
import com.kcy.fitapet.domain.log.domain.CareLogId;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class CareLogSaveService {
public class CareLogUpdateService {
private final CareLogRepository careLogRepository;

public CareLog save(CareLog careLog) {
Expand Down
11 changes: 9 additions & 2 deletions src/main/java/com/kcy/fitapet/domain/memo/api/MemoApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.data.web.SortDefault;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
Expand Down Expand Up @@ -89,7 +90,10 @@ public ResponseEntity<?> deleteSubMemoCategory(@PathVariable("pet_id") Long petI
public ResponseEntity<?> getMemosAndSubCategories(
@PathVariable("pet_id") Long petId, @PathVariable("memo_category_id") Long memoCategoryId,
@RequestParam(value = "search", defaultValue = "", required = false) String search,
@PageableDefault(size = 15, page = 0, sort = "memo.createdAt", direction = Sort.Direction.DESC) Pageable pageable
@PageableDefault(size = 5, page = 0) @SortDefault.SortDefaults({
@SortDefault(sort = "memo.createdAt", direction = Sort.Direction.DESC),
@SortDefault(sort = "memoImage.id", direction = Sort.Direction.ASC)}
) Pageable pageable
) {
MemoInfoDto.PageResponse res = memoManageService.findMemosInMemoCategory(memoCategoryId, pageable, search);
return ResponseEntity.ok(SuccessResponse.from(res));
Expand All @@ -112,7 +116,10 @@ public ResponseEntity<?> getMemosAndSubCategories(
@PreAuthorize("isAuthenticated() and @managerAuthorize.isManager(principal.userId, #petId)")
public ResponseEntity<?> getMemosByPet(
@PathVariable("pet_id") Long petId,
@PageableDefault(size = 5, page = 0, sort = "memo.createdAt", direction = Sort.Direction.DESC) Pageable pageable
@PageableDefault(size = 5, page = 0) @SortDefault.SortDefaults({
@SortDefault(sort = "memo.createdAt", direction = Sort.Direction.DESC),
@SortDefault(sort = "memoImage.id", direction = Sort.Direction.ASC)}
) Pageable pageable
) {
MemoInfoDto.PageResponse res = memoManageService.findMemosByPetId(petId, pageable);
return ResponseEntity.ok(SuccessResponse.from(res));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@

public interface MemoQueryDslRepository {
Optional<MemoInfoDto.MemoInfo> findMemoAndMemoImageUrlsById(Long memoId);
Slice<MemoInfoDto.MemoInfo> findMemosInMemoCategory(Long memoCategoryId, Pageable pageable, String target);
Slice<MemoInfoDto.MemoInfo> findMemosByPetId(Long petId, Pageable pageable);
Slice<MemoInfoDto.MemoSummaryInfo> findMemosInMemoCategory(Long memoCategoryId, Pageable pageable, String target);
Slice<MemoInfoDto.MemoSummaryInfo> findMemosByPetId(Long petId, Pageable pageable);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.kcy.fitapet.global.common.util.querydsl.QueryDslUtil;
import com.kcy.fitapet.global.common.util.querydsl.RepositorySliceHelper;
import com.querydsl.core.ResultTransformer;
import com.querydsl.core.group.GroupBy;
import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.Expressions;
Expand All @@ -21,7 +22,7 @@
import java.util.Optional;

import static com.querydsl.core.group.GroupBy.groupBy;
import static com.querydsl.core.types.Projections.list;
import static com.querydsl.core.group.GroupBy.list;

@Repository
@RequiredArgsConstructor
Expand All @@ -34,28 +35,32 @@ public class MemoQueryDslRepositoryImpl implements MemoQueryDslRepository {

@Override
public Optional<MemoInfoDto.MemoInfo> findMemoAndMemoImageUrlsById(Long memoId) {
return Optional.of(queryFactory
.select(
Projections.constructor(
MemoInfoDto.MemoInfo.class,
memo.id,
memoCategory.categoryName,
QueryDslUtil.left(memo.title, Expressions.constant(19)),
QueryDslUtil.left(memo.content, Expressions.constant(16)),
memo.createdAt,
list(
Projections.constructor(
MemoInfoDto.MemoImageInfo.class,
memoImage.id,
memoImage.imgUrl
).skipNulls()
).skipNulls()
)
)
List<MemoInfoDto.MemoInfo> result = queryFactory
.from(memo)
.leftJoin(memoCategory).on(memoCategory.id.eq(memo.memoCategory.id))
.leftJoin(memoImage).on(memo.id.eq(memoImage.memo.id))
.where(memo.id.eq(memoId))
.fetchFirst());
.transform(
groupBy(memoCategory.id, memo.id).list(
Projections.constructor(
MemoInfoDto.MemoInfo.class,
memo.id,
memoCategory.categoryName,
memo.title,
memo.content,
memo.createdAt,
list(
Projections.constructor(
MemoInfoDto.MemoImageInfo.class,
memoImage.id,
memoImage.imgUrl
).skipNulls()
)
)
)
);

return result.isEmpty() ? Optional.empty() : Optional.of(result.get(0));
}

/**
Expand All @@ -81,8 +86,8 @@ public Optional<MemoInfoDto.MemoInfo> findMemoAndMemoImageUrlsById(Long memoId)
* </pre>
*/
@Override
public Slice<MemoInfoDto.MemoInfo> findMemosInMemoCategory(Long memoCategoryId, Pageable pageable, String target) {
List<MemoInfoDto.MemoInfo> results = queryFactory
public Slice<MemoInfoDto.MemoSummaryInfo> findMemosInMemoCategory(Long memoCategoryId, Pageable pageable, String target) {
List<MemoInfoDto.MemoSummaryInfo> results = queryFactory
.from(memo)
.leftJoin(memoImage).on(memoImage.memo.id.eq(memo.id))
.where(memo.id.in(
Expand All @@ -104,8 +109,8 @@ public Slice<MemoInfoDto.MemoInfo> findMemosInMemoCategory(Long memoCategoryId,
}

@Override
public Slice<MemoInfoDto.MemoInfo> findMemosByPetId(Long petId, Pageable pageable) {
List<MemoInfoDto.MemoInfo> results = queryFactory
public Slice<MemoInfoDto.MemoSummaryInfo> findMemosByPetId(Long petId, Pageable pageable) {
List<MemoInfoDto.MemoSummaryInfo> results = queryFactory
.from(memoCategory)
.leftJoin(memo).on(memo.memoCategory.id.eq(memoCategory.id))
.leftJoin(memoImage).on(memoImage.memo.id.eq(memo.id))
Expand All @@ -125,10 +130,10 @@ public Slice<MemoInfoDto.MemoInfo> findMemosByPetId(Long petId, Pageable pageabl
return RepositorySliceHelper.toSlice(results, pageable);
}

private ResultTransformer<List<MemoInfoDto.MemoInfo>> createMemoInfoDtoResultTransformer() {
private ResultTransformer<List<MemoInfoDto.MemoSummaryInfo>> createMemoInfoDtoResultTransformer() {
return groupBy(memo.id).list(
Projections.constructor(
MemoInfoDto.MemoInfo.class,
MemoInfoDto.MemoSummaryInfo.class,
memo.id,
queryFactory.select(memoCategory.categoryName).from(memoCategory).where(memoCategory.id.eq(memo.memoCategory.id)),
QueryDslUtil.left(memo.title, Expressions.constant(19)),
Expand All @@ -139,8 +144,13 @@ private ResultTransformer<List<MemoInfoDto.MemoInfo>> createMemoInfoDtoResultTra
MemoInfoDto.MemoImageInfo.class,
memoImage.id,
memoImage.imgUrl
).skipNulls()
).skipNulls()
)
).getExpression()
// Projections.constructor( // TODO: 2024-02-02 : memoImage ๊ฒฐ๊ณผ๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ์ผ ๋•Œ, ์–ด๋–ค ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š”์ง€? LIMIT์„ ๋ฐ–์œผ๋กœ ๋นผ๋„ ๋˜๋Š”์ง€?
// MemoInfoDto.MemoImageInfo.class,
// memoImage.id,
// memoImage.imgUrl
// )
)
);
}
Expand Down
37 changes: 32 additions & 5 deletions src/main/java/com/kcy/fitapet/domain/memo/dto/MemoInfoDto.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.kcy.fitapet.domain.memo.dto;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.kcy.fitapet.domain.memo.domain.Memo;
Expand All @@ -11,9 +12,11 @@
import lombok.Getter;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Slice;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

@Getter
public class MemoInfoDto {
Expand Down Expand Up @@ -42,31 +45,55 @@ public record MemoInfo(
public MemoInfo(Long memoId, String categorySuffix, String title, String content, LocalDateTime createdAt, List<MemoImageInfo> memoImages) {
this.memoId = memoId;
this.categorySuffix = categorySuffix;
this.title = title.length() == 19 ? title + "..." : title;
this.content = content.length() == 16 ? content + "..." : content;
this.title = title;
this.content = content;
this.createdAt = createdAt;
this.memoImages = (memoImages == null) ? List.of() : memoImages;
}
}

@Builder
@Dto(name = "memo")
public record MemoSummaryInfo(
Long memoId,
String categorySuffix,
String title,
String content,
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
LocalDateTime createdAt,
MemoImageInfo memoImage
) {
public MemoSummaryInfo(Long memoId, String categorySuffix, String title, String content, LocalDateTime createdAt, MemoImageInfo memoImage) {
this.memoId = memoId;
this.categorySuffix = categorySuffix;
this.title = title.length() == 19 ? title + "..." : title;
this.content = content.length() == 16 ? content.replace("\n", " ") + "..." : content.replace("\n", " ");
this.createdAt = createdAt;
this.memoImage = memoImage;
}
}

public record MemoImageInfo(
@JsonInclude(JsonInclude.Include.NON_NULL)
Long memoImageId,
@JsonInclude(JsonInclude.Include.NON_EMPTY)
String imgUrl
) {
public MemoImageInfo(Long memoImageId, String imgUrl) {
this.memoImageId = memoImageId;
this.imgUrl = imgUrl;
this.imgUrl = Objects.toString(imgUrl, "");
}
}

public record PageResponse(
@Schema(description = "๋ฉ”๋ชจ ๋ชฉ๋ก") List<MemoInfo> memos,
@Schema(description = "๋ฉ”๋ชจ ๋ชฉ๋ก") List<?> memos,
@Schema(description = "ํ˜„์žฌ ํŽ˜์ด์ง€") int currentPageNumber,
@Schema(description = "ํŽ˜์ด์ง€ ํฌ๊ธฐ") int pageSize,
@Schema(description = "ํ˜„์žฌ ํŽ˜์ด์ง€์˜ ๋ฐ์ดํ„ฐ ๊ฐœ์ˆ˜") int numberOfElements,
@Schema(description = "๋‹ค์Œ ํŽ˜์ด์ง€ ์กด์žฌ ์—ฌ๋ถ€") boolean hasNext
) {
public static PageResponse from(@NotNull Slice<MemoInfo> page) {
public static PageResponse from(@NotNull Slice<?> page) {
return new PageResponse(page.getContent(), page.getPageable().getPageNumber(), page.getPageable().getPageSize(), page.getNumberOfElements(), page.hasNext());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,14 @@ public MemoInfoDto.MemoInfo findMemoAndMemoImageUrlsById(Long memoId) {

@Transactional(readOnly = true)
public MemoInfoDto.PageResponse findMemosInMemoCategory(Long memoCategoryId, Pageable pageable, String target) {
Slice<MemoInfoDto.MemoInfo> page = memoRepository.findMemosInMemoCategory(memoCategoryId, pageable, target);
Slice<MemoInfoDto.MemoSummaryInfo> page = memoRepository.findMemosInMemoCategory(memoCategoryId, pageable, target);

return MemoInfoDto.PageResponse.from(page);
}

@Transactional(readOnly = true)
public MemoInfoDto.PageResponse findMemosByPetId(Long petId, Pageable pageable) {
Slice<MemoInfoDto.MemoInfo> page = memoRepository.findMemosByPetId(petId, pageable);
Slice<MemoInfoDto.MemoSummaryInfo> page = memoRepository.findMemosByPetId(petId, pageable);

return MemoInfoDto.PageResponse.from(page);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import java.util.Optional;

public interface OauthRepository extends ExtendedJpaRepository<OauthAccount, Long> {
Optional<OauthAccount> findByOauthIdAndProvider(BigInteger oauthId, ProviderType provider);
boolean existsByOauthIdAndProvider(BigInteger oauthId, ProviderType provider);
Optional<OauthAccount> findByOauthIdAndProvider(String oauthId, ProviderType provider);
boolean existsByOauthIdAndProvider(String oauthId, ProviderType provider);
boolean existsByEmail(String email);
}
Loading
Loading