diff --git a/.DS_Store b/.DS_Store index ecced65f..8276b0d6 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/likelion-admin/build.gradle b/likelion-admin/build.gradle index 8e166c42..2acdf417 100644 --- a/likelion-admin/build.gradle +++ b/likelion-admin/build.gradle @@ -1,14 +1,11 @@ dependencies { - implementation 'org.springframework.boot:spring-boot-starter-validation' - testImplementation platform('org.junit:junit-bom:5.9.1') - testImplementation 'org.junit.jupiter:junit-jupiter' implementation group: 'org.springframework.data', name: 'spring-data-commons' //pageable - /* security */ - implementation("org.springframework.boot:spring-boot-starter-security") implementation 'org.springdoc:springdoc-openapi-ui:1.6.9' + /* security */ + implementation("org.springframework.boot:spring-boot-starter-security") /* core 모듈 추가 */ implementation project(':likelion-core') /* redis 모듈 추가 */ @@ -19,5 +16,9 @@ dependencies { implementation project(':likelion-security') /* infrastructure 모듈 추가 */ implementation project(':likelion-infrastructure') + + testImplementation platform('org.junit:junit-bom:5.9.1') + testImplementation 'org.junit.jupiter:junit-jupiter' + testImplementation 'io.rest-assured:rest-assured' } diff --git a/likelion-admin/src/main/java/likelion/univ/LikelionAdminApplication.java b/likelion-admin/src/main/java/likelion/univ/LikelionAdminApplication.java index 818adc51..38fca7bc 100644 --- a/likelion-admin/src/main/java/likelion/univ/LikelionAdminApplication.java +++ b/likelion-admin/src/main/java/likelion/univ/LikelionAdminApplication.java @@ -2,13 +2,11 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.cache.annotation.EnableCaching; @SpringBootApplication public class LikelionAdminApplication { - public static void main(String[] args) { - SpringApplication.run(LikelionAdminApplication.class, args); - } - + public static void main(String[] args) { + SpringApplication.run(LikelionAdminApplication.class, args); + } } diff --git a/likelion-admin/src/main/java/likelion/univ/adminPost/controller/RepresentativeController.java b/likelion-admin/src/main/java/likelion/univ/adminPost/controller/RepresentativeController.java deleted file mode 100644 index 21595602..00000000 --- a/likelion-admin/src/main/java/likelion/univ/adminPost/controller/RepresentativeController.java +++ /dev/null @@ -1,50 +0,0 @@ -package likelion.univ.adminPost.controller; - -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.tags.Tag; -import likelion.univ.adminPost.dto.response.PostInfoResponseDto; -import likelion.univ.adminPost.usecase.DeleteSelectedPostsUseCase; -import likelion.univ.adminPost.usecase.GetPostsByCategoriesAndUniversityUseCase; -import likelion.univ.common.response.PageResponse; -import likelion.univ.domain.post.dto.enums.MainCategory; -import likelion.univ.domain.post.dto.enums.SubCategory; -import likelion.univ.response.SuccessResponse; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springdoc.api.annotations.ParameterObject; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.data.web.PageableDefault; -import org.springframework.web.bind.annotation.*; - -import java.util.List; - -@Slf4j -@RestController("adminPost.controller.RepresentativeController") -@RequestMapping(value = "/v1/univAdmin") -@RequiredArgsConstructor -@Tag(name = "PostByUnivAdmin", description = "학교 대표에 의한 게시글 관련 API") -public class RepresentativeController { - - - private final DeleteSelectedPostsUseCase deleteSelectedPostsUseCase; - private final GetPostsByCategoriesAndUniversityUseCase getPostsByCategoriesAndUniversityUseCase; - - @Operation(summary = "카테고리 별 게시글 조회") - @GetMapping("/posts") - public SuccessResponse getProjectsOfFreeBoardPosts(@ParameterObject @PageableDefault(size = 6, page = 0, sort = "created_date", direction = Sort.Direction.DESC)Pageable pageable, - @RequestParam MainCategory mainCategory, - @RequestParam SubCategory subCategory) { - PageResponse response = getPostsByCategoriesAndUniversityUseCase.execute(pageable, - mainCategory, subCategory); - return SuccessResponse.of(response); - } - @Operation(summary = "선택된 게시글들 삭제") - @DeleteMapping("/posts") - - public SuccessResponse getProjectsOfFreeBoardPosts(@RequestParam List selectedIds){ - deleteSelectedPostsUseCase.execute(selectedIds); - return SuccessResponse.empty(); - } -} - diff --git a/likelion-admin/src/main/java/likelion/univ/adminPost/usecase/DeleteSelectedPostsUseCase.java b/likelion-admin/src/main/java/likelion/univ/adminPost/usecase/DeleteSelectedPostsUseCase.java deleted file mode 100644 index a985aead..00000000 --- a/likelion-admin/src/main/java/likelion/univ/adminPost/usecase/DeleteSelectedPostsUseCase.java +++ /dev/null @@ -1,16 +0,0 @@ -package likelion.univ.adminPost.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.domain.post.adaptor.PostAdaptor; -import lombok.RequiredArgsConstructor; - -import java.util.List; - -@UseCase -@RequiredArgsConstructor -public class DeleteSelectedPostsUseCase { - private final PostAdaptor postAdaptor; - public void execute(List selectedIds){ - postAdaptor.deleteAllByIdInBatch(selectedIds); - } -} diff --git a/likelion-admin/src/main/java/likelion/univ/adminPost/usecase/GetPostsByCategoriesAndUniversityUseCase.java b/likelion-admin/src/main/java/likelion/univ/adminPost/usecase/GetPostsByCategoriesAndUniversityUseCase.java deleted file mode 100644 index cc50e75c..00000000 --- a/likelion-admin/src/main/java/likelion/univ/adminPost/usecase/GetPostsByCategoriesAndUniversityUseCase.java +++ /dev/null @@ -1,55 +0,0 @@ -package likelion.univ.adminPost.usecase; - -import likelion.univ.adminPost.dto.response.PostInfoResponseDto; -import likelion.univ.annotation.UseCase; -import likelion.univ.common.response.PageResponse; -import likelion.univ.domain.comment.adaptor.CommentAdaptor; -import likelion.univ.domain.like.postlike.adaptor.PostLikeAdaptor; -import likelion.univ.domain.post.adaptor.PostAdaptor; -import likelion.univ.domain.post.dto.enums.MainCategory; -import likelion.univ.domain.post.dto.enums.SubCategory; -import likelion.univ.domain.post.entity.Post; -import likelion.univ.domain.user.entity.User; -import likelion.univ.post.dao.PostCountInfoRedisDao; -import likelion.univ.post.entity.PostCountInfo; -import likelion.univ.post.service.PostCountInfoRedisService; -import likelion.univ.utils.AuthenticatedUserUtils; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; - -import java.util.Optional; - -@UseCase -@RequiredArgsConstructor -public class GetPostsByCategoriesAndUniversityUseCase { - private final PostAdaptor postAdaptor; - private final PostLikeAdaptor postLikeAdaptor; - private final CommentAdaptor commentAdaptor; - private final PostCountInfoRedisDao postCountInfoRedisDao; - private final PostCountInfoRedisService postCountInfoRedisService; - - private final AuthenticatedUserUtils authentiatedUserUtils; - public PageResponse execute(Pageable pageable, MainCategory mainCategory, SubCategory subCategory){ - User user = authentiatedUserUtils.getCurrentUser(); - - Page posts = postAdaptor.findPostsByCategoriesAndUniversityOrderByCreatedDate - (mainCategory, subCategory, user.getUniversityInfo().getUniversity().getId(), pageable); - - return PageResponse.of(posts.map(post -> createResult(post))); - } - - private PostInfoResponseDto createResult(Post post){ - PostCountInfo postCountInfo = getPostCountInfo(post.getId()); - return PostInfoResponseDto.of(post, postCountInfo.getLikeCount(), postCountInfo.getCommentCount()); - } - private PostCountInfo getPostCountInfo(Long postId){ - Optional postCountInfo = postCountInfoRedisDao.findById(postId); - if(postCountInfo.isEmpty()){ - Long commentCount = commentAdaptor.countByPostId(postId); - Long likeCount = postLikeAdaptor.countByPostId(postId); - return postCountInfoRedisService.save(postId, commentCount, likeCount); - }else return postCountInfo.get(); - } - -} \ No newline at end of file diff --git a/likelion-admin/src/main/java/likelion/univ/adminUser/controller/AdminUserController.java b/likelion-admin/src/main/java/likelion/univ/adminUser/controller/AdminUserController.java deleted file mode 100644 index 5bf70d49..00000000 --- a/likelion-admin/src/main/java/likelion/univ/adminUser/controller/AdminUserController.java +++ /dev/null @@ -1,69 +0,0 @@ -package likelion.univ.adminUser.controller; - -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.tags.Tag; -import likelion.univ.adminUser.dto.request.DeletedUserListRequestDto; -import likelion.univ.adminUser.dto.request.UpdateUserRequestDto; -import likelion.univ.adminUser.dto.response.UserInfoResponseDto; -import likelion.univ.adminUser.usecase.DeleteAllUserUseCase; -import likelion.univ.adminUser.usecase.DeleteUserUseCase; -import likelion.univ.adminUser.usecase.FindAllByUnivAdminUseCase; -import likelion.univ.adminUser.usecase.UpdateUserUseCase; -import likelion.univ.common.response.PageResponse; -import likelion.univ.response.SuccessResponse; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springdoc.api.annotations.ParameterObject; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.data.web.PageableDefault; -import org.springframework.web.bind.annotation.*; - -import javax.validation.Valid; - -@Slf4j -@RestController("adminUser.controller.RepresentativeController") -@RequestMapping(value = "/v1/univAdmin") -@RequiredArgsConstructor -@Tag(name = "UserByUnivAdmin", description = "학교 대표에 의한 사용자 관련 API") -public class AdminUserController { - - private final UpdateUserUseCase updateUserUseCase; - private final DeleteUserUseCase deleteUserUseCase; - private final DeleteAllUserUseCase deleteallUserUseCase; - private final FindAllByUnivAdminUseCase findAllByUnivAdminUseCase; - - @Operation(summary = "우리 학교 동아리 멤버 전체 조회") - @GetMapping("/univ/users") - public SuccessResponse> findUsersByUnivOfUser(@ParameterObject @PageableDefault(size=10, page = 0,sort="createdDate", direction = Sort.Direction.DESC)Pageable pageable) { - PageResponse response = findAllByUnivAdminUseCase.execute(pageable); - return SuccessResponse.of(response); - } - - - @Operation(summary = "우리 학교 동아리 특정 멤버 수정") - @PatchMapping("/users/{userId}") - public SuccessResponse updateUser(@PathVariable("userId")Long userId, - @RequestBody UpdateUserRequestDto updateUserRequestDto){ - - UserInfoResponseDto response = updateUserUseCase.execute(userId, updateUserRequestDto); - return SuccessResponse.of(response); - } - - - @Operation(summary = "우리 학교 동아리 특정 멤버 삭제") - @DeleteMapping("/users/{userId}") - public SuccessResponse deleteUser(@PathVariable("userId")Long userId){ - - deleteUserUseCase.execute(userId); - return SuccessResponse.empty(); - } - - @Operation(summary = "우리 학교 동아리 멤버(리스트) 삭제") - @DeleteMapping("/users") - public SuccessResponse deleteUserList(@Valid @RequestBody DeletedUserListRequestDto deletedUserListRequestDto){ - - deleteallUserUseCase.execute(deletedUserListRequestDto); - return SuccessResponse.empty(); - } -} diff --git a/likelion-admin/src/main/java/likelion/univ/adminUser/controller/HeadquatersController.java b/likelion-admin/src/main/java/likelion/univ/adminUser/controller/HeadquatersController.java deleted file mode 100644 index 632084e4..00000000 --- a/likelion-admin/src/main/java/likelion/univ/adminUser/controller/HeadquatersController.java +++ /dev/null @@ -1,40 +0,0 @@ -package likelion.univ.adminUser.controller; - -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.tags.Tag; -import likelion.univ.adminUser.dto.response.UserInfoResponseDto; -import likelion.univ.adminUser.usecase.FindAllByHeadqueatersUseCase; -import likelion.univ.common.response.PageResponse; -import likelion.univ.domain.user.entity.Role; -import likelion.univ.response.SuccessResponse; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springdoc.api.annotations.ParameterObject; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.data.web.PageableDefault; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -@Slf4j -@RestController -@RequestMapping(value = "/v1/headquaters") -@RequiredArgsConstructor -@Tag(name = "UserByHeadquaters", description = "본사에 의한 사용자 관련 API") -public class HeadquatersController { - - private final FindAllByHeadqueatersUseCase findAllByHeadqueatersUseCase; - - @Operation(summary = "회원 전체 조회") - @GetMapping("/users") - public SuccessResponse> findUsersByHeadquaters( - @ParameterObject @PageableDefault(size=10, page = 0, - sort="createdDate", direction = Sort.Direction.DESC) Pageable pageable, - @RequestParam(required = false) Role role, @RequestParam(required = false) String univName) { - PageResponse response = findAllByHeadqueatersUseCase.execute(role, univName, pageable); - return SuccessResponse.of(response); - } - -} diff --git a/likelion-admin/src/main/java/likelion/univ/adminUser/usecase/DeleteAllUserUseCase.java b/likelion-admin/src/main/java/likelion/univ/adminUser/usecase/DeleteAllUserUseCase.java deleted file mode 100644 index c952db95..00000000 --- a/likelion-admin/src/main/java/likelion/univ/adminUser/usecase/DeleteAllUserUseCase.java +++ /dev/null @@ -1,23 +0,0 @@ -package likelion.univ.adminUser.usecase; - -import likelion.univ.adminUser.dto.request.DeletedUserListRequestDto; -import likelion.univ.annotation.UseCase; -import likelion.univ.domain.user.adaptor.UserAdaptor; -import likelion.univ.domain.user.entity.User; -import likelion.univ.domain.user.service.UserDomainService; -import lombok.RequiredArgsConstructor; - -import java.util.List; - -@UseCase -@RequiredArgsConstructor -public class DeleteAllUserUseCase { - - private final UserAdaptor userAdaptor; - private final UserDomainService userDomainService; - - public void execute(DeletedUserListRequestDto deletedUserListRequestDto){ - List users = userAdaptor.findAllByIdIn(deletedUserListRequestDto.getIds()); - userDomainService.deleteAll(users); - } -} \ No newline at end of file diff --git a/likelion-admin/src/main/java/likelion/univ/adminUser/usecase/DeleteUserUseCase.java b/likelion-admin/src/main/java/likelion/univ/adminUser/usecase/DeleteUserUseCase.java deleted file mode 100644 index 287bb6e7..00000000 --- a/likelion-admin/src/main/java/likelion/univ/adminUser/usecase/DeleteUserUseCase.java +++ /dev/null @@ -1,20 +0,0 @@ -package likelion.univ.adminUser.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.domain.user.adaptor.UserAdaptor; -import likelion.univ.domain.user.entity.User; -import likelion.univ.domain.user.service.UserDomainService; -import lombok.RequiredArgsConstructor; - -@UseCase -@RequiredArgsConstructor -public class DeleteUserUseCase { - - private final UserAdaptor userAdaptor; - private final UserDomainService userDomainService; - - public void execute(Long userId){ - User user=userAdaptor.findById(userId); - userDomainService.deleteUser(user); - } -} diff --git a/likelion-admin/src/main/java/likelion/univ/adminUser/usecase/FindAllByHeadqueatersUseCase.java b/likelion-admin/src/main/java/likelion/univ/adminUser/usecase/FindAllByHeadqueatersUseCase.java deleted file mode 100644 index 726ca66e..00000000 --- a/likelion-admin/src/main/java/likelion/univ/adminUser/usecase/FindAllByHeadqueatersUseCase.java +++ /dev/null @@ -1,26 +0,0 @@ -package likelion.univ.adminUser.usecase; - -import likelion.univ.adminUser.dto.response.UserInfoResponseDto; -import likelion.univ.annotation.UseCase; -import likelion.univ.common.response.PageResponse; -import likelion.univ.domain.user.adaptor.UserAdaptor; -import likelion.univ.domain.user.entity.Role; -import likelion.univ.domain.user.entity.User; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; - -@UseCase -@RequiredArgsConstructor -public class FindAllByHeadqueatersUseCase { - - private final UserAdaptor userAdaptor; - - public PageResponse execute(Role role, String univName, Pageable pageable) { - - Page users = userAdaptor.findByUnivNameAndRole(role, univName, pageable); - - return PageResponse.of(users.map(u -> UserInfoResponseDto.of(u))); - - } -} diff --git a/likelion-admin/src/main/java/likelion/univ/adminUser/usecase/FindAllByUnivAdminUseCase.java b/likelion-admin/src/main/java/likelion/univ/adminUser/usecase/FindAllByUnivAdminUseCase.java deleted file mode 100644 index 530dc982..00000000 --- a/likelion-admin/src/main/java/likelion/univ/adminUser/usecase/FindAllByUnivAdminUseCase.java +++ /dev/null @@ -1,27 +0,0 @@ -package likelion.univ.adminUser.usecase; - -import likelion.univ.adminUser.dto.response.UserInfoResponseDto; -import likelion.univ.annotation.UseCase; -import likelion.univ.common.response.PageResponse; -import likelion.univ.domain.user.adaptor.UserAdaptor; -import likelion.univ.domain.user.entity.User; -import likelion.univ.utils.AuthenticatedUserUtils; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; - -@UseCase -@RequiredArgsConstructor -public class FindAllByUnivAdminUseCase { - - private final UserAdaptor userAdaptor; - private final AuthenticatedUserUtils authentiatedUserUtils; - - public PageResponse execute(Pageable pageable) { - User user = authentiatedUserUtils.getCurrentUser(); - - Page users = userAdaptor.findByUniversityInfoUniversityId(user.getUniversityInfo().getUniversity().getId(), pageable); - - return PageResponse.of(users.map(u->UserInfoResponseDto.of(u))); - } -} \ No newline at end of file diff --git a/likelion-admin/src/main/java/likelion/univ/adminUser/usecase/UpdateUserUseCase.java b/likelion-admin/src/main/java/likelion/univ/adminUser/usecase/UpdateUserUseCase.java deleted file mode 100644 index fd89a0b4..00000000 --- a/likelion-admin/src/main/java/likelion/univ/adminUser/usecase/UpdateUserUseCase.java +++ /dev/null @@ -1,27 +0,0 @@ -package likelion.univ.adminUser.usecase; - -import likelion.univ.adminUser.dto.request.UpdateUserRequestDto; -import likelion.univ.adminUser.dto.response.UserInfoResponseDto; -import likelion.univ.annotation.UseCase; -import likelion.univ.domain.user.adaptor.UserAdaptor; -import likelion.univ.domain.user.entity.User; -import likelion.univ.domain.user.service.UserDomainService; -import lombok.RequiredArgsConstructor; - - -@UseCase -@RequiredArgsConstructor -public class UpdateUserUseCase { - - private final UserAdaptor userAdaptor; - private final UserDomainService userDomainService; - - - public UserInfoResponseDto execute(Long userId, UpdateUserRequestDto updateUserRequestDto){ - User user = userAdaptor.findByIdWithUniversity(userId); - userDomainService.updateUser(user, updateUserRequestDto.getName(), - updateUserRequestDto.getPart(),updateUserRequestDto.getMajor(), - updateUserRequestDto.getOrdinal(), updateUserRequestDto.getRole()); - return UserInfoResponseDto.of(user); - } -} diff --git a/likelion-admin/src/main/java/likelion/univ/adminpost/controller/RepresentativeController.java b/likelion-admin/src/main/java/likelion/univ/adminpost/controller/RepresentativeController.java new file mode 100644 index 00000000..89a6b58b --- /dev/null +++ b/likelion-admin/src/main/java/likelion/univ/adminpost/controller/RepresentativeController.java @@ -0,0 +1,57 @@ +package likelion.univ.adminpost.controller; + +import static org.springframework.data.domain.Sort.Direction.DESC; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import java.util.List; +import likelion.univ.adminpost.dto.response.PostInfoResponseDto; +import likelion.univ.adminpost.service.AdminPostService; +import likelion.univ.common.response.PageResponse; +import likelion.univ.domain.post.dto.enums.MainCategory; +import likelion.univ.domain.post.dto.enums.SubCategory; +import likelion.univ.response.SuccessResponse; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springdoc.api.annotations.ParameterObject; +import org.springframework.data.domain.Pageable; +import org.springframework.data.web.PageableDefault; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@Slf4j +@RestController("adminpost.controller.RepresentativeController") +@RequestMapping("/v1/univAdmin") +@RequiredArgsConstructor +@Tag(name = "PostByUnivAdmin", description = "학교 대표에 의한 게시글 관련 API") +public class RepresentativeController { + + private final AdminPostService adminPostService; + + @Operation(summary = "카테고리 별 게시글 조회") + @GetMapping("/posts") + public SuccessResponse> getProjectsOfFreeBoardPosts( + @ParameterObject + @PageableDefault(size = 6, page = 0, sort = "created_date", direction = DESC) + Pageable pageable, + @RequestParam("mainCategory") MainCategory mainCategory, + @RequestParam("subCategory") SubCategory subCategory + ) { + PageResponse response = + adminPostService.getPostsByCategoriesAndUniversity(pageable, mainCategory, subCategory); + return SuccessResponse.of(response); + } + + @Operation(summary = "선택된 게시글들 삭제") + @DeleteMapping("/posts") + public SuccessResponse getProjectsOfFreeBoardPosts( + @RequestParam("selectedIds") List selectedIds + ) { + adminPostService.deletePosts(selectedIds); + return SuccessResponse.empty(); + } +} + diff --git a/likelion-admin/src/main/java/likelion/univ/adminPost/dto/response/PostInfoResponseDto.java b/likelion-admin/src/main/java/likelion/univ/adminpost/dto/response/PostInfoResponseDto.java similarity index 79% rename from likelion-admin/src/main/java/likelion/univ/adminPost/dto/response/PostInfoResponseDto.java rename to likelion-admin/src/main/java/likelion/univ/adminpost/dto/response/PostInfoResponseDto.java index 1a4cd968..b43afe92 100644 --- a/likelion-admin/src/main/java/likelion/univ/adminPost/dto/response/PostInfoResponseDto.java +++ b/likelion-admin/src/main/java/likelion/univ/adminpost/dto/response/PostInfoResponseDto.java @@ -1,18 +1,16 @@ -package likelion.univ.adminPost.dto.response; +package likelion.univ.adminpost.dto.response; -import likelion.univ.domain.post.adaptor.PostAdaptor; +import java.time.LocalDateTime; import likelion.univ.domain.post.entity.Post; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; -import org.springframework.transaction.annotation.Transactional; - -import java.time.LocalDateTime; @Data @Builder @AllArgsConstructor public class PostInfoResponseDto { + private Long id; private String title; private String body; @@ -21,10 +19,7 @@ public class PostInfoResponseDto { private Long commentsCounts; private LocalDateTime createDate; - private PostAdaptor postAdaptor; - - - public static PostInfoResponseDto of(Post post, Long postLikeCount, Long commentsCounts){ + public static PostInfoResponseDto of(Post post, Long postLikeCount, Long commentsCounts) { return new PostInfoResponseDtoBuilder() .id(post.getId()) .title(post.getTitle()) @@ -34,7 +29,6 @@ public static PostInfoResponseDto of(Post post, Long postLikeCount, Long comment .commentsCounts(commentsCounts) .createDate(post.getCreatedDate()) .build(); - } } diff --git a/likelion-admin/src/main/java/likelion/univ/adminpost/service/AdminPostService.java b/likelion-admin/src/main/java/likelion/univ/adminpost/service/AdminPostService.java new file mode 100644 index 00000000..6e4034a3 --- /dev/null +++ b/likelion-admin/src/main/java/likelion/univ/adminpost/service/AdminPostService.java @@ -0,0 +1,67 @@ +package likelion.univ.adminpost.service; + +import java.util.List; +import java.util.Optional; +import likelion.univ.adminpost.dto.response.PostInfoResponseDto; +import likelion.univ.common.response.PageResponse; +import likelion.univ.domain.comment.repository.CommentRepository; +import likelion.univ.domain.like.postlike.repository.PostLikeRepository; +import likelion.univ.domain.post.dto.enums.MainCategory; +import likelion.univ.domain.post.dto.enums.SubCategory; +import likelion.univ.domain.post.entity.Post; +import likelion.univ.domain.post.repository.PostRepository; +import likelion.univ.domain.user.entity.User; +import likelion.univ.post.dao.PostCountInfoRedisDao; +import likelion.univ.post.entity.PostCountInfo; +import likelion.univ.post.service.PostCountInfoRedisService; +import likelion.univ.utils.AuthenticatedUserUtils; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@RequiredArgsConstructor +@Transactional(readOnly = true) +@Service +public class AdminPostService { + + private final PostRepository postRepository; + private final PostLikeRepository postLikeRepository; + private final CommentRepository commentRepository; + private final PostCountInfoRedisDao postCountInfoRedisDao; + private final PostCountInfoRedisService postCountInfoRedisService; + + private final AuthenticatedUserUtils authenticatedUserUtils; + + @Transactional + public void deletePosts(List postIds) { + postRepository.deleteAllByIdInBatch(postIds); + } + + public PageResponse getPostsByCategoriesAndUniversity( + Pageable pageable, + MainCategory mainCategory, + SubCategory subCategory + ) { + User user = authenticatedUserUtils.getCurrentUser(); + Page posts = postRepository.findByCategoriesAndUniversityOrderByCreatedDate + (mainCategory, subCategory, user.getUniversityInfo().getUniversity().getId(), pageable); + return PageResponse.of(posts.map(this::createResult)); + } + + private PostInfoResponseDto createResult(Post post) { + PostCountInfo postCountInfo = getPostCountInfo(post.getId()); + return PostInfoResponseDto.of(post, postCountInfo.getLikeCount(), postCountInfo.getCommentCount()); + } + + private PostCountInfo getPostCountInfo(Long postId) { + Optional postCountInfo = postCountInfoRedisDao.findById(postId); + if (postCountInfo.isEmpty()) { + Long commentCount = commentRepository.countByPostId(postId); + Long likeCount = postLikeRepository.countByPostId(postId); + return postCountInfoRedisService.save(postId, commentCount, likeCount); + } + return postCountInfo.get(); + } +} diff --git a/likelion-admin/src/main/java/likelion/univ/adminuser/controller/AdminUserController.java b/likelion-admin/src/main/java/likelion/univ/adminuser/controller/AdminUserController.java new file mode 100644 index 00000000..9f1bc602 --- /dev/null +++ b/likelion-admin/src/main/java/likelion/univ/adminuser/controller/AdminUserController.java @@ -0,0 +1,74 @@ +package likelion.univ.adminuser.controller; + +import static org.springframework.data.domain.Sort.Direction.DESC; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import javax.validation.Valid; +import likelion.univ.adminuser.dto.request.DeletedUserListRequestDto; +import likelion.univ.adminuser.dto.request.UpdateUserRequestDto; +import likelion.univ.adminuser.dto.response.UserInfoResponseDto; +import likelion.univ.adminuser.service.AdminUserService; +import likelion.univ.common.response.PageResponse; +import likelion.univ.response.SuccessResponse; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springdoc.api.annotations.ParameterObject; +import org.springframework.data.domain.Pageable; +import org.springframework.data.web.PageableDefault; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Slf4j +@RestController("adminuser.controller.RepresentativeController") +@RequestMapping("/v1/univAdmin") +@RequiredArgsConstructor +@Tag(name = "UserByUnivAdmin", description = "학교 대표에 의한 사용자 관련 API") +public class AdminUserController { + + private final AdminUserService adminUserService; + + @Operation(summary = "우리 학교 동아리 멤버 전체 조회") + @GetMapping("/univ/users") + public SuccessResponse> findUsersByUnivOfUser( + @ParameterObject + @PageableDefault(size = 10, page = 0, sort = "createdDate", direction = DESC) + Pageable pageable + ) { + PageResponse response = adminUserService.findAllByAdminUserUniv(pageable); + return SuccessResponse.of(response); + } + + @Operation(summary = "우리 학교 동아리 특정 멤버 수정") + @PatchMapping("/users/{userId}") + public SuccessResponse updateUser( + @PathVariable("userId") Long userId, + @RequestBody UpdateUserRequestDto updateUserRequestDto + ) { + UserInfoResponseDto response = adminUserService.updateUser(userId, updateUserRequestDto); + return SuccessResponse.of(response); + } + + @Operation(summary = "우리 학교 동아리 특정 멤버 삭제") + @DeleteMapping("/users/{userId}") + public SuccessResponse deleteUser( + @PathVariable("userId") Long userId + ) { + adminUserService.delete(userId); + return SuccessResponse.empty(); + } + + @Operation(summary = "우리 학교 동아리 멤버(리스트) 삭제") + @DeleteMapping("/users") + public SuccessResponse deleteUserList( + @Valid @RequestBody DeletedUserListRequestDto dto + ) { + adminUserService.deleteAllUser(dto.getIds()); + return SuccessResponse.empty(); + } +} diff --git a/likelion-admin/src/main/java/likelion/univ/adminuser/controller/HeadquarterUserController.java b/likelion-admin/src/main/java/likelion/univ/adminuser/controller/HeadquarterUserController.java new file mode 100644 index 00000000..84ef610d --- /dev/null +++ b/likelion-admin/src/main/java/likelion/univ/adminuser/controller/HeadquarterUserController.java @@ -0,0 +1,41 @@ +package likelion.univ.adminuser.controller; + +import static org.springframework.data.domain.Sort.Direction.DESC; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import likelion.univ.adminuser.dto.response.UserInfoResponseDto; +import likelion.univ.adminuser.service.HeadquarterUserService; +import likelion.univ.common.response.PageResponse; +import likelion.univ.domain.user.entity.Role; +import likelion.univ.response.SuccessResponse; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springdoc.api.annotations.ParameterObject; +import org.springframework.data.domain.Pageable; +import org.springframework.data.web.PageableDefault; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; + +@Slf4j +@RequestMapping("/v1/headquarters") +@RequiredArgsConstructor +@Tag(name = "UserByHeadquarters", description = "본사에 의한 사용자 관련 API") +public class HeadquarterUserController { + + private final HeadquarterUserService headquarterUserService; + + @Operation(summary = "회원 전체 조회") + @GetMapping("/users") + public SuccessResponse> findUsersByHeadquaters( + @ParameterObject + @PageableDefault(size = 10, page = 0, sort = "createdDate", direction = DESC) + Pageable pageable, + @RequestParam(value = "role", required = false) Role role, + @RequestParam(value = "univName", required = false) String univName + ) { + PageResponse response = headquarterUserService.findAll(role, univName, pageable); + return SuccessResponse.of(response); + } +} diff --git a/likelion-admin/src/main/java/likelion/univ/adminUser/dto/request/DeletedUserListRequestDto.java b/likelion-admin/src/main/java/likelion/univ/adminuser/dto/request/DeletedUserListRequestDto.java similarity index 93% rename from likelion-admin/src/main/java/likelion/univ/adminUser/dto/request/DeletedUserListRequestDto.java rename to likelion-admin/src/main/java/likelion/univ/adminuser/dto/request/DeletedUserListRequestDto.java index 84db180b..d51d8183 100644 --- a/likelion-admin/src/main/java/likelion/univ/adminUser/dto/request/DeletedUserListRequestDto.java +++ b/likelion-admin/src/main/java/likelion/univ/adminuser/dto/request/DeletedUserListRequestDto.java @@ -1,21 +1,21 @@ -package likelion.univ.adminUser.dto.request; +package likelion.univ.adminuser.dto.request; import io.swagger.v3.oas.annotations.media.Schema; +import java.util.List; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Positive; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Positive; -import java.util.List; - @Getter @Builder @NoArgsConstructor @AllArgsConstructor public class DeletedUserListRequestDto { + @NotNull @NotEmpty(message = " 삭제할 유저 ID들을 입력해주세요.") @Schema(description = "유저 ID", example = "[111111, 222222]") diff --git a/likelion-admin/src/main/java/likelion/univ/adminUser/dto/request/UpdateUserRequestDto.java b/likelion-admin/src/main/java/likelion/univ/adminuser/dto/request/UpdateUserRequestDto.java similarity index 95% rename from likelion-admin/src/main/java/likelion/univ/adminUser/dto/request/UpdateUserRequestDto.java rename to likelion-admin/src/main/java/likelion/univ/adminuser/dto/request/UpdateUserRequestDto.java index 8363424c..1a84a4f2 100644 --- a/likelion-admin/src/main/java/likelion/univ/adminUser/dto/request/UpdateUserRequestDto.java +++ b/likelion-admin/src/main/java/likelion/univ/adminuser/dto/request/UpdateUserRequestDto.java @@ -1,33 +1,35 @@ -package likelion.univ.adminUser.dto.request; +package likelion.univ.adminuser.dto.request; import io.swagger.v3.oas.annotations.media.Schema; +import javax.validation.constraints.NotBlank; import likelion.univ.domain.user.entity.Role; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; -import javax.validation.constraints.NotBlank; - @Getter @NoArgsConstructor(access = AccessLevel.PRIVATE) @AllArgsConstructor public class UpdateUserRequestDto { + @NotBlank @Schema(description = "이름", example = "멋쟁이", required = true) private String name; + @NotBlank @Schema(description = "전공", example = "컴퓨터공학과", required = true) private String major; + @NotBlank @Schema(description = "파트", example = "BACKEND", required = true) private String part; + @NotBlank @Schema(description = "기수", example = "11", required = true) private Long ordinal; + @NotBlank @Schema(description = "역할", example = "MANAGER", required = true) private Role role; - - -} \ No newline at end of file +} diff --git a/likelion-admin/src/main/java/likelion/univ/adminUser/dto/response/UserInfoResponseDto.java b/likelion-admin/src/main/java/likelion/univ/adminuser/dto/response/UserInfoResponseDto.java similarity index 83% rename from likelion-admin/src/main/java/likelion/univ/adminUser/dto/response/UserInfoResponseDto.java rename to likelion-admin/src/main/java/likelion/univ/adminuser/dto/response/UserInfoResponseDto.java index d1b52072..7626f891 100644 --- a/likelion-admin/src/main/java/likelion/univ/adminUser/dto/response/UserInfoResponseDto.java +++ b/likelion-admin/src/main/java/likelion/univ/adminuser/dto/response/UserInfoResponseDto.java @@ -1,14 +1,17 @@ -package likelion.univ.adminUser.dto.response; +package likelion.univ.adminuser.dto.response; import likelion.univ.domain.user.entity.Part; import likelion.univ.domain.user.entity.Role; import likelion.univ.domain.user.entity.User; -import lombok.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; @Data @Builder @AllArgsConstructor public class UserInfoResponseDto { + private Long id; private String name; private String email; @@ -18,8 +21,7 @@ public class UserInfoResponseDto { private Long ordinal; private Role role; - - public static UserInfoResponseDto of(User user){ + public static UserInfoResponseDto of(User user) { return new UserInfoResponseDtoBuilder() .id(user.getId()) .name(user.getProfile().getName()) @@ -31,4 +33,4 @@ public static UserInfoResponseDto of(User user){ .role(user.getAuthInfo().getRole()) .build(); } -} \ No newline at end of file +} diff --git a/likelion-admin/src/main/java/likelion/univ/adminuser/service/AdminUserService.java b/likelion-admin/src/main/java/likelion/univ/adminuser/service/AdminUserService.java new file mode 100644 index 00000000..6b0dd949 --- /dev/null +++ b/likelion-admin/src/main/java/likelion/univ/adminuser/service/AdminUserService.java @@ -0,0 +1,54 @@ +package likelion.univ.adminuser.service; + +import java.util.List; +import likelion.univ.adminuser.dto.request.UpdateUserRequestDto; +import likelion.univ.adminuser.dto.response.UserInfoResponseDto; +import likelion.univ.common.response.PageResponse; +import likelion.univ.domain.user.entity.User; +import likelion.univ.domain.user.repository.UserRepository; +import likelion.univ.domain.user.service.UserService; +import likelion.univ.utils.AuthenticatedUserUtils; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@RequiredArgsConstructor +@Transactional(readOnly = true) +@Service +public class AdminUserService { + + private final UserRepository userRepository; + private final UserService userService; + private final AuthenticatedUserUtils authenticatedUserUtils; + + public void delete(Long userId) { + User user = userRepository.getById(userId); + userService.deleteUser(user); + } + + public void deleteAllUser(List userIds) { + List users = userRepository.findAllByIdsExactly(userIds); + userService.deleteAll(users); + } + + public PageResponse findAllByAdminUserUniv(Pageable pageable) { + User user = authenticatedUserUtils.getCurrentUser(); + Page users = userRepository.findByUniversityInfoUniversityId( + user.getUniversityInfo().getUniversity().getId(), + pageable + ); + return PageResponse.of(users.map(UserInfoResponseDto::of)); + } + + public UserInfoResponseDto updateUser(Long userId, UpdateUserRequestDto updateUserRequestDto) { + User user = userRepository.getByIdWithUniversity(userId); + userService.updateUser( + user, updateUserRequestDto.getName(), + updateUserRequestDto.getPart(), updateUserRequestDto.getMajor(), + updateUserRequestDto.getOrdinal(), updateUserRequestDto.getRole() + ); + return UserInfoResponseDto.of(user); + } +} diff --git a/likelion-admin/src/main/java/likelion/univ/adminuser/service/HeadquarterUserService.java b/likelion-admin/src/main/java/likelion/univ/adminuser/service/HeadquarterUserService.java new file mode 100644 index 00000000..d7413406 --- /dev/null +++ b/likelion-admin/src/main/java/likelion/univ/adminuser/service/HeadquarterUserService.java @@ -0,0 +1,25 @@ +package likelion.univ.adminuser.service; + +import likelion.univ.adminuser.dto.response.UserInfoResponseDto; +import likelion.univ.common.response.PageResponse; +import likelion.univ.domain.user.entity.Role; +import likelion.univ.domain.user.entity.User; +import likelion.univ.domain.user.repository.UserRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@RequiredArgsConstructor +@Transactional(readOnly = true) +@Service +public class HeadquarterUserService { + + private final UserRepository userRepository; + + public PageResponse findAll(Role role, String univName, Pageable pageable) { + Page users = userRepository.findByUnivNameAndRole(role, univName, pageable); + return PageResponse.of(users.map(UserInfoResponseDto::of)); + } +} diff --git a/likelion-admin/src/main/java/likelion/univ/alarm/controller/AlarmController.java b/likelion-admin/src/main/java/likelion/univ/alarm/controller/AlarmController.java index 81779668..86af38a8 100644 --- a/likelion-admin/src/main/java/likelion/univ/alarm/controller/AlarmController.java +++ b/likelion-admin/src/main/java/likelion/univ/alarm/controller/AlarmController.java @@ -1,59 +1,67 @@ package likelion.univ.alarm.controller; +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; +import static org.springframework.http.MediaType.MULTIPART_FORM_DATA_VALUE; + import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; -import likelion.univ.alarm.dto.*; -import likelion.univ.alarm.usecase.*; +import java.util.List; +import likelion.univ.alarm.dto.GetAlarmsDto; +import likelion.univ.alarm.dto.SendEmailDto; +import likelion.univ.alarm.service.AdminAlarmService; import likelion.univ.response.SuccessResponse; import lombok.RequiredArgsConstructor; -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RequestPart; +import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; -import java.util.List; - @Tag(name = "Alarm", description = "알람을 보내는 API") @RestController @RequestMapping(value = "/v1/alarm", produces = "application/json") @RequiredArgsConstructor public class AlarmController { - private final SendEmailUseCase sendEmailUseCase; - private final GetAlarmsUseCase getAlarmsUseCase; - private final DeleteAlarmUseCase deleteAlarmUseCase; + private final AdminAlarmService adminAlarmService; - @PostMapping( - value = "/email" , - consumes = {MediaType.APPLICATION_JSON_VALUE, MediaType.MULTIPART_FORM_DATA_VALUE} - ) @Operation( summary = "이메일 알람 전송 API", description = "이메일 알람을 보내는 API 입니다." ) + @PostMapping( + value = "/email", + consumes = {APPLICATION_JSON_VALUE, MULTIPART_FORM_DATA_VALUE} + ) public SuccessResponse sendEmail( @RequestPart SendEmailDto sendEmailDto, - @RequestPart(required = false) List attachments) { - sendEmailUseCase.execute(sendEmailDto, attachments); + @RequestPart(required = false) List attachments + ) { + adminAlarmService.sendEmail(sendEmailDto, attachments); return SuccessResponse.of("리크루팅 알람 전송 성공"); } - @GetMapping @Operation( summary = "알람 등록 조회 API", description = "알람 전송을 희망하는 분들을 조회하는 API 입니다." ) + @GetMapping public SuccessResponse getAlarms(@RequestParam Long ordinal) { - GetAlarmsDto response = getAlarmsUseCase.execute(ordinal); + GetAlarmsDto response = adminAlarmService.getAlarms(ordinal); return SuccessResponse.of(response); } - @DeleteMapping("/{id}") @Operation( summary = "알람 삭제 API", description = "등록된 알람을 삭제하는 API 입니다." ) + @DeleteMapping("/{id}") public SuccessResponse deleteAlarm(@PathVariable Long id) { - deleteAlarmUseCase.execute(id); + adminAlarmService.deleteAlarm(id); return SuccessResponse.of(id); } } diff --git a/likelion-admin/src/main/java/likelion/univ/alarm/dto/GetAlarmsDto.java b/likelion-admin/src/main/java/likelion/univ/alarm/dto/GetAlarmsDto.java index 09363d8c..5e82e9e6 100644 --- a/likelion-admin/src/main/java/likelion/univ/alarm/dto/GetAlarmsDto.java +++ b/likelion-admin/src/main/java/likelion/univ/alarm/dto/GetAlarmsDto.java @@ -1,13 +1,12 @@ package likelion.univ.alarm.dto; +import java.util.List; import likelion.univ.common.processor.DateCustomFormatter; import likelion.univ.domain.alarm.entity.Alarm; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; -import java.util.List; - @Getter @NoArgsConstructor @AllArgsConstructor diff --git a/likelion-admin/src/main/java/likelion/univ/alarm/dto/SendEmailDto.java b/likelion-admin/src/main/java/likelion/univ/alarm/dto/SendEmailDto.java index 33745035..381f24d1 100644 --- a/likelion-admin/src/main/java/likelion/univ/alarm/dto/SendEmailDto.java +++ b/likelion-admin/src/main/java/likelion/univ/alarm/dto/SendEmailDto.java @@ -1,11 +1,10 @@ package likelion.univ.alarm.dto; import io.swagger.v3.oas.annotations.media.Schema; +import java.util.List; import lombok.Getter; import lombok.NoArgsConstructor; -import java.util.List; - @Getter @NoArgsConstructor public class SendEmailDto { diff --git a/likelion-admin/src/main/java/likelion/univ/alarm/service/AdminAlarmService.java b/likelion-admin/src/main/java/likelion/univ/alarm/service/AdminAlarmService.java new file mode 100644 index 00000000..6a9a5aa5 --- /dev/null +++ b/likelion-admin/src/main/java/likelion/univ/alarm/service/AdminAlarmService.java @@ -0,0 +1,42 @@ +package likelion.univ.alarm.service; + +import java.util.List; +import likelion.univ.alarm.dto.GetAlarmsDto; +import likelion.univ.alarm.dto.SendEmailDto; +import likelion.univ.domain.alarm.entity.Alarm; +import likelion.univ.domain.alarm.service.AlarmService; +import likelion.univ.email.sender.EmailContent; +import likelion.univ.email.sender.EmailSender; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; + +@RequiredArgsConstructor +@Service +public class AdminAlarmService { + + private final AlarmService alarmService; + private final EmailSender emailSender; + + @Transactional + public void deleteAlarm(Long id) { + alarmService.deleteById(id); + } + + @Transactional(readOnly = true) + public GetAlarmsDto getAlarms(Long ordinal) { + List alarms = alarmService.findAllByOrdinal(ordinal); + return GetAlarmsDto.of(alarms); + } + + public void sendEmail(SendEmailDto sendEmailDto, List attachments) { + EmailContent emailContent = EmailContent.builder() + .subject(sendEmailDto.getSubject()) + .contents(sendEmailDto.getContents()) + .receivers(sendEmailDto.getReceivers()) + .attachments(attachments) + .build(); + emailSender.send(emailContent); + } +} diff --git a/likelion-admin/src/main/java/likelion/univ/alarm/usecase/DeleteAlarmUseCase.java b/likelion-admin/src/main/java/likelion/univ/alarm/usecase/DeleteAlarmUseCase.java deleted file mode 100644 index de238391..00000000 --- a/likelion-admin/src/main/java/likelion/univ/alarm/usecase/DeleteAlarmUseCase.java +++ /dev/null @@ -1,16 +0,0 @@ -package likelion.univ.alarm.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.domain.alarm.service.AlarmDomainService; -import lombok.RequiredArgsConstructor; - -@UseCase -@RequiredArgsConstructor -public class DeleteAlarmUseCase { - - private final AlarmDomainService alarmDomainService; - - public void execute(Long id) { - alarmDomainService.deleteById(id); - } -} diff --git a/likelion-admin/src/main/java/likelion/univ/alarm/usecase/GetAlarmsUseCase.java b/likelion-admin/src/main/java/likelion/univ/alarm/usecase/GetAlarmsUseCase.java deleted file mode 100644 index c2767860..00000000 --- a/likelion-admin/src/main/java/likelion/univ/alarm/usecase/GetAlarmsUseCase.java +++ /dev/null @@ -1,21 +0,0 @@ -package likelion.univ.alarm.usecase; - -import likelion.univ.alarm.dto.GetAlarmsDto; -import likelion.univ.annotation.UseCase; -import likelion.univ.domain.alarm.entity.Alarm; -import likelion.univ.domain.alarm.service.AlarmDomainService; -import lombok.RequiredArgsConstructor; - -import java.util.List; - -@UseCase -@RequiredArgsConstructor -public class GetAlarmsUseCase { - - private final AlarmDomainService alarmDomainService; - - public GetAlarmsDto execute(Long ordinal) { - List alarms = alarmDomainService.findAllByOrdinal(ordinal); - return GetAlarmsDto.of(alarms); - } -} diff --git a/likelion-admin/src/main/java/likelion/univ/alarm/usecase/SendEmailUseCase.java b/likelion-admin/src/main/java/likelion/univ/alarm/usecase/SendEmailUseCase.java deleted file mode 100644 index 854839c6..00000000 --- a/likelion-admin/src/main/java/likelion/univ/alarm/usecase/SendEmailUseCase.java +++ /dev/null @@ -1,28 +0,0 @@ -package likelion.univ.alarm.usecase; - -import likelion.univ.alarm.dto.SendEmailDto; -import likelion.univ.annotation.UseCase; -import likelion.univ.email.sender.EmailContent; -import likelion.univ.email.sender.EmailSender; -import lombok.RequiredArgsConstructor; -import org.springframework.web.multipart.MultipartFile; - -import java.util.List; - -@UseCase -@RequiredArgsConstructor -public class SendEmailUseCase { - - private final EmailSender emailSender; - - public void execute(SendEmailDto sendEmailDto, List attachments) { - EmailContent emailContent = EmailContent.builder() - .subject(sendEmailDto.getSubject()) - .contents(sendEmailDto.getContents()) - .receivers(sendEmailDto.getReceivers()) - .attachments(attachments) - .build(); - - emailSender.send(emailContent); - } -} diff --git a/likelion-admin/src/main/java/likelion/univ/config/AdminExceptionHandler.java b/likelion-admin/src/main/java/likelion/univ/config/AdminExceptionHandler.java index 48a4a6a8..55b1177f 100644 --- a/likelion-admin/src/main/java/likelion/univ/config/AdminExceptionHandler.java +++ b/likelion-admin/src/main/java/likelion/univ/config/AdminExceptionHandler.java @@ -1,5 +1,6 @@ package likelion.univ.config; +import java.net.BindException; import likelion.univ.exception.GlobalErrorCode; import likelion.univ.exception.base.BaseException; import likelion.univ.feign.exception.FeignClientException; @@ -13,14 +14,13 @@ import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; -import java.net.BindException; - @RestControllerAdvice @Slf4j public class AdminExceptionHandler { + /* - javax.validation.Valid or @Validated 으로 binding error 발생시 발생 - 주로 @RequestBody, @RequestPart 어노테이션에서 발생 + javax.validation.Valid or @Validated 으로 binding error 발생시 발생 + 주로 @RequestBody, @RequestPart 어노테이션에서 발생 */ @ExceptionHandler(MethodArgumentNotValidException.class) private ResponseEntity handleMethodArgumentNotValidException(MethodArgumentNotValidException e) { @@ -32,14 +32,15 @@ private ResponseEntity handleMethodArgumentNotValidException(Meth /* @ModelAttribute 으로 binding error 발생시 BindException 발생 */ @ExceptionHandler(BindException.class) - private ResponseEntity handleBindException(BindException e) { + private ResponseEntity handleBindException(BindException e) { ErrorResponse error = ErrorResponse.of(GlobalErrorCode.INVALID_HTTP_MESSAGE_BODY); return ResponseEntity.status(error.getHttpStatus()).body(error); } /* enum type 일치하지 않아 binding 못할 경우 발생 */ @ExceptionHandler(MethodArgumentTypeMismatchException.class) - private ResponseEntity handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e) { + private ResponseEntity handleMethodArgumentTypeMismatchException( + MethodArgumentTypeMismatchException e) { log.error("MethodArgumentTypeMismatchException Error", e); ErrorResponse error = ErrorResponse.of(GlobalErrorCode.INVALID_HTTP_MESSAGE_BODY); return ResponseEntity.status(error.getHttpStatus()).body(error); @@ -47,15 +48,17 @@ private ResponseEntity handleMethodArgumentTypeMismatchException /* 지원하지 않은 HTTP method 호출 할 경우 발생 */ @ExceptionHandler(HttpRequestMethodNotSupportedException.class) - private ResponseEntity handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) { + private ResponseEntity handleHttpRequestMethodNotSupportedException( + HttpRequestMethodNotSupportedException e) { log.error("HttpRequestMethodNotSupportedException Error", e); ErrorResponse error = ErrorResponse.of(GlobalErrorCode.UNSUPPORTED_HTTP_METHOD); return ResponseEntity.status(error.getHttpStatus()).body(error); } + /* request 값을 읽을 수 없을 때 발생 */ @ExceptionHandler(HttpMessageNotReadableException.class) - protected ResponseEntity handleHttpMessageNotReadableException(HttpMessageNotReadableException e) { + protected ResponseEntity handleHttpMessageNotReadableException(HttpMessageNotReadableException e) { log.error("HttpMessageNotReadableException error", e); ErrorResponse error = ErrorResponse.of(GlobalErrorCode.BAD_REQUEST_ERROR); @@ -64,24 +67,25 @@ protected ResponseEntity handleHttpMessageNotReadableException(H /* Feign Client 에러 */ @ExceptionHandler(FeignClientException.class) - private ResponseEntity handleFeignClientException(FeignClientException e) { + private ResponseEntity handleFeignClientException(FeignClientException e) { log.error("FeignClientError : " + e.getMethodKey()); log.error(e.getMessage()); - ErrorResponse error = ErrorResponse.of(e.getCode(),e.getMessage(), e.getHttpStatus()); + ErrorResponse error = ErrorResponse.of(e.getCode(), e.getMessage(), e.getHttpStatus()); return ResponseEntity.status(error.getHttpStatus()).body(error); } /* 비지니스 로직 에러 */ @ExceptionHandler(BaseException.class) - private ResponseEntity handleBusinessException(BaseException e) { + private ResponseEntity handleBusinessException(BaseException e) { log.error("BusinessError "); log.error(e.getErrorCode().getMessage()); ErrorResponse error = ErrorResponse.of(e.getErrorCode()); return ResponseEntity.status(error.getHttpStatus()).body(error); } + /* 나머지 예외 처리 */ @ExceptionHandler(Exception.class) - private ResponseEntity handleException(Exception e) { + private ResponseEntity handleException(Exception e) { log.error("Exception Error ", e); ErrorResponse error = ErrorResponse.of(GlobalErrorCode.SERVER_ERROR); return ResponseEntity.status(error.getHttpStatus()).body(error); diff --git a/likelion-admin/src/main/java/likelion/univ/config/SecurityConfig.java b/likelion-admin/src/main/java/likelion/univ/config/SecurityConfig.java index c37f8d57..cde65971 100644 --- a/likelion-admin/src/main/java/likelion/univ/config/SecurityConfig.java +++ b/likelion-admin/src/main/java/likelion/univ/config/SecurityConfig.java @@ -1,5 +1,7 @@ package likelion.univ.config; +import static likelion.univ.constant.StaticValue.SwaggerUrlPatterns; + import likelion.univ.security.AccessProcessor; import likelion.univ.security.filter.FilterProcessor; import lombok.RequiredArgsConstructor; @@ -11,12 +13,11 @@ import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.web.SecurityFilterChain; -import static likelion.univ.constant.StaticValue.SwaggerUrlPatterns; - @Configuration @RequiredArgsConstructor @EnableWebSecurity public class SecurityConfig { + private final FilterProcessor filterProcessor; private final AccessProcessor accessProcessor; @@ -26,11 +27,11 @@ public BCryptPasswordEncoder encoder() { } @Bean - public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{ + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.httpBasic().disable().cors();// cors 적용 http.csrf().disable(); http.formLogin().disable(); - http.sessionManagement( ).sessionCreationPolicy(SessionCreationPolicy.STATELESS); // JWT이용으로 세션 이용 x + http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); // JWT이용으로 세션 이용 x filterProcessor.common(http); http.authorizeRequests().expressionHandler(accessProcessor.expressionHandler()); @@ -40,6 +41,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{ .permitAll() .antMatchers("/v1/univAdmin/**").hasRole("MANAGER") .antMatchers("/v1/headquaters/**").hasRole("SUPER_ADMIN") + .antMatchers("/v1/hackathons/**").hasRole("SUPER_ADMIN") // .antMatchers("/v1/**").hasRole(ROLE_USER) // .anyRequest().authenticated(); .anyRequest().permitAll(); //임시 diff --git a/likelion-admin/src/main/java/likelion/univ/config/SwaggerConfig.java b/likelion-admin/src/main/java/likelion/univ/config/SwaggerConfig.java index ae316fbb..26155e5a 100644 --- a/likelion-admin/src/main/java/likelion/univ/config/SwaggerConfig.java +++ b/likelion-admin/src/main/java/likelion/univ/config/SwaggerConfig.java @@ -10,15 +10,15 @@ import io.swagger.v3.oas.models.security.SecurityRequirement; import io.swagger.v3.oas.models.security.SecurityScheme; import io.swagger.v3.oas.models.servers.Server; +import java.util.List; +import javax.servlet.ServletContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpHeaders; -import javax.servlet.ServletContext; -import java.util.List; - @Configuration public class SwaggerConfig { + @Bean public OpenAPI openAPI(ServletContext servletContext) { String contextPath = servletContext.getContextPath(); @@ -32,11 +32,13 @@ public OpenAPI openAPI(ServletContext servletContext) { .components(new Components() .addSecuritySchemes("Authorization(accessToken)", securityScheme())); } + @Bean public ModelResolver modelResolver(ObjectMapper objectMapper) { return new ModelResolver(objectMapper); } - private Info info(){ + + private Info info() { return new Info() .title("Likelion-Univ Admin API") .version("v1") @@ -46,7 +48,8 @@ private Info info(){ .name("Likelion-Univ") .email("tmfrk0426@gmail.com")); } - private License license(){ + + private License license() { License license = new License(); license.setUrl("https://github.com/LikelionUniv/LikelionUniv-Server"); license.setName("멋쟁이 사자처럼"); @@ -63,7 +66,7 @@ private SecurityScheme securityScheme() { } // Security 요청 설정 - private SecurityRequirement securityItem(){ + private SecurityRequirement securityItem() { SecurityRequirement securityItem = new SecurityRequirement(); securityItem.addList("Authorization(accessToken)"); return securityItem; diff --git a/likelion-admin/src/main/java/likelion/univ/example/controller/ExampleController.java b/likelion-admin/src/main/java/likelion/univ/example/controller/ExampleController.java index a5668d20..6a05a200 100644 --- a/likelion-admin/src/main/java/likelion/univ/example/controller/ExampleController.java +++ b/likelion-admin/src/main/java/likelion/univ/example/controller/ExampleController.java @@ -4,58 +4,58 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import likelion.univ.example.dto.request.CreateExampleRequestDto; - -import likelion.univ.example.usecase.CreateExampleUseCase; -import likelion.univ.example.usecase.DeleteExampleUseCase; -import likelion.univ.example.usecase.EditExampleUseCase; -import likelion.univ.example.usecase.GetExampleUseCase; +import likelion.univ.example.service.ExampleAdminService; import likelion.univ.response.SuccessResponse; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +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; @Slf4j @RestController @RequiredArgsConstructor -@RequestMapping(value = "/v1/example") +@RequestMapping("/v1/example") @Tag(name = "Example", description = "예시 API") public class ExampleController { - private final CreateExampleUseCase createExampleUseCase; - private final EditExampleUseCase editExampleUseCase; - private final GetExampleUseCase getExampleUseCase; - private final DeleteExampleUseCase deleteExampleUseCase; - - @GetMapping(value = "/{exampleId}") - @Operation(summary = "예시 조회",description = "예시를 조회합니다.") - public SuccessResponse GetExample(@PathVariable Long exampleId){ - return SuccessResponse.of(getExampleUseCase.excute(exampleId)); + + private final ExampleAdminService exampleAdminService; + + @Operation(summary = "예시 조회", description = "예시를 조회합니다.") + @GetMapping("/{exampleId}") + public SuccessResponse getExample(@PathVariable Long exampleId) { + return SuccessResponse.of(exampleAdminService.get(exampleId)); } - @PostMapping @Operation(summary = "예시 생성", description = "예시를 생성합니다.") + @PostMapping public SuccessResponse createExample( - @Validated @RequestBody CreateExampleRequestDto exampleRequestDto){ - //log.info("예시 생성 API 호출 USER = {}", user.getId()); - createExampleUseCase.excute(exampleRequestDto); + @Validated @RequestBody CreateExampleRequestDto exampleRequestDto + ) { + exampleAdminService.create(exampleRequestDto); return SuccessResponse.empty(); } - @PatchMapping(value = "/{exampleId}") @Operation(summary = "예시 수정", description = "예시를 수정합니다.") + @PatchMapping("/{exampleId}") public SuccessResponse editExample( - @PathVariable Long exampleId, - @Validated @RequestBody CreateExampleRequestDto exampleRequestDto){ - //log.info("예시 생성 API 호출 USER = {}", user.getId()); - editExampleUseCase.excute(exampleId,exampleRequestDto); + @PathVariable("exampleId") Long exampleId, + @Validated @RequestBody CreateExampleRequestDto exampleRequestDto + ) { + exampleAdminService.edit(exampleId, exampleRequestDto); return SuccessResponse.empty(); } - @DeleteMapping(value = "/{exampleId}") @Operation(summary = "예시 삭제", description = "예시를 삭제합니다.") - public SuccessResponse deleteExample(@PathVariable Long exampleId){ - //log.info("예시 생성 API 호출 USER = {}", user.getId()); - deleteExampleUseCase.excute(exampleId); + @DeleteMapping("/{exampleId}") + public SuccessResponse deleteExample(@PathVariable Long exampleId) { + exampleAdminService.delete(exampleId); return SuccessResponse.empty(); } } diff --git a/likelion-admin/src/main/java/likelion/univ/example/dto/request/CreateExampleRequestDto.java b/likelion-admin/src/main/java/likelion/univ/example/dto/request/CreateExampleRequestDto.java index 9dc67a48..cd957053 100644 --- a/likelion-admin/src/main/java/likelion/univ/example/dto/request/CreateExampleRequestDto.java +++ b/likelion-admin/src/main/java/likelion/univ/example/dto/request/CreateExampleRequestDto.java @@ -1,17 +1,11 @@ package likelion.univ.example.dto.request; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.NoArgsConstructor; - - import javax.validation.constraints.NotBlank; -@Data -@NoArgsConstructor -public class CreateExampleRequestDto { - - @NotBlank - @Schema(description = "댓글 내용", example = "안녕하세요. 멋쟁이사자처럼입니다.", required = true) - private String body; +public record CreateExampleRequestDto( + @NotBlank + @Schema(description = "댓글 내용", example = "안녕하세요. 멋쟁이사자처럼입니다.", required = true) + String body +) { } diff --git a/likelion-admin/src/main/java/likelion/univ/example/dto/response/ExampleInfoResponseDto.java b/likelion-admin/src/main/java/likelion/univ/example/dto/response/ExampleInfoResponseDto.java index e8235d06..35afe64b 100644 --- a/likelion-admin/src/main/java/likelion/univ/example/dto/response/ExampleInfoResponseDto.java +++ b/likelion-admin/src/main/java/likelion/univ/example/dto/response/ExampleInfoResponseDto.java @@ -1,16 +1,16 @@ package likelion.univ.example.dto.response; import likelion.univ.domain.example.entity.Example; -import likelion.univ.example.dto.request.CreateExampleRequestDto; import lombok.Builder; import lombok.Data; @Data @Builder public class ExampleInfoResponseDto { + private String body; - public static ExampleInfoResponseDto of(Example example){ + public static ExampleInfoResponseDto of(Example example) { return ExampleInfoResponseDto.builder() .body(example.getBody()) .build(); diff --git a/likelion-admin/src/main/java/likelion/univ/example/service/ExampleAdminService.java b/likelion-admin/src/main/java/likelion/univ/example/service/ExampleAdminService.java new file mode 100644 index 00000000..946cbe00 --- /dev/null +++ b/likelion-admin/src/main/java/likelion/univ/example/service/ExampleAdminService.java @@ -0,0 +1,37 @@ +package likelion.univ.example.service; + +import likelion.univ.domain.example.entity.Example; +import likelion.univ.domain.example.repository.ExampleRepository; +import likelion.univ.domain.example.service.ExampleService; +import likelion.univ.example.dto.request.CreateExampleRequestDto; +import likelion.univ.example.dto.response.ExampleInfoResponseDto; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@RequiredArgsConstructor +@Transactional(readOnly = true) +@Service +public class ExampleAdminService { + + private final ExampleService exampleService; + private final ExampleRepository exampleRepository; + + public void create(CreateExampleRequestDto createExampleRequestDto) { + exampleService.createExample(createExampleRequestDto.body()); + } + + public void delete(Long id) { + Example example = exampleRepository.getById(id); + exampleRepository.delete(example); + } + + public void edit(Long id, CreateExampleRequestDto createExampleRequestDto) { + exampleService.editExample(id, createExampleRequestDto.body()); + } + + public ExampleInfoResponseDto get(Long id) { + Example example = exampleRepository.getById(id); + return ExampleInfoResponseDto.of(example); + } +} diff --git a/likelion-admin/src/main/java/likelion/univ/example/usecase/CreateExampleUseCase.java b/likelion-admin/src/main/java/likelion/univ/example/usecase/CreateExampleUseCase.java deleted file mode 100644 index da695c71..00000000 --- a/likelion-admin/src/main/java/likelion/univ/example/usecase/CreateExampleUseCase.java +++ /dev/null @@ -1,31 +0,0 @@ -package likelion.univ.example.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.domain.example.adaptor.ExampleAdaptor; -import likelion.univ.domain.example.service.ExampleDomainService; -import likelion.univ.domain.user.adaptor.UserAdaptor; -import likelion.univ.domain.user.service.UserDomainService; -import likelion.univ.example.dto.request.CreateExampleRequestDto; -import lombok.RequiredArgsConstructor; - -@UseCase -@RequiredArgsConstructor -public class CreateExampleUseCase { - - /* 예시로 적어놓은 유저어댑터 및 도메인서비스입니다. 필요하지않는 싱글톤 인스턴스들은 제거해주세요. */ - private final UserAdaptor userAdaptor; - private final UserDomainService userDomainService; - - private final ExampleAdaptor exampleAdaptor; - private final ExampleDomainService exampleDomainService; - - /* - 하나의 usecase엔 하나의 기능만 담기 - 여기엔 여러개의 domainservice및 adapter을 호출하여 사용 할 수 있습니다. - Transaction을 배제한 도메인에 영향을 주지않는 service라고 생각하시면 쉽습니다. - Transaction의 영역의 로직은 domainservice 혹의 엔티티에 구현해주세요. (but, 엔티티에 구현은 최대한 자제)(예를들어 유저의경우 changeProfile 같은걸 엔티티에 구현) - */ - public void excute(CreateExampleRequestDto createExampleRequestDto){ - exampleDomainService.createExample(createExampleRequestDto.getBody()); - } -} diff --git a/likelion-admin/src/main/java/likelion/univ/example/usecase/DeleteExampleUseCase.java b/likelion-admin/src/main/java/likelion/univ/example/usecase/DeleteExampleUseCase.java deleted file mode 100644 index 908b16a8..00000000 --- a/likelion-admin/src/main/java/likelion/univ/example/usecase/DeleteExampleUseCase.java +++ /dev/null @@ -1,33 +0,0 @@ -package likelion.univ.example.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.domain.example.adaptor.ExampleAdaptor; -import likelion.univ.domain.example.entity.Example; -import likelion.univ.domain.example.service.ExampleDomainService; -import likelion.univ.domain.user.adaptor.UserAdaptor; -import likelion.univ.domain.user.service.UserDomainService; -import lombok.RequiredArgsConstructor; - -@UseCase -@RequiredArgsConstructor -public class DeleteExampleUseCase { - /* 예시로 적어놓은 유저어댑터 및 도메인서비스입니다. 필요하지않는 싱글톤 인스턴스들은 제거해주세요. */ - - private final UserAdaptor userAdaptor; - private final UserDomainService userDomainService; - - private final ExampleAdaptor exampleAdaptor; - private final ExampleDomainService exampleDomainService; - - /* - 하나의 usecase엔 하나의 기능만 담기 - 여기엔 여러개의 domainservice및 adapter을 호출하여 사용 할 수 있습니다. - Transaction을 배제한 도메인에 영향을 주지않는 service라고 생각하시면 쉽습니다. - Transaction의 영역의 로직은 domainservice 혹의 엔티티에 구현해주세요. (but, 엔티티에 구현은 최대한 자제)(예를들어 유저의경우 changeProfile 같은걸 엔티티에 구현) - */ - public void excute(Long id){ - Example example = exampleAdaptor.findById(id); - exampleAdaptor.delete(example); - } - -} diff --git a/likelion-admin/src/main/java/likelion/univ/example/usecase/EditExampleUseCase.java b/likelion-admin/src/main/java/likelion/univ/example/usecase/EditExampleUseCase.java deleted file mode 100644 index 1add6544..00000000 --- a/likelion-admin/src/main/java/likelion/univ/example/usecase/EditExampleUseCase.java +++ /dev/null @@ -1,31 +0,0 @@ -package likelion.univ.example.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.domain.example.adaptor.ExampleAdaptor; -import likelion.univ.domain.example.service.ExampleDomainService; -import likelion.univ.domain.user.adaptor.UserAdaptor; -import likelion.univ.domain.user.service.UserDomainService; -import likelion.univ.example.dto.request.CreateExampleRequestDto; -import lombok.RequiredArgsConstructor; - -@UseCase -@RequiredArgsConstructor -public class EditExampleUseCase { - /* 예시로 적어놓은 유저어댑터 및 도메인서비스입니다. 필요하지않는 싱글톤 인스턴스들은 제거해주세요. */ - private final UserAdaptor userAdaptor; - private final UserDomainService userDomainService; - - private final ExampleAdaptor exampleAdaptor; - private final ExampleDomainService exampleDomainService; - - /* - 하나의 usecase엔 하나의 기능만 담기 - 여기엔 여러개의 domainservice및 adapter을 호출하여 사용 할 수 있습니다. - Transaction을 배제한 도메인에 영향을 주지않는 service라고 생각하시면 쉽습니다. - Transaction의 영역의 로직은 domainservice 혹의 엔티티에 구현해주세요. (but, 엔티티에 구현은 최대한 자제)(예를들어 유저의경우 changeProfile 같은걸 엔티티에 구현) - */ - public void excute(Long id,CreateExampleRequestDto createExampleRequestDto){ - exampleDomainService.editExample(id,createExampleRequestDto.getBody()); - } - -} \ No newline at end of file diff --git a/likelion-admin/src/main/java/likelion/univ/example/usecase/GetExampleUseCase.java b/likelion-admin/src/main/java/likelion/univ/example/usecase/GetExampleUseCase.java deleted file mode 100644 index 773c2d4e..00000000 --- a/likelion-admin/src/main/java/likelion/univ/example/usecase/GetExampleUseCase.java +++ /dev/null @@ -1,32 +0,0 @@ -package likelion.univ.example.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.domain.example.adaptor.ExampleAdaptor; -import likelion.univ.domain.example.entity.Example; -import likelion.univ.domain.example.service.ExampleDomainService; -import likelion.univ.domain.user.adaptor.UserAdaptor; -import likelion.univ.domain.user.service.UserDomainService; -import likelion.univ.example.dto.response.ExampleInfoResponseDto; -import lombok.RequiredArgsConstructor; - -@UseCase -@RequiredArgsConstructor -public class GetExampleUseCase { - /* 예시로 적어놓은 유저어댑터 및 도메인서비스입니다. 필요하지않는 싱글톤 인스턴스들은 제거해주세요. */ - private final UserAdaptor userAdaptor; - private final UserDomainService userDomainService; - - private final ExampleAdaptor exampleAdaptor; - private final ExampleDomainService exampleDomainService; - - /* - 하나의 usecase엔 하나의 기능만 담기 - 여기엔 여러개의 domainservice및 adapter을 호출하여 사용 할 수 있습니다. - Transaction을 배제한 도메인에 영향을 주지않는 service라고 생각하시면 쉽습니다. - Transaction의 영역의 로직은 domainservice 혹의 엔티티에 구현해주세요. (but, 엔티티에 구현은 최대한 자제)(예를들어 유저의경우 changeProfile 같은걸 엔티티에 구현) - */ - public ExampleInfoResponseDto excute(Long id){ - Example example = exampleAdaptor.findById(id); - return ExampleInfoResponseDto.of(example); - } -} diff --git a/likelion-admin/src/main/java/likelion/univ/hackathon/controller/HackathonController.java b/likelion-admin/src/main/java/likelion/univ/hackathon/controller/HackathonController.java new file mode 100644 index 00000000..ed254597 --- /dev/null +++ b/likelion-admin/src/main/java/likelion/univ/hackathon/controller/HackathonController.java @@ -0,0 +1,36 @@ +package likelion.univ.hackathon.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import javax.validation.Valid; +import likelion.univ.common.response.PageResponse; +import likelion.univ.domain.hackathon.entity.HackathonForm; +import likelion.univ.domain.hackathon.response.HackathonFindResponse; +import likelion.univ.domain.hackathon.service.HackathonService; +import likelion.univ.hackathon.dto.request.HackathonFormSearchRequest; +import lombok.RequiredArgsConstructor; +import org.springdoc.api.annotations.ParameterObject; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/v1/hackathons") +@Tag(name = "해커톤", description = "어드민 해커톤 API") +public class HackathonController { + + private final HackathonService hackathonService; + + @Operation(summary = "해커톤 신청 조회") + @GetMapping + public PageResponse searchHackathons( + @ParameterObject @Valid HackathonFormSearchRequest request, + @ParameterObject Pageable pageable + ) { + Page result = hackathonService.search(request.toCondition(), pageable); + return PageResponse.of(result.map(HackathonFindResponse::from)); + } +} diff --git a/likelion-admin/src/main/java/likelion/univ/hackathon/dto/request/HackathonFormSearchRequest.java b/likelion-admin/src/main/java/likelion/univ/hackathon/dto/request/HackathonFormSearchRequest.java new file mode 100644 index 00000000..579eff6a --- /dev/null +++ b/likelion-admin/src/main/java/likelion/univ/hackathon/dto/request/HackathonFormSearchRequest.java @@ -0,0 +1,26 @@ +package likelion.univ.hackathon.dto.request; + +import io.swagger.v3.oas.annotations.media.Schema; +import javax.validation.constraints.NotNull; +import likelion.univ.domain.hackathon.repository.condition.HackathonFormSearchCondition; +import lombok.AllArgsConstructor; +import lombok.Getter; + +// 추후 레코드로 변경하기 +@Getter +@AllArgsConstructor +public class HackathonFormSearchRequest { + @Schema(description = "검색 키워드", example = "김멋사") + String keyword; + + @NotNull(message = "엑셀 다운로드 여부가 비었습니다.") + @Schema(description = "엑셀 다운로드 여부", example = "true") + Boolean isExcelData; + + public HackathonFormSearchCondition toCondition() { + return new HackathonFormSearchCondition( + keyword, + isExcelData + ); + } +} \ No newline at end of file diff --git a/likelion-admin/src/main/java/likelion/univ/utils/AuthenticatedUserUtils.java b/likelion-admin/src/main/java/likelion/univ/utils/AuthenticatedUserUtils.java index 03bd8af1..abca0360 100644 --- a/likelion-admin/src/main/java/likelion/univ/utils/AuthenticatedUserUtils.java +++ b/likelion-admin/src/main/java/likelion/univ/utils/AuthenticatedUserUtils.java @@ -1,21 +1,23 @@ package likelion.univ.utils; -import likelion.univ.domain.user.adaptor.UserAdaptor; import likelion.univ.domain.user.entity.User; +import likelion.univ.domain.user.repository.UserRepository; import likelion.univ.security.SecurityUtils; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; +// TODO 이거 반드시 지우기.. 서비스 layer 단에서 절대 시큐리티 쓰지 말고, 프레젠테이션에서 Id로 넘겨주는걸로.. @Component @RequiredArgsConstructor public class AuthenticatedUserUtils { - private final UserAdaptor userAdaptor; + + private final UserRepository userRepository; public Long getCurrentUserId() { return SecurityUtils.getCurrentUserId(); } public User getCurrentUser() { - return userAdaptor.findById(getCurrentUserId()); + return userRepository.getById(getCurrentUserId()); } } diff --git a/likelion-admin/src/test/java/likelion/univ/acceptance/AcceptanceSteps.java b/likelion-admin/src/test/java/likelion/univ/acceptance/AcceptanceSteps.java new file mode 100644 index 00000000..10442a52 --- /dev/null +++ b/likelion-admin/src/test/java/likelion/univ/acceptance/AcceptanceSteps.java @@ -0,0 +1,23 @@ +package likelion.univ.acceptance; + +import static io.restassured.http.ContentType.JSON; + +import io.restassured.RestAssured; +import io.restassured.specification.RequestSpecification; + +@SuppressWarnings("NonAsciiCharacters") +public final class AcceptanceSteps { + + public static RequestSpecification given() { + return RestAssured + .given() + .contentType(JSON); + } + + public static RequestSpecification given(String token) { + return RestAssured + .given() + .header("Authorization", "Bearer " + token) + .contentType(JSON); + } +} diff --git a/likelion-admin/src/test/java/likelion/univ/acceptance/AcceptanceTest.java b/likelion-admin/src/test/java/likelion/univ/acceptance/AcceptanceTest.java new file mode 100644 index 00000000..5804d943 --- /dev/null +++ b/likelion-admin/src/test/java/likelion/univ/acceptance/AcceptanceTest.java @@ -0,0 +1,27 @@ +package likelion.univ.acceptance; + +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; + +import io.restassured.RestAssured; +import likelion.univ.LikelionAdminApplication; +import likelion.univ.support.DataClearExtension; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.server.LocalServerPort; + +@ExtendWith(DataClearExtension.class) // DB 데이터를 매 테스트별로 지움으로써 테스트 간 격리 +@DisplayNameGeneration(ReplaceUnderscores.class) +@SpringBootTest(webEnvironment = RANDOM_PORT, classes = LikelionAdminApplication.class) +public abstract class AcceptanceTest { + + @LocalServerPort + private int port; + + @BeforeEach + protected void setUp() { + RestAssured.port = port; + } +} diff --git a/likelion-admin/src/test/java/likelion/univ/acceptance/example/ExampleAcceptanceSteps.java b/likelion-admin/src/test/java/likelion/univ/acceptance/example/ExampleAcceptanceSteps.java new file mode 100644 index 00000000..47e038e8 --- /dev/null +++ b/likelion-admin/src/test/java/likelion/univ/acceptance/example/ExampleAcceptanceSteps.java @@ -0,0 +1,30 @@ +package likelion.univ.acceptance.example; + +import static likelion.univ.acceptance.AcceptanceSteps.given; + +import io.restassured.response.ExtractableResponse; +import io.restassured.response.Response; +import likelion.univ.example.dto.request.CreateExampleRequestDto; + +@SuppressWarnings("NonAsciiCharacters") +public class ExampleAcceptanceSteps { + + public static ExtractableResponse 예시_생성_요청(CreateExampleRequestDto request) { + return given() + .body(request) + .post("/api/admin/v1/example") + .then() + .extract(); + } + + public static ExtractableResponse 예시_수정_요청( + CreateExampleRequestDto request, + Long exampleId + ) { + return given() + .body(request) + .patch("/api/admin/v1/example/{exampleId}", exampleId) + .then() + .extract(); + } +} diff --git a/likelion-admin/src/test/java/likelion/univ/acceptance/example/ExampleAcceptanceTest.java b/likelion-admin/src/test/java/likelion/univ/acceptance/example/ExampleAcceptanceTest.java new file mode 100644 index 00000000..b10e2a0c --- /dev/null +++ b/likelion-admin/src/test/java/likelion/univ/acceptance/example/ExampleAcceptanceTest.java @@ -0,0 +1,61 @@ +package likelion.univ.acceptance.example; + +import static likelion.univ.acceptance.example.ExampleAcceptanceSteps.예시_생성_요청; +import static likelion.univ.acceptance.example.ExampleAcceptanceSteps.예시_수정_요청; +import static org.assertj.core.api.Assertions.assertThat; + +import likelion.univ.acceptance.AcceptanceTest; +import likelion.univ.domain.example.entity.Example; +import likelion.univ.domain.example.repository.ExampleRepository; +import likelion.univ.example.dto.request.CreateExampleRequestDto; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; + +@DisplayName("인수테스트 예시") +@SuppressWarnings("NonAsciiCharacters") +@DisplayNameGeneration(ReplaceUnderscores.class) +public class ExampleAcceptanceTest extends AcceptanceTest { + + @Autowired + private ExampleRepository exampleRepository; + + @Nested + class 예시_생성_API { + + @Test + void 예시를_생성한다() { + // given + var request = new CreateExampleRequestDto("example"); + + // when + var response = 예시_생성_요청(request); + + // then + assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value()); + } + + @Test + void 예시를_수정한다() { + // given + /* + 참고 - 생성 시 Location 헤더에 /v1/example/{생성된 예시 ID} 식으로 id값을 반환한다면 아래와 같이 사용할 수 있음 + var request = new CreateExampleRequestDto("example"); + Long exampleId = ID_추출(예시_생성_요청(request)); + */ + Long exampleId = exampleRepository.save(new Example("sample", "sample")) + .getId(); + var request = new CreateExampleRequestDto("update"); + + // when + var response = 예시_수정_요청(request, exampleId); + + // then + assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value()); + } + } +} diff --git a/likelion-admin/src/test/java/likelion/univ/support/DataCleaner.java b/likelion-admin/src/test/java/likelion/univ/support/DataCleaner.java new file mode 100644 index 00000000..59fb1ad0 --- /dev/null +++ b/likelion-admin/src/test/java/likelion/univ/support/DataCleaner.java @@ -0,0 +1,65 @@ +package likelion.univ.support; + +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import javax.annotation.PostConstruct; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.sql.DataSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.jdbc.DatabaseDriver; +import org.springframework.stereotype.Component; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.transaction.annotation.Transactional; + +@Component +@ActiveProfiles("test") +public class DataCleaner { + + private static final String H2_FOREIGN_KEY_CHECK_FORMAT = "SET REFERENTIAL_INTEGRITY %d"; + private static final String TRUNCATE_FORMAT = "TRUNCATE TABLE %s"; + + private final List tableNames = new ArrayList<>(); + + private DatabaseDriver databaseDriver = null; + + @PersistenceContext + private EntityManager entityManager; + + @Autowired + private DataSource dataSource; + + @PostConstruct + public void checkDatabase() { + try { + databaseDriver = DatabaseDriver.fromJdbcUrl(dataSource.getConnection().getMetaData().getURL()); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } + + @SuppressWarnings("unchecked") + @PostConstruct + public void findDatabaseTableNames() { + List tableInfos = entityManager.createNativeQuery("SHOW TABLES").getResultList(); + for (Object[] tableInfo : tableInfos) { + String tableName = (String) tableInfo[0]; + tableNames.add(tableName); + } + } + + @Transactional + public void clear() { + entityManager.clear(); + truncate(); + } + + private void truncate() { + entityManager.createNativeQuery(String.format(H2_FOREIGN_KEY_CHECK_FORMAT, 0)).executeUpdate(); + for (String tableName : tableNames) { + entityManager.createNativeQuery(String.format(TRUNCATE_FORMAT, tableName)).executeUpdate(); + } + entityManager.createNativeQuery(String.format(H2_FOREIGN_KEY_CHECK_FORMAT, 1)).executeUpdate(); + } +} diff --git a/likelion-admin/src/test/java/likelion/univ/support/DataClearExtension.java b/likelion-admin/src/test/java/likelion/univ/support/DataClearExtension.java new file mode 100644 index 00000000..b996dd42 --- /dev/null +++ b/likelion-admin/src/test/java/likelion/univ/support/DataClearExtension.java @@ -0,0 +1,20 @@ +package likelion.univ.support; + + +import org.junit.jupiter.api.extension.BeforeEachCallback; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +public class DataClearExtension implements BeforeEachCallback { + + @Override + public void beforeEach(ExtensionContext context) { + DataCleaner dataCleaner = getDataCleaner(context); + dataCleaner.clear(); + } + + private DataCleaner getDataCleaner(ExtensionContext extensionContext) { + return SpringExtension.getApplicationContext(extensionContext) + .getBean(DataCleaner.class); + } +} diff --git a/likelion-admin/src/test/resources/application.yml b/likelion-admin/src/test/resources/application.yml new file mode 100644 index 00000000..939e703b --- /dev/null +++ b/likelion-admin/src/test/resources/application.yml @@ -0,0 +1,27 @@ +spring: + profiles: + include: + - common-test + - core-test + - infrastructure-test + - security-test + - redis-test + active: test + + servlet: + multipart: + max-file-size: 100MB + max-request-size: 100MB + +server: + port: 8090 + servlet: + context-path: /api/admin + +springdoc: + default-consumes-media-type: application/json;charset=UTF-8 + default-produces-media-type: application/json;charset=UTF-8 + api-docs: + enabled: false + swagger-ui: + enabled: false diff --git a/likelion-client/build.gradle b/likelion-client/build.gradle index 3555fded..c61119a7 100644 --- a/likelion-client/build.gradle +++ b/likelion-client/build.gradle @@ -1,15 +1,10 @@ dependencies { implementation('org.springframework.boot:spring-boot-starter-validation') - /* swagger */ - implementation 'org.springdoc:springdoc-openapi-ui:1.6.9' implementation 'org.jetbrains:annotations:24.0.0' - testImplementation platform('org.junit:junit-bom:5.9.1') - testImplementation 'org.junit.jupiter:junit-jupiter' - - - + /* swagger */ + implementation 'org.springdoc:springdoc-openapi-ui:1.6.9' /* core 모듈 추가 */ implementation project(':likelion-core') /* redis 모듈 추가 */ @@ -20,5 +15,9 @@ dependencies { implementation project(':likelion-security') /* infrastructure 모듈 추가 */ implementation project(':likelion-infrastructure') + + testImplementation 'io.rest-assured:rest-assured' + testImplementation platform('org.junit:junit-bom:5.9.1') + testImplementation 'org.junit.jupiter:junit-jupiter' } diff --git a/likelion-client/src/main/java/likelion/univ/LikelionClientApplication.java b/likelion-client/src/main/java/likelion/univ/LikelionClientApplication.java index e6ed9749..22704404 100644 --- a/likelion-client/src/main/java/likelion/univ/LikelionClientApplication.java +++ b/likelion-client/src/main/java/likelion/univ/LikelionClientApplication.java @@ -3,19 +3,16 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCaching; -import org.springframework.data.jpa.repository.config.EnableJpaAuditing; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableScheduling; @EnableCaching -@EnableJpaAuditing @EnableScheduling @EnableAsync @SpringBootApplication public class LikelionClientApplication { - public static void main(String[] args) { - SpringApplication.run(LikelionClientApplication.class, args); - } - + public static void main(String[] args) { + SpringApplication.run(LikelionClientApplication.class, args); + } } diff --git a/likelion-client/src/main/java/likelion/univ/alarm/controller/AlarmController.java b/likelion-client/src/main/java/likelion/univ/alarm/controller/AlarmController.java index dfb96159..17d1cad8 100644 --- a/likelion-client/src/main/java/likelion/univ/alarm/controller/AlarmController.java +++ b/likelion-client/src/main/java/likelion/univ/alarm/controller/AlarmController.java @@ -2,26 +2,32 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import javax.validation.Valid; import likelion.univ.alarm.dto.request.AlarmRegisterRequestDto; -import likelion.univ.alarm.usecase.RegisterAlarmUseCase; +import likelion.univ.alarm.service.ClientAlarmService; import likelion.univ.response.SuccessResponse; import lombok.RequiredArgsConstructor; -import org.springframework.web.bind.annotation.*; - -import javax.validation.Valid; +import org.springframework.web.bind.annotation.PathVariable; +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; @RestController @RequiredArgsConstructor @RequestMapping(value = "/v1/alarm") @Tag(name = "알람", description = "알람 API") public class AlarmController { - private final RegisterAlarmUseCase registerAlarmUseCase; + + private final ClientAlarmService clientAlarmService; @Operation(summary = "알람 등록", description = "이메일과 알람 타입을 입력받아 해당 기수의 알람을 등록합니다.") @PostMapping("/{ordinal}/register") - public SuccessResponse registerAlarm(@PathVariable Long ordinal, - @RequestBody @Valid AlarmRegisterRequestDto alarmRegisterRequestDto){ - registerAlarmUseCase.execute(ordinal, alarmRegisterRequestDto); + public SuccessResponse registerAlarm( + @PathVariable("ordinal") Long ordinal, + @RequestBody @Valid AlarmRegisterRequestDto alarmRegisterRequestDto + ) { + clientAlarmService.registerAlarm(ordinal, alarmRegisterRequestDto); return SuccessResponse.empty(); } } diff --git a/likelion-client/src/main/java/likelion/univ/alarm/dto/request/AlarmRegisterRequestDto.java b/likelion-client/src/main/java/likelion/univ/alarm/dto/request/AlarmRegisterRequestDto.java index 3e5db452..aac8ae4e 100644 --- a/likelion-client/src/main/java/likelion/univ/alarm/dto/request/AlarmRegisterRequestDto.java +++ b/likelion-client/src/main/java/likelion/univ/alarm/dto/request/AlarmRegisterRequestDto.java @@ -1,5 +1,7 @@ package likelion.univ.alarm.dto.request; +import static likelion.univ.domain.alarm.entity.SendStatus.NOT_SENT; + import io.swagger.v3.oas.annotations.media.Schema; import likelion.univ.domain.alarm.entity.Alarm; import lombok.Getter; @@ -7,17 +9,16 @@ import org.hibernate.validator.constraints.Email; import org.jetbrains.annotations.NotNull; -import static likelion.univ.domain.alarm.entity.SendStatus.NOT_SENT; - @Getter @NoArgsConstructor public class AlarmRegisterRequestDto { + @NotNull @Schema(description = "이메일", example = "tmfrk0426@gmail.com", required = true) @Email(message = "이메일 형식이 올바르지 않습니다.") private String email; - public static Alarm toEntity(Long ordinal, AlarmRegisterRequestDto alarmRegisterRequestDto){ + public static Alarm toEntity(Long ordinal, AlarmRegisterRequestDto alarmRegisterRequestDto) { return Alarm.builder() .ordinal(ordinal) .email(alarmRegisterRequestDto.getEmail()) diff --git a/likelion-client/src/main/java/likelion/univ/alarm/service/ClientAlarmService.java b/likelion-client/src/main/java/likelion/univ/alarm/service/ClientAlarmService.java new file mode 100644 index 00000000..50c96f73 --- /dev/null +++ b/likelion-client/src/main/java/likelion/univ/alarm/service/ClientAlarmService.java @@ -0,0 +1,25 @@ +package likelion.univ.alarm.service; + +import likelion.univ.alarm.dto.request.AlarmRegisterRequestDto; +import likelion.univ.annotation.UseCase; +import likelion.univ.domain.alarm.entity.Alarm; +import likelion.univ.domain.alarm.exception.EmailAlreadyRegisteredAsAlarmException; +import likelion.univ.domain.alarm.repository.AlarmRepository; +import likelion.univ.domain.alarm.service.AlarmService; +import lombok.RequiredArgsConstructor; + +@UseCase +@RequiredArgsConstructor +public class ClientAlarmService { + + private final AlarmRepository alarmRepository; + private final AlarmService alarmService; + + public void registerAlarm(Long ordinal, AlarmRegisterRequestDto alarmRegisterRequestDto) { + if (alarmRepository.existsByOrdinalAndEmail(ordinal, alarmRegisterRequestDto.getEmail())) { + throw new EmailAlreadyRegisteredAsAlarmException(); + } + Alarm newAlarm = AlarmRegisterRequestDto.toEntity(ordinal, alarmRegisterRequestDto); + alarmService.createAlarm(newAlarm); + } +} diff --git a/likelion-client/src/main/java/likelion/univ/alarm/usecase/RegisterAlarmUseCase.java b/likelion-client/src/main/java/likelion/univ/alarm/usecase/RegisterAlarmUseCase.java deleted file mode 100644 index fbbd4b69..00000000 --- a/likelion-client/src/main/java/likelion/univ/alarm/usecase/RegisterAlarmUseCase.java +++ /dev/null @@ -1,21 +0,0 @@ -package likelion.univ.alarm.usecase; - -import likelion.univ.alarm.dto.request.AlarmRegisterRequestDto; -import likelion.univ.annotation.UseCase; -import likelion.univ.domain.alarm.adaptor.AlarmAdaptor; -import likelion.univ.domain.alarm.entity.Alarm; -import likelion.univ.domain.alarm.service.AlarmDomainService; -import lombok.RequiredArgsConstructor; - -@UseCase -@RequiredArgsConstructor -public class RegisterAlarmUseCase { - private final AlarmAdaptor alarmAdaptor; - private final AlarmDomainService alarmDomainService; - - public void execute(Long ordinal, AlarmRegisterRequestDto alarmRegisterRequestDto){ - alarmAdaptor.existsByOrdinalAndEmailAndAlarmType(ordinal, alarmRegisterRequestDto.getEmail()); - Alarm newAlarm = AlarmRegisterRequestDto.toEntity(ordinal, alarmRegisterRequestDto); - alarmDomainService.createAlarm(newAlarm); - } -} \ No newline at end of file diff --git a/likelion-client/src/main/java/likelion/univ/auth/controller/AuthController.java b/likelion-client/src/main/java/likelion/univ/auth/controller/AuthController.java index 1c61588e..1b31e803 100644 --- a/likelion-client/src/main/java/likelion/univ/auth/controller/AuthController.java +++ b/likelion-client/src/main/java/likelion/univ/auth/controller/AuthController.java @@ -2,15 +2,21 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import likelion.univ.auth.dto.request.SignUpRequestDto; import likelion.univ.auth.dto.response.AccountTokenDto; import likelion.univ.auth.dto.response.AccountUserInfoDto; import likelion.univ.auth.dto.response.IdTokenDto; -import likelion.univ.auth.usecase.*; -import likelion.univ.auth.dto.request.SignUpRequestDto; +import likelion.univ.auth.service.ClientAuthService; +import likelion.univ.auth.service.LocalClientAuthService; import likelion.univ.response.SuccessResponse; -import likelion.univ.utils.AuthenticatedUserUtils; import lombok.RequiredArgsConstructor; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +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.RequestParam; +import org.springframework.web.bind.annotation.RestController; @RestController @RequiredArgsConstructor @@ -18,39 +24,40 @@ @Tag(name = "Auth", description = "인증 API") public class AuthController { - private final LoginUseCase loginUseCase; - private final RequestIdTokenUseCase requestIdTokenUseCase; - private final SignUpUseCase signUpUseCase; - private final RefreshTokenUseCase refreshTokenUseCase; - private final AuthenticatedUserUtils userUtils; - private final GetUserInfoUseCase getUserInfoUsecase; + private final ClientAuthService clientAuthService; + private final LocalClientAuthService localClientAuthService; @Operation(summary = "id token 발급", description = "인가 코드로 id token을 발급받습니다.") @GetMapping("/{logintype}/idtoken") - public SuccessResponse getIdToken( + public SuccessResponse getIdToken( @RequestParam("code") String code, - @PathVariable("logintype") String loginType){ - - IdTokenDto idTokenDto = requestIdTokenUseCase.execute(loginType,code); + @PathVariable("logintype") String loginType + ) { + IdTokenDto idTokenDto = clientAuthService.requestIdToken(loginType, code); return SuccessResponse.of(idTokenDto); } - @Operation(summary = "id token 발급 (local용)", description = "인가 코드로 id token을 발급받습니다.(개발용으로 redirect url의 도메인이)" + - "localhostt:3000입니다. (나머지 경로는 같습니다.)") - @GetMapping("/{logintype}/idtoken/local") + + @Operation( + summary = "id token 발급 (local용)", + description = "인가 코드로 id token을 발급받습니다.(개발용으로 redirect url의 도메인이)" + + "localhost:3000입니다. (나머지 경로는 같습니다.)" + ) + @GetMapping("/{loginType}/idToken/local") public SuccessResponse getIdTokenForLocal( @RequestParam("code") String code, - @PathVariable("logintype") String loginType){ - - IdTokenDto idTokenDto = requestIdTokenUseCase.executeForLocal(loginType,code); + @PathVariable("loginType") String loginType + ) { + IdTokenDto idTokenDto = localClientAuthService.requestIdTokenForLocal(loginType, code); return SuccessResponse.of(idTokenDto); } + @Operation(summary = "로그인", description = "id token과 login type으로 로그인 합니다.") @PostMapping("/{logintype}/login") public SuccessResponse login( @RequestParam("idtoken") String idToken, - @PathVariable("logintype") String loginType){ - - AccountTokenDto accountTokenDto = loginUseCase.execute(loginType,idToken); + @PathVariable("logintype") String loginType + ) { + AccountTokenDto accountTokenDto = clientAuthService.login(loginType, idToken); return SuccessResponse.of(accountTokenDto); } @@ -59,23 +66,25 @@ public SuccessResponse login( public SuccessResponse signUp( @RequestParam("idtoken") String idToken, @PathVariable("logintype") String loginType, - @RequestBody SignUpRequestDto signUpRequestDto){ - AccountTokenDto accountTokenDto = signUpUseCase.execute(loginType,idToken,signUpRequestDto); + @RequestBody SignUpRequestDto signUpRequestDto + ) { + AccountTokenDto accountTokenDto = clientAuthService.signup(loginType, idToken, signUpRequestDto); return SuccessResponse.of(accountTokenDto); } @Operation(summary = "유저 정보 조회", description = "간단한 유저정보를 조회합니다.") - @GetMapping("/userinfo") - public SuccessResponse getUserInfo(){ - AccountUserInfoDto accountUserInfoDto = getUserInfoUsecase.execute(); + @GetMapping("/userInfo") + public SuccessResponse getUserInfo() { + AccountUserInfoDto accountUserInfoDto = clientAuthService.getUserInfo(); return SuccessResponse.of(accountUserInfoDto); } @Operation(summary = "토큰 재발급", description = "refresh token으로 access token을 재발급합니다.") @PostMapping("/refresh") public SuccessResponse refreshToken( - @RequestParam("token") String refreshToken){ - AccountTokenDto accountTokenDto = refreshTokenUseCase.execute(refreshToken); + @RequestParam("token") String refreshToken + ) { + AccountTokenDto accountTokenDto = clientAuthService.refreshToken(refreshToken); return SuccessResponse.of(accountTokenDto); } } diff --git a/likelion-client/src/main/java/likelion/univ/auth/dto/request/SignUpRequestDto.java b/likelion-client/src/main/java/likelion/univ/auth/dto/request/SignUpRequestDto.java index 49d85e94..9aa432b1 100644 --- a/likelion-client/src/main/java/likelion/univ/auth/dto/request/SignUpRequestDto.java +++ b/likelion-client/src/main/java/likelion/univ/auth/dto/request/SignUpRequestDto.java @@ -8,6 +8,7 @@ @Getter @NoArgsConstructor public class SignUpRequestDto { + @NotNull @Schema(description = "이름", example = "김슬기", required = true) private String name; diff --git a/likelion-client/src/main/java/likelion/univ/auth/dto/response/AccountTokenDto.java b/likelion-client/src/main/java/likelion/univ/auth/dto/response/AccountTokenDto.java index cd64ecae..f65c1690 100644 --- a/likelion-client/src/main/java/likelion/univ/auth/dto/response/AccountTokenDto.java +++ b/likelion-client/src/main/java/likelion/univ/auth/dto/response/AccountTokenDto.java @@ -1,29 +1,30 @@ package likelion.univ.auth.dto.response; +import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; + import com.fasterxml.jackson.annotation.JsonInclude; -import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Data; -import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; - @Data @Builder public class AccountTokenDto { + @JsonInclude(NON_NULL) private String accessToken; @JsonInclude(NON_NULL) private String refreshToken; private Boolean isRegistered; - public static AccountTokenDto of(String accessToken,String refreshToken){ + public static AccountTokenDto of(String accessToken, String refreshToken) { return AccountTokenDto.builder() .accessToken(accessToken) .refreshToken(refreshToken) .isRegistered(true) .build(); } - public static AccountTokenDto notRegistered(){ + + public static AccountTokenDto notRegistered() { return AccountTokenDto.builder() .accessToken(null) .refreshToken(null) diff --git a/likelion-client/src/main/java/likelion/univ/auth/dto/response/AccountUserInfoDto.java b/likelion-client/src/main/java/likelion/univ/auth/dto/response/AccountUserInfoDto.java index 121b1499..331273da 100644 --- a/likelion-client/src/main/java/likelion/univ/auth/dto/response/AccountUserInfoDto.java +++ b/likelion-client/src/main/java/likelion/univ/auth/dto/response/AccountUserInfoDto.java @@ -7,13 +7,14 @@ @Getter @Builder public class AccountUserInfoDto { + private Long userId; private String profileImage; private String universityName; private String role; private String name; - public static AccountUserInfoDto of(User user, String universityName){ + public static AccountUserInfoDto of(User user, String universityName) { return AccountUserInfoDto.builder() .userId(user.getId()) .profileImage(user.getProfile().getProfileImage()) @@ -22,5 +23,4 @@ public static AccountUserInfoDto of(User user, String universityName){ .name(user.getProfile().getName()) .build(); } - } diff --git a/likelion-client/src/main/java/likelion/univ/auth/dto/response/IdTokenDto.java b/likelion-client/src/main/java/likelion/univ/auth/dto/response/IdTokenDto.java index 7ff1321b..d76423f6 100644 --- a/likelion-client/src/main/java/likelion/univ/auth/dto/response/IdTokenDto.java +++ b/likelion-client/src/main/java/likelion/univ/auth/dto/response/IdTokenDto.java @@ -9,7 +9,7 @@ public class IdTokenDto { private String idToken; - public static IdTokenDto of(String idToken){ + public static IdTokenDto of(String idToken) { return IdTokenDto.builder() .idToken(idToken) .build(); diff --git a/likelion-client/src/main/java/likelion/univ/auth/processor/GenerateAccountTokenProcessor.java b/likelion-client/src/main/java/likelion/univ/auth/processor/GenerateAccountTokenProcessor.java index 3e8e2345..f1593859 100644 --- a/likelion-client/src/main/java/likelion/univ/auth/processor/GenerateAccountTokenProcessor.java +++ b/likelion-client/src/main/java/likelion/univ/auth/processor/GenerateAccountTokenProcessor.java @@ -10,19 +10,20 @@ @Processor @RequiredArgsConstructor public class GenerateAccountTokenProcessor { + private final JwtProvider jwtProvider; private final RefreshTokenRedisService refreshTokenRedisService; - public AccountTokenDto createToken(User user){ + public AccountTokenDto createToken(User user) { String accessToken = jwtProvider.generateAccessToken(user.getId(), user.getAuthInfo().getRole().getValue()); String refreshToken = jwtProvider.generateRefreshToken(user.getId(), user.getAuthInfo().getRole().getValue()); /* refreshToken 캐쉬에 저장 */ refreshTokenRedisService.save(user.getId(), refreshToken); - return AccountTokenDto.of(accessToken,refreshToken); + return AccountTokenDto.of(accessToken, refreshToken); } - public AccountTokenDto refreshToken(User user, String refreshToken){ + public AccountTokenDto refreshToken(User user, String refreshToken) { String accessToken = jwtProvider.generateAccessToken(user.getId(), user.getAuthInfo().getRole().getValue()); - return AccountTokenDto.of(accessToken,refreshToken); + return AccountTokenDto.of(accessToken, refreshToken); } } diff --git a/likelion-client/src/main/java/likelion/univ/auth/processor/LoginByIdTokenProcessor.java b/likelion-client/src/main/java/likelion/univ/auth/processor/LoginByIdTokenProcessor.java index 3c5e3633..b66fb570 100644 --- a/likelion-client/src/main/java/likelion/univ/auth/processor/LoginByIdTokenProcessor.java +++ b/likelion-client/src/main/java/likelion/univ/auth/processor/LoginByIdTokenProcessor.java @@ -1,10 +1,10 @@ package likelion.univ.auth.processor; import likelion.univ.annotation.Processor; -import likelion.univ.feign.oauth.oidc.PublicKeyDto; -import likelion.univ.feign.oauth.oidc.PublicKeysDto; import likelion.univ.domain.user.exception.NotSupportedLoginTypeException; import likelion.univ.exception.IncorrectIssuerTokenException; +import likelion.univ.feign.oauth.oidc.PublicKeyDto; +import likelion.univ.feign.oauth.oidc.PublicKeysDto; import likelion.univ.jwt.JwtIdTokenProvider; import likelion.univ.jwt.dto.UserInfoFromIdToken; import likelion.univ.properties.GoogleProperties; @@ -15,13 +15,14 @@ @Processor @RequiredArgsConstructor public class LoginByIdTokenProcessor { + private final PublicKeyProcessor publicKeyProcessor; private final JwtIdTokenProvider jwtIdTokenProvider; private final KakaoProperties kakaoProperties; private final GoogleProperties googleProperties; - public UserInfoFromIdToken execute(String loginType, String idToken){ + public UserInfoFromIdToken execute(String loginType, String idToken) { String kid = jwtIdTokenProvider.getKid(idToken); PublicKeysDto publicKeys = new PublicKeysDto(); String iss = new String(); @@ -49,5 +50,4 @@ public UserInfoFromIdToken execute(String loginType, String idToken){ .orElseThrow(() -> new IncorrectIssuerTokenException()); return jwtIdTokenProvider.getUserInfo(idToken, publicKeyProcessor.generatePublicKey(key), iss, aud); } - } diff --git a/likelion-client/src/main/java/likelion/univ/auth/processor/PublicKeyProcessor.java b/likelion-client/src/main/java/likelion/univ/auth/processor/PublicKeyProcessor.java index d4e4b49b..68e8cbd8 100644 --- a/likelion-client/src/main/java/likelion/univ/auth/processor/PublicKeyProcessor.java +++ b/likelion-client/src/main/java/likelion/univ/auth/processor/PublicKeyProcessor.java @@ -1,5 +1,9 @@ package likelion.univ.auth.processor; +import static likelion.univ.common.constant.RedisKey.GOOGLE_PUBLIC_KEYS; +import static likelion.univ.common.constant.RedisKey.KAKAO_PUBLIC_KEYS; + +import java.security.interfaces.RSAPublicKey; import likelion.univ.annotation.Processor; import likelion.univ.feign.oauth.google.RequestGooglePublicKeysClient; import likelion.univ.feign.oauth.kakao.RequestKakaoTokenClient; @@ -9,28 +13,24 @@ import lombok.RequiredArgsConstructor; import org.springframework.cache.annotation.Cacheable; -import java.security.interfaces.RSAPublicKey; - -import static likelion.univ.common.constant.RedisKey.GOOGLE_PUBLIC_KEYS; -import static likelion.univ.common.constant.RedisKey.KAKAO_PUBLIC_KEYS; - @Processor @RequiredArgsConstructor public class PublicKeyProcessor { + private final RequestKakaoTokenClient requestKakaoTokenClient; private final RequestGooglePublicKeysClient requestGooglePublicKeysClient; @Cacheable(value = KAKAO_PUBLIC_KEYS, cacheManager = "redisCacheManager") - public PublicKeysDto getCachedKakaoPublicKeys(){ + public PublicKeysDto getCachedKakaoPublicKeys() { return requestKakaoTokenClient.getPublicKeys(); } + @Cacheable(value = GOOGLE_PUBLIC_KEYS, cacheManager = "redisCacheManager") - public PublicKeysDto getCachedGooglePublicKeys(){ + public PublicKeysDto getCachedGooglePublicKeys() { return requestGooglePublicKeysClient.getPublicKeys(); } - - public RSAPublicKey generatePublicKey(PublicKeyDto key){ - return PublicKeyGenerator.excute(key.getKty(), key.getN(), key.getE()); + public RSAPublicKey generatePublicKey(PublicKeyDto key) { + return PublicKeyGenerator.execute(key.getKty(), key.getN(), key.getE()); } } diff --git a/likelion-client/src/main/java/likelion/univ/auth/service/ClientAuthService.java b/likelion-client/src/main/java/likelion/univ/auth/service/ClientAuthService.java new file mode 100644 index 00000000..b641980f --- /dev/null +++ b/likelion-client/src/main/java/likelion/univ/auth/service/ClientAuthService.java @@ -0,0 +1,132 @@ +package likelion.univ.auth.service; + +import static likelion.univ.constant.StaticValue.REFRESH_TOKEN; + +import likelion.univ.auth.dto.request.SignUpRequestDto; +import likelion.univ.auth.dto.response.AccountTokenDto; +import likelion.univ.auth.dto.response.AccountUserInfoDto; +import likelion.univ.auth.dto.response.IdTokenDto; +import likelion.univ.auth.processor.GenerateAccountTokenProcessor; +import likelion.univ.auth.processor.LoginByIdTokenProcessor; +import likelion.univ.domain.university.entity.University; +import likelion.univ.domain.university.repository.UniversityRepository; +import likelion.univ.domain.user.entity.AuthInfo; +import likelion.univ.domain.user.entity.LoginType; +import likelion.univ.domain.user.entity.Profile; +import likelion.univ.domain.user.entity.UniversityInfo; +import likelion.univ.domain.user.entity.User; +import likelion.univ.domain.user.exception.EmailAlreadyRegistered; +import likelion.univ.domain.user.exception.NotSupportedLoginTypeException; +import likelion.univ.domain.user.repository.UserRepository; +import likelion.univ.domain.user.service.UserService; +import likelion.univ.exception.ExpiredTokenException; +import likelion.univ.exception.InvalidTokenException; +import likelion.univ.feign.oauth.google.RequestGoogleTokenClient; +import likelion.univ.feign.oauth.google.dto.GoogleTokenInfoDto; +import likelion.univ.feign.oauth.kakao.RequestKakaoTokenClient; +import likelion.univ.feign.oauth.kakao.dto.KakaoTokenInfoDto; +import likelion.univ.jwt.JwtProvider; +import likelion.univ.jwt.dto.DecodedJwtToken; +import likelion.univ.jwt.dto.UserInfoFromIdToken; +import likelion.univ.properties.GoogleProperties; +import likelion.univ.properties.KakaoProperties; +import likelion.univ.refreshtoken.exception.ExpiredRefreshTokenException; +import likelion.univ.refreshtoken.service.RefreshTokenRedisService; +import likelion.univ.utils.AuthenticatedUserUtils; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@RequiredArgsConstructor +@Service +public class ClientAuthService { + + private final AuthenticatedUserUtils authenticatedUserUtils; + private final UserRepository userRepository; + private final LoginByIdTokenProcessor loginByIdTokenProcessor; + private final UserService userService; + private final GenerateAccountTokenProcessor generateAccountTokenProcessor; + private final RefreshTokenRedisService refreshTokenRedisService; + private final JwtProvider jwtProvider; + private final RequestKakaoTokenClient requestKakaoTokenClient; + private final RequestGoogleTokenClient requestGoogleTokenClient; + private final KakaoProperties kakaoProperties; + private final GoogleProperties googleProperties; + private final UniversityRepository universityRepository; + + public AccountUserInfoDto getUserInfo() { + Long currentUserId = authenticatedUserUtils.getCurrentUserId(); + User user = userRepository.getByIdWithUniversity(currentUserId); + if (user.getUniversityInfo().getUniversity() == null) { + return AccountUserInfoDto.of(user, null); + } + return AccountUserInfoDto.of(user, user.getUniversityInfo().getUniversity().getName()); + } + + public AccountTokenDto login(String loginType, String idToken) { + UserInfoFromIdToken userInfo = loginByIdTokenProcessor.execute(loginType, idToken); + if (!userRepository.existsByAuthInfoEmail(userInfo.getEmail())) { + return AccountTokenDto.notRegistered(); + } + User user = userService.login(LoginType.fromValue(loginType), userInfo.getEmail()); + return generateAccountTokenProcessor.createToken(user); + } + + public AccountTokenDto refreshToken(String refreshToken) { + DecodedJwtToken decodedJwtToken = decodeRefreshToken(refreshToken); + User user = userRepository.getById(decodedJwtToken.getUserId()); + if (refreshTokenRedisService.checkToken(user.getId(), refreshToken)) { + return generateAccountTokenProcessor.refreshToken(user, refreshToken); + } + throw new InvalidTokenException(); + } + + private DecodedJwtToken decodeRefreshToken(String refreshToken) { + try { + return jwtProvider.decodeToken(refreshToken, REFRESH_TOKEN); + } catch (ExpiredTokenException e) { + throw new ExpiredRefreshTokenException(); + } + } + + public IdTokenDto requestIdToken(String loginType, String code) { + switch (loginType) { + case "kakao": + KakaoTokenInfoDto kakaoTokenInfoDto = requestKakaoTokenClient.getToken( + kakaoProperties.getClientId(), + kakaoProperties.getRedirectUrl(), + code, + kakaoProperties.getClientSecret()); + return IdTokenDto.of(kakaoTokenInfoDto.getIdToken()); + case "google": + GoogleTokenInfoDto googleTokenInfoDto = requestGoogleTokenClient.getToken( + googleProperties.getClientId(), + googleProperties.getClientSecret(), + code, + googleProperties.getRedirectUrl()); + return IdTokenDto.of(googleTokenInfoDto.getIdToken()); + } + throw new NotSupportedLoginTypeException(); + } + + @Transactional + public AccountTokenDto signup( + String loginType, + String idToken, + SignUpRequestDto signUpRequestDto + ) { + UserInfoFromIdToken userInfo = loginByIdTokenProcessor.execute(loginType, idToken); + if (!userRepository.existsByAuthInfoEmail(userInfo.getEmail())) { + Profile profile = Profile.fromName(signUpRequestDto.getName()); + University university = universityRepository.getByName(signUpRequestDto.getUniversityName()); + UniversityInfo universityInfo = UniversityInfo.universityInfoForSignUp( + university, + signUpRequestDto.getMajor() + ); + AuthInfo authInfo = AuthInfo.authInfoForSignUp((LoginType.fromValue(loginType)), userInfo.getEmail()); + User user = userService.signUp(profile, authInfo, universityInfo); + return generateAccountTokenProcessor.createToken(user); + } + throw new EmailAlreadyRegistered(); + } +} diff --git a/likelion-client/src/main/java/likelion/univ/auth/usecase/RequestIdTokenUseCase.java b/likelion-client/src/main/java/likelion/univ/auth/service/LocalClientAuthService.java similarity index 59% rename from likelion-client/src/main/java/likelion/univ/auth/usecase/RequestIdTokenUseCase.java rename to likelion-client/src/main/java/likelion/univ/auth/service/LocalClientAuthService.java index d5c2ca9f..6b03eaca 100644 --- a/likelion-client/src/main/java/likelion/univ/auth/usecase/RequestIdTokenUseCase.java +++ b/likelion-client/src/main/java/likelion/univ/auth/service/LocalClientAuthService.java @@ -1,45 +1,26 @@ -package likelion.univ.auth.usecase; +package likelion.univ.auth.service; - -import likelion.univ.annotation.UseCase; +import likelion.univ.auth.dto.response.IdTokenDto; +import likelion.univ.domain.user.exception.NotSupportedLoginTypeException; import likelion.univ.feign.oauth.google.RequestGoogleTokenClient; import likelion.univ.feign.oauth.google.dto.GoogleTokenInfoDto; import likelion.univ.feign.oauth.kakao.RequestKakaoTokenClient; import likelion.univ.feign.oauth.kakao.dto.KakaoTokenInfoDto; -import likelion.univ.auth.dto.response.IdTokenDto; -import likelion.univ.domain.user.exception.NotSupportedLoginTypeException; import likelion.univ.properties.GoogleProperties; import likelion.univ.properties.KakaoProperties; import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; -@UseCase @RequiredArgsConstructor -public class RequestIdTokenUseCase { +@Service +public class LocalClientAuthService { + private final RequestKakaoTokenClient requestKakaoTokenClient; private final RequestGoogleTokenClient requestGoogleTokenClient; private final KakaoProperties kakaoProperties; private final GoogleProperties googleProperties; - public IdTokenDto execute(String loginType, String code){ - switch (loginType) { - case "kakao": - KakaoTokenInfoDto kakaoTokenInfoDto = requestKakaoTokenClient.getToken( - kakaoProperties.getClientId(), - kakaoProperties.getRedirectUrl(), - code, - kakaoProperties.getClientSecret()); - return IdTokenDto.of(kakaoTokenInfoDto.getIdToken()); - case "google": - GoogleTokenInfoDto googleTokenInfoDto = requestGoogleTokenClient.getToken( - googleProperties.getClientId(), - googleProperties.getClientSecret(), - code, - googleProperties.getRedirectUrl()); - return IdTokenDto.of(googleTokenInfoDto.getIdToken()); - } - throw new NotSupportedLoginTypeException(); - } - public IdTokenDto executeForLocal(String loginType, String code){ + public IdTokenDto requestIdTokenForLocal(String loginType, String code) { switch (loginType) { case "kakao": KakaoTokenInfoDto kakaoTokenInfoDto = requestKakaoTokenClient.getToken( diff --git a/likelion-client/src/main/java/likelion/univ/auth/usecase/GetUserInfoUseCase.java b/likelion-client/src/main/java/likelion/univ/auth/usecase/GetUserInfoUseCase.java deleted file mode 100644 index 062e2a8e..00000000 --- a/likelion-client/src/main/java/likelion/univ/auth/usecase/GetUserInfoUseCase.java +++ /dev/null @@ -1,24 +0,0 @@ -package likelion.univ.auth.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.auth.dto.response.AccountUserInfoDto; -import likelion.univ.domain.user.adaptor.UserAdaptor; -import likelion.univ.domain.user.entity.User; -import likelion.univ.utils.AuthenticatedUserUtils; -import lombok.RequiredArgsConstructor; - -@UseCase -@RequiredArgsConstructor -public class GetUserInfoUseCase { - - private final AuthenticatedUserUtils authentiatedUserUtils; - private final UserAdaptor userAdaptor; - - public AccountUserInfoDto execute(){ - Long currentUserId = authentiatedUserUtils.getCurrentUserId(); - User user = userAdaptor.findByIdWithUniversity(currentUserId); - if(user.getUniversityInfo().getUniversity() == null) - return AccountUserInfoDto.of(user, null); - else return AccountUserInfoDto.of(user, user.getUniversityInfo().getUniversity().getName()); - } -} diff --git a/likelion-client/src/main/java/likelion/univ/auth/usecase/LoginUseCase.java b/likelion-client/src/main/java/likelion/univ/auth/usecase/LoginUseCase.java deleted file mode 100644 index 2f0d1e9b..00000000 --- a/likelion-client/src/main/java/likelion/univ/auth/usecase/LoginUseCase.java +++ /dev/null @@ -1,31 +0,0 @@ -package likelion.univ.auth.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.auth.dto.response.AccountTokenDto; -import likelion.univ.auth.processor.GenerateAccountTokenProcessor; -import likelion.univ.auth.processor.LoginByIdTokenProcessor; -import likelion.univ.domain.user.adaptor.UserAdaptor; -import likelion.univ.domain.user.entity.LoginType; -import likelion.univ.domain.user.entity.User; -import likelion.univ.domain.user.service.UserDomainService; -import likelion.univ.jwt.dto.UserInfoFromIdToken; -import lombok.RequiredArgsConstructor; - -@UseCase -@RequiredArgsConstructor -public class LoginUseCase { - private final LoginByIdTokenProcessor loginByIdTokenProcessor; - private final UserAdaptor userAdaptor; - private final UserDomainService userDomainService; - private final GenerateAccountTokenProcessor generateAccountTokenProcessor; - - public AccountTokenDto execute(String loginType, String idToken){ - UserInfoFromIdToken userInfo = loginByIdTokenProcessor.execute(loginType, idToken); - if (!userAdaptor.checkEmail(userInfo.getEmail())){ - return AccountTokenDto.notRegistered(); - } - - User user = userDomainService.login(LoginType.fromValue(loginType), userInfo.getEmail()); - return generateAccountTokenProcessor.createToken(user); - } -} diff --git a/likelion-client/src/main/java/likelion/univ/auth/usecase/RefreshTokenUseCase.java b/likelion-client/src/main/java/likelion/univ/auth/usecase/RefreshTokenUseCase.java deleted file mode 100644 index e0eee3c5..00000000 --- a/likelion-client/src/main/java/likelion/univ/auth/usecase/RefreshTokenUseCase.java +++ /dev/null @@ -1,42 +0,0 @@ -package likelion.univ.auth.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.auth.dto.response.AccountTokenDto; -import likelion.univ.auth.processor.GenerateAccountTokenProcessor; -import likelion.univ.domain.user.adaptor.UserAdaptor; -import likelion.univ.domain.user.entity.User; -import likelion.univ.exception.ExpiredTokenException; -import likelion.univ.exception.InvalidTokenException; -import likelion.univ.jwt.JwtProvider; -import likelion.univ.jwt.dto.DecodedJwtToken; -import likelion.univ.refreshtoken.exception.ExpiredRefreshTokenException; -import likelion.univ.refreshtoken.service.RefreshTokenRedisService; -import lombok.RequiredArgsConstructor; - -import static likelion.univ.constant.StaticValue.REFRESH_TOKEN; - -@UseCase -@RequiredArgsConstructor -public class RefreshTokenUseCase { - private final RefreshTokenRedisService refreshTokenRedisService; - private final GenerateAccountTokenProcessor generateAccountTokenProcessor; - private final JwtProvider jwtProvider; - private final UserAdaptor userAdaptor; - public AccountTokenDto execute(String refreshToken){ - DecodedJwtToken decodedJwtToken = decodeRefreshToken(refreshToken); - User user = userAdaptor.findById(decodedJwtToken.getUserId()); - - if(refreshTokenRedisService.checkToken(user.getId(), refreshToken)){ - return generateAccountTokenProcessor.refreshToken(user,refreshToken); - }else throw new InvalidTokenException(); - } - - private DecodedJwtToken decodeRefreshToken(String refreshToken){ - try { - return jwtProvider.decodeToken(refreshToken,REFRESH_TOKEN); - } - catch (ExpiredTokenException e) { - throw new ExpiredRefreshTokenException(); - } - } -} diff --git a/likelion-client/src/main/java/likelion/univ/auth/usecase/SignUpUseCase.java b/likelion-client/src/main/java/likelion/univ/auth/usecase/SignUpUseCase.java deleted file mode 100644 index f22d634c..00000000 --- a/likelion-client/src/main/java/likelion/univ/auth/usecase/SignUpUseCase.java +++ /dev/null @@ -1,42 +0,0 @@ -package likelion.univ.auth.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.auth.dto.request.SignUpRequestDto; -import likelion.univ.auth.dto.response.AccountTokenDto; -import likelion.univ.auth.processor.GenerateAccountTokenProcessor; -import likelion.univ.auth.processor.LoginByIdTokenProcessor; -import likelion.univ.domain.university.adaptor.UniversityAdaptor; -import likelion.univ.domain.university.entity.University; -import likelion.univ.domain.user.adaptor.UserAdaptor; -import likelion.univ.domain.user.entity.*; -import likelion.univ.domain.user.exception.EmailAlreadyRegistered; -import likelion.univ.domain.user.service.UserDomainService; -import likelion.univ.jwt.dto.UserInfoFromIdToken; -import lombok.RequiredArgsConstructor; - -@UseCase -@RequiredArgsConstructor -public class SignUpUseCase { - private final UniversityAdaptor universityAdaptor; - private final UserDomainService userDomainService; - private final UserAdaptor userAdaptor; - private final LoginByIdTokenProcessor loginByIdTokenProcessor; - private final GenerateAccountTokenProcessor generateAccountTokenProcessor; - - public AccountTokenDto execute(String loginType, - String idToken, - SignUpRequestDto signUpRequestDto){ - UserInfoFromIdToken userInfo = loginByIdTokenProcessor.execute(loginType, idToken); - if (!userAdaptor.checkEmail(userInfo.getEmail())){ - Profile profile = Profile.fromName(signUpRequestDto.getName()); - - University university = universityAdaptor.findByName(signUpRequestDto.getUniversityName()); - UniversityInfo universityInfo = UniversityInfo.universityInfoForSignUp(university, - signUpRequestDto.getMajor()); - - AuthInfo authInfo = AuthInfo.authInfoForSignUp((LoginType.fromValue(loginType)), userInfo.getEmail()); - User user = userDomainService.signUp(profile, authInfo, universityInfo); - return generateAccountTokenProcessor.createToken(user); - }else throw new EmailAlreadyRegistered(); - } -} diff --git a/likelion-client/src/main/java/likelion/univ/comment/controller/CommentController.java b/likelion-client/src/main/java/likelion/univ/comment/controller/CommentController.java index 8e4261a6..9731014e 100644 --- a/likelion-client/src/main/java/likelion/univ/comment/controller/CommentController.java +++ b/likelion-client/src/main/java/likelion/univ/comment/controller/CommentController.java @@ -2,17 +2,26 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import java.util.List; import likelion.univ.comment.dto.request.CommentCreateChildRequestDto; import likelion.univ.comment.dto.request.CommentCreateParentRequestDto; import likelion.univ.comment.dto.request.CommentUpdateRequestDto; import likelion.univ.comment.dto.response.CommentResponseDto; -import likelion.univ.comment.usecase.*; +import likelion.univ.comment.service.ClientCommentService; +import likelion.univ.domain.comment.dto.request.DeleteCommentCommand; import likelion.univ.response.SuccessResponse; +import likelion.univ.utils.AuthenticatedUserUtils; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.web.bind.annotation.*; - -import java.util.List; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +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.RequestParam; +import org.springframework.web.bind.annotation.RestController; @Slf4j @@ -21,61 +30,79 @@ @RequestMapping("/v1/community") @Tag(name = "댓글", description = "커뮤니티 APIs") public class CommentController { - private final CreateParentCommentUseCase createParentCommentUseCase; - private final CreateChildCommentUseCase createChildCommentUseCase; - private final UpdateCommentUseCase updateCommentUseCase; - private final SoftDeleteCommentUseCase softDeleteCommentUseCase; - private final HardDeleteCommentUseCase hardDeleteCommentUseCase; - private final GetCommentUseCase getCommentUseCase; - /* read */ + private final AuthenticatedUserUtils userUtils; + private final ClientCommentService commentService; + @Operation(summary = "게시글에 대한 댓글 전체 조회", description = """ ### params - 게시글 id """) @GetMapping("/comments") - public SuccessResponse> getCommentsByPost(@RequestParam Long postId) { - List response = getCommentUseCase.execute(postId); + public SuccessResponse> getCommentsByPost( + @RequestParam("postId") Long postId + ) { + List response = commentService.getComments(postId); return SuccessResponse.of(response); } - /* command */ @Operation(summary = "댓글 작성", description = "부모 댓글을 생성합니다.") @PostMapping("/comments/parent") - public SuccessResponse createParentComment(@RequestParam Long postId, @RequestBody CommentCreateParentRequestDto request) { - createParentCommentUseCase.execute(postId, request); + public SuccessResponse createParentComment( + @RequestParam("postId") Long postId, + @RequestBody CommentCreateParentRequestDto request + ) { + Long userId = userUtils.getCurrentUserId(); + commentService.createParentComment(request.toCommand(postId, userId)); return SuccessResponse.of(null, "201"); } @Operation(summary = "대댓글 작성", description = "자식 댓글을 생성합니다.") @PostMapping("/comments/{parentCommentId}/child") - public SuccessResponse createChildComment(@PathVariable Long parentCommentId, @RequestBody CommentCreateChildRequestDto request) { - createChildCommentUseCase.execute(parentCommentId, request); + public SuccessResponse createChildComment( + @PathVariable("parentCommentId") Long parentCommentId, + @RequestBody CommentCreateChildRequestDto request + ) { + Long userId = userUtils.getCurrentUserId(); + commentService.createChildComment(request.toCommand(parentCommentId, userId)); return SuccessResponse.of(null, "201"); } @Operation(summary = "댓글 내용 수정", description = "댓글의 내용(body only)을 수정합니다.") @PatchMapping("/{commentId}") - public SuccessResponse updateComment(@PathVariable Long commentId, @RequestBody CommentUpdateRequestDto request) { - Long updatedCommentId = updateCommentUseCase.execute(commentId, request); + public SuccessResponse updateComment( + @PathVariable("commentId") Long commentId, + @RequestBody CommentUpdateRequestDto request + ) { + Long userId = userUtils.getCurrentUserId(); + Long updatedCommentId = commentService.updateComment(request.toCommand(commentId, userId)); return SuccessResponse.of(updatedCommentId); } @Operation(summary = "댓글 soft 삭제", description = "댓글을 soft delete 합니다.") @PatchMapping("/disable/{commentId}") - public SuccessResponse deleteCommentSoft(@PathVariable Long commentId) { - softDeleteCommentUseCase.execute(commentId);// soft delete + public SuccessResponse deleteCommentSoft( + @PathVariable("commentId") Long commentId + ) { + Long loginUserId = userUtils.getCurrentUserId(); + DeleteCommentCommand command = DeleteCommentCommand.of(commentId, loginUserId); + commentService.softDeleteComment(command); // soft delete return SuccessResponse.empty(); } - @Operation(summary = "(시스템용) 댓글 완전 삭제", description = """ - 댓글을 hard delete 합니다. - (주의) 시스템 관리자용이므로 클라이언트에 노출되지 않도록 합니다.""") - + @Operation( + summary = "(시스템용) 댓글 완전 삭제", + description = """ + 댓글을 hard delete 합니다. + (주의) 시스템 관리자용이므로 클라이언트에 노출되지 않도록 합니다. + """) @DeleteMapping("/{commentId}") - public SuccessResponse deleteCommentHard(@PathVariable Long commentId) { - hardDeleteCommentUseCase.execute(commentId); + public SuccessResponse deleteCommentHard( + @PathVariable("commentId") Long commentId + ) { + DeleteCommentCommand command = new DeleteCommentCommand(commentId, userUtils.getCurrentUserId()); + commentService.hardDeleteComment(command); return SuccessResponse.empty(); } } diff --git a/likelion-client/src/main/java/likelion/univ/comment/dto/request/CommentCreateChildRequestDto.java b/likelion-client/src/main/java/likelion/univ/comment/dto/request/CommentCreateChildRequestDto.java index 1e83c308..569619cf 100644 --- a/likelion-client/src/main/java/likelion/univ/comment/dto/request/CommentCreateChildRequestDto.java +++ b/likelion-client/src/main/java/likelion/univ/comment/dto/request/CommentCreateChildRequestDto.java @@ -1,17 +1,29 @@ package likelion.univ.comment.dto.request; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.*; - import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; +import likelion.univ.domain.comment.dto.request.CreateChildCommentCommand; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; @Data @Builder @AllArgsConstructor @NoArgsConstructor(access = AccessLevel.PRIVATE) public class CommentCreateChildRequestDto { + @NotBlank @Schema(description = "대댓글 내용", example = "대댓글 내용입니다.") private String body; + + public CreateChildCommentCommand toCommand(Long parentCommentId, Long userId) { + return CreateChildCommentCommand.builder() + .parentCommentId(parentCommentId) + .loginUserId(userId) + .body(body) + .build(); + } } diff --git a/likelion-client/src/main/java/likelion/univ/comment/dto/request/CommentCreateParentRequestDto.java b/likelion-client/src/main/java/likelion/univ/comment/dto/request/CommentCreateParentRequestDto.java index f1e597e3..f2d08370 100644 --- a/likelion-client/src/main/java/likelion/univ/comment/dto/request/CommentCreateParentRequestDto.java +++ b/likelion-client/src/main/java/likelion/univ/comment/dto/request/CommentCreateParentRequestDto.java @@ -1,17 +1,29 @@ package likelion.univ.comment.dto.request; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.*; - import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; +import likelion.univ.domain.comment.dto.request.CreateParentCommentCommand; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; @Data @Builder @AllArgsConstructor @NoArgsConstructor(access = AccessLevel.PRIVATE) public class CommentCreateParentRequestDto { + @NotBlank @Schema(description = "댓글 내용", example = "댓글 내용입니다.") private String body; + + public CreateParentCommentCommand toCommand(Long postId, Long userId) { + return CreateParentCommentCommand.builder() + .postId(postId) + .loginUserId(userId) + .body(body) + .build(); + } } diff --git a/likelion-client/src/main/java/likelion/univ/comment/dto/request/CommentUpdateRequestDto.java b/likelion-client/src/main/java/likelion/univ/comment/dto/request/CommentUpdateRequestDto.java index 8676a2be..aea613fd 100644 --- a/likelion-client/src/main/java/likelion/univ/comment/dto/request/CommentUpdateRequestDto.java +++ b/likelion-client/src/main/java/likelion/univ/comment/dto/request/CommentUpdateRequestDto.java @@ -1,17 +1,25 @@ package likelion.univ.comment.dto.request; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.*; - import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; +import likelion.univ.domain.comment.dto.request.UpdateCommentCommand; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; @Data @Builder @AllArgsConstructor @NoArgsConstructor(access = AccessLevel.PRIVATE) public class CommentUpdateRequestDto { + @NotBlank @Schema(description = "변경하려는 댓글 내용", example = "변경된 댓글 내용입니다.") private String body; + + public UpdateCommentCommand toCommand(Long commentId, Long userId) { + return new UpdateCommentCommand(commentId, userId, body); + } } diff --git a/likelion-client/src/main/java/likelion/univ/comment/dto/response/ChildCommentResponseDto.java b/likelion-client/src/main/java/likelion/univ/comment/dto/response/ChildCommentResponseDto.java index 55b934bc..1d9f28ab 100644 --- a/likelion-client/src/main/java/likelion/univ/comment/dto/response/ChildCommentResponseDto.java +++ b/likelion-client/src/main/java/likelion/univ/comment/dto/response/ChildCommentResponseDto.java @@ -5,10 +5,6 @@ import likelion.univ.domain.comment.dto.response.ChildCommentData; import lombok.Builder; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.List; - @Builder public record ChildCommentResponseDto( @Schema(description = "대댓글 pk", example = "1") @@ -39,6 +35,7 @@ public record ChildCommentResponseDto( @Schema(description = "대댓글 생성 일자", example = "yyyy. MM. dd") String createdDate ) { + public static ChildCommentResponseDto of(ChildCommentData childComment, Long loginUserId, Long postAuthorId) { return ChildCommentResponseDto.builder() .commentId(childComment.commentId()) @@ -56,5 +53,4 @@ public static ChildCommentResponseDto of(ChildCommentData childComment, Long log .createdDate(childComment.getFormattedDate()) .build(); } - } diff --git a/likelion-client/src/main/java/likelion/univ/comment/dto/response/CommentResponseDto.java b/likelion-client/src/main/java/likelion/univ/comment/dto/response/CommentResponseDto.java index 2be25e22..9814dce6 100644 --- a/likelion-client/src/main/java/likelion/univ/comment/dto/response/CommentResponseDto.java +++ b/likelion-client/src/main/java/likelion/univ/comment/dto/response/CommentResponseDto.java @@ -2,15 +2,11 @@ import com.fasterxml.jackson.annotation.JsonInclude; import io.swagger.v3.oas.annotations.media.Schema; +import java.util.List; import likelion.univ.domain.comment.dto.response.ChildCommentData; import likelion.univ.domain.comment.dto.response.ParentCommentData; import lombok.Builder; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.List; -import java.util.stream.Stream; - @Builder public record CommentResponseDto( @Schema(description = "댓글 pk", example = "1") @@ -44,9 +40,13 @@ public record CommentResponseDto( @JsonInclude(JsonInclude.Include.NON_EMPTY) List childComments ) { - public static CommentResponseDto of(ParentCommentData parentComment, List allChildComments, Long loginUserId, Long postAuthorId) { - List childCommentData = allChildComments.stream().filter(i -> i.parentId().equals(parentComment.commentId())).toList(); - List childComments = childCommentData.stream().map(c -> ChildCommentResponseDto.of(c, loginUserId, postAuthorId)).toList(); + + public static CommentResponseDto of(ParentCommentData parentComment, List allChildComments, + Long loginUserId, Long postAuthorId) { + List childCommentData = allChildComments.stream() + .filter(i -> i.parentId().equals(parentComment.commentId())).toList(); + List childComments = childCommentData.stream() + .map(c -> ChildCommentResponseDto.of(c, loginUserId, postAuthorId)).toList(); return CommentResponseDto.builder() .commentId(parentComment.commentId()) .userId(parentComment.userId()) @@ -64,6 +64,4 @@ public static CommentResponseDto of(ParentCommentData parentComment, List getComments(Long postId) { + Long loginUserId = userUtils.getCurrentUserId(); + CommentData commentData = commentService.getComment(new GetCommentCommand(postId, loginUserId)); + Long postAuthorId = commentData.postAuthorId(); + List parentCommentData = commentData.parentComments(); + List childCommentData = commentData.childComments(); + return parentCommentData.stream() + .map(pc -> CommentResponseDto.of( + pc, + childCommentData, + userUtils.getCurrentUserId(), + postAuthorId) + ).toList(); + } + + public void hardDeleteComment(DeleteCommentCommand command) { + commentService.deleteCommentHard(command); + } + + public void softDeleteComment(DeleteCommentCommand command) { + DeleteCommentData deleteCommentData = commentService.deleteCommentSoft(command); + if (!deleteCommentData.isDeleted()) { + throw new CommentAlreadyDeletedException(); + } + Long postId = deleteCommentData.postId(); + // redis update + PostCountInfo countInfo = getOrCreatePostCountInfoProcessor.execute(postId); + Long commentCount = countInfo.getCommentCount(); + Long likeCount = countInfo.getLikeCount(); + updatePostCountInfoProcessor.execute(postId, --commentCount, likeCount); + } + + public Long updateComment(UpdateCommentCommand command) { + return commentService.updateCommentBody(command); + } +} diff --git a/likelion-client/src/main/java/likelion/univ/comment/usecase/CreateChildCommentUseCase.java b/likelion-client/src/main/java/likelion/univ/comment/usecase/CreateChildCommentUseCase.java deleted file mode 100644 index dea6be71..00000000 --- a/likelion-client/src/main/java/likelion/univ/comment/usecase/CreateChildCommentUseCase.java +++ /dev/null @@ -1,38 +0,0 @@ -package likelion.univ.comment.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.comment.dto.request.CommentCreateChildRequestDto; -import likelion.univ.domain.comment.dto.request.CreateChildCommentCommand; -import likelion.univ.domain.comment.dto.response.SimpleCommentData; -import likelion.univ.domain.comment.service.CommentDomainService; -import likelion.univ.post.entity.PostCountInfo; -import likelion.univ.post.processor.GetOrCreatePostCountInfoProcessor; -import likelion.univ.post.processor.UpdatePostCountInfoProcessor; -import likelion.univ.utils.AuthenticatedUserUtils; -import lombok.RequiredArgsConstructor; - -@UseCase -@RequiredArgsConstructor -public class CreateChildCommentUseCase { - private final AuthenticatedUserUtils userUtils; - private final CommentDomainService commentDomainService; - private final GetOrCreatePostCountInfoProcessor getOrCreatePostCountInfoProcessor; - private final UpdatePostCountInfoProcessor updatePostCountInfoProcessor; - - public void execute(Long parentCommentId, CommentCreateChildRequestDto request) { - Long postId = commentDomainService.createChildComment(serviceDtoBy(parentCommentId, request)); - - // redis update - PostCountInfo postCountInfo = getOrCreatePostCountInfoProcessor.execute(postId); - Long commentCount = postCountInfo.getCommentCount(); - Long likeCount = postCountInfo.getLikeCount(); - updatePostCountInfoProcessor.execute(postId, ++commentCount, likeCount); - } - private CreateChildCommentCommand serviceDtoBy(Long parentCommentId, CommentCreateChildRequestDto request) { - return CreateChildCommentCommand.builder() - .parentCommentId(parentCommentId) - .loginUserId(userUtils.getCurrentUserId()) - .body(request.getBody()) - .build(); - } -} diff --git a/likelion-client/src/main/java/likelion/univ/comment/usecase/CreateParentCommentUseCase.java b/likelion-client/src/main/java/likelion/univ/comment/usecase/CreateParentCommentUseCase.java deleted file mode 100644 index 686d5d62..00000000 --- a/likelion-client/src/main/java/likelion/univ/comment/usecase/CreateParentCommentUseCase.java +++ /dev/null @@ -1,38 +0,0 @@ -package likelion.univ.comment.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.comment.dto.request.CommentCreateParentRequestDto; -import likelion.univ.domain.comment.dto.request.CreateParentCommentCommand; -import likelion.univ.domain.comment.service.CommentDomainService; -import likelion.univ.post.entity.PostCountInfo; -import likelion.univ.post.processor.GetOrCreatePostCountInfoProcessor; -import likelion.univ.post.processor.UpdatePostCountInfoProcessor; -import likelion.univ.utils.AuthenticatedUserUtils; -import lombok.RequiredArgsConstructor; - -@UseCase -@RequiredArgsConstructor -public class CreateParentCommentUseCase { - private final AuthenticatedUserUtils userUtils; - private final CommentDomainService commentDomainService; - private final GetOrCreatePostCountInfoProcessor getOrCreatePostCountInfoProcessor; - private final UpdatePostCountInfoProcessor updatePostCountInfoProcessor; - - public void execute(Long postId, CommentCreateParentRequestDto createRequestDto) { - commentDomainService.createParentComment(serviceDtoBy(postId, createRequestDto)); - - // redis update - PostCountInfo countInfo = getOrCreatePostCountInfoProcessor.execute(postId); - Long commentCount = countInfo.getCommentCount(); - Long likeCount = countInfo.getLikeCount(); - updatePostCountInfoProcessor.execute(postId, ++commentCount, likeCount); - } - - private CreateParentCommentCommand serviceDtoBy(Long postId, CommentCreateParentRequestDto createParentRequest) { - return CreateParentCommentCommand.builder() - .postId(postId) - .loginUserId(userUtils.getCurrentUserId()) - .body(createParentRequest.getBody()) - .build(); - } -} diff --git a/likelion-client/src/main/java/likelion/univ/comment/usecase/GetCommentUseCase.java b/likelion-client/src/main/java/likelion/univ/comment/usecase/GetCommentUseCase.java deleted file mode 100644 index 95c08a70..00000000 --- a/likelion-client/src/main/java/likelion/univ/comment/usecase/GetCommentUseCase.java +++ /dev/null @@ -1,32 +0,0 @@ -package likelion.univ.comment.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.comment.dto.response.CommentResponseDto; -import likelion.univ.domain.comment.dto.request.GetCommentCommand; -import likelion.univ.domain.comment.dto.response.ChildCommentData; -import likelion.univ.domain.comment.dto.response.CommentData; -import likelion.univ.domain.comment.dto.response.ParentCommentData; -import likelion.univ.domain.comment.service.CommentDomainService; -import likelion.univ.utils.AuthenticatedUserUtils; -import lombok.RequiredArgsConstructor; - -import java.util.List; - -@UseCase -@RequiredArgsConstructor -public class GetCommentUseCase { - private final CommentDomainService commentDomainService; - private final AuthenticatedUserUtils authenticatedUser; - - public List execute(Long postId) { - Long loginUserId = authenticatedUser.getCurrentUserId(); - CommentData commentData = commentDomainService.getComment(new GetCommentCommand(postId, loginUserId)); - - Long postAuthorId = commentData.postAuthorId(); - List parentCommentData = commentData.parentComments(); - List childCommentData = commentData.childComments(); - - List response = parentCommentData.stream().map(pc -> CommentResponseDto.of(pc, childCommentData, authenticatedUser.getCurrentUserId(), postAuthorId)).toList(); - return response; - } -} diff --git a/likelion-client/src/main/java/likelion/univ/comment/usecase/HardDeleteCommentUseCase.java b/likelion-client/src/main/java/likelion/univ/comment/usecase/HardDeleteCommentUseCase.java deleted file mode 100644 index 3b3ef87f..00000000 --- a/likelion-client/src/main/java/likelion/univ/comment/usecase/HardDeleteCommentUseCase.java +++ /dev/null @@ -1,25 +0,0 @@ -package likelion.univ.comment.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.domain.comment.dto.request.DeleteCommentCommand; -import likelion.univ.domain.comment.service.CommentDomainService; -import likelion.univ.response.SuccessResponse; -import likelion.univ.utils.AuthenticatedUserUtils; -import lombok.RequiredArgsConstructor; - -@UseCase -@RequiredArgsConstructor -public class HardDeleteCommentUseCase { - private final AuthenticatedUserUtils userUtils; - private final CommentDomainService commentDomainService; - - public void execute(Long commentId) { - commentDomainService.deleteCommentHard(serviceDtoBy(commentId)); - } - private DeleteCommentCommand serviceDtoBy(Long commentId) { - return DeleteCommentCommand.builder() - .commentId(commentId) - .loginUserId(userUtils.getCurrentUserId()) - .build(); - } -} diff --git a/likelion-client/src/main/java/likelion/univ/comment/usecase/SoftDeleteCommentUseCase.java b/likelion-client/src/main/java/likelion/univ/comment/usecase/SoftDeleteCommentUseCase.java deleted file mode 100644 index 488a20ac..00000000 --- a/likelion-client/src/main/java/likelion/univ/comment/usecase/SoftDeleteCommentUseCase.java +++ /dev/null @@ -1,37 +0,0 @@ -package likelion.univ.comment.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.domain.comment.dto.request.DeleteCommentCommand; -import likelion.univ.domain.comment.dto.response.DeleteCommentData; -import likelion.univ.domain.comment.exception.CommentAlreadyDeletedException; -import likelion.univ.domain.comment.service.CommentDomainService; -import likelion.univ.post.entity.PostCountInfo; -import likelion.univ.post.processor.GetOrCreatePostCountInfoProcessor; -import likelion.univ.post.processor.UpdatePostCountInfoProcessor; -import likelion.univ.utils.AuthenticatedUserUtils; -import lombok.RequiredArgsConstructor; - -@UseCase -@RequiredArgsConstructor -public class SoftDeleteCommentUseCase { - private final AuthenticatedUserUtils userUtils; - private final CommentDomainService commentDomainService; - private final GetOrCreatePostCountInfoProcessor getOrCreatePostCountInfoProcessor; - private final UpdatePostCountInfoProcessor updatePostCountInfoProcessor; - - public void execute(Long commentId) { - Long loginUserId = userUtils.getCurrentUserId(); - DeleteCommentData deleteCommentData = commentDomainService.deleteCommentSoft(DeleteCommentCommand.of(commentId, loginUserId)); - - if (deleteCommentData.isDeleted()) { - Long postId = deleteCommentData.postId(); - // redis update - PostCountInfo countInfo = getOrCreatePostCountInfoProcessor.execute(postId); - Long commentCount = countInfo.getCommentCount(); - Long likeCount = countInfo.getLikeCount(); - updatePostCountInfoProcessor.execute(postId, --commentCount, likeCount); - return; - } - throw new CommentAlreadyDeletedException(); - } -} diff --git a/likelion-client/src/main/java/likelion/univ/comment/usecase/UpdateCommentUseCase.java b/likelion-client/src/main/java/likelion/univ/comment/usecase/UpdateCommentUseCase.java deleted file mode 100644 index b03ae076..00000000 --- a/likelion-client/src/main/java/likelion/univ/comment/usecase/UpdateCommentUseCase.java +++ /dev/null @@ -1,29 +0,0 @@ -package likelion.univ.comment.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.comment.dto.request.CommentUpdateRequestDto; -import likelion.univ.domain.comment.dto.request.UpdateCommentCommand; -import likelion.univ.domain.comment.service.CommentDomainService; -import likelion.univ.utils.AuthenticatedUserUtils; -import lombok.RequiredArgsConstructor; - - -@UseCase -@RequiredArgsConstructor -public class UpdateCommentUseCase { - private final AuthenticatedUserUtils userUtils; - private final CommentDomainService commentDomainService; - - public Long execute(Long commentId, CommentUpdateRequestDto request) { - Long updatedCommentId = commentDomainService.updateCommentBody(serviceDtoBy(commentId, request)); - return updatedCommentId; - } - - private UpdateCommentCommand serviceDtoBy(Long commentId, CommentUpdateRequestDto request) { - return UpdateCommentCommand.builder() - .commentId(commentId) - .loginUserId(userUtils.getCurrentUserId()) - .body(request.getBody()) - .build(); - } -} diff --git a/likelion-client/src/main/java/likelion/univ/config/ClientExceptionHandler.java b/likelion-client/src/main/java/likelion/univ/config/ClientExceptionHandler.java index 0dc3cd27..9e7a41c6 100644 --- a/likelion-client/src/main/java/likelion/univ/config/ClientExceptionHandler.java +++ b/likelion-client/src/main/java/likelion/univ/config/ClientExceptionHandler.java @@ -1,5 +1,6 @@ package likelion.univ.config; +import java.net.BindException; import likelion.univ.exception.GlobalErrorCode; import likelion.univ.exception.base.BaseException; import likelion.univ.feign.exception.FeignClientException; @@ -13,11 +14,10 @@ import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; -import java.net.BindException; - @RestControllerAdvice @Slf4j public class ClientExceptionHandler { + /* javax.validation.Valid or @Validated 으로 binding error 발생시 발생 주로 @RequestBody, @RequestPart 어노테이션에서 발생 @@ -32,14 +32,15 @@ private ResponseEntity handleMethodArgumentNotValidException(Meth /* @ModelAttribute 으로 binding error 발생시 BindException 발생 */ @ExceptionHandler(BindException.class) - private ResponseEntity handleBindException(BindException e) { + private ResponseEntity handleBindException(BindException e) { ErrorResponse error = ErrorResponse.of(GlobalErrorCode.INVALID_HTTP_MESSAGE_BODY); return ResponseEntity.status(error.getHttpStatus()).body(error); } /* enum type 일치하지 않아 binding 못할 경우 발생 */ @ExceptionHandler(MethodArgumentTypeMismatchException.class) - private ResponseEntity handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e) { + private ResponseEntity handleMethodArgumentTypeMismatchException( + MethodArgumentTypeMismatchException e) { log.error("MethodArgumentTypeMismatchException Error", e); ErrorResponse error = ErrorResponse.of(GlobalErrorCode.INVALID_HTTP_MESSAGE_BODY); return ResponseEntity.status(error.getHttpStatus()).body(error); @@ -47,44 +48,44 @@ private ResponseEntity handleMethodArgumentTypeMismatchException /* 지원하지 않은 HTTP method 호출 할 경우 발생 */ @ExceptionHandler(HttpRequestMethodNotSupportedException.class) - private ResponseEntity handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) { + private ResponseEntity handleHttpRequestMethodNotSupportedException( + HttpRequestMethodNotSupportedException e) { log.error("HttpRequestMethodNotSupportedException Error", e); - ErrorResponse error = ErrorResponse.of(GlobalErrorCode.UNSUPPORTED_HTTP_METHOD); return ResponseEntity.status(error.getHttpStatus()).body(error); } + /* request 값을 읽을 수 없을 때 발생 */ @ExceptionHandler(HttpMessageNotReadableException.class) - protected ResponseEntity handleHttpMessageNotReadableException(HttpMessageNotReadableException e) { + protected ResponseEntity handleHttpMessageNotReadableException(HttpMessageNotReadableException e) { log.error("HttpMessageNotReadableException error", e); ErrorResponse error = ErrorResponse.of(GlobalErrorCode.BAD_REQUEST_ERROR); - return ResponseEntity.status(error.getHttpStatus()).body(error); } /* Feign Client 에러 */ @ExceptionHandler(FeignClientException.class) - private ResponseEntity handleFeignClientException(FeignClientException e) { + private ResponseEntity handleFeignClientException(FeignClientException e) { log.error("FeignClientError : " + e.getMethodKey()); log.error(e.getMessage()); - ErrorResponse error = ErrorResponse.of(e.getCode(),e.getMessage(), e.getHttpStatus()); + ErrorResponse error = ErrorResponse.of(e.getCode(), e.getMessage(), e.getHttpStatus()); return ResponseEntity.status(error.getHttpStatus()).body(error); } /* 비지니스 로직 에러 */ @ExceptionHandler(BaseException.class) - private ResponseEntity handleBusinessException(BaseException e) { + private ResponseEntity handleBusinessException(BaseException e) { log.error("BusinessError "); log.error(e.getErrorCode().getMessage()); ErrorResponse error = ErrorResponse.of(e.getErrorCode()); return ResponseEntity.status(error.getHttpStatus()).body(error); } + /* 나머지 예외 처리 */ @ExceptionHandler(Exception.class) - private ResponseEntity handleException(Exception e) { + private ResponseEntity handleException(Exception e) { log.error("Exception Error ", e); ErrorResponse error = ErrorResponse.of(GlobalErrorCode.SERVER_ERROR); return ResponseEntity.status(error.getHttpStatus()).body(error); } - } diff --git a/likelion-client/src/main/java/likelion/univ/config/CustomAuthenticationEntryPoint.java b/likelion-client/src/main/java/likelion/univ/config/CustomAuthenticationEntryPoint.java index b42c2d52..d459de1f 100644 --- a/likelion-client/src/main/java/likelion/univ/config/CustomAuthenticationEntryPoint.java +++ b/likelion-client/src/main/java/likelion/univ/config/CustomAuthenticationEntryPoint.java @@ -1,24 +1,25 @@ package likelion.univ.config; import com.fasterxml.jackson.databind.ObjectMapper; -import likelion.univ.exception.GlobalErrorCode; +import java.io.IOException; +import java.io.PrintWriter; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import likelion.univ.exception.SecurityErrorCode; import likelion.univ.response.ErrorResponse; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.AuthenticationEntryPoint; import org.springframework.stereotype.Component; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.io.PrintWriter; -import java.time.LocalDateTime; - @Component public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint { + @Override - public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException { + public void commence( + HttpServletRequest request, + HttpServletResponse response, + AuthenticationException authException + ) throws IOException { response.setContentType("application/json;charset=UTF-8"); response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); // Error Response Body diff --git a/likelion-client/src/main/java/likelion/univ/config/SecurityConfig.java b/likelion-client/src/main/java/likelion/univ/config/SecurityConfig.java index f0969e3c..cc250158 100644 --- a/likelion-client/src/main/java/likelion/univ/config/SecurityConfig.java +++ b/likelion-client/src/main/java/likelion/univ/config/SecurityConfig.java @@ -1,41 +1,38 @@ package likelion.univ.config; +import static likelion.univ.constant.StaticValue.SwaggerUrlPatterns; + import likelion.univ.security.AccessProcessor; import likelion.univ.security.filter.FilterProcessor; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpMethod; -import org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.web.SecurityFilterChain; -import org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler; - -import static likelion.univ.constant.StaticValue.SwaggerUrlPatterns; @Configuration @RequiredArgsConstructor @EnableWebSecurity public class SecurityConfig { + private final FilterProcessor filterProcessor; private final AccessProcessor accessProcessor; private final CustomAuthenticationEntryPoint entryPoint; - @Bean public BCryptPasswordEncoder encoder() { return new BCryptPasswordEncoder(); } @Bean - public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{ + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.httpBasic().disable().cors();// cors 적용 http.csrf().disable(); http.formLogin().disable(); - http.sessionManagement( ).sessionCreationPolicy(SessionCreationPolicy.STATELESS); // JWT이용으로 세션 이용 x + http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); // JWT이용으로 세션 이용 x filterProcessor.common(http); http.exceptionHandling().authenticationEntryPoint(entryPoint); // 로그인 x 유저에 대한 Custom ErrorResponse 제공 http.authorizeRequests().expressionHandler(accessProcessor.expressionHandler()); @@ -48,7 +45,6 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{ // .antMatchers(HttpMethod.GET, "/v1/community/**").authenticated() // 추후 조회에 대하여는 로그인만 요청할 계획이라 주석으로 냅둠 .antMatchers("/v1/community/**").hasRole("USER") - // .anyRequest().authenticated(); .anyRequest().permitAll(); //임시 diff --git a/likelion-client/src/main/java/likelion/univ/config/SwaggerConfig.java b/likelion-client/src/main/java/likelion/univ/config/SwaggerConfig.java index 4f79960e..549c25ba 100644 --- a/likelion-client/src/main/java/likelion/univ/config/SwaggerConfig.java +++ b/likelion-client/src/main/java/likelion/univ/config/SwaggerConfig.java @@ -10,16 +10,16 @@ import io.swagger.v3.oas.models.security.SecurityRequirement; import io.swagger.v3.oas.models.security.SecurityScheme; import io.swagger.v3.oas.models.servers.Server; +import java.util.List; +import javax.servlet.ServletContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpHeaders; -import javax.servlet.ServletContext; -import java.util.List; - @Configuration public class SwaggerConfig { + @Bean public OpenAPI openAPI(ServletContext servletContext) { String contextPath = servletContext.getContextPath(); @@ -33,11 +33,13 @@ public OpenAPI openAPI(ServletContext servletContext) { .components(new Components() .addSecuritySchemes("Authorization(accessToken)", securityScheme())); } + @Bean public ModelResolver modelResolver(ObjectMapper objectMapper) { return new ModelResolver(objectMapper); } - private Info info(){ + + private Info info() { return new Info() .title("Likelion-Univ Client API") .version("v1") @@ -47,7 +49,8 @@ private Info info(){ .name("Likelion-Univ") .email("tmfrk0426@gmail.com")); } - private License license(){ + + private License license() { License license = new License(); license.setUrl("https://github.com/LikelionUniv/LikelionUniv-Server"); license.setName("멋쟁이 사자처럼"); @@ -64,7 +67,7 @@ private SecurityScheme securityScheme() { } // Security 요청 설정 - private SecurityRequirement securityItem(){ + private SecurityRequirement securityItem() { SecurityRequirement securityItem = new SecurityRequirement(); securityItem.addList("Authorization(accessToken)"); return securityItem; diff --git a/likelion-client/src/main/java/likelion/univ/donation_history/controller/DonationHistoryController.java b/likelion-client/src/main/java/likelion/univ/donation_history/controller/DonationHistoryController.java deleted file mode 100644 index fcdf34f9..00000000 --- a/likelion-client/src/main/java/likelion/univ/donation_history/controller/DonationHistoryController.java +++ /dev/null @@ -1,40 +0,0 @@ -package likelion.univ.donation_history.controller; - -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.tags.Tag; -import likelion.univ.common.response.PageResponse; -import likelion.univ.donation_history.dto.response.DonationHistoriesDetailsResponseDto; -import likelion.univ.donation_history.dto.response.DonationHistoriesSearchResponseDto; -import likelion.univ.donation_history.usecase.GetDonationHistoryDetailsUseCase; -import likelion.univ.donation_history.usecase.SearchDontionHistoryUseCase; -import likelion.univ.response.SuccessResponse; -import lombok.RequiredArgsConstructor; -import org.springdoc.api.annotations.ParameterObject; -import org.springframework.data.domain.Pageable; -import org.springframework.data.web.PageableDefault; -import org.springframework.web.bind.annotation.*; - -@RestController -@RequiredArgsConstructor -@RequestMapping(value = "/v1/donation_history") -@Tag(name = "기부금 게시판", description = "기부금 게시판관련 API입니다.") -public class DonationHistoryController { - private final SearchDontionHistoryUseCase searchDontionHistoryUseCase; - private final GetDonationHistoryDetailsUseCase getDonationHistoryDetailsUseCase; - - @Operation(summary = "기부금 게시글 목록 검색", description = "기부금 게시글을 검색합니다. 파라미터로 search를 포함하지 않을 시 전체 조회입니다.") - @GetMapping("") - public SuccessResponse searchDonationHistories(@RequestParam(value="sort", required = false, defaultValue="created_date") String sort, - @RequestParam(value="search", required = false) String search, - @ParameterObject @PageableDefault(size = 10, page = 0) Pageable pageable){ - PageResponse result = searchDontionHistoryUseCase.execute(sort, search, pageable); - return SuccessResponse.of(result); - } - - @Operation(summary = "기부금 게시글 상세정보", description = "해당 기부금 게시글의 상세정보를 조회합니다.") - @GetMapping("/{donationHistoryId}") - public SuccessResponse searchDonationHistories(@PathVariable Long donationHistoryId){ - DonationHistoriesDetailsResponseDto result = getDonationHistoryDetailsUseCase.execute(donationHistoryId); - return SuccessResponse.of(result); - } -} diff --git a/likelion-client/src/main/java/likelion/univ/donation_history/usecase/GetDonationHistoryDetailsUseCase.java b/likelion-client/src/main/java/likelion/univ/donation_history/usecase/GetDonationHistoryDetailsUseCase.java deleted file mode 100644 index f1098964..00000000 --- a/likelion-client/src/main/java/likelion/univ/donation_history/usecase/GetDonationHistoryDetailsUseCase.java +++ /dev/null @@ -1,19 +0,0 @@ -package likelion.univ.donation_history.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.domain.donation_history.entity.DonationHistory; -import likelion.univ.domain.donation_history.service.DonationHistoryDomainService; -import likelion.univ.donation_history.dto.response.DonationHistoriesDetailsResponseDto; -import lombok.RequiredArgsConstructor; - -@UseCase -@RequiredArgsConstructor -public class GetDonationHistoryDetailsUseCase { - private final DonationHistoryDomainService donationHistoryDomainService; - - public DonationHistoriesDetailsResponseDto execute(Long donationHistoryId){ - DonationHistory donationHistory = donationHistoryDomainService.getAndViewCountUp(donationHistoryId); - /* 임시 (유저 도메인 배포 후 변경 예정) */ - return DonationHistoriesDetailsResponseDto.of(donationHistory,false); - } -} diff --git a/likelion-client/src/main/java/likelion/univ/donation_history/usecase/SearchDontionHistoryUseCase.java b/likelion-client/src/main/java/likelion/univ/donation_history/usecase/SearchDontionHistoryUseCase.java deleted file mode 100644 index 027a8ee0..00000000 --- a/likelion-client/src/main/java/likelion/univ/donation_history/usecase/SearchDontionHistoryUseCase.java +++ /dev/null @@ -1,21 +0,0 @@ -package likelion.univ.donation_history.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.common.response.PageResponse; -import likelion.univ.domain.donation_history.adaptor.DonationHistoryAdaptor; -import likelion.univ.domain.donation_history.entity.DonationHistory; -import likelion.univ.donation_history.dto.response.DonationHistoriesSearchResponseDto; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; - -@UseCase -@RequiredArgsConstructor -public class SearchDontionHistoryUseCase { - private final DonationHistoryAdaptor donationHistoryAdaptor; - - public PageResponse execute(String sort, String search, Pageable pageable){ - Page donationHistories = donationHistoryAdaptor.searchDonationHistoryWithSort(pageable, sort, search); - return PageResponse.of(donationHistories.map(d ->DonationHistoriesSearchResponseDto.of(d))); - } -} diff --git a/likelion-client/src/main/java/likelion/univ/donationhistory/controller/DonationHistoryController.java b/likelion-client/src/main/java/likelion/univ/donationhistory/controller/DonationHistoryController.java new file mode 100644 index 00000000..85fa3d31 --- /dev/null +++ b/likelion-client/src/main/java/likelion/univ/donationhistory/controller/DonationHistoryController.java @@ -0,0 +1,48 @@ +package likelion.univ.donationhistory.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import likelion.univ.common.response.PageResponse; +import likelion.univ.donationhistory.dto.response.DonationHistoriesDetailsResponseDto; +import likelion.univ.donationhistory.dto.response.DonationHistoriesSearchResponseDto; +import likelion.univ.donationhistory.service.ClientDonationHistoryService; +import likelion.univ.response.SuccessResponse; +import lombok.RequiredArgsConstructor; +import org.springdoc.api.annotations.ParameterObject; +import org.springframework.data.domain.Pageable; +import org.springframework.data.web.PageableDefault; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/v1/donation-history") +@Tag(name = "기부금 게시판", description = "기부금 게시판관련 API입니다.") +public class DonationHistoryController { + + private final ClientDonationHistoryService clientDonationHistoryService; + + @Operation(summary = "기부금 게시글 목록 검색", description = "기부금 게시글을 검색합니다. 파라미터로 search를 포함하지 않을 시 전체 조회입니다.") + @GetMapping + public SuccessResponse searchDonationHistories( + @RequestParam(value = "sort", required = false, defaultValue = "created_date") String sort, + @RequestParam(value = "search", required = false) String search, + @ParameterObject @PageableDefault(size = 10, page = 0) Pageable pageable + ) { + PageResponse result = clientDonationHistoryService.search(sort, search, + pageable); + return SuccessResponse.of(result); + } + + @Operation(summary = "기부금 게시글 상세정보", description = "해당 기부금 게시글의 상세정보를 조회합니다.") + @GetMapping("/{donationHistoryId}") + public SuccessResponse searchDonationHistories( + @PathVariable("donationHistoryId") Long donationHistoryId + ) { + DonationHistoriesDetailsResponseDto result = clientDonationHistoryService.getDetails(donationHistoryId); + return SuccessResponse.of(result); + } +} diff --git a/likelion-client/src/main/java/likelion/univ/donation_history/dto/response/DonationHistoriesDetailsResponseDto.java b/likelion-client/src/main/java/likelion/univ/donationhistory/dto/response/DonationHistoriesDetailsResponseDto.java similarity index 91% rename from likelion-client/src/main/java/likelion/univ/donation_history/dto/response/DonationHistoriesDetailsResponseDto.java rename to likelion-client/src/main/java/likelion/univ/donationhistory/dto/response/DonationHistoriesDetailsResponseDto.java index c59140d0..12677deb 100644 --- a/likelion-client/src/main/java/likelion/univ/donation_history/dto/response/DonationHistoriesDetailsResponseDto.java +++ b/likelion-client/src/main/java/likelion/univ/donationhistory/dto/response/DonationHistoriesDetailsResponseDto.java @@ -1,16 +1,16 @@ -package likelion.univ.donation_history.dto.response; - -import likelion.univ.domain.donation_history.entity.DonationHistory; -import lombok.Builder; -import lombok.Getter; +package likelion.univ.donationhistory.dto.response; import java.time.LocalDate; import java.util.List; import java.util.stream.Collectors; +import likelion.univ.domain.donationhistory.entity.DonationHistory; +import lombok.Builder; +import lombok.Getter; @Getter @Builder public class DonationHistoriesDetailsResponseDto { + private Long donationHistoryId; private Long authorId; private String authorName; @@ -22,7 +22,7 @@ public class DonationHistoriesDetailsResponseDto { private Long viewCount; private List attachments; - public static DonationHistoriesDetailsResponseDto of(DonationHistory donationHistory, Boolean isAuthor){ + public static DonationHistoriesDetailsResponseDto of(DonationHistory donationHistory, Boolean isAuthor) { return DonationHistoriesDetailsResponseDto.builder() .donationHistoryId(donationHistory.getId()) .authorId(donationHistory.getAuthor().getId()) diff --git a/likelion-client/src/main/java/likelion/univ/donation_history/dto/response/DonationHistoriesSearchResponseDto.java b/likelion-client/src/main/java/likelion/univ/donationhistory/dto/response/DonationHistoriesSearchResponseDto.java similarity index 87% rename from likelion-client/src/main/java/likelion/univ/donation_history/dto/response/DonationHistoriesSearchResponseDto.java rename to likelion-client/src/main/java/likelion/univ/donationhistory/dto/response/DonationHistoriesSearchResponseDto.java index 978dde8c..b64d779e 100644 --- a/likelion-client/src/main/java/likelion/univ/donation_history/dto/response/DonationHistoriesSearchResponseDto.java +++ b/likelion-client/src/main/java/likelion/univ/donationhistory/dto/response/DonationHistoriesSearchResponseDto.java @@ -1,14 +1,14 @@ -package likelion.univ.donation_history.dto.response; +package likelion.univ.donationhistory.dto.response; -import likelion.univ.domain.donation_history.entity.DonationHistory; +import java.time.LocalDate; +import likelion.univ.domain.donationhistory.entity.DonationHistory; import lombok.Builder; import lombok.Getter; -import java.time.LocalDate; - @Getter @Builder public class DonationHistoriesSearchResponseDto { + private Long donationHistoryId; private Long authorId; private String authorName; @@ -17,7 +17,7 @@ public class DonationHistoriesSearchResponseDto { private LocalDate createdDate; private Long viewCount; - public static DonationHistoriesSearchResponseDto of(DonationHistory donationHistory){ + public static DonationHistoriesSearchResponseDto of(DonationHistory donationHistory) { return DonationHistoriesSearchResponseDto.builder() .donationHistoryId(donationHistory.getId()) .authorId(donationHistory.getAuthor().getId()) diff --git a/likelion-client/src/main/java/likelion/univ/donation_history/dto/response/DonationHistoryAttachmentDto.java b/likelion-client/src/main/java/likelion/univ/donationhistory/dto/response/DonationHistoryAttachmentDto.java similarity index 76% rename from likelion-client/src/main/java/likelion/univ/donation_history/dto/response/DonationHistoryAttachmentDto.java rename to likelion-client/src/main/java/likelion/univ/donationhistory/dto/response/DonationHistoryAttachmentDto.java index 30b42468..a788ce31 100644 --- a/likelion-client/src/main/java/likelion/univ/donation_history/dto/response/DonationHistoryAttachmentDto.java +++ b/likelion-client/src/main/java/likelion/univ/donationhistory/dto/response/DonationHistoryAttachmentDto.java @@ -1,19 +1,18 @@ -package likelion.univ.donation_history.dto.response; +package likelion.univ.donationhistory.dto.response; -import likelion.univ.domain.donation_history.entity.DonationHistoryAttachment; +import likelion.univ.domain.donationhistory.entity.DonationHistoryAttachment; import lombok.Builder; import lombok.Getter; @Getter @Builder public class DonationHistoryAttachmentDto { - private String fileName; + private String fileName; private String fileExtension; - private String fileUrl; - public static DonationHistoryAttachmentDto of(DonationHistoryAttachment donationHistoryAttachment){ + public static DonationHistoryAttachmentDto of(DonationHistoryAttachment donationHistoryAttachment) { return DonationHistoryAttachmentDto.builder() .fileName(donationHistoryAttachment.getFileName()) .fileExtension(donationHistoryAttachment.getFileExtension()) diff --git a/likelion-client/src/main/java/likelion/univ/donationhistory/service/ClientDonationHistoryService.java b/likelion-client/src/main/java/likelion/univ/donationhistory/service/ClientDonationHistoryService.java new file mode 100644 index 00000000..a4e92a7a --- /dev/null +++ b/likelion-client/src/main/java/likelion/univ/donationhistory/service/ClientDonationHistoryService.java @@ -0,0 +1,34 @@ +package likelion.univ.donationhistory.service; + +import likelion.univ.common.response.PageResponse; +import likelion.univ.domain.donationhistory.entity.DonationHistory; +import likelion.univ.domain.donationhistory.repository.DonationHistoryRepository; +import likelion.univ.domain.donationhistory.service.DonationHistoryService; +import likelion.univ.donationhistory.dto.response.DonationHistoriesDetailsResponseDto; +import likelion.univ.donationhistory.dto.response.DonationHistoriesSearchResponseDto; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@RequiredArgsConstructor +@Transactional(readOnly = true) +@Service +public class ClientDonationHistoryService { + + private final DonationHistoryRepository donationHistoryRepository; + private final DonationHistoryService donationHistoryService; + + public DonationHistoriesDetailsResponseDto getDetails(Long donationHistoryId) { + DonationHistory donationHistory = donationHistoryService.getAndViewCountUp(donationHistoryId); + /* 임시 (유저 도메인 배포 후 변경 예정) */ + return DonationHistoriesDetailsResponseDto.of(donationHistory, false); + } + + public PageResponse search(String sort, String search, Pageable pageable) { + return PageResponse.of(donationHistoryRepository + .searchDonationHistoryWithSort(pageable, sort, search) + .map(DonationHistoriesSearchResponseDto::of) + ); + } +} diff --git a/likelion-client/src/main/java/likelion/univ/follow/controller/FollowController.java b/likelion-client/src/main/java/likelion/univ/follow/controller/FollowController.java index 33a7cbc9..79899e6d 100644 --- a/likelion-client/src/main/java/likelion/univ/follow/controller/FollowController.java +++ b/likelion-client/src/main/java/likelion/univ/follow/controller/FollowController.java @@ -2,31 +2,38 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; -import likelion.univ.follow.usecase.CancelFollowUseCase; -import likelion.univ.follow.usecase.FollowUserUseCase; +import likelion.univ.follow.service.ClientFollowService; import likelion.univ.response.SuccessResponse; import lombok.RequiredArgsConstructor; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; @RestController @RequiredArgsConstructor @RequestMapping(value = "/v1/follow") @Tag(name = "팔로우", description = "팔로우 관련 API입니다.") public class FollowController { - private final FollowUserUseCase followUserUseCase; - private final CancelFollowUseCase cancelFollowUseCase; + + private final ClientFollowService clientFollowService; @Operation(summary = "팔로우 ", description = "해당 유저를 팔로우 합니다.") @PostMapping("/{userId}") - public SuccessResponse follow(@PathVariable("userId") Long userId){ - followUserUseCase.execute(userId); + public SuccessResponse follow( + @PathVariable("userId") Long userId + ) { + clientFollowService.follow(userId); return SuccessResponse.empty(); } @Operation(summary = "팔로우 취소", description = "해당 유저를 팔로우 취소 합니다.") @DeleteMapping("/{userId}") - public SuccessResponse deleteFollow(@PathVariable("userId") Long userId) { - cancelFollowUseCase.execute(userId); + public SuccessResponse deleteFollow( + @PathVariable("userId") Long userId + ) { + clientFollowService.cancelFollow(userId); return SuccessResponse.empty(); } } diff --git a/likelion-client/src/main/java/likelion/univ/follow/service/ClientFollowService.java b/likelion-client/src/main/java/likelion/univ/follow/service/ClientFollowService.java new file mode 100644 index 00000000..b313a17a --- /dev/null +++ b/likelion-client/src/main/java/likelion/univ/follow/service/ClientFollowService.java @@ -0,0 +1,40 @@ +package likelion.univ.follow.service; + +import likelion.univ.domain.follow.exception.AlreadyFollowingUserException; +import likelion.univ.domain.follow.repository.FollowRepository; +import likelion.univ.follow.dao.FollowNumRedisDao; +import likelion.univ.utils.AuthenticatedUserUtils; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@RequiredArgsConstructor +@Service +public class ClientFollowService { + + private final AuthenticatedUserUtils authenticatedUserUtils; + private final FollowRepository followRepository; + private final FollowNumRedisDao followNumRedisDao; + private final FollowNumRedisService followNumRedisService; + + public void follow(Long userId) { + Long currentUserId = authenticatedUserUtils.getCurrentUserId(); + try { + followRepository.save(currentUserId, userId); + } catch (Exception e) { + throw new AlreadyFollowingUserException(); + } + followNumRedisDao.findById(currentUserId) + .ifPresent(it -> followNumRedisService.followingUp(currentUserId, it)); + followNumRedisDao.findById(userId) + .ifPresent(it -> followNumRedisService.followerUp(userId, it)); + } + + public void cancelFollow(Long userId) { + Long currentUserId = authenticatedUserUtils.getCurrentUserId(); + followRepository.delete(currentUserId, userId); + followNumRedisDao.findById(currentUserId) + .ifPresent(it -> followNumRedisService.followingDown(currentUserId, it)); + followNumRedisDao.findById(userId) + .ifPresent(it -> followNumRedisService.followerDown(userId, it)); + } +} diff --git a/likelion-client/src/main/java/likelion/univ/follow/usecase/CancelFollowUseCase.java b/likelion-client/src/main/java/likelion/univ/follow/usecase/CancelFollowUseCase.java deleted file mode 100644 index 1aba4225..00000000 --- a/likelion-client/src/main/java/likelion/univ/follow/usecase/CancelFollowUseCase.java +++ /dev/null @@ -1,33 +0,0 @@ -package likelion.univ.follow.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.domain.follow.adaptor.FollowAdaptor; -import likelion.univ.follow.dao.FollowNumRedisDao; -import likelion.univ.follow.entity.FollowNum; -import likelion.univ.follow.service.FollowNumRedisService; -import likelion.univ.utils.AuthenticatedUserUtils; -import lombok.RequiredArgsConstructor; - -import java.util.Optional; - -@UseCase -@RequiredArgsConstructor -public class CancelFollowUseCase { - private final AuthenticatedUserUtils authentiatedUserUtils; - private final FollowAdaptor followAdaptor; - private final FollowNumRedisDao followNumRedisDao; - private final FollowNumRedisService followNumRedisService; - - public void execute(Long userId){ - Long currentUserId = authentiatedUserUtils.getCurrentUserId(); - followAdaptor.delete(currentUserId, userId); - updateFollowNumRedis(currentUserId, userId); - } - - private void updateFollowNumRedis(Long currentUserId, Long userId){ - Optional myFollowNum = followNumRedisDao.findById(currentUserId); - if(myFollowNum.isPresent()) followNumRedisService.followingDown(currentUserId, myFollowNum.get()); - Optional targetFollowNum = followNumRedisDao.findById(userId); - if(targetFollowNum.isPresent()) followNumRedisService.followerDown(userId, targetFollowNum.get()); - } -} diff --git a/likelion-client/src/main/java/likelion/univ/follow/usecase/FollowUserUseCase.java b/likelion-client/src/main/java/likelion/univ/follow/usecase/FollowUserUseCase.java deleted file mode 100644 index 4cf7ed6c..00000000 --- a/likelion-client/src/main/java/likelion/univ/follow/usecase/FollowUserUseCase.java +++ /dev/null @@ -1,33 +0,0 @@ -package likelion.univ.follow.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.domain.follow.adaptor.FollowAdaptor; -import likelion.univ.follow.dao.FollowNumRedisDao; -import likelion.univ.follow.entity.FollowNum; -import likelion.univ.follow.service.FollowNumRedisService; -import likelion.univ.utils.AuthenticatedUserUtils; -import lombok.RequiredArgsConstructor; - -import java.util.Optional; - -@UseCase -@RequiredArgsConstructor -public class FollowUserUseCase { - private final AuthenticatedUserUtils authentiatedUserUtils; - private final FollowAdaptor followAdaptor; - private final FollowNumRedisDao followNumRedisDao; - private final FollowNumRedisService followNumRedisService; - - public void execute(Long userId){ - Long currentUserId = authentiatedUserUtils.getCurrentUserId(); - followAdaptor.save(currentUserId, userId); - updateFollowNumRedis(currentUserId, userId); - } - - private void updateFollowNumRedis(Long currentUserId, Long userId){ - Optional myFollowNum = followNumRedisDao.findById(currentUserId); - if(myFollowNum.isPresent()) followNumRedisService.followingUp(currentUserId, myFollowNum.get()); - Optional targetFollowNum = followNumRedisDao.findById(userId); - if(targetFollowNum.isPresent()) followNumRedisService.followerUp(userId, targetFollowNum.get()); - } -} diff --git a/likelion-client/src/main/java/likelion/univ/hackathon/controller/HackathonController.java b/likelion-client/src/main/java/likelion/univ/hackathon/controller/HackathonController.java new file mode 100644 index 00000000..eb810163 --- /dev/null +++ b/likelion-client/src/main/java/likelion/univ/hackathon/controller/HackathonController.java @@ -0,0 +1,64 @@ +package likelion.univ.hackathon.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import javax.validation.Valid; +import likelion.univ.domain.hackathon.response.HackathonFindResponse; +import likelion.univ.domain.hackathon.service.HackathonService; +import likelion.univ.email.sender.EmailSender; +import likelion.univ.hackathon.request.HackathonApplyRequest; +import likelion.univ.hackathon.request.HackathonModifyRequest; +import likelion.univ.response.SuccessResponse; +import likelion.univ.utils.AuthenticatedUserUtils; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/v1/hackathons") +@Tag(name = "해커톤", description = "해커톤 API") +public class HackathonController { + + private final AuthenticatedUserUtils userUtils; + private final HackathonService hackathonService; + private final EmailSender emailSender; + + @Operation(summary = "해커톤 신청") + @PostMapping + public SuccessResponse apply( + @Valid @RequestBody HackathonApplyRequest request + ) { + Long userId = userUtils.getCurrentUserId(); + Long projectId = hackathonService.apply(request.toCommand(userId)); + // TODO: emailSender.send(); ??? + return SuccessResponse.of(projectId); + } + + @Operation(summary = "해커톤 신청 조회") + @GetMapping("/{hackathonFormId}") + public SuccessResponse find( + @PathVariable("hackathonFormId") Long hackathonFormId + ) { + Long userId = userUtils.getCurrentUserId(); + HackathonFindResponse response = hackathonService.find(userId, hackathonFormId); + return SuccessResponse.of(response); + } + + @Operation(summary = "해커톤 신청 수정") + @PutMapping("/{hackathonFormId}") + public SuccessResponse modify( + @Valid @RequestBody HackathonModifyRequest request, + @PathVariable("hackathonFormId") Long hackathonFormId + ) { + Long userId = userUtils.getCurrentUserId(); + hackathonService.modify(request.toCommand(userId, hackathonFormId)); + return SuccessResponse.of(null); + } + +} diff --git a/likelion-client/src/main/java/likelion/univ/hackathon/request/HackathonApplyRequest.java b/likelion-client/src/main/java/likelion/univ/hackathon/request/HackathonApplyRequest.java new file mode 100644 index 00000000..2b46656d --- /dev/null +++ b/likelion-client/src/main/java/likelion/univ/hackathon/request/HackathonApplyRequest.java @@ -0,0 +1,62 @@ +package likelion.univ.hackathon.request; + + +import io.swagger.v3.oas.annotations.media.Schema; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import likelion.univ.domain.hackathon.entity.HackathonPart; +import likelion.univ.domain.hackathon.service.command.HackathonApplyCommand; + +public record HackathonApplyRequest( + @NotBlank + @Schema(description = "신청자 이름", example = "김멋사") + String name, + + @NotBlank + @Schema(description = "신청자 이메일", example = "likelion@likelion.com") + String email, + + @NotBlank + @Schema(description = "신청자 학교 이름", example = "멋사대학교") + String universityName, + + @NotBlank + @Schema(description = "신청자 전공", example = "멋쟁이과") + String major, + + @NotBlank + @Schema(description = "신청자 전화번호 (-생략, 숫자만)", example = "01012341234") + String phone, + + @NotNull + @Schema(description = "해커톤 파트", example = "PM") + HackathonPart hackathonPart, + + @NotBlank + @Size(max = 10, message = "팀명은 10자 이하여야 합니다.") + @Schema(description = "팀명", example = "멋쟁이팀") + String teamName, + + @Schema(description = "오프라인 참가 여부", example = "true") + boolean offlineParticipation, + + @Size(max = 100, message = "불참사유는 100자 이내여야 합니다.") + @Schema(description = "불참 사유", example = "개인 사정으로 인해 불참합니다.") + String reasonForNotOffline +) { + public HackathonApplyCommand toCommand(Long userId) { + return new HackathonApplyCommand( + userId, + name, + email, + universityName, + major, + phone, + hackathonPart, + teamName, + offlineParticipation, + reasonForNotOffline + ); + } +} diff --git a/likelion-client/src/main/java/likelion/univ/hackathon/request/HackathonModifyRequest.java b/likelion-client/src/main/java/likelion/univ/hackathon/request/HackathonModifyRequest.java new file mode 100644 index 00000000..a25aaa07 --- /dev/null +++ b/likelion-client/src/main/java/likelion/univ/hackathon/request/HackathonModifyRequest.java @@ -0,0 +1,43 @@ +package likelion.univ.hackathon.request; + + +import io.swagger.v3.oas.annotations.media.Schema; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import likelion.univ.domain.hackathon.entity.HackathonPart; +import likelion.univ.domain.hackathon.service.command.HackathonModifyCommand; + +public record HackathonModifyRequest( + @NotBlank + @Schema(description = "신청자 전화번호 (-생략, 숫자만)", example = "01012341234") + String phone, + + @NotNull + @Schema(description = "해커톤 파트", example = "PM") + HackathonPart hackathonPart, + + @NotBlank + @Size(max = 10, message = "팀명은 10자 이하여야 합니다.") + @Schema(description = "팀명", example = "멋쟁이팀") + String teamName, + + @Schema(description = "오프라인 참가 여부", example = "true") + boolean offlineParticipation, + + @Size(max = 100, message = "불참사유는 100자 이내여야 합니다.") + @Schema(description = "불참 사유", example = "개인 사정으로 인해 불참합니다.") + String reasonForNotOffline +) { + public HackathonModifyCommand toCommand(Long userId, Long hackathonFormId) { + return new HackathonModifyCommand( + hackathonFormId, + userId, + phone, + hackathonPart, + teamName, + offlineParticipation, + reasonForNotOffline + ); + } +} diff --git a/likelion-client/src/main/java/likelion/univ/image/controller/ImageController.java b/likelion-client/src/main/java/likelion/univ/image/controller/ImageController.java index be764abc..8f56a47b 100644 --- a/likelion-client/src/main/java/likelion/univ/image/controller/ImageController.java +++ b/likelion-client/src/main/java/likelion/univ/image/controller/ImageController.java @@ -3,30 +3,43 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import likelion.univ.image.dto.response.ImageUrlResponseDto; -import likelion.univ.image.usecase.CreateDraftPresignedUrlUseCase; -import likelion.univ.image.usecase.CreatePresignedUrlUseCase; +import likelion.univ.image.service.ClientImageService; import likelion.univ.response.SuccessResponse; import lombok.RequiredArgsConstructor; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; @RestController @RequiredArgsConstructor -@RequestMapping(value = "/v1/image") +@RequestMapping("/v1/image") @Tag(name = "이미지 업로드", description = "Presigned-url 발급 API") public class ImageController { - private final CreatePresignedUrlUseCase createPresignedUrlUseCase; - private final CreateDraftPresignedUrlUseCase createDraftPresignedUrlUseCase; + + private final ClientImageService clientImageService; @Operation(summary = "project 이미지용입니다.") @GetMapping("/project") - public SuccessResponse getProjectPresignedUrl(@RequestParam String fileNameExtension) { - ImageUrlResponseDto imageUrlResponseDto = createDraftPresignedUrlUseCase.execute("project", fileNameExtension); + public SuccessResponse getProjectPresignedUrl( + @RequestParam("fileNameExtension") String fileNameExtension + ) { + ImageUrlResponseDto imageUrlResponseDto = clientImageService.createProjectImagePresignedUrl( + "project", fileNameExtension + ); return SuccessResponse.of(imageUrlResponseDto); } + @Operation(summary = "user 프로필 이미지용입니다.") @GetMapping("/user/{userId}") - public SuccessResponse getUserPresignedUrl(@PathVariable Long userId , @RequestParam String fileNameExtension) { - ImageUrlResponseDto imageUrlResponseDto = createPresignedUrlUseCase.execute("user", userId, fileNameExtension); + public SuccessResponse getUserPresignedUrl( + @PathVariable("userId") Long userId, + @RequestParam("fileNameExtension") String fileNameExtension + ) { + ImageUrlResponseDto imageUrlResponseDto = clientImageService.createUserProfileImagePresignedUrl( + "user", userId, fileNameExtension + ); return SuccessResponse.of(imageUrlResponseDto); } } diff --git a/likelion-client/src/main/java/likelion/univ/image/dto/response/ImageUrlResponseDto.java b/likelion-client/src/main/java/likelion/univ/image/dto/response/ImageUrlResponseDto.java index 98b748af..a3aa8b0a 100644 --- a/likelion-client/src/main/java/likelion/univ/image/dto/response/ImageUrlResponseDto.java +++ b/likelion-client/src/main/java/likelion/univ/image/dto/response/ImageUrlResponseDto.java @@ -6,6 +6,7 @@ @Data @Builder public class ImageUrlResponseDto { + private String presignedUrl; private String imageUrl; private String fileName; diff --git a/likelion-client/src/main/java/likelion/univ/image/service/ClientImageService.java b/likelion-client/src/main/java/likelion/univ/image/service/ClientImageService.java new file mode 100644 index 00000000..021e8ca4 --- /dev/null +++ b/likelion-client/src/main/java/likelion/univ/image/service/ClientImageService.java @@ -0,0 +1,40 @@ +package likelion.univ.image.service; + +import java.util.UUID; +import likelion.univ.image.dto.response.ImageUrlResponseDto; +import likelion.univ.s3.GeneratePresignedUrlProcessor; +import likelion.univ.s3.S3Properties; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@RequiredArgsConstructor +@Service +public class ClientImageService { + + private final GeneratePresignedUrlProcessor generatePresignedUrlProcessor; + private final S3Properties s3Properties; + + public ImageUrlResponseDto createProjectImagePresignedUrl(String prefix, String fileNameExtension) { + String fileName = createFileName(prefix, fileNameExtension); + String presignedUrl = generatePresignedUrlProcessor.execute(fileName); + String imageUrl = s3Properties.getAccessDomain() + fileName; + return ImageUrlResponseDto.of(presignedUrl, imageUrl, fileName); + } + + private String createFileName(String prefix, String fileNameExtension) { + String fileName = UUID.randomUUID().toString(); + return "image/" + prefix + "/" + fileName + "." + fileNameExtension; + } + + public ImageUrlResponseDto createUserProfileImagePresignedUrl(String prefix, Long id, String fileNameExtension) { + String fileName = createFileName(prefix, id, fileNameExtension); + String presignedUrl = generatePresignedUrlProcessor.execute(fileName); + String imageUrl = s3Properties.getAccessDomain() + fileName; + return ImageUrlResponseDto.of(presignedUrl, imageUrl, fileName); + } + + private String createFileName(String prefix, Long id, String fileNameExtension) { + String uuid = UUID.randomUUID().toString(); + return "image/" + prefix + "/" + id.toString() + "/" + uuid + "." + fileNameExtension; + } +} diff --git a/likelion-client/src/main/java/likelion/univ/image/usecase/CreateDraftPresignedUrlUseCase.java b/likelion-client/src/main/java/likelion/univ/image/usecase/CreateDraftPresignedUrlUseCase.java deleted file mode 100644 index a6859134..00000000 --- a/likelion-client/src/main/java/likelion/univ/image/usecase/CreateDraftPresignedUrlUseCase.java +++ /dev/null @@ -1,27 +0,0 @@ -package likelion.univ.image.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.image.dto.response.ImageUrlResponseDto; -import likelion.univ.s3.GeneratePresignedUrlProcessor; -import likelion.univ.s3.S3Properties; -import lombok.RequiredArgsConstructor; - -import java.util.UUID; - -@UseCase -@RequiredArgsConstructor -public class CreateDraftPresignedUrlUseCase { - private final GeneratePresignedUrlProcessor generatePresignedUrlProcessor; - private final S3Properties s3Properties; - - public ImageUrlResponseDto execute(String prefix, String fileNameExtension) { - String fileName = createFileName(prefix, fileNameExtension); - String presignedUrl = generatePresignedUrlProcessor.execute(fileName); - String imageUrl = s3Properties.getAccessDomain() + fileName; - return ImageUrlResponseDto.of(presignedUrl, imageUrl, fileName); - } - private String createFileName(String prefix, String fileNameExtension){ - String fileName = UUID.randomUUID().toString(); - return "image/" + prefix + "/" + fileName + "." + fileNameExtension; - } -} \ No newline at end of file diff --git a/likelion-client/src/main/java/likelion/univ/image/usecase/CreatePresignedUrlUseCase.java b/likelion-client/src/main/java/likelion/univ/image/usecase/CreatePresignedUrlUseCase.java deleted file mode 100644 index bd21b62b..00000000 --- a/likelion-client/src/main/java/likelion/univ/image/usecase/CreatePresignedUrlUseCase.java +++ /dev/null @@ -1,27 +0,0 @@ -package likelion.univ.image.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.image.dto.response.ImageUrlResponseDto; -import likelion.univ.s3.GeneratePresignedUrlProcessor; -import likelion.univ.s3.S3Properties; -import lombok.RequiredArgsConstructor; - -import java.util.UUID; - -@UseCase -@RequiredArgsConstructor -public class CreatePresignedUrlUseCase { - private final GeneratePresignedUrlProcessor generatePresignedUrlProcessor; - private final S3Properties s3Properties; - - public ImageUrlResponseDto execute(String prefix, Long id, String fileNameExtension) { - String fileName = createFileName(prefix, id, fileNameExtension); - String presignedUrl = generatePresignedUrlProcessor.execute(fileName); - String imageUrl = s3Properties.getAccessDomain() + fileName; - return ImageUrlResponseDto.of(presignedUrl, imageUrl, fileName); - } - private String createFileName(String prefix, Long id, String fileNameExtension){ - String uuid = UUID.randomUUID().toString(); - return "image/" + prefix + "/" + id.toString() + "/" + uuid + "." + fileNameExtension; - } -} \ No newline at end of file diff --git a/likelion-client/src/main/java/likelion/univ/like/commentlike/controller/CommentLikeController.java b/likelion-client/src/main/java/likelion/univ/like/commentlike/controller/CommentLikeController.java index f51c0b14..ecdf8ca3 100644 --- a/likelion-client/src/main/java/likelion/univ/like/commentlike/controller/CommentLikeController.java +++ b/likelion-client/src/main/java/likelion/univ/like/commentlike/controller/CommentLikeController.java @@ -3,13 +3,16 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import likelion.univ.domain.comment.exception.NotAuthorizedException; -import likelion.univ.domain.like.commentlike.dto.response.CommentLikeIdData; import likelion.univ.like.commentlike.dto.CommentLikeRequestDto; -import likelion.univ.like.commentlike.usecase.CreateOrDeleteCommentLikeUseCase; +import likelion.univ.like.commentlike.service.ClientCommentLikeService; import likelion.univ.response.SuccessResponse; +import likelion.univ.utils.AuthenticatedUserUtils; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.web.bind.annotation.*; +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; @Slf4j @RestController @@ -17,18 +20,23 @@ @RequestMapping("/v1/community/comment-likes") @Tag(name = "댓글 좋아요", description = "커뮤니티 APIs") public class CommentLikeController { - private final CreateOrDeleteCommentLikeUseCase createOrDeleteCommentLikeUseCase; + + private final AuthenticatedUserUtils userUtils; + private final ClientCommentLikeService clientCommentLikeService; + @Operation(summary = "댓글 좋아요 수행 / 취소", description = """ - commentId에 대하여 댓글 좋아요 수행 - 만약 이미 좋아요를 했으면 좋아요 hard delete 수행 """) - @PostMapping("") - public SuccessResponse createOrDeleteCommentLike(@RequestBody CommentLikeRequestDto request) throws NotAuthorizedException { - boolean likeCreated = createOrDeleteCommentLikeUseCase.execute(request); + @PostMapping + public SuccessResponse createOrDeleteCommentLike( + @RequestBody CommentLikeRequestDto request + ) throws NotAuthorizedException { + Long userId = userUtils.getCurrentUserId(); + boolean likeCreated = clientCommentLikeService.createOrDelete(request.toCommand(userId)); if (likeCreated) { return SuccessResponse.of("좋아요가 생성되었습니다.", "201"); } return SuccessResponse.of("좋아요가 취소되었습니다."); } - } diff --git a/likelion-client/src/main/java/likelion/univ/like/commentlike/dto/CommentLikeRequestDto.java b/likelion-client/src/main/java/likelion/univ/like/commentlike/dto/CommentLikeRequestDto.java index 1642fcef..d09d000d 100644 --- a/likelion-client/src/main/java/likelion/univ/like/commentlike/dto/CommentLikeRequestDto.java +++ b/likelion-client/src/main/java/likelion/univ/like/commentlike/dto/CommentLikeRequestDto.java @@ -1,19 +1,18 @@ package likelion.univ.like.commentlike.dto; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - import javax.validation.constraints.NotNull; +import likelion.univ.domain.like.commentlike.dto.request.CommentLikeCommand; -@Data -@Builder -@AllArgsConstructor -@NoArgsConstructor -public class CommentLikeRequestDto { - @NotNull - @Schema(description = "좋아요를 누르는 댓글 id") - private Long commentId; +public record CommentLikeRequestDto( + @NotNull + @Schema(description = "좋아요를 누르는 댓글 id") + Long commentId +) { + public CommentLikeCommand toCommand(Long userId) { + return CommentLikeCommand.builder() + .loginUserId(userId) + .commentId(commentId) + .build(); + } } diff --git a/likelion-client/src/main/java/likelion/univ/like/commentlike/service/ClientCommentLikeService.java b/likelion-client/src/main/java/likelion/univ/like/commentlike/service/ClientCommentLikeService.java new file mode 100644 index 00000000..dec79108 --- /dev/null +++ b/likelion-client/src/main/java/likelion/univ/like/commentlike/service/ClientCommentLikeService.java @@ -0,0 +1,18 @@ +package likelion.univ.like.commentlike.service; + +import likelion.univ.annotation.UseCase; +import likelion.univ.domain.comment.exception.NotAuthorizedException; +import likelion.univ.domain.like.commentlike.dto.request.CommentLikeCommand; +import likelion.univ.domain.like.commentlike.service.CommentLikeService; +import lombok.RequiredArgsConstructor; + +@UseCase +@RequiredArgsConstructor +public class ClientCommentLikeService { + + private final CommentLikeService commentLikeService; + + public boolean createOrDelete(CommentLikeCommand command) throws NotAuthorizedException { + return commentLikeService.createOrDeleteCommentLike(command); + } +} diff --git a/likelion-client/src/main/java/likelion/univ/like/commentlike/usecase/CreateOrDeleteCommentLikeUseCase.java b/likelion-client/src/main/java/likelion/univ/like/commentlike/usecase/CreateOrDeleteCommentLikeUseCase.java deleted file mode 100644 index a98b01ee..00000000 --- a/likelion-client/src/main/java/likelion/univ/like/commentlike/usecase/CreateOrDeleteCommentLikeUseCase.java +++ /dev/null @@ -1,32 +0,0 @@ -package likelion.univ.like.commentlike.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.domain.comment.exception.NotAuthorizedException; -import likelion.univ.like.commentlike.dto.CommentLikeRequestDto; -import likelion.univ.domain.like.commentlike.dto.request.CommentLikeCommand; -import likelion.univ.domain.like.commentlike.dto.response.CommentLikeIdData; -import likelion.univ.domain.like.commentlike.service.CommentLikeDomainService; -import likelion.univ.post.processor.GetOrCreatePostCountInfoProcessor; -import likelion.univ.post.processor.UpdatePostCountInfoProcessor; -import likelion.univ.utils.AuthenticatedUserUtils; -import lombok.RequiredArgsConstructor; - -@UseCase -@RequiredArgsConstructor -public class CreateOrDeleteCommentLikeUseCase { - private final AuthenticatedUserUtils userUtils; - private final CommentLikeDomainService commentLikeDomainService; - public boolean execute(CommentLikeRequestDto request) throws NotAuthorizedException { - CommentLikeCommand serviceDto = getServiceDto(request); - boolean isCreated = commentLikeDomainService.createOrDeleteCommentLike(serviceDto); - return isCreated; - } - - private CommentLikeCommand getServiceDto(CommentLikeRequestDto request) { - return CommentLikeCommand.builder() - .loginUserId(userUtils.getCurrentUserId()) - .commentId(request.getCommentId()) - .build(); - } - -} diff --git a/likelion-client/src/main/java/likelion/univ/like/postlike/controller/PostLikeController.java b/likelion-client/src/main/java/likelion/univ/like/postlike/controller/PostLikeController.java index e05c7220..7a944b8d 100644 --- a/likelion-client/src/main/java/likelion/univ/like/postlike/controller/PostLikeController.java +++ b/likelion-client/src/main/java/likelion/univ/like/postlike/controller/PostLikeController.java @@ -4,22 +4,31 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import likelion.univ.like.postlike.dto.PostLikeRequestDto; -import likelion.univ.like.postlike.usecase.CreateOrDeletePostLikeUseCase; +import likelion.univ.like.postlike.service.ClientPostLikeService; import likelion.univ.response.SuccessResponse; +import likelion.univ.utils.AuthenticatedUserUtils; import lombok.RequiredArgsConstructor; -import org.springframework.web.bind.annotation.*; +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; @RestController @RequiredArgsConstructor @RequestMapping("/v1/community/post-likes") @Tag(name = "게시글 좋아요", description = "커뮤니티 APIs") public class PostLikeController { - private final CreateOrDeletePostLikeUseCase createOrDeletePostLikeUseCase; + + private final AuthenticatedUserUtils userUtils; + private final ClientPostLikeService clientPostLikeService; @Operation(summary = "게시글 좋아요 수행", description = "게시글 좋아요를 생성함") - @PostMapping("") - public SuccessResponse createOrDeletePostLike(@RequestBody PostLikeRequestDto request) { - boolean likeCreated = createOrDeletePostLikeUseCase.execute(request); + @PostMapping + public SuccessResponse createOrDeletePostLike( + @RequestBody PostLikeRequestDto request + ) { + Long userId = userUtils.getCurrentUserId(); + boolean likeCreated = clientPostLikeService.createOrDelete(request.toCommand(userId)); if (likeCreated) { return SuccessResponse.of("좋아요가 생성되었습니다.", "201"); } diff --git a/likelion-client/src/main/java/likelion/univ/like/postlike/dto/PostLikeRequestDto.java b/likelion-client/src/main/java/likelion/univ/like/postlike/dto/PostLikeRequestDto.java index 80e7097c..d9a41d43 100644 --- a/likelion-client/src/main/java/likelion/univ/like/postlike/dto/PostLikeRequestDto.java +++ b/likelion-client/src/main/java/likelion/univ/like/postlike/dto/PostLikeRequestDto.java @@ -1,17 +1,15 @@ package likelion.univ.like.postlike.dto; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - import javax.validation.constraints.NotNull; +import likelion.univ.domain.like.postlike.dto.PostLikeCommand; public record PostLikeRequestDto( @NotNull @Schema(description = "좋아요를 누르는 게시글 id") Long postId ) { - + public PostLikeCommand toCommand(Long userId) { + return new PostLikeCommand(postId, userId); + } } diff --git a/likelion-client/src/main/java/likelion/univ/like/postlike/usecase/CreateOrDeletePostLikeUseCase.java b/likelion-client/src/main/java/likelion/univ/like/postlike/service/ClientPostLikeService.java similarity index 56% rename from likelion-client/src/main/java/likelion/univ/like/postlike/usecase/CreateOrDeletePostLikeUseCase.java rename to likelion-client/src/main/java/likelion/univ/like/postlike/service/ClientPostLikeService.java index 409c6b51..9a00342b 100644 --- a/likelion-client/src/main/java/likelion/univ/like/postlike/usecase/CreateOrDeletePostLikeUseCase.java +++ b/likelion-client/src/main/java/likelion/univ/like/postlike/service/ClientPostLikeService.java @@ -1,26 +1,24 @@ -package likelion.univ.like.postlike.usecase; +package likelion.univ.like.postlike.service; import likelion.univ.annotation.UseCase; import likelion.univ.domain.like.postlike.dto.PostLikeCommand; -import likelion.univ.domain.like.postlike.service.PostLikeDomainService; -import likelion.univ.like.postlike.dto.PostLikeRequestDto; +import likelion.univ.domain.like.postlike.service.PostLikeService; import likelion.univ.post.entity.PostCountInfo; import likelion.univ.post.processor.GetOrCreatePostCountInfoProcessor; import likelion.univ.post.processor.UpdatePostCountInfoProcessor; -import likelion.univ.utils.AuthenticatedUserUtils; import lombok.RequiredArgsConstructor; @UseCase @RequiredArgsConstructor -public class CreateOrDeletePostLikeUseCase { - private final PostLikeDomainService postLikeDomainService; - private final AuthenticatedUserUtils userUtils; +public class ClientPostLikeService { + + private final PostLikeService postLikeService; private final GetOrCreatePostCountInfoProcessor getOrCreatePostCountInfoProcessor; private final UpdatePostCountInfoProcessor updatePostCountInfoProcessor; - public boolean execute(PostLikeRequestDto request) { - boolean hasCreated = postLikeDomainService.createOrDeletePostLike(getServiceDto(request)); - Long postId = request.postId(); + public boolean createOrDelete(PostLikeCommand command) { + boolean hasCreated = postLikeService.createOrDeletePostLike(command); + Long postId = command.postId(); PostCountInfo countInfo = getOrCreatePostCountInfoProcessor.execute(postId); Long commentCount = countInfo.getCommentCount(); Long likeCount = countInfo.getLikeCount(); @@ -29,13 +27,6 @@ public boolean execute(PostLikeRequestDto request) { } else { updatePostCountInfoProcessor.execute(postId, commentCount, --likeCount); } - return hasCreated; } - - private PostLikeCommand getServiceDto(PostLikeRequestDto request) { - return new PostLikeCommand(request.postId(), userUtils.getCurrentUserId()); - } - - } diff --git a/likelion-client/src/main/java/likelion/univ/post/controller/PostController.java b/likelion-client/src/main/java/likelion/univ/post/controller/PostController.java index 5edac2fe..9c094ad0 100644 --- a/likelion-client/src/main/java/likelion/univ/post/controller/PostController.java +++ b/likelion-client/src/main/java/likelion/univ/post/controller/PostController.java @@ -3,42 +3,48 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import javax.validation.Valid; import likelion.univ.common.response.PageResponse; -import likelion.univ.domain.post.dto.enums.PostOrderCondition; import likelion.univ.domain.post.dto.enums.MainCategory; +import likelion.univ.domain.post.dto.enums.PostOrderCondition; import likelion.univ.domain.post.dto.enums.SubCategory; +import likelion.univ.domain.post.dto.request.DeletePostCommand; import likelion.univ.domain.post.exception.PostErrorCode; import likelion.univ.post.dto.request.PostCreateRequestDto; import likelion.univ.post.dto.request.PostUpdateRequestDto; import likelion.univ.post.dto.response.PostDetailResponseDto; import likelion.univ.post.dto.response.PostEditResponseDto; import likelion.univ.post.dto.response.PostResponseDto; -import likelion.univ.post.usecase.*; +import likelion.univ.post.service.ClientPostQueryService; +import likelion.univ.post.service.ClientPostService; import likelion.univ.response.BaseResponse; import likelion.univ.response.ErrorResponse; import likelion.univ.response.SuccessResponse; +import likelion.univ.utils.AuthenticatedUserUtils; import lombok.RequiredArgsConstructor; import org.springdoc.api.annotations.ParameterObject; import org.springframework.data.domain.Pageable; import org.springframework.data.web.PageableDefault; -import org.springframework.web.bind.annotation.*; - -import javax.validation.Valid; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +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.RequestParam; +import org.springframework.web.bind.annotation.RestController; @RestController @RequiredArgsConstructor -@RequestMapping("/v1") +@RequestMapping("/v1/community/posts") @Tag(name = "게시글", description = "커뮤니티 APIs") public class PostController { - private final CreatePostUseCase createPostUseCase; - private final EditPostUseCase editPostUsecase; - private final DeletePostUseCase deletePostUseCase; - private final GetPostsByCategoriesUseCase getPostsByCategoriesUseCase; - private final GetPostDetailUseCase getPostDetailUseCase; - private final GetPostEditUseCase getPostEditUseCase; - private final GetPostsBySearchTitleUseCase getPostsBySearchTitleUseCase; + private final AuthenticatedUserUtils userUtils; + private final ClientPostService postService; + private final ClientPostQueryService postQueryService; /* ----- read ----- */ @Operation( @@ -48,9 +54,11 @@ public class PostController { ### 게시글 상세 조회 api입니다. - 테스트 완료(황제철) - 게시글 / 댓글에 profile projectImage url이 없으면 boolean 타입만 전달 (url : null 포함x)""") - @GetMapping("/community/posts/{postId}") - public SuccessResponse findPostDetail(@PathVariable Long postId) { - PostDetailResponseDto response = getPostDetailUseCase.execute(postId); + @GetMapping("/{postId}") + public SuccessResponse findPostDetail( + @PathVariable("postId") Long postId + ) { + PostDetailResponseDto response = postQueryService.getDetail(postId); return SuccessResponse.of(response); } @@ -62,13 +70,14 @@ public SuccessResponse findPostDetail(@PathVariable Long - postId에 해당하는 게시글 없으면 404 반환 """ ) - @GetMapping("/community/posts/{postId}/simple") - public SuccessResponse findPostEdit(@PathVariable Long postId) { - PostEditResponseDto response = getPostEditUseCase.execute(postId); + @GetMapping("/{postId}/simple") + public SuccessResponse findPostEdit( + @PathVariable("postId") Long postId + ) { + PostEditResponseDto response = postQueryService.getPostEdit(postId); return SuccessResponse.of(response); } - @Operation( summary = "카테고리별 posts 조회", description = @@ -88,51 +97,57 @@ public SuccessResponse findPostEdit(@PathVariable Long post - **s (size ; 페이지 크기)** : 양수 """ ) - @GetMapping("/community/posts") + @GetMapping public BaseResponse findCategorizedPosts( - @RequestParam PostOrderCondition oc, - @RequestParam(defaultValue = "멋쟁이사자처럼") String mc, - @RequestParam(defaultValue = "공지 사항") String sc, - @ParameterObject @PageableDefault(size = 5, page = 1) Pageable pageable) { + @RequestParam("oc") PostOrderCondition oc, + @RequestParam(value = "mc", defaultValue = "멋쟁이사자처럼") String mc, + @RequestParam(value = "sc", defaultValue = "공지 사항") String sc, + @ParameterObject @PageableDefault(size = 5, page = 1) Pageable pageable + ) { if (!MainCategory.isValid(mc) || !SubCategory.isValid(sc)) { return ErrorResponse.of(PostErrorCode.CATEGORY_NOT_FOUND); } - PageResponse response = getPostsByCategoriesUseCase.execute(oc, mc, sc, pageable); + PageResponse response = postQueryService.getPostsByCategories( + oc, mc, sc, pageable + ); return SuccessResponse.of(response); } @Operation( summary = "게시글 제목으로 검색", description = """ - ### Search Title(st) - - 대소문자 구분 없이 제목 일부를 검색어로 활용 가능 - - 최신순 정렬 기준 조회 - - **카테고리는 한글로 기입하되, 띄어쓰기 준수** - - ### Main Category(mc) - - **ALL**(전체 게시글 대상 검색) - - **HQ_BOARD**(멋대 중앙) - - **FREE_BOARD**(자유게시판) - - **OVERFLOW**(멋사 오버플로우) - - ### Sub Category(sc) - - **ALL** : (mainCategory에서 "ALL"로 설정하면 sub category는 아무거나 해도 되지만, 가급적 ALL 권장) - - **HQ_BOARD(멋대 중앙)** : NOTICE(공지사항), QNA(질문건의), INFO(정보공유) - - **FREE_BOARD(자유게시판)** : INFO(정보공유), GET_MEMBER(팀원모집), GET_PROJECT(플젝모집), SHOWOFF(플젝자랑) - - **OVERFLOW(멋사 오버플로우)** : FRONTEND(프론트), BACKEND(백), PM(기획), UXUI(디자인), ETC(기타)""" + ### Search Title(st) + - 대소문자 구분 없이 제목 일부를 검색어로 활용 가능 + - 최신순 정렬 기준 조회 + - **카테고리는 한글로 기입하되, 띄어쓰기 준수** + + ### Main Category(mc) + - **ALL**(전체 게시글 대상 검색) + - **HQ_BOARD**(멋대 중앙) + - **FREE_BOARD**(자유게시판) + - **OVERFLOW**(멋사 오버플로우) + + ### Sub Category(sc) + - **ALL** : (mainCategory에서 "ALL"로 설정하면 sub category는 아무거나 해도 되지만, 가급적 ALL 권장) + - **HQ_BOARD(멋대 중앙)** : NOTICE(공지사항), QNA(질문건의), INFO(정보공유) + - **FREE_BOARD(자유게시판)** : INFO(정보공유), GET_MEMBER(팀원모집), GET_PROJECT(플젝모집), SHOWOFF(플젝자랑) + - **OVERFLOW(멋사 오버플로우)** : FRONTEND(프론트), BACKEND(백), PM(기획), UXUI(디자인), ETC(기타)""" ) - @GetMapping("/community/posts/search") + @GetMapping("/search") public BaseResponse searchPost( - @RequestParam PostOrderCondition oc, - @RequestParam(defaultValue = "검색어") String st, - @RequestParam(defaultValue = "전체 게시판") String mc, - @RequestParam(defaultValue = "전체 게시판") String sc, - @ParameterObject @PageableDefault(size = 5, page = 1) Pageable pageable) { + @RequestParam("oc") PostOrderCondition oc, + @RequestParam(value = "st", defaultValue = "검색어") String st, + @RequestParam(value = "mc", defaultValue = "전체 게시판") String mc, + @RequestParam(value = "sc", defaultValue = "전체 게시판") String sc, + @ParameterObject @PageableDefault(size = 5, page = 1) Pageable pageable + ) { if (!mc.equals("전체 게시판") && (!MainCategory.isValid(mc) || !SubCategory.isValid(sc))) { return ErrorResponse.of(PostErrorCode.CATEGORY_NOT_FOUND); } - PageResponse response = getPostsBySearchTitleUseCase.execute(oc, st, mc, sc, pageable); + PageResponse response = postQueryService.getPostBySearchTitle( + oc, st, mc, sc, pageable + ); return SuccessResponse.of(response); } @@ -151,28 +166,37 @@ public BaseResponse searchPost( - **HQ_BOARD(멋대 중앙)** : NOTICE(공지사항), QNA(질문건의), INFO(정보공유) - **FREE_BOARD(자유게시판)** : INFO(정보공유), GET_MEMBER(팀원모집), GET_PROJECT(플젝모집), SHOWOFF(플젝자랑) - **OVERFLOW(멋사 오버플로우)** : FRONTEND(프론트), BACKEND(백), PM(기획), UXUI(디자인), ETC(기타)""") - @PostMapping("/community/posts/new") - public SuccessResponse createPost(@RequestBody @Valid PostCreateRequestDto request/*, BindingResult bindingResult*/) { - Long savedPostId = createPostUseCase.execute(request); + @PostMapping("/new") + public SuccessResponse createPost( + @RequestBody @Valid PostCreateRequestDto request + ) { + Long userId = userUtils.getCurrentUserId(); + Long savedPostId = postService.create(request.toCommand(userId)); return SuccessResponse.of(savedPostId); } @Operation( summary = "게시글 수정", description = "제목, 내용, 썸네일 수정 : 수정을 안하는 값은 기존 데이터로 넘겨줘야 함") - @PatchMapping("/community/posts/{postId}") - public SuccessResponse updatePost(@PathVariable Long postId, @RequestBody PostUpdateRequestDto request) { - Long updatedPostId = editPostUsecase.execute(postId, request); + @PatchMapping("/{postId}") + public SuccessResponse updatePost( + @PathVariable("postId") Long postId, + @RequestBody PostUpdateRequestDto request + ) { + Long userId = userUtils.getCurrentUserId(); + Long updatedPostId = postService.update(request.toCommand(postId, userId)); return SuccessResponse.of(updatedPostId); } @Operation( summary = "게시글 hard delete", description = "게시글을 database로부터 hard delete") - @DeleteMapping("/community/posts/{postId}") - public SuccessResponse deletePost(@PathVariable Long postId) { - deletePostUseCase.execute(postId); + @DeleteMapping("/{postId}") + public SuccessResponse deletePost( + @PathVariable("postId") Long postId + ) { + Long userId = userUtils.getCurrentUserId(); + postService.delete(new DeletePostCommand(postId, userId)); return SuccessResponse.empty(); } - } diff --git a/likelion-client/src/main/java/likelion/univ/post/dto/request/PostCreateRequestDto.java b/likelion-client/src/main/java/likelion/univ/post/dto/request/PostCreateRequestDto.java index 749d488d..9a0c386a 100644 --- a/likelion-client/src/main/java/likelion/univ/post/dto/request/PostCreateRequestDto.java +++ b/likelion-client/src/main/java/likelion/univ/post/dto/request/PostCreateRequestDto.java @@ -1,29 +1,40 @@ package likelion.univ.post.dto.request; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; - import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; +import likelion.univ.domain.post.dto.enums.MainCategory; +import likelion.univ.domain.post.dto.enums.SubCategory; +import likelion.univ.domain.post.dto.request.CreatePostCommand; + +public record PostCreateRequestDto( + @NotBlank + @Schema(description = "제목", example = "LIKELIONUNIV 프로젝트 회고", required = true) + String title, + + @NotBlank + @Schema(description = "내용", example = "프로젝트 재밌었다.", required = true) + String body, + + @Schema(description = "썸네일 이미지", example = "string") + String thumbnail, + + @NotNull + @Schema(description = "메인 카테고리", example = "자유게시판", required = true) + String mainCategory, -@Data -@Builder -@AllArgsConstructor -public class PostCreateRequestDto { - @NotBlank - @Schema(description = "제목", example = "LIKELIONUNIV 프로젝트 회고", required = true) - private String title; - @NotBlank - @Schema(description = "내용", example = "프로젝트 재밌었다.", required = true) - private String body; - @Schema(description = "썸네일 이미지", example = "string") - private String thumbnail; - @NotNull - @Schema(description = "메인 카테고리", example = "자유게시판", required = true) - private String mainCategory; - @NotNull - @Schema(description = "서브 카테고리", example = "정보공유", required = true) - private String subCategory; + @NotNull + @Schema(description = "서브 카테고리", example = "정보공유", required = true) + String subCategory +) { + public CreatePostCommand toCommand(Long userId) { + return CreatePostCommand.builder() + .title(title) + .body(body) + .authorId(userId) + .thumbnail(thumbnail) + .mainCategory(MainCategory.findByTitle(mainCategory)) + .subCategory(SubCategory.findByTitle(subCategory)) + .build(); + } } diff --git a/likelion-client/src/main/java/likelion/univ/post/dto/request/PostDeleteRequestDto.java b/likelion-client/src/main/java/likelion/univ/post/dto/request/PostDeleteRequestDto.java index 8cb95d82..6cfb2075 100644 --- a/likelion-client/src/main/java/likelion/univ/post/dto/request/PostDeleteRequestDto.java +++ b/likelion-client/src/main/java/likelion/univ/post/dto/request/PostDeleteRequestDto.java @@ -1,16 +1,16 @@ package likelion.univ.post.dto.request; import io.swagger.v3.oas.annotations.media.Schema; +import javax.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; -import javax.validation.constraints.NotNull; - @Data @Builder @AllArgsConstructor public class PostDeleteRequestDto { + @NotNull @Schema(description = "지우려는 게시글 id") private Long postId; diff --git a/likelion-client/src/main/java/likelion/univ/post/dto/request/PostUpdateRequestDto.java b/likelion-client/src/main/java/likelion/univ/post/dto/request/PostUpdateRequestDto.java index 496ee915..559bdf62 100644 --- a/likelion-client/src/main/java/likelion/univ/post/dto/request/PostUpdateRequestDto.java +++ b/likelion-client/src/main/java/likelion/univ/post/dto/request/PostUpdateRequestDto.java @@ -1,29 +1,36 @@ package likelion.univ.post.dto.request; import io.swagger.v3.oas.annotations.media.Schema; +import javax.validation.constraints.NotBlank; import likelion.univ.domain.post.dto.request.UpdatePostCommand; -import lombok.AllArgsConstructor; import lombok.Builder; -import lombok.Data; - -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; @Builder public record PostUpdateRequestDto( - @NotBlank - @Schema(description = "게시글 제목 수정", example = "수정된 제목입니다.") - String title, - @NotBlank - @Schema(description = "게시글 내용 수정", example = "수정된 내용입니다.") - String body, - @Schema(description = "게시글 썸네일 수정", example = "수정된 썸네일입니다.") - String thumbnail, - @NotBlank - @Schema(description = "게시글 메인 카테고리 수정", example = "멋대 중앙") - String mainCategory, - @NotBlank - @Schema(description = "게시글 서브 카테고리 수정", example = "정보공유") - String subCategory + @NotBlank + @Schema(description = "게시글 제목 수정", example = "수정된 제목입니다.") + String title, + @NotBlank + @Schema(description = "게시글 내용 수정", example = "수정된 내용입니다.") + String body, + @Schema(description = "게시글 썸네일 수정", example = "수정된 썸네일입니다.") + String thumbnail, + @NotBlank + @Schema(description = "게시글 메인 카테고리 수정", example = "멋대 중앙") + String mainCategory, + @NotBlank + @Schema(description = "게시글 서브 카테고리 수정", example = "정보공유") + String subCategory ) { + public UpdatePostCommand toCommand(Long postId, Long userId) { + return UpdatePostCommand.builder() + .loginUserId(userId) + .postId(postId) + .title(title) + .thumbnail(thumbnail) + .body(body) + .mainCategory(mainCategory) + .subCategory(subCategory) + .build(); + } } diff --git a/likelion-client/src/main/java/likelion/univ/post/dto/response/PostDetailResponseDto.java b/likelion-client/src/main/java/likelion/univ/post/dto/response/PostDetailResponseDto.java index e33a328a..64a72657 100644 --- a/likelion-client/src/main/java/likelion/univ/post/dto/response/PostDetailResponseDto.java +++ b/likelion-client/src/main/java/likelion/univ/post/dto/response/PostDetailResponseDto.java @@ -2,17 +2,11 @@ import com.fasterxml.jackson.annotation.JsonInclude; import io.swagger.v3.oas.annotations.media.Schema; +import java.util.List; import likelion.univ.comment.dto.response.CommentResponseDto; -import likelion.univ.domain.comment.dto.response.ChildCommentData; -import likelion.univ.domain.comment.dto.response.ParentCommentData; -import likelion.univ.domain.post.dto.enums.MainCategory; -import likelion.univ.domain.post.dto.enums.SubCategory; import likelion.univ.domain.post.dto.response.PostDetailData; -import likelion.univ.domain.post.dto.response.PostSimpleData; import likelion.univ.post.entity.PostCountInfo; -import java.util.List; - public record PostDetailResponseDto( @Schema(description = "게시글 pk", example = "1") Long postId, @@ -50,6 +44,7 @@ public record PostDetailResponseDto( @Schema(description = "게시글 작성일자", example = "2023. 6. 15") String createdDate ) { + public PostDetailResponseDto(PostDetailData post, Integer likeCount, Integer commentCount, Long loginUserId) { this( post.postId(), @@ -85,8 +80,9 @@ private static Integer commentCount(List comments) { commentCount += comments.stream().mapToInt(i -> Math.toIntExact(i.childComments().size())).sum(); return commentCount; } + public static PostDetailResponseDto of(PostDetailData post, PostCountInfo postCountInfo, long loginUserId) { - return new PostDetailResponseDto(post, Math.toIntExact(postCountInfo.getLikeCount()), Math.toIntExact(postCountInfo.getCommentCount()), loginUserId); + return new PostDetailResponseDto(post, Math.toIntExact(postCountInfo.getLikeCount()), + Math.toIntExact(postCountInfo.getCommentCount()), loginUserId); } - } diff --git a/likelion-client/src/main/java/likelion/univ/post/dto/response/PostEditResponseDto.java b/likelion-client/src/main/java/likelion/univ/post/dto/response/PostEditResponseDto.java index 112bdd9c..a586d9ab 100644 --- a/likelion-client/src/main/java/likelion/univ/post/dto/response/PostEditResponseDto.java +++ b/likelion-client/src/main/java/likelion/univ/post/dto/response/PostEditResponseDto.java @@ -17,8 +17,16 @@ public record PostEditResponseDto( @Schema(description = "게시글 서브 카테고리", example = "정보공유") String subCategory ) { + public static PostEditResponseDto of(PostEditData postEditData) { - PostEditResponseDto responseDto = new PostEditResponseDto(postEditData.postId(), postEditData.title(), postEditData.body(), postEditData.thumbnail(), postEditData.mainCategory().getTitle(), postEditData.subCategory().getTitle()); + PostEditResponseDto responseDto = new PostEditResponseDto( + postEditData.postId(), + postEditData.title(), + postEditData.body(), + postEditData.thumbnail(), + postEditData.mainCategory().getTitle(), + postEditData.subCategory().getTitle() + ); return responseDto; } } diff --git a/likelion-client/src/main/java/likelion/univ/post/dto/response/PostResponseDto.java b/likelion-client/src/main/java/likelion/univ/post/dto/response/PostResponseDto.java index 8796bc38..765e6178 100644 --- a/likelion-client/src/main/java/likelion/univ/post/dto/response/PostResponseDto.java +++ b/likelion-client/src/main/java/likelion/univ/post/dto/response/PostResponseDto.java @@ -60,5 +60,4 @@ private PostResponseDto(PostSimpleData post, Long likeCount, Long commentCount) public static PostResponseDto of(PostSimpleData post, PostCountInfo postCountInfo) { return new PostResponseDto(post, postCountInfo.getLikeCount(), postCountInfo.getCommentCount()); } - } diff --git a/likelion-client/src/main/java/likelion/univ/post/processor/GetOrCreatePostCountInfoProcessor.java b/likelion-client/src/main/java/likelion/univ/post/processor/GetOrCreatePostCountInfoProcessor.java index 2633fb7c..4586b89f 100644 --- a/likelion-client/src/main/java/likelion/univ/post/processor/GetOrCreatePostCountInfoProcessor.java +++ b/likelion-client/src/main/java/likelion/univ/post/processor/GetOrCreatePostCountInfoProcessor.java @@ -1,30 +1,31 @@ package likelion.univ.post.processor; +import java.util.Optional; import likelion.univ.annotation.Processor; -import likelion.univ.domain.comment.adaptor.CommentAdaptor; -import likelion.univ.domain.like.postlike.adaptor.PostLikeAdaptor; +import likelion.univ.domain.comment.repository.CommentRepository; +import likelion.univ.domain.like.postlike.repository.PostLikeRepository; import likelion.univ.post.dao.PostCountInfoRedisDao; import likelion.univ.post.entity.PostCountInfo; import likelion.univ.post.service.PostCountInfoRedisService; import lombok.RequiredArgsConstructor; -import java.util.Optional; - @Processor @RequiredArgsConstructor public class GetOrCreatePostCountInfoProcessor { private final PostCountInfoRedisDao postCountInfoRedisDao; private final PostCountInfoRedisService postCountInfoRedisService; - private final CommentAdaptor commentAdaptor; - private final PostLikeAdaptor postLikeAdaptor; + private final CommentRepository commentRepository; + private final PostLikeRepository postLikeRepository; - public PostCountInfo execute(Long postId){ + public PostCountInfo execute(Long postId) { Optional postCountInfo = postCountInfoRedisDao.findById(postId); - if(postCountInfo.isEmpty()){ - Long commentCount = commentAdaptor.countByPostIdAndIsDeletedEquals(postId, false); - Long likeCount = postLikeAdaptor.countByPostId(postId); + if (postCountInfo.isEmpty()) { + Long commentCount = commentRepository.countByPostIdAndIsDeletedEquals(postId, false); + Long likeCount = postLikeRepository.countByPostId(postId); return postCountInfoRedisService.save(postId, commentCount, likeCount); - }else return postCountInfo.get(); + } else { + return postCountInfo.get(); + } } } diff --git a/likelion-client/src/main/java/likelion/univ/post/processor/UpdatePostCountInfoProcessor.java b/likelion-client/src/main/java/likelion/univ/post/processor/UpdatePostCountInfoProcessor.java index e0bf3d38..0949c131 100644 --- a/likelion-client/src/main/java/likelion/univ/post/processor/UpdatePostCountInfoProcessor.java +++ b/likelion-client/src/main/java/likelion/univ/post/processor/UpdatePostCountInfoProcessor.java @@ -1,16 +1,13 @@ package likelion.univ.post.processor; import likelion.univ.annotation.Processor; -import likelion.univ.post.dao.PostCountInfoRedisDao; -import likelion.univ.post.entity.PostCountInfo; import likelion.univ.post.service.PostCountInfoRedisService; import lombok.RequiredArgsConstructor; -import java.util.Optional; - @Processor @RequiredArgsConstructor public class UpdatePostCountInfoProcessor { + private final PostCountInfoRedisService postCountInfoRedisService; public void execute(Long postId, Long commentCount, Long likeCount) { diff --git a/likelion-client/src/main/java/likelion/univ/post/service/ClientPostQueryService.java b/likelion-client/src/main/java/likelion/univ/post/service/ClientPostQueryService.java new file mode 100644 index 00000000..0e639b07 --- /dev/null +++ b/likelion-client/src/main/java/likelion/univ/post/service/ClientPostQueryService.java @@ -0,0 +1,115 @@ +package likelion.univ.post.service; + +import static likelion.univ.domain.post.dto.enums.PostOrderCondition.COMMENT_COUNT_ORDER; +import static likelion.univ.domain.post.dto.enums.PostOrderCondition.LIKE_COUNT_ORDER; + +import likelion.univ.common.response.PageResponse; +import likelion.univ.domain.post.dto.enums.MainCategory; +import likelion.univ.domain.post.dto.enums.PostOrderCondition; +import likelion.univ.domain.post.dto.enums.SubCategory; +import likelion.univ.domain.post.dto.request.GetPostDetailCommand; +import likelion.univ.domain.post.dto.request.GetPostsByCategoriesCommand; +import likelion.univ.domain.post.dto.request.GetPostsByCategorySearchCommand; +import likelion.univ.domain.post.dto.request.GetPostsBySearchTitleCommand; +import likelion.univ.domain.post.dto.response.PostDetailData; +import likelion.univ.domain.post.dto.response.PostEditData; +import likelion.univ.domain.post.dto.response.PostSimpleData; +import likelion.univ.domain.post.service.PostService; +import likelion.univ.post.dto.response.PostDetailResponseDto; +import likelion.univ.post.dto.response.PostEditResponseDto; +import likelion.univ.post.dto.response.PostResponseDto; +import likelion.univ.post.processor.GetOrCreatePostCountInfoProcessor; +import likelion.univ.utils.AuthenticatedUserUtils; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@RequiredArgsConstructor +@Transactional(readOnly = true) +@Service +public class ClientPostQueryService { + + private final PostService postService; + private final AuthenticatedUserUtils authenticatedUserUtils; + private final GetOrCreatePostCountInfoProcessor getOrCreatePostCountInfoProcessor; + + public PostDetailResponseDto getDetail(Long postId) { + Long loginUserId = authenticatedUserUtils.getCurrentUserId(); + GetPostDetailCommand serviceRequestDto = new GetPostDetailCommand(postId, loginUserId); + PostDetailData serviceResponseDto = postService.getPostDetail(serviceRequestDto); + return PostDetailResponseDto.of( + serviceResponseDto, + getOrCreatePostCountInfoProcessor.execute(serviceResponseDto.postId()), + loginUserId + ); + } + + public PostEditResponseDto getPostEdit(Long postId) { + PostEditData postEdit = postService.getPostEditById(postId); + return PostEditResponseDto.of(postEdit); + } + + public PageResponse getPostsByCategories( + PostOrderCondition orderCondition, + String mainCategory, + String subCategory, + Pageable pageable + ) { + GetPostsByCategoriesCommand request = new GetPostsByCategoriesCommand( + MainCategory.findByTitle(mainCategory), + SubCategory.findByTitle(subCategory) + ); + if (orderCondition.equals(LIKE_COUNT_ORDER)) { + Page postSimpleDataPage = postService.getByCategoriesOrderByLikeCount( + request, pageable + ); + return PageResponse.of(postSimpleDataPage.map( + p -> PostResponseDto.of(p, getOrCreatePostCountInfoProcessor.execute(p.postId())) + )); + + } else if (orderCondition.equals(COMMENT_COUNT_ORDER)) { + Page postSimpleDataPage = postService.getByCategoriesOrderByCommentCount(request, + pageable); + return PageResponse.of(postSimpleDataPage.map( + p -> PostResponseDto.of(p, getOrCreatePostCountInfoProcessor.execute(p.postId())) + )); + } + Page postSimpleDataPage = postService.getByCategoriesOrderByCreatedData(request, + pageable); + return PageResponse.of(postSimpleDataPage.map( + p -> PostResponseDto.of(p, getOrCreatePostCountInfoProcessor.execute(p.postId())) + )); + } + + public PageResponse getPostBySearchTitle( + PostOrderCondition orderCondition, + String searchTitle, + String mainCategory, + String subCategory, + Pageable pageable + ) { + if (!mainCategory.equals("전체 게시판")) { + var request = new GetPostsByCategorySearchCommand( + orderCondition, + searchTitle, + mainCategory, + subCategory + ); + var result = postService.getByCategoriesAndSearchTitle(request, pageable); + return PageResponse.of(result.map(p -> + PostResponseDto.of( + p, + getOrCreatePostCountInfoProcessor.execute(p.postId()) + ))); + } + var request = new GetPostsBySearchTitleCommand(orderCondition, searchTitle); + var result = postService.getBySearchTitle(request, pageable); + return PageResponse.of(result.map(p -> + PostResponseDto.of( + p, + getOrCreatePostCountInfoProcessor.execute(p.postId()) + ))); + } +} diff --git a/likelion-client/src/main/java/likelion/univ/post/service/ClientPostService.java b/likelion-client/src/main/java/likelion/univ/post/service/ClientPostService.java new file mode 100644 index 00000000..f3ddff80 --- /dev/null +++ b/likelion-client/src/main/java/likelion/univ/post/service/ClientPostService.java @@ -0,0 +1,29 @@ +package likelion.univ.post.service; + +import likelion.univ.domain.post.dto.request.CreatePostCommand; +import likelion.univ.domain.post.dto.request.DeletePostCommand; +import likelion.univ.domain.post.dto.request.UpdatePostCommand; +import likelion.univ.domain.post.service.PostService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@RequiredArgsConstructor +@Transactional +@Service +public class ClientPostService { + + private final PostService postService; + + public Long create(CreatePostCommand command) { + return postService.createPost(command); + } + + public Long update(UpdatePostCommand command) { + return postService.editPost(command); + } + + public void delete(DeletePostCommand command) { + postService.deletePost(command); + } +} diff --git a/likelion-client/src/main/java/likelion/univ/post/usecase/CreatePostUseCase.java b/likelion-client/src/main/java/likelion/univ/post/usecase/CreatePostUseCase.java deleted file mode 100644 index 30ebe841..00000000 --- a/likelion-client/src/main/java/likelion/univ/post/usecase/CreatePostUseCase.java +++ /dev/null @@ -1,34 +0,0 @@ -package likelion.univ.post.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.domain.post.dto.enums.MainCategory; -import likelion.univ.domain.post.dto.enums.SubCategory; -import likelion.univ.domain.post.dto.request.CreatePostCommand; -import likelion.univ.domain.post.exception.NoSuchCategoryException; -import likelion.univ.domain.post.service.PostDomainService; -import likelion.univ.post.dto.request.PostCreateRequestDto; -import likelion.univ.utils.AuthenticatedUserUtils; -import lombok.RequiredArgsConstructor; - -@UseCase -@RequiredArgsConstructor -public class CreatePostUseCase { - private final PostDomainService postDomainService; - private final AuthenticatedUserUtils userUtils; - public Long execute(PostCreateRequestDto request) { - return postDomainService.createPost(serviceDtoBy(request)); - } - - CreatePostCommand serviceDtoBy(PostCreateRequestDto request) { - String mainCategory = request.getMainCategory(); - String subCategory = request.getSubCategory(); - return CreatePostCommand.builder() - .title(request.getTitle()) - .body(request.getBody()) - .authorId(userUtils.getCurrentUserId()) - .thumbnail(request.getThumbnail()) - .mainCategory(MainCategory.findByTitle(mainCategory)) - .subCategory(SubCategory.findByTitle(subCategory)) - .build(); - } -} diff --git a/likelion-client/src/main/java/likelion/univ/post/usecase/DeletePostUseCase.java b/likelion-client/src/main/java/likelion/univ/post/usecase/DeletePostUseCase.java deleted file mode 100644 index 0140ee0d..00000000 --- a/likelion-client/src/main/java/likelion/univ/post/usecase/DeletePostUseCase.java +++ /dev/null @@ -1,25 +0,0 @@ -package likelion.univ.post.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.domain.post.dto.request.DeletePostCommand; -import likelion.univ.domain.post.service.PostDomainService; -import likelion.univ.utils.AuthenticatedUserUtils; -import lombok.RequiredArgsConstructor; - -@UseCase -@RequiredArgsConstructor -public class DeletePostUseCase { - private final PostDomainService postDomainService; - private final AuthenticatedUserUtils userUtils; - - public void execute(Long postId) { - postDomainService.deletePost(serviceDtoBy(postId)); - } - - private DeletePostCommand serviceDtoBy(Long postId) { - return DeletePostCommand.builder() - .postId(postId) - .loginUserId(userUtils.getCurrentUserId()) - .build(); - } -} diff --git a/likelion-client/src/main/java/likelion/univ/post/usecase/EditPostUseCase.java b/likelion-client/src/main/java/likelion/univ/post/usecase/EditPostUseCase.java deleted file mode 100644 index df1574c4..00000000 --- a/likelion-client/src/main/java/likelion/univ/post/usecase/EditPostUseCase.java +++ /dev/null @@ -1,32 +0,0 @@ -package likelion.univ.post.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.domain.post.dto.request.UpdatePostCommand; -import likelion.univ.domain.post.service.PostDomainService; -import likelion.univ.post.dto.request.PostUpdateRequestDto; -import likelion.univ.utils.AuthenticatedUserUtils; -import lombok.RequiredArgsConstructor; - - -@UseCase -@RequiredArgsConstructor -public class EditPostUseCase { - private final PostDomainService postDomainService; - private final AuthenticatedUserUtils userUtils; - - public Long execute(Long postId, PostUpdateRequestDto request) { - return postDomainService.editPost(buildDTO(postId, request)); - } - - private UpdatePostCommand buildDTO(Long postId, PostUpdateRequestDto request) { - return UpdatePostCommand.builder() - .loginUserId(userUtils.getCurrentUserId()) - .postId(postId) - .title(request.title()) - .thumbnail(request.thumbnail()) - .body(request.body()) - .mainCategory(request.mainCategory()) - .subCategory(request.subCategory()) - .build(); - } -} diff --git a/likelion-client/src/main/java/likelion/univ/post/usecase/GetPostDetailUseCase.java b/likelion-client/src/main/java/likelion/univ/post/usecase/GetPostDetailUseCase.java deleted file mode 100644 index 542eb4d4..00000000 --- a/likelion-client/src/main/java/likelion/univ/post/usecase/GetPostDetailUseCase.java +++ /dev/null @@ -1,28 +0,0 @@ -package likelion.univ.post.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.domain.post.dto.request.GetPostDetailCommand; -import likelion.univ.domain.post.dto.response.PostDetailData; -import likelion.univ.domain.post.service.PostDomainService; -import likelion.univ.post.dto.response.PostDetailResponseDto; -import likelion.univ.post.processor.GetOrCreatePostCountInfoProcessor; -import likelion.univ.utils.AuthenticatedUserUtils; -import lombok.RequiredArgsConstructor; - -@UseCase -@RequiredArgsConstructor -public class GetPostDetailUseCase { - private final PostDomainService postDomainService; - private final AuthenticatedUserUtils authenticatedUserUtils; - private final GetOrCreatePostCountInfoProcessor getOrCreatePostCountInfoProcessor; - - - public PostDetailResponseDto execute(Long postId) { - Long loginUserId = authenticatedUserUtils.getCurrentUserId(); - GetPostDetailCommand serviceRequestDto = new GetPostDetailCommand(postId, loginUserId); - - PostDetailData serviceResponseDto = postDomainService.getPostDetail(serviceRequestDto); - PostDetailResponseDto response = PostDetailResponseDto.of(serviceResponseDto, getOrCreatePostCountInfoProcessor.execute(serviceResponseDto.postId()), loginUserId); - return response; - } -} diff --git a/likelion-client/src/main/java/likelion/univ/post/usecase/GetPostEditUseCase.java b/likelion-client/src/main/java/likelion/univ/post/usecase/GetPostEditUseCase.java deleted file mode 100644 index d05473ac..00000000 --- a/likelion-client/src/main/java/likelion/univ/post/usecase/GetPostEditUseCase.java +++ /dev/null @@ -1,19 +0,0 @@ -package likelion.univ.post.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.domain.post.dto.response.PostEditData; -import likelion.univ.domain.post.service.PostDomainService; -import likelion.univ.post.dto.response.PostEditResponseDto; -import lombok.RequiredArgsConstructor; - -@UseCase -@RequiredArgsConstructor -public class GetPostEditUseCase { - private final PostDomainService postDomainService; - - public PostEditResponseDto execute(Long postId) { - PostEditData postEdit = postDomainService.getPostEditById(postId); - PostEditResponseDto response = PostEditResponseDto.of(postEdit); - return response; - } -} diff --git a/likelion-client/src/main/java/likelion/univ/post/usecase/GetPostsByCategoriesUseCase.java b/likelion-client/src/main/java/likelion/univ/post/usecase/GetPostsByCategoriesUseCase.java deleted file mode 100644 index cd93e455..00000000 --- a/likelion-client/src/main/java/likelion/univ/post/usecase/GetPostsByCategoriesUseCase.java +++ /dev/null @@ -1,41 +0,0 @@ -package likelion.univ.post.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.common.response.PageResponse; -import likelion.univ.domain.post.dto.enums.PostOrderCondition; -import likelion.univ.domain.post.dto.request.GetPostsByCategoriesCommand; -import likelion.univ.domain.post.dto.response.PostSimpleData; -import likelion.univ.domain.post.dto.enums.MainCategory; -import likelion.univ.domain.post.dto.enums.SubCategory; -import likelion.univ.domain.post.service.PostDomainService; -import likelion.univ.post.dto.response.PostResponseDto; -import likelion.univ.post.processor.GetOrCreatePostCountInfoProcessor; -import likelion.univ.user.dto.response.UserPagePostsDto; -import lombok.RequiredArgsConstructor; -import org.jetbrains.annotations.NotNull; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; -import org.springframework.data.domain.Pageable; - -import java.util.List; - -@UseCase -@RequiredArgsConstructor -public class GetPostsByCategoriesUseCase { - private final PostDomainService postDomainService; - private final GetOrCreatePostCountInfoProcessor getOrCreatePostCountInfoProcessor; - - public PageResponse execute(PostOrderCondition orderCondition, String mainCategory, String subCategory, Pageable pageable) { - GetPostsByCategoriesCommand request = new GetPostsByCategoriesCommand(MainCategory.findByTitle(mainCategory), SubCategory.findByTitle(subCategory)); - if (orderCondition.equals(PostOrderCondition.LIKE_COUNT_ORDER)) { - Page postSimpleDataPage = postDomainService.getByCategoriesOrderByLikeCount(request, pageable); - return PageResponse.of(postSimpleDataPage.map(p-> PostResponseDto.of(p, getOrCreatePostCountInfoProcessor.execute(p.postId())))); - - } else if (orderCondition.equals(PostOrderCondition.COMMENT_COUNT_ORDER)) { - Page postSimpleDataPage = postDomainService.getByCategoriesOrderByCommentCount(request, pageable); - return PageResponse.of(postSimpleDataPage.map(p-> PostResponseDto.of(p, getOrCreatePostCountInfoProcessor.execute(p.postId())))); - } - Page postSimpleDataPage = postDomainService.getByCategoriesOrderByCreatedData(request, pageable); - return PageResponse.of(postSimpleDataPage.map(p-> PostResponseDto.of(p, getOrCreatePostCountInfoProcessor.execute(p.postId())))); - } -} diff --git a/likelion-client/src/main/java/likelion/univ/post/usecase/GetPostsBySearchTitleUseCase.java b/likelion-client/src/main/java/likelion/univ/post/usecase/GetPostsBySearchTitleUseCase.java deleted file mode 100644 index 4984db69..00000000 --- a/likelion-client/src/main/java/likelion/univ/post/usecase/GetPostsBySearchTitleUseCase.java +++ /dev/null @@ -1,47 +0,0 @@ -package likelion.univ.post.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.common.response.PageResponse; -import likelion.univ.domain.post.dto.enums.PostOrderCondition; -import likelion.univ.domain.post.dto.request.GetPostsBySearchTitleCommand; -import likelion.univ.domain.post.dto.request.GetPostsByCategorySearchCommand; -import likelion.univ.domain.post.dto.response.PostSimpleData; -import likelion.univ.domain.post.service.PostDomainService; -import likelion.univ.post.dto.response.PostResponseDto; -import likelion.univ.post.processor.GetOrCreatePostCountInfoProcessor; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; - -@UseCase -@RequiredArgsConstructor -public class GetPostsBySearchTitleUseCase { - private final PostDomainService postDomainService; - private final GetOrCreatePostCountInfoProcessor getOrCreatePostCountInfoProcessor; - - public PageResponse execute(PostOrderCondition orderCondition, String searchTitle, String mainCategory, String subCategory, Pageable pageable) { - if (isSearchWithCategories(mainCategory)) { - Page postSimpleDataPage = getByCategoriesAndSearchTitle(orderCondition, searchTitle, mainCategory, subCategory, pageable); - return PageResponse.of(postSimpleDataPage.map(p -> PostResponseDto.of(p, getOrCreatePostCountInfoProcessor.execute(p.postId())))); - } - Page postSimpleDataPage = getBySearchTitle(orderCondition, searchTitle, pageable); - return PageResponse.of(postSimpleDataPage.map(p -> PostResponseDto.of(p, getOrCreatePostCountInfoProcessor.execute(p.postId())))); - } - - /* ----- 내부메서드 ----- */ - private static boolean isSearchWithCategories(String mainCategory) { - return !mainCategory.equals("전체 게시판"); - } - - private Page getByCategoriesAndSearchTitle(PostOrderCondition orderCondition, String searchTitle, String mainCategory, String subCategory, Pageable pageable) { - GetPostsByCategorySearchCommand request = new GetPostsByCategorySearchCommand(orderCondition, searchTitle, mainCategory, subCategory); - Page postSimpleDataPage = postDomainService.getByCategoriesAndSearchTitle(request, pageable); - return postSimpleDataPage; - } - - private Page getBySearchTitle(PostOrderCondition orderCondition, String searchTitle, Pageable pageable) { - GetPostsBySearchTitleCommand request = new GetPostsBySearchTitleCommand(orderCondition, searchTitle); - Page postSimpleDataPage = postDomainService.getBySearchTitle(request, pageable); - return postSimpleDataPage; - } -} diff --git a/likelion-client/src/main/java/likelion/univ/project/controller/ProjectController.java b/likelion-client/src/main/java/likelion/univ/project/controller/ProjectController.java index f7fb59c4..73753bab 100644 --- a/likelion-client/src/main/java/likelion/univ/project/controller/ProjectController.java +++ b/likelion-client/src/main/java/likelion/univ/project/controller/ProjectController.java @@ -2,86 +2,99 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import javax.validation.Valid; import likelion.univ.common.response.PageResponse; import likelion.univ.project.dto.request.ProjectRequestDto; import likelion.univ.project.dto.response.ProjectIdResponseDto; import likelion.univ.project.dto.response.ProjectListResponseDto; import likelion.univ.project.dto.response.ProjectResponseDto; -import likelion.univ.project.usecase.*; +import likelion.univ.project.service.ClientProjectQueryService; +import likelion.univ.project.service.ClientProjectService; import likelion.univ.response.SuccessResponse; +import likelion.univ.utils.AuthenticatedUserUtils; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springdoc.api.annotations.ParameterObject; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.web.PageableDefault; -import org.springframework.web.bind.annotation.*; - -import javax.validation.Valid; -import java.util.Objects; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +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; @Slf4j @RestController @RequiredArgsConstructor -@RequestMapping(value = "/v1/project") +@RequestMapping("/v1/projects") @Tag(name = "Project", description = "프로젝트 API") public class ProjectController { - private final GetProjectUsecase getProjectUsecase; - private final GetAllPorjectUsecase getAllPorjectUsecase; - private final CreateProjectUsecase createProjectUsecase; - private final UpdateProjectUsecase updateProjectUsecase; - private final DeleteProjectUsecase deleteProjectUsecase; - private final GetProjectByUsecase getProjectByUsecase; + private final AuthenticatedUserUtils userUtils; + private final ClientProjectService projectService; + private final ClientProjectQueryService projectQueryService; - //-----------프로젝트 한 개 조회 --------// - @GetMapping("/{projectId}") @Operation(summary = "프로젝트 조회", description = "프로젝트 id로 프로젝트를 조회했습니다.") - public SuccessResponse getProject(@PathVariable("projectId") Long projectId) { - ProjectResponseDto projectResponseDto = getProjectUsecase.execute(projectId); + @GetMapping("/{projectId}") + public SuccessResponse getProject( + @PathVariable("projectId") Long projectId + ) { + ProjectResponseDto projectResponseDto = projectQueryService.getProject(projectId); return SuccessResponse.of(projectResponseDto); } - //-----------프로젝트 목록 --------// - @GetMapping("/") @Operation(summary = "프로젝트 목록", description = "프로젝트 목록을 출력했습니다.") + @GetMapping public SuccessResponse> getAllProject( - @ParameterObject @PageableDefault(size=12, sort="createdDate", direction = Sort.Direction.DESC) Pageable pageable) { - PageResponse projectList = getAllPorjectUsecase.execute(pageable); + @ParameterObject + @PageableDefault(size = 12, sort = "createdDate", direction = Sort.Direction.DESC) + Pageable pageable + ) { + PageResponse projectList = projectQueryService.getAllProject(pageable); return SuccessResponse.of(projectList); } - //-------- 기수별 프로젝트 -----// - @GetMapping("/ordinal/{ordinal}") @Operation(summary = "기수별 프로젝트", description = "선택한 기수에 따라 프로젝트 목록을 출력했습니다. 최근 5개의 기수보다 이전의 기수는 한번에 보여집니다.") + @GetMapping("/ordinal/{ordinal}") public SuccessResponse> getProjectByOrdinal( - @ParameterObject @PageableDefault(size=12, sort="createdDate", direction = Sort.Direction.DESC) Pageable pageable, - @PathVariable Long ordinal) { - PageResponse projectList = getProjectByUsecase.execute(ordinal,pageable); + @ParameterObject + @PageableDefault(size = 12, sort = "createdDate", direction = Sort.Direction.DESC) Pageable pageable, + @PathVariable("ordinal") Long ordinal + ) { + PageResponse projectList = projectQueryService.getProjectBy(ordinal, pageable); return SuccessResponse.of(projectList); } - //--------- 프로젝트 등록 ------------// - @PostMapping("/") @Operation(summary = "프로젝트 등록", description = "새로운 프로젝트를 등록했습니다.") - public SuccessResponse createProject(@Valid @RequestBody ProjectRequestDto projectRequestDto){ - ProjectIdResponseDto projectIdResponseDto = createProjectUsecase.execute(projectRequestDto); - return SuccessResponse.of(projectIdResponseDto); + @PostMapping + public SuccessResponse createProject( + @Valid @RequestBody ProjectRequestDto projectRequestDto + ) { + Long userId = userUtils.getCurrentUserId(); + Long projectId = projectService.create(userId, projectRequestDto); + return SuccessResponse.of(ProjectIdResponseDto.of(projectId)); } - //-----------프로젝트 수정 --------// - @PatchMapping("/{projectId}") @Operation(summary = "프로젝트 수정", description = "프로젝트의 내용을 수정하였습니다.") - public SuccessResponse updateProject(@PathVariable("projectId") Long projectId, @Valid @RequestBody ProjectRequestDto projectRequestDto) { - ProjectIdResponseDto projectIdResponseDto = updateProjectUsecase.execute(projectId, projectRequestDto); - return SuccessResponse.of(projectIdResponseDto); + @PatchMapping("/{projectId}") + public SuccessResponse updateProject( + @PathVariable("projectId") Long projectId, + @Valid @RequestBody ProjectRequestDto projectRequestDto + ) { + projectService.update(projectId, projectRequestDto); + return SuccessResponse.of(ProjectIdResponseDto.of(projectId)); } - //-----------프로젝트 삭제 --------// - @DeleteMapping("/{projectId}") @Operation(summary = "프로젝트 삭제", description = "프로젝트를 삭제했습니다.") - public SuccessResponse deleteProject(@PathVariable("projectId") Long projectId) { - deleteProjectUsecase.execute(projectId); + @DeleteMapping("/{projectId}") + public SuccessResponse deleteProject( + @PathVariable("projectId") Long projectId + ) { + projectService.delete(projectId); return SuccessResponse.empty(); } } diff --git a/likelion-client/src/main/java/likelion/univ/project/dto/request/ProjectMemberRequestDto.java b/likelion-client/src/main/java/likelion/univ/project/dto/request/ProjectMemberRequestDto.java index 76c046bf..622b6d07 100644 --- a/likelion-client/src/main/java/likelion/univ/project/dto/request/ProjectMemberRequestDto.java +++ b/likelion-client/src/main/java/likelion/univ/project/dto/request/ProjectMemberRequestDto.java @@ -7,6 +7,7 @@ @Getter @NoArgsConstructor public class ProjectMemberRequestDto { + private Long userId; private Part part; } diff --git a/likelion-client/src/main/java/likelion/univ/project/dto/request/ProjectRequestDto.java b/likelion-client/src/main/java/likelion/univ/project/dto/request/ProjectRequestDto.java index 8d0d074a..83a71aca 100644 --- a/likelion-client/src/main/java/likelion/univ/project/dto/request/ProjectRequestDto.java +++ b/likelion-client/src/main/java/likelion/univ/project/dto/request/ProjectRequestDto.java @@ -1,6 +1,10 @@ package likelion.univ.project.dto.request; import io.swagger.v3.oas.annotations.media.Schema; +import java.time.LocalDate; +import java.util.List; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; import likelion.univ.domain.project.entity.Project; import likelion.univ.domain.project.entity.enums.Output; import lombok.AllArgsConstructor; @@ -8,11 +12,6 @@ import lombok.Getter; import lombok.NoArgsConstructor; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; -import java.time.LocalDate; -import java.util.List; - /** * thumnail 제외 */ @@ -27,7 +26,6 @@ public class ProjectRequestDto { @Schema(example = "해커톤") private String activity; - @Schema(example = "WEB") private Output outPut; @@ -46,7 +44,6 @@ public class ProjectRequestDto { @Schema(example = "2023-10-10") private LocalDate startDate; - @NotNull @Schema(example = "2023-11-14") private LocalDate endDate; @@ -67,12 +64,12 @@ public class ProjectRequestDto { private List imageUrl; @Schema(example = "[{" + - " \"userId\" : \"3\"," + - " \"part\" : \"BACKEND\"" + - "},{" + - " \"userId\" : \"2\"," + - " \"part\" : \"FRONTEND\"" + - "}]") + " \"userId\" : \"3\"," + + " \"part\" : \"BACKEND\"" + + "},{" + + " \"userId\" : \"2\"," + + " \"part\" : \"FRONTEND\"" + + "}]") private List projectMembers; public Project toEntity() { @@ -88,5 +85,4 @@ public Project toEntity() { .productionUrl(productionUrl) .build(); } - } diff --git a/likelion-client/src/main/java/likelion/univ/project/dto/response/ProjectListResponseDto.java b/likelion-client/src/main/java/likelion/univ/project/dto/response/ProjectListResponseDto.java index ead70ba0..3e4a96c6 100644 --- a/likelion-client/src/main/java/likelion/univ/project/dto/response/ProjectListResponseDto.java +++ b/likelion-client/src/main/java/likelion/univ/project/dto/response/ProjectListResponseDto.java @@ -8,6 +8,7 @@ @Getter @Builder public class ProjectListResponseDto { + private Long id; private String activity; private Output outPut; diff --git a/likelion-client/src/main/java/likelion/univ/project/dto/response/ProjectMemberResponseDto.java b/likelion-client/src/main/java/likelion/univ/project/dto/response/ProjectMemberResponseDto.java index d804ddfa..ea0a17de 100644 --- a/likelion-client/src/main/java/likelion/univ/project/dto/response/ProjectMemberResponseDto.java +++ b/likelion-client/src/main/java/likelion/univ/project/dto/response/ProjectMemberResponseDto.java @@ -20,6 +20,7 @@ public static ProjectMemberResponseDto of(Long userId, String name, Part part) { .part(part) .build(); } + public static ProjectMemberResponseDto of(ProjectMember projectMember) { return ProjectMemberResponseDto.builder() .userId(projectMember.getUser().getId()) diff --git a/likelion-client/src/main/java/likelion/univ/project/dto/response/ProjectResponseDto.java b/likelion-client/src/main/java/likelion/univ/project/dto/response/ProjectResponseDto.java index 04ecabfe..e48c76bb 100644 --- a/likelion-client/src/main/java/likelion/univ/project/dto/response/ProjectResponseDto.java +++ b/likelion-client/src/main/java/likelion/univ/project/dto/response/ProjectResponseDto.java @@ -1,17 +1,15 @@ package likelion.univ.project.dto.response; -import likelion.univ.domain.project.entity.ProjectImage; +import java.time.LocalDate; +import java.util.List; +import java.util.stream.Collectors; import likelion.univ.domain.project.entity.Project; +import likelion.univ.domain.project.entity.ProjectImage; import likelion.univ.domain.project.entity.Tech; import likelion.univ.domain.project.entity.enums.Output; -import likelion.univ.domain.user.entity.User; import lombok.Builder; import lombok.Data; -import java.time.LocalDate; -import java.util.List; -import java.util.stream.Collectors; - @Data @Builder public class ProjectResponseDto { @@ -31,7 +29,9 @@ public class ProjectResponseDto { private List imageUrl; private List members; - public static ProjectResponseDto of(Project project, String univ, List projectTeches, List projectImages, List projectMembers) { + public static ProjectResponseDto of(Project project, String univ, List projectTeches, + List projectImages, + List projectMembers) { return ProjectResponseDto.builder() .id(project.getId()) .activity(project.getActivity()) diff --git a/likelion-client/src/main/java/likelion/univ/project/service/ClientProjectQueryService.java b/likelion-client/src/main/java/likelion/univ/project/service/ClientProjectQueryService.java new file mode 100644 index 00000000..0d7e1859 --- /dev/null +++ b/likelion-client/src/main/java/likelion/univ/project/service/ClientProjectQueryService.java @@ -0,0 +1,82 @@ +package likelion.univ.project.service; + +import java.util.List; +import likelion.univ.common.response.PageResponse; +import likelion.univ.domain.project.entity.Project; +import likelion.univ.domain.project.entity.ProjectImage; +import likelion.univ.domain.project.entity.ProjectTech; +import likelion.univ.domain.project.entity.Tech; +import likelion.univ.domain.project.repository.ProjectImageRepository; +import likelion.univ.domain.project.repository.ProjectMemberRepository; +import likelion.univ.domain.project.repository.ProjectRepository; +import likelion.univ.domain.project.repository.ProjectTechRepository; +import likelion.univ.domain.project.repository.TechRepository; +import likelion.univ.domain.university.repository.UniversityRepository; +import likelion.univ.project.dto.response.ProjectListResponseDto; +import likelion.univ.project.dto.response.ProjectMemberResponseDto; +import likelion.univ.project.dto.response.ProjectResponseDto; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@RequiredArgsConstructor +@Transactional(readOnly = true) +@Service +public class ClientProjectQueryService { + + private final ProjectRepository projectRepository; + private final ProjectImageRepository projectImageRepository; + private final UniversityRepository universityRepository; + private final ProjectMemberRepository projectMemberRepository; + private final ProjectTechRepository projectTechRepository; + private final TechRepository techRepository; + + public PageResponse getAllProject(Pageable pageable) { + Page projects = projectRepository.findAll(pageable); + return PageResponse.of(projects.map(project -> ProjectListResponseDto.of( + project, + project.getUniv() == null ? null : project.getUniv().getName(), + projectImageRepository.findByProject(project).isEmpty() + ? null + : projectImageRepository.findByProject(project).get(0).getImageUrl())) + ); + } + + public PageResponse getProjectBy(Long ordinal, Pageable pageable) { + long recentOrdinal = projectRepository.findLatestOrdinal(); + if (ordinal > recentOrdinal - 5) { + return getProjectResponseDtos(projectRepository.findByOrdinal(ordinal, pageable)); + } + return getProjectResponseDtos(projectRepository.findArchiveProject(recentOrdinal - 5, pageable)); + } + + public PageResponse getProjectResponseDtos(Page projects) { + return PageResponse.of(projects.map(project -> ProjectListResponseDto.of( + project, + project.getUniv() == null ? null : project.getUniv().getName(), + projectImageRepository.findByProject(project).isEmpty() + ? null + : projectImageRepository.findByProject(project).get(0).getImageUrl())) + ); + } + + public ProjectResponseDto getProject(Long id) { + Project project = projectRepository.getById(id); + String univ = null; + if (project.getUniv() != null) { + univ = universityRepository.getById(project.getUniv().getId()).getName(); + } + List projectTeaches = projectTechRepository.findByProject(project).stream() + .map(ProjectTech::getTech) + .map(tech -> techRepository.getById(tech.getId())) + .toList(); + List projectImages = projectImageRepository.findByProject(project); + List projectMembers = projectMemberRepository.findByProject(project) + .stream() + .map(ProjectMemberResponseDto::of) + .toList(); + return ProjectResponseDto.of(project, univ, projectTeaches, projectImages, projectMembers); + } +} diff --git a/likelion-client/src/main/java/likelion/univ/project/service/ClientProjectService.java b/likelion-client/src/main/java/likelion/univ/project/service/ClientProjectService.java new file mode 100644 index 00000000..f09470d5 --- /dev/null +++ b/likelion-client/src/main/java/likelion/univ/project/service/ClientProjectService.java @@ -0,0 +1,119 @@ +package likelion.univ.project.service; + +import java.util.List; +import java.util.stream.Collectors; +import likelion.univ.domain.project.entity.Project; +import likelion.univ.domain.project.entity.ProjectImage; +import likelion.univ.domain.project.entity.ProjectMember; +import likelion.univ.domain.project.repository.ProjectMemberRepository; +import likelion.univ.domain.project.repository.ProjectRepository; +import likelion.univ.domain.project.service.ProjectImageService; +import likelion.univ.domain.project.service.ProjectMemberService; +import likelion.univ.domain.project.service.ProjectService; +import likelion.univ.domain.project.service.ProjectTechService; +import likelion.univ.domain.university.repository.UniversityRepository; +import likelion.univ.domain.user.entity.User; +import likelion.univ.domain.user.repository.UserRepository; +import likelion.univ.project.dto.request.ProjectMemberRequestDto; +import likelion.univ.project.dto.request.ProjectRequestDto; +import likelion.univ.utils.AuthenticatedUserUtils; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@RequiredArgsConstructor +@Transactional +@Service +public class ClientProjectService { + + private final AuthenticatedUserUtils authenticatedUserUtils; + private final ProjectService projectService; + private final ProjectTechService projectTechService; + private final ProjectImageService projectImageService; + private final UserRepository userRepository; + private final ProjectMemberRepository projectMemberRepository; + private final UniversityRepository universityRepository; + private final ProjectMemberService projectMemberService; + private final ProjectRepository projectRepository; + + public Long create(Long userId, ProjectRequestDto projectRequestDto) { + User user = userRepository.getById(userId); + Project request = projectRequestDto.toEntity(); + request.updateAuthor(user); + if (!projectRequestDto.getUniv().isEmpty()) { + request.updateUniv(universityRepository.getByName(projectRequestDto.getUniv())); + } + Project project = projectService.createProject(request); + List techNames = projectRequestDto.getProjectTeches(); + projectTechService.addProjectTech(project, techNames.stream().map(tech -> tech.toUpperCase()).toList()); + projectImageService.addImage( + projectRequestDto.getImageUrl().stream() + .map(imageUrl -> new ProjectImage(project, imageUrl)) + .toList() + ); + List projectMembersRequest = projectRequestDto.getProjectMembers(); + List ids = projectMembersRequest.stream() + .map(ProjectMemberRequestDto::getUserId) + .toList(); + List requestUsers = userRepository.findAllByIdsExactly(ids); + List projectMembers = projectMembersRequest.stream() + .map(pm -> matchProjectMembers(pm, project, requestUsers)) + .toList(); + projectMemberRepository.saveAll(projectMembers); + return project.getId(); + } + + public void update(Long projectId, ProjectRequestDto projectRequestDto) { + Project project = projectRepository.getById(projectId); + authenticatedUserUtils.checkIdentification(project.getAuthor().getId()); + List techNames = projectRequestDto.getProjectTeches(); + List projectImage = projectRequestDto.getImageUrl().stream() + .map(imageUrl -> new ProjectImage(project, imageUrl)) + .collect(Collectors.toList()); + Project editProject = projectRequestDto.toEntity(); + if (!projectRequestDto.getUniv().isEmpty()) { + editProject.updateUniv(universityRepository.getByName(projectRequestDto.getUniv())); + } else { + editProject.updateUniv(null); + } + List projectMembersRequest = projectRequestDto.getProjectMembers(); + List ids = projectMembersRequest.stream() + .map(ProjectMemberRequestDto::getUserId) + .toList(); + List requestUsers = userRepository.findAllByIdsExactly(ids); + List projectMembers = projectMembersRequest.stream() + .map(p -> matchProjectMembers(p, project, requestUsers)) + .toList(); + projectService.updateProject(projectId, editProject); + projectTechService.updateProjectTech(project, techNames); + projectImageService.updateImage(project, projectImage); + projectMemberService.updateProjectMember(project, projectMembers); + } + + // projectMemberRequestDto의 userId와 일치하는 user를 유저리스트에서 찾아서 ProjectMember로 변환합니다. + private ProjectMember matchProjectMembers( + ProjectMemberRequestDto projectMemberRequestDto, + Project project, + List users + ) { + return users.stream() + .distinct() + .filter(user -> user.getId().equals(projectMemberRequestDto.getUserId())) + .map(user -> ProjectMember.builder() + .project(project) + .user(user) + .part(projectMemberRequestDto.getPart()) + .build()) + .findFirst() + .orElseThrow(); + } + + public void delete(Long projectId) { + Project project = projectRepository.getById(projectId); + authenticatedUserUtils.checkIdentification(project.getAuthor().getId()); + projectTechService.deleteProjectTech(projectId); + projectImageService.deleteImage(projectId); + projectMemberService.deleteProjectMember(projectId); + projectService.deleteProject(projectId); + } +} diff --git a/likelion-client/src/main/java/likelion/univ/project/usecase/CreateProjectUsecase.java b/likelion-client/src/main/java/likelion/univ/project/usecase/CreateProjectUsecase.java deleted file mode 100644 index ef54e482..00000000 --- a/likelion-client/src/main/java/likelion/univ/project/usecase/CreateProjectUsecase.java +++ /dev/null @@ -1,89 +0,0 @@ -package likelion.univ.project.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.domain.project.adapter.ProjectAdaptor; -import likelion.univ.domain.project.adapter.ProjectMemberAdaptor; -import likelion.univ.domain.project.entity.ProjectImage; -import likelion.univ.domain.project.entity.Project; -import likelion.univ.domain.project.entity.ProjectMember; -import likelion.univ.domain.project.service.ProjectImageService; -import likelion.univ.domain.project.service.ProjectMemberService; -import likelion.univ.domain.project.service.ProjectService; -import likelion.univ.domain.project.service.ProjectTechService; -import likelion.univ.domain.university.adaptor.UniversityAdaptor; -import likelion.univ.domain.user.adaptor.UserAdaptor; -import likelion.univ.domain.user.entity.Part; -import likelion.univ.domain.user.entity.User; -import likelion.univ.project.dto.request.ProjectMemberRequestDto; -import likelion.univ.project.dto.request.ProjectRequestDto; -import likelion.univ.project.dto.response.ProjectIdResponseDto; -import likelion.univ.utils.AuthenticatedUserUtils; -import lombok.RequiredArgsConstructor; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; -import java.util.stream.Collectors; - -@UseCase -@RequiredArgsConstructor -public class CreateProjectUsecase { - - private final AuthenticatedUserUtils authenticatedUserUtils; - private final ProjectService projectService; - private final ProjectTechService projectTechService; - private final ProjectImageService projectImageService; - private final ProjectMemberService projectMemberService; - private final UserAdaptor userAdaptor; - private final ProjectMemberAdaptor projectMemberAdaptor; - private final ProjectAdaptor projectAdaptor; - private final UniversityAdaptor universityAdaptor; - - @Transactional - public ProjectIdResponseDto execute(ProjectRequestDto projectRequestDto) { - - User user = authenticatedUserUtils.getCurrentUser(); -// if(user.getAuthInfo().getRole() != Role.UNIVERSITY_ADMIN) { -// throw new NotAdminForbiddenException(); -// } - - Project request = projectRequestDto.toEntity(); - request.updateAuthor(user); - if(!projectRequestDto.getUniv().isEmpty()) - request.updateUniv(universityAdaptor.findByName(projectRequestDto.getUniv())); - - Project project = projectService.createProject(request); - List techNames = projectRequestDto.getProjectTeches(); - projectTechService.addProjectTech(project, techNames.stream().map(tech -> tech.toUpperCase()).toList()); - - projectImageService.addImage( - projectRequestDto.getImageUrl().stream() - .map(imageUrl -> new ProjectImage(project, imageUrl)) - .collect(Collectors.toList())); - - List projectMembersRequest = projectRequestDto.getProjectMembers(); - List ids = projectMembersRequest.stream() - .map(projectMemberRequestDto -> projectMemberRequestDto.getUserId()).toList(); - List requestUsers = userAdaptor.findAllByIdIn(ids); - - List projectMembers = projectMembersRequest.stream() - .map(p -> matchProjectMembers(p, project, requestUsers)).toList(); - - projectMemberAdaptor.saveAll(projectMembers); - - return ProjectIdResponseDto.of(project.getId()); - } - - /* projectMemberRequestDto의 userId와 일치하는 user를 유저리스트에서 찾아서 ProjectMember로 변환합니다.*/ - private ProjectMember matchProjectMembers(ProjectMemberRequestDto projectMemberRequestDto, Project project, List users){ - return users.stream().distinct().filter(user -> user.getId().equals(projectMemberRequestDto.getUserId())) - .findFirst().map(user -> createProjectMember(project, user, projectMemberRequestDto.getPart())).get(); - } - - private ProjectMember createProjectMember(Project project, User user, Part part){ - return ProjectMember.builder() - .project(project) - .user(user) - .part(part) - .build(); - } -} diff --git a/likelion-client/src/main/java/likelion/univ/project/usecase/DeleteProjectUsecase.java b/likelion-client/src/main/java/likelion/univ/project/usecase/DeleteProjectUsecase.java deleted file mode 100644 index cf859624..00000000 --- a/likelion-client/src/main/java/likelion/univ/project/usecase/DeleteProjectUsecase.java +++ /dev/null @@ -1,34 +0,0 @@ -package likelion.univ.project.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.domain.project.adapter.ProjectAdaptor; -import likelion.univ.domain.project.entity.Project; -import likelion.univ.domain.project.service.ProjectImageService; -import likelion.univ.domain.project.service.ProjectMemberService; -import likelion.univ.domain.project.service.ProjectService; -import likelion.univ.domain.project.service.ProjectTechService; -import likelion.univ.utils.AuthenticatedUserUtils; -import lombok.RequiredArgsConstructor; - -@UseCase -@RequiredArgsConstructor -public class DeleteProjectUsecase { - - private final AuthenticatedUserUtils authenticatedUserUtils; - private final ProjectTechService projectTechService; - private final ProjectImageService projectImageService; - private final ProjectMemberService projectMemberService; - private final ProjectService projectService; - private final ProjectAdaptor projectAdaptor; - - public void execute(Long projectId) { - Project project = projectAdaptor.findById(projectId); - - authenticatedUserUtils.checkidentification(project.getAuthor().getId()); - - projectTechService.deleteProjectTech(projectId); - projectImageService.deleteImage(projectId); - projectMemberService.deleteProjectMember(projectId); - projectService.deleteProject(projectId); - } -} diff --git a/likelion-client/src/main/java/likelion/univ/project/usecase/GetAllPorjectUsecase.java b/likelion-client/src/main/java/likelion/univ/project/usecase/GetAllPorjectUsecase.java deleted file mode 100644 index 9a248665..00000000 --- a/likelion-client/src/main/java/likelion/univ/project/usecase/GetAllPorjectUsecase.java +++ /dev/null @@ -1,41 +0,0 @@ -package likelion.univ.project.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.common.response.PageResponse; -import likelion.univ.domain.project.adapter.ProjectImageAdaptor; -import likelion.univ.domain.project.adapter.ProjectAdaptor; -import likelion.univ.domain.project.adapter.ProjectMemberAdaptor; -import likelion.univ.domain.project.adapter.ProjectTechAdaptor; -import likelion.univ.domain.project.entity.Project; -import likelion.univ.domain.university.adaptor.UniversityAdaptor; -import likelion.univ.domain.user.adaptor.UserAdaptor; -import likelion.univ.project.dto.response.ProjectListResponseDto; -import likelion.univ.project.dto.response.ProjectResponseDto; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; - -import java.util.stream.Collectors; - -@UseCase -@RequiredArgsConstructor -public class GetAllPorjectUsecase { - - private final ProjectAdaptor projectAdaptor; - private final ProjectImageAdaptor projectImageAdaptor; - private final UniversityAdaptor universityAdaptor; - - public PageResponse execute(Pageable pageable) { - Page projects = projectAdaptor.findAll(pageable); - - return PageResponse.of(projects.map(project -> ProjectListResponseDto.of(project, - getUniversityName(project), - projectImageAdaptor.findByProject(project).isEmpty()? - null : projectImageAdaptor.findByProject(project).get(0).getImageUrl()))); - } - public String getUniversityName(Project project) { - if(project.getUniv() != null) - return universityAdaptor.findById(project.getUniv().getId()).getName(); - return null; - } -} diff --git a/likelion-client/src/main/java/likelion/univ/project/usecase/GetProjectByUsecase.java b/likelion-client/src/main/java/likelion/univ/project/usecase/GetProjectByUsecase.java deleted file mode 100644 index a0ca8ce8..00000000 --- a/likelion-client/src/main/java/likelion/univ/project/usecase/GetProjectByUsecase.java +++ /dev/null @@ -1,52 +0,0 @@ -package likelion.univ.project.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.common.response.PageResponse; -import likelion.univ.domain.project.adapter.ProjectImageAdaptor; -import likelion.univ.domain.project.adapter.ProjectAdaptor; -import likelion.univ.domain.project.adapter.ProjectMemberAdaptor; -import likelion.univ.domain.project.adapter.ProjectTechAdaptor; -import likelion.univ.domain.project.entity.Project; -import likelion.univ.domain.project.entity.ProjectImage; -import likelion.univ.domain.university.adaptor.UniversityAdaptor; -import likelion.univ.domain.user.adaptor.UserAdaptor; -import likelion.univ.project.dto.response.ProjectListResponseDto; -import likelion.univ.project.dto.response.ProjectResponseDto; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; - -import java.util.stream.Collectors; - -@UseCase -@RequiredArgsConstructor -public class GetProjectByUsecase { - private final ProjectAdaptor projectAdaptor; - private final ProjectImageAdaptor projectImageAdaptor; - private final UniversityAdaptor universityAdaptor; - - public PageResponse execute(Long ordinal, Pageable pageable){ - long recentOrdinal = projectAdaptor.getCurrentOrdinal(); - if(ordinal > recentOrdinal - 5){ - return getProjectResponseDtos(projectAdaptor.findProject(ordinal, pageable)); - } - else { - return getProjectResponseDtos(projectAdaptor.findArchiveProject(recentOrdinal - 5, pageable)); - } - } - - public PageResponse getProjectResponseDtos(Page projects) { - - return PageResponse.of(projects.map(project -> ProjectListResponseDto.of( - project, - getUniversityName(project), - projectImageAdaptor.findByProject(project).isEmpty()? - null : projectImageAdaptor.findByProject(project).get(0).getImageUrl()))); - } - - public String getUniversityName(Project project) { - if(project.getUniv() != null) - return universityAdaptor.findById(project.getUniv().getId()).getName(); - return null; - } -} diff --git a/likelion-client/src/main/java/likelion/univ/project/usecase/GetProjectUsecase.java b/likelion-client/src/main/java/likelion/univ/project/usecase/GetProjectUsecase.java deleted file mode 100644 index 264ce171..00000000 --- a/likelion-client/src/main/java/likelion/univ/project/usecase/GetProjectUsecase.java +++ /dev/null @@ -1,49 +0,0 @@ -package likelion.univ.project.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.domain.project.adapter.ProjectImageAdaptor; -import likelion.univ.domain.project.adapter.ProjectAdaptor; -import likelion.univ.domain.project.adapter.ProjectMemberAdaptor; -import likelion.univ.domain.project.adapter.ProjectTechAdaptor; -import likelion.univ.domain.project.entity.ProjectImage; -import likelion.univ.domain.project.entity.Project; -import likelion.univ.domain.project.entity.Tech; -import likelion.univ.domain.university.adaptor.UniversityAdaptor; -import likelion.univ.domain.user.adaptor.UserAdaptor; -import likelion.univ.domain.user.entity.User; -import likelion.univ.project.dto.response.ProjectMemberResponseDto; -import likelion.univ.project.dto.response.ProjectResponseDto; -import lombok.RequiredArgsConstructor; - -import java.util.List; -import java.util.stream.Collectors; - -@UseCase -@RequiredArgsConstructor -public class GetProjectUsecase { - - private final ProjectAdaptor projectAdaptor; - private final ProjectImageAdaptor projectImageAdaptor; - private final ProjectMemberAdaptor projectMemberAdaptor; - private final ProjectTechAdaptor projectTechAdaptor; - private final UserAdaptor userAdaptor; - private final UniversityAdaptor universityAdaptor; - - public ProjectResponseDto execute(Long id) { - Project project = projectAdaptor.findById(id); - String univ = null; - if(project.getUniv() != null) - univ = universityAdaptor.findById(project.getUniv().getId()).getName(); - - List projectTeches = projectTechAdaptor.findByProject(project).stream() - .map(projectTech -> projectTech.getTech()) - .map(tech -> projectTechAdaptor.findById(tech.getId())) - .collect(Collectors.toList()); - - List projectImages = projectImageAdaptor.findByProject(project); - - List projectMembers = projectMemberAdaptor.findByProject(project) - .stream().map(projectMember -> ProjectMemberResponseDto.of(projectMember)).toList(); - return ProjectResponseDto.of(project, univ, projectTeches, projectImages, projectMembers); - } -} diff --git a/likelion-client/src/main/java/likelion/univ/project/usecase/UpdateProjectUsecase.java b/likelion-client/src/main/java/likelion/univ/project/usecase/UpdateProjectUsecase.java deleted file mode 100644 index 3d3eb359..00000000 --- a/likelion-client/src/main/java/likelion/univ/project/usecase/UpdateProjectUsecase.java +++ /dev/null @@ -1,92 +0,0 @@ -package likelion.univ.project.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.domain.project.adapter.ProjectAdaptor; -import likelion.univ.domain.project.adapter.ProjectTechAdaptor; -import likelion.univ.domain.project.entity.ProjectImage; -import likelion.univ.domain.project.entity.Project; -import likelion.univ.domain.project.entity.ProjectMember; -import likelion.univ.domain.project.service.ProjectImageService; -import likelion.univ.domain.project.service.ProjectMemberService; -import likelion.univ.domain.project.service.ProjectService; -import likelion.univ.domain.project.service.ProjectTechService; -import likelion.univ.domain.university.adaptor.UniversityAdaptor; -import likelion.univ.domain.user.adaptor.UserAdaptor; -import likelion.univ.domain.user.entity.Part; -import likelion.univ.domain.user.entity.User; -import likelion.univ.project.dto.request.ProjectMemberRequestDto; -import likelion.univ.project.dto.request.ProjectRequestDto; -import likelion.univ.project.dto.response.ProjectIdResponseDto; -import likelion.univ.utils.AuthenticatedUserUtils; -import lombok.RequiredArgsConstructor; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; -import java.util.stream.Collectors; - -@UseCase -@RequiredArgsConstructor -public class UpdateProjectUsecase { - - private final AuthenticatedUserUtils authenticatedUserUtils; - private final ProjectService projectService; - private final ProjectTechService projectTechService; - private final ProjectImageService projectImageService; - private final ProjectMemberService projectMemberService; - private final ProjectAdaptor projectAdaptor; - private final ProjectTechAdaptor projectTechAdaptor; - private final UserAdaptor userAdaptor; - private final UniversityAdaptor universityAdaptor; - - @Transactional - public ProjectIdResponseDto execute(Long projectId, ProjectRequestDto projectRequestDto) { - - Project project = projectAdaptor.findById(projectId); - - authenticatedUserUtils.checkidentification(project.getAuthor().getId()); - - List techNames = projectRequestDto.getProjectTeches(); -// List techList = techNames.stream() -// .flatMap(techName -> projectTechAdaptor.findByName(techName.toUpperCase()).stream()) -// .collect(Collectors.toList()); - - List projectImage = projectRequestDto.getImageUrl().stream() - .map(imageUrl -> new ProjectImage(project, imageUrl)) - .collect(Collectors.toList()); - - Project editProject = projectRequestDto.toEntity(); - if(!projectRequestDto.getUniv().isEmpty()) - editProject.updateUniv(universityAdaptor.findByName(projectRequestDto.getUniv())); - else - editProject.updateUniv(null); - - - List projectMembersRequest = projectRequestDto.getProjectMembers(); - List ids = projectMembersRequest.stream() - .map(projectMemberRequestDto -> projectMemberRequestDto.getUserId()).toList(); - List requestUsers = userAdaptor.findAllByIdIn(ids); - - List projectMembers = projectMembersRequest.stream() - .map(p -> matchProjectMembers(p, project, requestUsers)).toList(); - - projectService.updateProject(projectId, editProject); - projectTechService.updateProjectTech(project,techNames); - projectImageService.updateImage(project, projectImage); - projectMemberService.updateProjectMember(project, projectMembers); - - return ProjectIdResponseDto.of(projectId); - } - - /* projectMemberRequestDto의 userId와 일치하는 user를 유저리스트에서 찾아서 ProjectMember로 변환합니다.*/ - private ProjectMember matchProjectMembers(ProjectMemberRequestDto projectMemberRequestDto, Project project, List users){ - return users.stream().distinct().filter(user -> user.getId().equals(projectMemberRequestDto.getUserId())) - .findFirst().map(user -> createProjectMember(project, user, projectMemberRequestDto.getPart())).get(); - } - private ProjectMember createProjectMember(Project project, User user, Part part){ - return ProjectMember.builder() - .project(project) - .user(user) - .part(part) - .build(); - } -} diff --git a/likelion-client/src/main/java/likelion/univ/recruit/controller/RecruitController.java b/likelion-client/src/main/java/likelion/univ/recruit/controller/RecruitController.java index 3b938435..579fda7f 100644 --- a/likelion-client/src/main/java/likelion/univ/recruit/controller/RecruitController.java +++ b/likelion-client/src/main/java/likelion/univ/recruit/controller/RecruitController.java @@ -3,10 +3,14 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import likelion.univ.recruit.dto.CreateRecruitDto; -import likelion.univ.recruit.usecase.CreateRecruitUsecase; +import likelion.univ.recruit.service.ClientRecruitService; import likelion.univ.response.SuccessResponse; import lombok.RequiredArgsConstructor; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.PathVariable; +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; @RestController @RequiredArgsConstructor @@ -14,14 +18,15 @@ @Tag(name = "Recruit", description = "리크루팅 알람 등록 API") public class RecruitController { - private final CreateRecruitUsecase createRecruitUsecase; + private final ClientRecruitService clientRecruitService; - @PostMapping("/{universityName}") @Operation(summary = "리크루팅 등록", description = "리크루팅 알람에 등록하는 API 입니다.") - public SuccessResponse register(@RequestBody CreateRecruitDto createRecruitDto, - @PathVariable String universityName) { - - Long recruitId = createRecruitUsecase.execute(createRecruitDto, universityName); + @PostMapping("/{universityName}") + public SuccessResponse register( + @RequestBody CreateRecruitDto createRecruitDto, + @PathVariable("universityName") String universityName + ) { + Long recruitId = clientRecruitService.create(createRecruitDto, universityName); return SuccessResponse.of(recruitId); } } diff --git a/likelion-client/src/main/java/likelion/univ/recruit/usecase/CreateRecruitUsecase.java b/likelion-client/src/main/java/likelion/univ/recruit/service/ClientRecruitService.java similarity index 81% rename from likelion-client/src/main/java/likelion/univ/recruit/usecase/CreateRecruitUsecase.java rename to likelion-client/src/main/java/likelion/univ/recruit/service/ClientRecruitService.java index 268eb6cf..fca6ab7c 100644 --- a/likelion-client/src/main/java/likelion/univ/recruit/usecase/CreateRecruitUsecase.java +++ b/likelion-client/src/main/java/likelion/univ/recruit/service/ClientRecruitService.java @@ -1,4 +1,4 @@ -package likelion.univ.recruit.usecase; +package likelion.univ.recruit.service; import likelion.univ.annotation.UseCase; import likelion.univ.domain.recruit.entity.Recruit; @@ -10,15 +10,14 @@ @UseCase @RequiredArgsConstructor -public class CreateRecruitUsecase { +public class ClientRecruitService { private final RecruitService recruitService; private final UniversityService universityService; - public Long execute(CreateRecruitDto createRecruitDto, String universityName) { + public Long create(CreateRecruitDto createRecruitDto, String universityName) { University university = universityService.findByName(universityName); Recruit recruit = createRecruitDto.toEntity(university); - return recruitService.register(recruit); } } diff --git a/likelion-client/src/main/java/likelion/univ/university/controller/UniversityController.java b/likelion-client/src/main/java/likelion/univ/university/controller/UniversityController.java index f7898b65..07b038ee 100644 --- a/likelion-client/src/main/java/likelion/univ/university/controller/UniversityController.java +++ b/likelion-client/src/main/java/likelion/univ/university/controller/UniversityController.java @@ -2,12 +2,11 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; -import likelion.univ.university.dto.response.UnivResponseDto; +import java.util.List; import likelion.univ.response.SuccessResponse; +import likelion.univ.university.dto.response.UnivResponseDto; import likelion.univ.university.dto.response.UniversityDetailResponseDto; -import likelion.univ.university.usecase.GetLocationUnivDetailsUseCase; -import likelion.univ.university.usecase.GetTotalUnivDetailsUseCase; -import likelion.univ.university.usecase.GetUnivUsecase; +import likelion.univ.university.service.ClientUniversityQueryService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.GetMapping; @@ -15,35 +14,35 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import java.util.List; - @Slf4j @RestController @RequiredArgsConstructor -@RequestMapping(value = "/v1/university") +@RequestMapping("/v1/universities") @Tag(name = "University", description = "대학교 API") public class UniversityController { - private final GetUnivUsecase getUnivUsecase; - private final GetTotalUnivDetailsUseCase getTotalUnivDetailsUseCase; - private final GetLocationUnivDetailsUseCase getLocationUnivDetailsUseCase; - //-----------대학교 조회 --------// - @GetMapping("/") + private final ClientUniversityQueryService universityQueryService; + @Operation(summary = "대학교 조회", description = "대학교를 조회합니다.") - public SuccessResponse getAllUniv(){ - List univList = getUnivUsecase.excute(); + @GetMapping + public SuccessResponse getAllUniv() { + List univList = universityQueryService.getUniv(); return SuccessResponse.of(univList); } + + @Operation(summary = "대학교 전체 조회", description = "대학교 전체를 조회합니다.") @GetMapping("/all") - @Operation(summary = "대학교 전체 조회", description = "대학교 잔체를 조회합니다.") - public SuccessResponse> getAllUnivList(){ - List result = getTotalUnivDetailsUseCase.execute(); + public SuccessResponse> getAllUnivList() { + List result = universityQueryService.getTotalUnivDetails(); return SuccessResponse.of(result); } - @GetMapping("/{location}") + @Operation(summary = "지역별 대학교 조회", description = "대학교를 지역별로 조회합니다.") - public SuccessResponse> getLocalUnivList(@PathVariable("location") String location){ - List result = getLocationUnivDetailsUseCase.execute(location); + @GetMapping("/{location}") + public SuccessResponse> getLocalUnivList( + @PathVariable("location") String location + ) { + List result = universityQueryService.getLocationUnivDetails(location); return SuccessResponse.of(result); } } diff --git a/likelion-client/src/main/java/likelion/univ/university/dto/response/UniversityDetailResponseDto.java b/likelion-client/src/main/java/likelion/univ/university/dto/response/UniversityDetailResponseDto.java index 208fd859..2e6c1c72 100644 --- a/likelion-client/src/main/java/likelion/univ/university/dto/response/UniversityDetailResponseDto.java +++ b/likelion-client/src/main/java/likelion/univ/university/dto/response/UniversityDetailResponseDto.java @@ -7,18 +7,18 @@ @Data @Builder public class UniversityDetailResponseDto { + private String universityName; private String location; private String image; - private String recuriteUrl; + private String recruitUrl; - public static UniversityDetailResponseDto of(University university){ + public static UniversityDetailResponseDto of(University university) { return UniversityDetailResponseDto.builder() .universityName(university.getName()) .location(university.getLocation()) .image(university.getImage()) - .recuriteUrl(university.getRecruiteUrl()) + .recruitUrl(university.getRecruitUrl()) .build(); } - } diff --git a/likelion-client/src/main/java/likelion/univ/university/service/ClientUniversityQueryService.java b/likelion-client/src/main/java/likelion/univ/university/service/ClientUniversityQueryService.java new file mode 100644 index 00000000..19e7f64c --- /dev/null +++ b/likelion-client/src/main/java/likelion/univ/university/service/ClientUniversityQueryService.java @@ -0,0 +1,36 @@ +package likelion.univ.university.service; + +import java.util.List; +import likelion.univ.domain.university.repository.UniversityRepository; +import likelion.univ.university.dto.response.UnivResponseDto; +import likelion.univ.university.dto.response.UniversityDetailResponseDto; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@RequiredArgsConstructor +@Service +public class ClientUniversityQueryService { + + private final UniversityRepository universityRepository; + + public List getLocationUnivDetails(String location) { + return universityRepository.findByLocationAndStatusIsActive(location) + .stream() + .map(UniversityDetailResponseDto::of) + .toList(); + } + + public List getTotalUnivDetails() { + return universityRepository.findAllByStatusIsActive() + .stream() + .map(UniversityDetailResponseDto::of) + .toList(); + } + + public List getUniv() { + return universityRepository.findAllByStatusIsActive() + .stream() + .map(university -> UnivResponseDto.of(university.getName())) + .toList(); + } +} diff --git a/likelion-client/src/main/java/likelion/univ/university/usecase/GetLocationUnivDetailsUseCase.java b/likelion-client/src/main/java/likelion/univ/university/usecase/GetLocationUnivDetailsUseCase.java deleted file mode 100644 index 7b006b56..00000000 --- a/likelion-client/src/main/java/likelion/univ/university/usecase/GetLocationUnivDetailsUseCase.java +++ /dev/null @@ -1,22 +0,0 @@ -package likelion.univ.university.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.domain.university.adaptor.UniversityAdaptor; -import likelion.univ.domain.university.entity.University; -import likelion.univ.university.dto.response.UniversityDetailResponseDto; -import lombok.RequiredArgsConstructor; - -import java.util.List; -import java.util.stream.Collectors; - -@UseCase -@RequiredArgsConstructor -public class GetLocationUnivDetailsUseCase { - private final UniversityAdaptor universityAdaptor; - - public List execute(String location){ - List universities = universityAdaptor.findByLocation(location); - return universities.stream().map(univ -> UniversityDetailResponseDto.of(univ)) - .collect(Collectors.toList()); - } -} \ No newline at end of file diff --git a/likelion-client/src/main/java/likelion/univ/university/usecase/GetTotalUnivDetailsUseCase.java b/likelion-client/src/main/java/likelion/univ/university/usecase/GetTotalUnivDetailsUseCase.java deleted file mode 100644 index 6f0c8eda..00000000 --- a/likelion-client/src/main/java/likelion/univ/university/usecase/GetTotalUnivDetailsUseCase.java +++ /dev/null @@ -1,22 +0,0 @@ -package likelion.univ.university.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.domain.university.adaptor.UniversityAdaptor; -import likelion.univ.domain.university.entity.University; -import likelion.univ.university.dto.response.UniversityDetailResponseDto; -import lombok.RequiredArgsConstructor; - -import java.util.List; -import java.util.stream.Collectors; - -@UseCase -@RequiredArgsConstructor -public class GetTotalUnivDetailsUseCase { - private final UniversityAdaptor universityAdaptor; - - public List execute(){ - List universities = universityAdaptor.findAll(); - return universities.stream().map(univ -> UniversityDetailResponseDto.of(univ)) - .collect(Collectors.toList()); - } -} diff --git a/likelion-client/src/main/java/likelion/univ/university/usecase/GetUnivUsecase.java b/likelion-client/src/main/java/likelion/univ/university/usecase/GetUnivUsecase.java deleted file mode 100644 index 56291b97..00000000 --- a/likelion-client/src/main/java/likelion/univ/university/usecase/GetUnivUsecase.java +++ /dev/null @@ -1,22 +0,0 @@ -package likelion.univ.university.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.domain.university.adaptor.UniversityAdaptor; -import likelion.univ.university.dto.response.UnivResponseDto; -import lombok.RequiredArgsConstructor; - -import java.util.List; -import java.util.stream.Collectors; - -@UseCase -@RequiredArgsConstructor -public class GetUnivUsecase { - - private final UniversityAdaptor universityAdaptor; - - public List excute() { - return universityAdaptor.findAll().stream() - .map(university -> UnivResponseDto.of(university.getName())) - .collect(Collectors.toList()); - } -} diff --git a/likelion-client/src/main/java/likelion/univ/user/controller/UserController.java b/likelion-client/src/main/java/likelion/univ/user/controller/UserController.java index a262c293..9419d96d 100644 --- a/likelion-client/src/main/java/likelion/univ/user/controller/UserController.java +++ b/likelion-client/src/main/java/likelion/univ/user/controller/UserController.java @@ -4,115 +4,129 @@ import io.swagger.v3.oas.annotations.tags.Tag; import likelion.univ.common.response.PageResponse; import likelion.univ.common.response.SliceResponse; -import likelion.univ.user.dto.request.ProfileEditRequestDto; -import likelion.univ.user.dto.response.*; -import likelion.univ.user.usecase.*; import likelion.univ.response.SuccessResponse; +import likelion.univ.user.dto.request.ProfileEditRequestDto; +import likelion.univ.user.dto.response.FollowUserInfoDto; +import likelion.univ.user.dto.response.ProfileDetailsDto; +import likelion.univ.user.dto.response.UserPagePostsDto; +import likelion.univ.user.dto.response.UserPageProjectsDto; +import likelion.univ.user.dto.response.UserSearchResultDto; +import likelion.univ.user.service.ClientUserQueryService; +import likelion.univ.user.service.ClientUserService; import lombok.RequiredArgsConstructor; import org.springdoc.api.annotations.ParameterObject; import org.springframework.data.domain.Pageable; import org.springframework.data.web.PageableDefault; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; @RestController @RequiredArgsConstructor -@RequestMapping(value = "/v1/user") +@RequestMapping("/v1/user") @Tag(name = "유저페이지", description = "유저페이지관련 API입니다.") public class UserController { - private final GetProfileUseCase getProfileUseCase; - private final EditProfileUseCase editProfileUseCase; - private final GetUserPostsUseCase getUserPostsUseCase; - private final GetPostsCommentedByMeUseCase getPostsCommentedByMeUseCase; - private final GetFollowInfoUseCase getFollowingListUseCase; - private final SearchUserByNameUseCase searchUserByNameUseCase; - private final GetUserLikedPostsUseCase getUserLikedPostsUseCase; - private final GetUserProjectsUseCase getUserProjectsUseCase; + + private final ClientUserService userService; + private final ClientUserQueryService userQueryService; @Operation(summary = "유저페이지 프로필 조회", description = "해당 유저의 프로필 정보를 조회합니다.") @GetMapping("/{userId}/profile") - public SuccessResponse getProfile(@PathVariable Long userId){ - ProfileDetailsDto profileDetailsDto = getProfileUseCase.execute(userId); + public SuccessResponse getProfile( + @PathVariable("userId") Long userId + ) { + ProfileDetailsDto profileDetailsDto = userQueryService.getProfile(userId); return SuccessResponse.of(profileDetailsDto); } @Operation(summary = "유저페이지 프로필 수정", description = "해당 유저의 프로필 정보를 수정합니다.") @PatchMapping("/{userId}/profile") - public SuccessResponse editProfile(@PathVariable Long userId, - @RequestBody ProfileEditRequestDto profileEditRequestDto){ - editProfileUseCase.execute(userId,profileEditRequestDto); + public SuccessResponse editProfile( + @PathVariable("userId") Long userId, + @RequestBody ProfileEditRequestDto profileEditRequestDto + ) { + userService.editProfile(userId, profileEditRequestDto); return SuccessResponse.empty(); } @Operation(summary = "팔로잉 목록 조회", description = "해당 유저의 팔로잉 목록을 조회합니다.") @GetMapping("/{userId}/following") - public SuccessResponse getFollowingList(@PathVariable Long userId, - @ParameterObject @PageableDefault(size = 4, page = 0) Pageable pageable){ - SliceResponse followingUsers = getFollowingListUseCase.executeForFollowing(userId,pageable); + public SuccessResponse getFollowingList( + @PathVariable("userId") Long userId, + @ParameterObject @PageableDefault(size = 4, page = 0) Pageable pageable + ) { + SliceResponse followingUsers = userQueryService.getFollowInfoForFollowing(userId, pageable); return SuccessResponse.of(followingUsers); } @Operation(summary = "팔로워 목록 조회", description = "해당 유저의 팔로워 목록을 조회합니다.") @GetMapping("/{userId}/follower") - public SuccessResponse getFollowerList(@PathVariable Long userId, - @ParameterObject @PageableDefault(size = 4, page = 0) Pageable pageable){ - SliceResponse followerUsers = getFollowingListUseCase.executeForFollower(userId,pageable); + public SuccessResponse getFollowerList( + @PathVariable("userId") Long userId, + @ParameterObject @PageableDefault(size = 4, page = 0) Pageable pageable + ) { + SliceResponse followerUsers = userQueryService.getFollowInfoForFollower(userId, pageable); return SuccessResponse.of(followerUsers); } + @Operation(summary = "해당 유저가 쓴 게시글 조회", description = "해당 유저가 작성한 게시글을 조회합니다.") @GetMapping("/{userId}/posts") - public SuccessResponse getPostsWritedByUser(@PathVariable Long userId, - @ParameterObject @PageableDefault(size = 6, page = 1) Pageable pageable){ - PageResponse myPagePostsPage = getUserPostsUseCase.execute(userId, pageable); + public SuccessResponse getPostsWrittenByUser( + @PathVariable("userId") Long userId, + @ParameterObject @PageableDefault(size = 6, page = 1) Pageable pageable + ) { + PageResponse myPagePostsPage = userQueryService.getUserPosts(userId, pageable); return SuccessResponse.of(myPagePostsPage); } @Operation(summary = "해당 유저가 좋아요 누른 게시글 조회", description = "해당 유저가 좋아요를 누른 게시글을 조회합니다. 파라미터로 search를 포함하지 않을 시 전체 조회입니다.") @GetMapping("/{userId}/posts/like") - public SuccessResponse getPostsLikedByUser(@PathVariable Long userId, - @RequestParam(value="sort", required = false, defaultValue="created_date") String sort, - @RequestParam(value="search", required = false) String search, - @ParameterObject @PageableDefault(size = 6, page = 0) Pageable pageable){ - PageResponse myPagePostsPageLikedByUser = getUserLikedPostsUseCase.execute(userId, pageable, sort, search); + public SuccessResponse getPostsLikedByUser( + @PathVariable("userId") Long userId, + @RequestParam(value = "sort", required = false, defaultValue = "created_date") String sort, + @RequestParam(value = "search", required = false) String search, + @ParameterObject @PageableDefault(size = 6, page = 0) Pageable pageable + ) { + PageResponse myPagePostsPageLikedByUser = userQueryService.getUserLikedPosts( + userId, pageable, sort, search + ); return SuccessResponse.of(myPagePostsPageLikedByUser); } - @Operation(summary = "해당 유저가 댓글 쓴 게시글 조회", description = "해당 유저가 댓글을 작성한 게시글을 조회합니다.") @GetMapping("/{userId}/posts/comment") - public SuccessResponse getPostsCommentedByUser(@PathVariable Long userId, - @ParameterObject @PageableDefault(size = 6, page = 0) Pageable pageable){ - PageResponse myPagePostsPageCommentedByUser = getPostsCommentedByMeUseCase.execute(userId, pageable); + public SuccessResponse getPostsCommentedByUser( + @PathVariable("userId") Long userId, + @ParameterObject @PageableDefault(size = 6, page = 0) Pageable pageable + ) { + PageResponse myPagePostsPageCommentedByUser = userQueryService.getPostsCommentedByMe( + userId, pageable + ); return SuccessResponse.of(myPagePostsPageCommentedByUser); } + @Operation(summary = "유저 검색 (Simple Data) (project page)", description = "이름으로 유저를 검색합니다. (프로젝트 페이지 모달)") @GetMapping("/search") - public SuccessResponse searchUser(@RequestParam(required = false) String name, - @ParameterObject @PageableDefault(size = 4, page = 0) Pageable pageable){ - SliceResponse searchedUsers = searchUserByNameUseCase.execute(name, pageable); + public SuccessResponse searchUser( + @RequestParam(value = "name", required = false) String name, + @ParameterObject @PageableDefault(size = 4, page = 0) Pageable pageable + ) { + SliceResponse searchedUsers = userQueryService.searchUserByName(name, pageable); return SuccessResponse.of(searchedUsers); } - @Operation(summary = "내가 참여한 프로젝트 조회", description = "참여한 프로젝트를 조회합니다.") @GetMapping("/{userId}/projects") - public SuccessResponse getMyProjects(@PathVariable Long userId, - @ParameterObject @PageableDefault(size = 6, page = 0) Pageable pageable){ - PageResponse myPageProjects = getUserProjectsUseCase.execute(userId, pageable); + public SuccessResponse getMyProjects( + @PathVariable("userId") Long userId, + @ParameterObject @PageableDefault(size = 6, page = 0) Pageable pageable + ) { + PageResponse myPageProjects = userQueryService.getUserProjects(userId, pageable); return SuccessResponse.of(myPageProjects); } -// -// @Operation(summary = "휴대폰 인증 요청", description = "휴대폰 번호 인증을 위해 서버 내부에 인증번호를 생성합니다.") -// @PostMapping("/phone/certify") -// public SuccessResponse login(@RequestParam("phonenum") String phoneNum){ -// return SuccessResponse.of(); -// } -// -// @Operation(summary = "휴대폰 인증번호 확인", description = "휴대폰 인증번호 확인 후 인증 토큰을 발급합니다.") -// @PostMapping("/phone/certify/check") -// public SuccessResponse getIdToken(@RequestParam("certifynum") Long certifyNum){ -// -// return SuccessResponse.of(); -// } - } diff --git a/likelion-client/src/main/java/likelion/univ/user/dto/request/ProfileEditRequestDto.java b/likelion-client/src/main/java/likelion/univ/user/dto/request/ProfileEditRequestDto.java index 3cff2535..4023559a 100644 --- a/likelion-client/src/main/java/likelion/univ/user/dto/request/ProfileEditRequestDto.java +++ b/likelion-client/src/main/java/likelion/univ/user/dto/request/ProfileEditRequestDto.java @@ -11,6 +11,7 @@ @Getter @NoArgsConstructor public class ProfileEditRequestDto { + @NotNull @Schema(description = "이름", example = "김슬기", required = true) private String name; @@ -25,7 +26,7 @@ public class ProfileEditRequestDto { @Schema(description = "트랙(파트)", example = "BACKEND", required = true, enumAsRef = true) private Part part; - public Profile toProfile(){ + public Profile toProfile() { return Profile.builder() .name(name) .profileImage(profileImage) diff --git a/likelion-client/src/main/java/likelion/univ/user/dto/response/FollowUserInfoDto.java b/likelion-client/src/main/java/likelion/univ/user/dto/response/FollowUserInfoDto.java index 7259d21a..2e497269 100644 --- a/likelion-client/src/main/java/likelion/univ/user/dto/response/FollowUserInfoDto.java +++ b/likelion-client/src/main/java/likelion/univ/user/dto/response/FollowUserInfoDto.java @@ -7,6 +7,7 @@ @Getter @Builder public class FollowUserInfoDto { + private Long userId; private String name; private String profileImage; @@ -14,7 +15,7 @@ public class FollowUserInfoDto { private String part; private Boolean isFollowed; - public static FollowUserInfoDto of(User user, Boolean isFollowed){ + public static FollowUserInfoDto of(User user, Boolean isFollowed) { return FollowUserInfoDto.builder() .userId(user.getId()) .name(user.getProfile().getName()) diff --git a/likelion-client/src/main/java/likelion/univ/user/dto/response/ProfileDetailsDto.java b/likelion-client/src/main/java/likelion/univ/user/dto/response/ProfileDetailsDto.java index de0b2128..0fddf7af 100644 --- a/likelion-client/src/main/java/likelion/univ/user/dto/response/ProfileDetailsDto.java +++ b/likelion-client/src/main/java/likelion/univ/user/dto/response/ProfileDetailsDto.java @@ -7,6 +7,7 @@ @Getter @Builder public class ProfileDetailsDto { + private Long id; private String profileImage; private String name; @@ -21,7 +22,7 @@ public class ProfileDetailsDto { private String introduction; private Boolean isMine; - public static ProfileDetailsDto of(User user, Boolean isMine,Long followerNum, Long followingNum){ + public static ProfileDetailsDto of(User user, Boolean isMine, Long followerNum, Long followingNum) { return ProfileDetailsDto.builder() .id(user.getId()) .profileImage(user.getProfile().getProfileImage()) diff --git a/likelion-client/src/main/java/likelion/univ/user/dto/response/UserPagePostsDto.java b/likelion-client/src/main/java/likelion/univ/user/dto/response/UserPagePostsDto.java index c8e1faa5..537733a6 100644 --- a/likelion-client/src/main/java/likelion/univ/user/dto/response/UserPagePostsDto.java +++ b/likelion-client/src/main/java/likelion/univ/user/dto/response/UserPagePostsDto.java @@ -1,16 +1,16 @@ package likelion.univ.user.dto.response; +import java.time.LocalDate; import likelion.univ.domain.post.entity.Post; import likelion.univ.post.entity.PostCountInfo; import lombok.Builder; import lombok.Getter; -import java.time.LocalDate; - @Getter @Builder public class UserPagePostsDto { + private Long id; private String title; private String body; @@ -21,10 +21,11 @@ public class UserPagePostsDto { private Long likeCount; private Long commentCount; - public static UserPagePostsDto of(Post post, Long likeCount, Long commentCount, Boolean isAuthor, Boolean isLiked){ + public static UserPagePostsDto of(Post post, Long likeCount, Long commentCount, Boolean isAuthor, Boolean isLiked) { String body = post.getBody().replaceAll("<(/)?([a-zA-Z]*)(\\s[a-zA-Z]*=[^>]*)?(\\s)*(/)?>", ""); - if(body.length() > 100) - body = body.substring(0,97) + "..."; + if (body.length() > 100) { + body = body.substring(0, 97) + "..."; + } return UserPagePostsDto.builder() .id(post.getId()) .title(post.getTitle()) @@ -38,9 +39,13 @@ public static UserPagePostsDto of(Post post, Long likeCount, Long commentCount, .build(); } - public static UserPagePostsDto of(Post post, Long userId, PostCountInfo postCountInfo, Boolean isLiked){ - if(post.getAuthor().getId().equals(userId)) - return UserPagePostsDto.of(post, postCountInfo.getLikeCount(), postCountInfo.getCommentCount(),true, isLiked); - else return UserPagePostsDto.of(post, postCountInfo.getLikeCount(), postCountInfo.getCommentCount(),false, isLiked); + public static UserPagePostsDto of(Post post, Long userId, PostCountInfo postCountInfo, Boolean isLiked) { + if (post.getAuthor().getId().equals(userId)) { + return UserPagePostsDto.of(post, postCountInfo.getLikeCount(), postCountInfo.getCommentCount(), true, + isLiked); + } else { + return UserPagePostsDto.of(post, postCountInfo.getLikeCount(), postCountInfo.getCommentCount(), false, + isLiked); + } } } diff --git a/likelion-client/src/main/java/likelion/univ/user/dto/response/UserPageProjectsDto.java b/likelion-client/src/main/java/likelion/univ/user/dto/response/UserPageProjectsDto.java index ceda45ec..6cd9cca5 100644 --- a/likelion-client/src/main/java/likelion/univ/user/dto/response/UserPageProjectsDto.java +++ b/likelion-client/src/main/java/likelion/univ/user/dto/response/UserPageProjectsDto.java @@ -4,6 +4,7 @@ import likelion.univ.domain.project.entity.enums.Output; import lombok.Builder; import lombok.Getter; + @Getter @Builder public class UserPageProjectsDto { @@ -17,7 +18,7 @@ public class UserPageProjectsDto { private String activity; private String thumbnail; - public static UserPageProjectsDto of(Project project){ + public static UserPageProjectsDto of(Project project) { return UserPageProjectsDto.builder() .projectId(project.getId()) .serviceName(project.getServiceName()) @@ -29,8 +30,8 @@ public static UserPageProjectsDto of(Project project){ .thumbnail(getThumbnail(project)) .build(); } - public static String getThumbnail(Project project){ + + public static String getThumbnail(Project project) { return project.getProjectImages().isEmpty() ? null : project.getProjectImages().get(0).getImageUrl(); } - } diff --git a/likelion-client/src/main/java/likelion/univ/user/dto/response/UserSearchResultDto.java b/likelion-client/src/main/java/likelion/univ/user/dto/response/UserSearchResultDto.java index 052e767d..66bf6c42 100644 --- a/likelion-client/src/main/java/likelion/univ/user/dto/response/UserSearchResultDto.java +++ b/likelion-client/src/main/java/likelion/univ/user/dto/response/UserSearchResultDto.java @@ -7,6 +7,7 @@ @Getter @Builder public class UserSearchResultDto { + private Long userId; private String name; private String profileImage; @@ -14,7 +15,7 @@ public class UserSearchResultDto { private Long ordinal; private String part; - public static UserSearchResultDto of(User user){ + public static UserSearchResultDto of(User user) { return UserSearchResultDto.builder() .userId(user.getId()) .name(user.getProfile().getName()) @@ -24,5 +25,4 @@ public static UserSearchResultDto of(User user){ .part(user.getProfile().getPart().getValue()) .build(); } - } diff --git a/likelion-client/src/main/java/likelion/univ/user/scheduler/UserPageScheduler.java b/likelion-client/src/main/java/likelion/univ/user/scheduler/UserPageScheduler.java deleted file mode 100644 index 45bb7cd9..00000000 --- a/likelion-client/src/main/java/likelion/univ/user/scheduler/UserPageScheduler.java +++ /dev/null @@ -1,4 +0,0 @@ -package likelion.univ.user.scheduler; - -//public class MyPageScheduler { -//} diff --git a/likelion-client/src/main/java/likelion/univ/user/service/ClientUserQueryService.java b/likelion-client/src/main/java/likelion/univ/user/service/ClientUserQueryService.java new file mode 100644 index 00000000..58e2b99e --- /dev/null +++ b/likelion-client/src/main/java/likelion/univ/user/service/ClientUserQueryService.java @@ -0,0 +1,151 @@ +package likelion.univ.user.service; + +import java.util.List; +import java.util.Optional; +import likelion.univ.common.response.PageResponse; +import likelion.univ.common.response.SliceResponse; +import likelion.univ.domain.follow.repository.FollowRepository; +import likelion.univ.domain.like.postlike.repository.PostLikeRepository; +import likelion.univ.domain.post.entity.Post; +import likelion.univ.domain.post.repository.PostRepository; +import likelion.univ.domain.project.entity.Project; +import likelion.univ.domain.project.repository.ProjectRepository; +import likelion.univ.domain.user.entity.User; +import likelion.univ.domain.user.repository.UserRepository; +import likelion.univ.follow.dao.FollowNumRedisDao; +import likelion.univ.follow.entity.FollowNum; +import likelion.univ.follow.service.FollowNumRedisService; +import likelion.univ.post.processor.GetOrCreatePostCountInfoProcessor; +import likelion.univ.user.dto.response.FollowUserInfoDto; +import likelion.univ.user.dto.response.ProfileDetailsDto; +import likelion.univ.user.dto.response.UserPagePostsDto; +import likelion.univ.user.dto.response.UserPageProjectsDto; +import likelion.univ.user.dto.response.UserSearchResultDto; +import likelion.univ.utils.AuthenticatedUserUtils; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Slice; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@RequiredArgsConstructor +@Transactional(readOnly = true) +@Service +public class ClientUserQueryService { + + private final AuthenticatedUserUtils authenticatedUserUtils; + private final UserRepository userRepository; + private final PostRepository postRepository; + private final GetOrCreatePostCountInfoProcessor getOrCreatePostCountInfoProcessor; + private final PostLikeRepository postLikeRepository; + private final FollowNumRedisDao followNumRedisDao; + private final FollowNumRedisService followNumRedisService; + private final FollowRepository followRepository; + private final ProjectRepository projectRepository; + + public SliceResponse getFollowInfoForFollowing(Long userId, Pageable pageable) { + Slice userSlice = userRepository.findFollowingUsersByFollowerId(userId, pageable); + List myFollowingUsers = getMyFollowingUsers(userSlice); + return SliceResponse.of(userSlice.map(u -> + FollowUserInfoDto.of(u, checkIFollowingTarget(u, myFollowingUsers))) + ); + } + + public SliceResponse getFollowInfoForFollower(Long userId, Pageable pageable) { + Slice userSlice = userRepository.findFollowerUsersByFollowingId(userId, pageable); + List myFollowingUsers = getMyFollowingUsers(userSlice); + return SliceResponse.of(userSlice.map(u -> + FollowUserInfoDto.of(u, checkIFollowingTarget(u, myFollowingUsers))) + ); + } + + private List getMyFollowingUsers(Slice userSlice) { + Long currentUserId = authenticatedUserUtils.getCurrentUserId(); + List followingUserIds = userSlice.getContent() + .stream() + .map(User::getId) + .toList(); + return userRepository.findMyFollowingUsersByFollowingIdIn(currentUserId, followingUserIds); + } + + private Boolean checkIFollowingTarget(User target, List myFollowingUsers) { + return myFollowingUsers.stream() + .anyMatch(u -> u.getId().equals(target.getId())); + } + + public PageResponse getPostsCommentedByMe(Long userId, Pageable pageable) { + Long currentUserId = authenticatedUserUtils.getCurrentUserId(); + Page posts = postRepository.findByCommentAuthorId(userId, pageable); + List postIds = posts.get() + .map(Post::getId) + .toList(); + List myLikedPostIds = postLikeRepository.findPostIdsByUserIdAndPostIdsIn(currentUserId, postIds); + return PageResponse.of(posts.map(p -> UserPagePostsDto.of( + p, + currentUserId, + getOrCreatePostCountInfoProcessor.execute(p.getId()), + myLikedPostIds.contains(p.getId())) + )); + } + + public ProfileDetailsDto getProfile(Long userId) { + Long currentUserId = authenticatedUserUtils.getCurrentUserId(); + User user = userRepository.getByIdWithUniversity(userId); + FollowNum followNum = getUserFollowNum(user.getId()); + if (user.getId().equals(currentUserId)) { + return ProfileDetailsDto.of(user, true, followNum.getFollowerNum(), followNum.getFollowingNum()); + } else { + return ProfileDetailsDto.of(user, false, followNum.getFollowerNum(), followNum.getFollowingNum()); + } + } + + private FollowNum getUserFollowNum(Long userId) { + Optional userFollowNum = followNumRedisDao.findById(userId); + if (userFollowNum.isEmpty()) { + Long followerNum = followRepository.countByFollowingId(userId); + Long followingNum = followRepository.countByFollowerId(userId); + return followNumRedisService.save(userId, followerNum, followingNum); + } + return userFollowNum.get(); + } + + public PageResponse getUserLikedPosts( + Long userId, + Pageable pageable, + String sort, + String search + ) { + Long currentUserId = authenticatedUserUtils.getCurrentUserId(); + Page posts = postRepository.findByPostLikeAuthorId(userId, pageable, sort, search); + List postIds = posts.get() + .map(Post::getId) + .toList(); + List myLikedPostIds = postLikeRepository.findPostIdsByUserIdAndPostIdsIn(currentUserId, postIds); + return PageResponse.of(posts.map(p -> UserPagePostsDto.of(p, currentUserId, + getOrCreatePostCountInfoProcessor.execute(p.getId()), + myLikedPostIds.contains(p.getId())))); + } + + public PageResponse getUserPosts(Long userId, Pageable pageable) { + Long currentUserId = authenticatedUserUtils.getCurrentUserId(); + Page posts = postRepository.findAllByAuthorId(userId, pageable); + List postIds = posts.get() + .map(Post::getId) + .toList(); + List myLikedPostIds = postLikeRepository.findPostIdsByUserIdAndPostIdsIn(currentUserId, postIds); + return PageResponse.of(posts.map(p -> UserPagePostsDto.of(p, currentUserId, + getOrCreatePostCountInfoProcessor.execute(p.getId()), + myLikedPostIds.contains(p.getId())))); + } + + public PageResponse getUserProjects(Long userId, Pageable pageable) { + Page projects = projectRepository.findByProjectMember(userId, pageable); + return PageResponse.of(projects.map(UserPageProjectsDto::of)); + } + + public SliceResponse searchUserByName(String name, Pageable pageable) { + Slice userSlice = userRepository.searchByName(name, pageable); + return SliceResponse.of(userSlice.map(UserSearchResultDto::of)); + } +} diff --git a/likelion-client/src/main/java/likelion/univ/user/service/ClientUserService.java b/likelion-client/src/main/java/likelion/univ/user/service/ClientUserService.java new file mode 100644 index 00000000..3dab0970 --- /dev/null +++ b/likelion-client/src/main/java/likelion/univ/user/service/ClientUserService.java @@ -0,0 +1,24 @@ +package likelion.univ.user.service; + +import likelion.univ.domain.user.entity.Profile; +import likelion.univ.domain.user.service.UserService; +import likelion.univ.user.dto.request.ProfileEditRequestDto; +import likelion.univ.utils.AuthenticatedUserUtils; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@RequiredArgsConstructor +@Transactional +@Service +public class ClientUserService { + + private final AuthenticatedUserUtils authenticatedUserUtils; + private final UserService userService; + + public void editProfile(Long userId, ProfileEditRequestDto profileEditRequestDto) { + authenticatedUserUtils.checkIdentification(userId); + Profile profile = profileEditRequestDto.toProfile(); + userService.editProfile(userId, profile); + } +} diff --git a/likelion-client/src/main/java/likelion/univ/user/usecase/EditProfileUseCase.java b/likelion-client/src/main/java/likelion/univ/user/usecase/EditProfileUseCase.java deleted file mode 100644 index a44bd8df..00000000 --- a/likelion-client/src/main/java/likelion/univ/user/usecase/EditProfileUseCase.java +++ /dev/null @@ -1,24 +0,0 @@ -package likelion.univ.user.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.domain.user.entity.Profile; -import likelion.univ.domain.user.entity.User; -import likelion.univ.domain.user.service.UserDomainService; -import likelion.univ.user.dto.request.ProfileEditRequestDto; -import likelion.univ.user.dto.response.ProfileDetailsDto; -import likelion.univ.utils.AuthenticatedUserUtils; -import lombok.RequiredArgsConstructor; - -@UseCase -@RequiredArgsConstructor -public class EditProfileUseCase { - private final AuthenticatedUserUtils authentiatedUserUtils; - private final UserDomainService userDomainService; - - public void execute(Long userId, ProfileEditRequestDto profileEditRequestDto){ - authentiatedUserUtils.checkidentification(userId); - - Profile profile = profileEditRequestDto.toProfile(); - User user = userDomainService.editProfile(userId, profile); - } -} diff --git a/likelion-client/src/main/java/likelion/univ/user/usecase/GetFollowInfoUseCase.java b/likelion-client/src/main/java/likelion/univ/user/usecase/GetFollowInfoUseCase.java deleted file mode 100644 index f5246839..00000000 --- a/likelion-client/src/main/java/likelion/univ/user/usecase/GetFollowInfoUseCase.java +++ /dev/null @@ -1,45 +0,0 @@ -package likelion.univ.user.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.common.response.SliceResponse; -import likelion.univ.domain.user.adaptor.UserAdaptor; -import likelion.univ.domain.user.entity.User; -import likelion.univ.user.dto.response.FollowUserInfoDto; -import likelion.univ.utils.AuthenticatedUserUtils; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; - -import java.util.List; - -@UseCase -@RequiredArgsConstructor -public class GetFollowInfoUseCase { - private final AuthenticatedUserUtils authentiatedUserUtils; - private final UserAdaptor userAdaptor; - - public SliceResponse executeForFollowing(Long userId, Pageable pageable){ - Slice userSlice = userAdaptor.findFollowingUsersByFollowerID(userId, pageable); - List myFollowingUsers = getMyFollowingUsers(userSlice); - - return SliceResponse.of(userSlice.map(u -> - FollowUserInfoDto.of(u, checkIFollowingTarget(u, myFollowingUsers)))); - } - - public SliceResponse executeForFollower(Long userId, Pageable pageable){ - Slice userSlice = userAdaptor.findFollowerUsersByFollowingID(userId, pageable); - List myFollowingUsers = getMyFollowingUsers(userSlice); - - return SliceResponse.of(userSlice.map(u -> - FollowUserInfoDto.of(u, checkIFollowingTarget(u, myFollowingUsers)))); - } - private List getMyFollowingUsers(Slice userSlice){ - Long currentUserId = authentiatedUserUtils.getCurrentUserId(); - List followingUserIds = userSlice.getContent().stream().map(user -> user.getId()).toList(); - return userAdaptor.findMyFollowingUsersByFollowingIdIn(currentUserId, followingUserIds); - } - - private Boolean checkIFollowingTarget(User target, List myFollowingUsers){ - return myFollowingUsers.stream().anyMatch(u -> u.getId().equals(target.getId())); - } -} diff --git a/likelion-client/src/main/java/likelion/univ/user/usecase/GetPostsCommentedByMeUseCase.java b/likelion-client/src/main/java/likelion/univ/user/usecase/GetPostsCommentedByMeUseCase.java deleted file mode 100644 index 0f17dc0d..00000000 --- a/likelion-client/src/main/java/likelion/univ/user/usecase/GetPostsCommentedByMeUseCase.java +++ /dev/null @@ -1,42 +0,0 @@ -package likelion.univ.user.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.common.response.PageResponse; -import likelion.univ.domain.post.adaptor.PostAdaptor; -import likelion.univ.domain.post.entity.Post; -import likelion.univ.post.processor.GetOrCreatePostCountInfoProcessor; -import likelion.univ.user.dto.response.UserPagePostsDto; -import likelion.univ.domain.comment.adaptor.CommentAdaptor; -import likelion.univ.domain.like.postlike.adaptor.PostLikeAdaptor; -import likelion.univ.post.dao.PostCountInfoRedisDao; -import likelion.univ.post.entity.PostCountInfo; -import likelion.univ.post.service.PostCountInfoRedisService; -import likelion.univ.utils.AuthenticatedUserUtils; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; - -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; - -@UseCase -@RequiredArgsConstructor -public class GetPostsCommentedByMeUseCase { - private final AuthenticatedUserUtils authentiatedUserUtils; - private final PostAdaptor postAdaptor; - private final GetOrCreatePostCountInfoProcessor getOrCreatePostCountInfoProcessor; - private final PostLikeAdaptor postLikeAdaptor; - - public PageResponse execute(Long userId, Pageable pageable){ - Long currentUserId = authentiatedUserUtils.getCurrentUserId(); - Page posts = postAdaptor.findByCommentAuthorId(userId, pageable); - - List postIds = posts.get().map(p -> p.getId()).collect(Collectors.toList()); - List myLikedPostIds = postLikeAdaptor.findPostIdsByUserIdAndPostIdsIn(currentUserId, postIds); - - return PageResponse.of(posts.map(p-> UserPagePostsDto.of(p, currentUserId, - getOrCreatePostCountInfoProcessor.execute(p.getId()), - myLikedPostIds.contains(p.getId())))); - } -} diff --git a/likelion-client/src/main/java/likelion/univ/user/usecase/GetProfileUseCase.java b/likelion-client/src/main/java/likelion/univ/user/usecase/GetProfileUseCase.java deleted file mode 100644 index c418b341..00000000 --- a/likelion-client/src/main/java/likelion/univ/user/usecase/GetProfileUseCase.java +++ /dev/null @@ -1,48 +0,0 @@ -package likelion.univ.user.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.domain.follow.adaptor.FollowAdaptor; -import likelion.univ.domain.user.adaptor.UserAdaptor; -import likelion.univ.domain.user.entity.User; -import likelion.univ.follow.dao.FollowNumRedisDao; -import likelion.univ.user.dto.response.ProfileDetailsDto; -import likelion.univ.follow.entity.FollowNum; -import likelion.univ.follow.service.FollowNumRedisService; -import likelion.univ.utils.AuthenticatedUserUtils; -import lombok.RequiredArgsConstructor; - -import java.util.Optional; - -@UseCase -@RequiredArgsConstructor -public class GetProfileUseCase { - private final AuthenticatedUserUtils authentiatedUserUtils; - private final UserAdaptor userAdaptor; - private final FollowNumRedisDao followNumRedisDao; - private final FollowNumRedisService followNumRedisService; - private final FollowAdaptor followAdaptor; - - public ProfileDetailsDto execute(Long userId){ - Long currentUserId = authentiatedUserUtils.getCurrentUserId(); - User user = userAdaptor.findByIdWithUniversity(userId); - - return createDto(user, currentUserId); - } - - private ProfileDetailsDto createDto(User user, Long currentUserId){ - FollowNum followNum = getUserFollowNum(user.getId()); - - if (user.getId().equals(currentUserId)) - return ProfileDetailsDto.of(user, true, followNum.getFollowerNum(), followNum.getFollowingNum()); - else return ProfileDetailsDto.of(user, false, followNum.getFollowerNum(), followNum.getFollowingNum()); - } - - private FollowNum getUserFollowNum(Long userId){ - Optional userFollowNum = followNumRedisDao.findById(userId); - if(userFollowNum.isEmpty()){ - Long followerNum = followAdaptor.countByFollowingId(userId); - Long followingNum = followAdaptor.countByFollowerId(userId); - return followNumRedisService.save(userId, followerNum, followingNum); - }else return userFollowNum.get(); - } -} diff --git a/likelion-client/src/main/java/likelion/univ/user/usecase/GetUserLikedPostsUseCase.java b/likelion-client/src/main/java/likelion/univ/user/usecase/GetUserLikedPostsUseCase.java deleted file mode 100644 index 2566da54..00000000 --- a/likelion-client/src/main/java/likelion/univ/user/usecase/GetUserLikedPostsUseCase.java +++ /dev/null @@ -1,38 +0,0 @@ -package likelion.univ.user.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.common.response.PageResponse; -import likelion.univ.domain.like.postlike.adaptor.PostLikeAdaptor; -import likelion.univ.domain.post.adaptor.PostAdaptor; -import likelion.univ.domain.post.entity.Post; -import likelion.univ.post.processor.GetOrCreatePostCountInfoProcessor; -import likelion.univ.user.dto.response.UserPagePostsDto; -import likelion.univ.utils.AuthenticatedUserUtils; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; - -import java.util.List; -import java.util.stream.Collectors; - -@UseCase -@RequiredArgsConstructor -public class GetUserLikedPostsUseCase { - private final AuthenticatedUserUtils authentiatedUserUtils; - private final PostAdaptor postAdaptor; - private final GetOrCreatePostCountInfoProcessor getOrCreatePostCountInfoProcessor; - private final PostLikeAdaptor postLikeAdaptor; - - public PageResponse execute(Long userId, Pageable pageable, String sort, String search){ - Long currentUserId = authentiatedUserUtils.getCurrentUserId(); - Page posts = postAdaptor.findByPostLikeAuthorId(userId, pageable, sort, search); - - List postIds = posts.get().map(p -> p.getId()).collect(Collectors.toList()); - List myLikedPostIds = postLikeAdaptor.findPostIdsByUserIdAndPostIdsIn(currentUserId, postIds); - - return PageResponse.of(posts.map(p-> UserPagePostsDto.of(p, currentUserId, - getOrCreatePostCountInfoProcessor.execute(p.getId()), - myLikedPostIds.contains(p.getId())))); - } - -} diff --git a/likelion-client/src/main/java/likelion/univ/user/usecase/GetUserPostsUseCase.java b/likelion-client/src/main/java/likelion/univ/user/usecase/GetUserPostsUseCase.java deleted file mode 100644 index cfc6e684..00000000 --- a/likelion-client/src/main/java/likelion/univ/user/usecase/GetUserPostsUseCase.java +++ /dev/null @@ -1,39 +0,0 @@ -package likelion.univ.user.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.common.response.PageResponse; -import likelion.univ.domain.like.postlike.adaptor.PostLikeAdaptor; -import likelion.univ.domain.post.adaptor.PostAdaptor; -import likelion.univ.domain.post.entity.Post; -import likelion.univ.post.processor.GetOrCreatePostCountInfoProcessor; -import likelion.univ.user.dto.response.UserPagePostsDto; -import likelion.univ.utils.AuthenticatedUserUtils; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; - -import java.util.List; -import java.util.stream.Collectors; - - -@UseCase -@RequiredArgsConstructor -public class GetUserPostsUseCase { - - private final AuthenticatedUserUtils authenticatedUserUtils; - private final PostAdaptor postAdaptor; - private final PostLikeAdaptor postLikeAdaptor; - private final GetOrCreatePostCountInfoProcessor getOrCreatePostCountInfoProcessor; - - public PageResponse execute(Long userId, Pageable pageable){ - Long currentUserId= authenticatedUserUtils.getCurrentUserId(); - Page posts = postAdaptor.findAllByAuthor_Id(userId, pageable); - - List postIds = posts.get().map(p -> p.getId()).collect(Collectors.toList()); - List myLikedPostIds = postLikeAdaptor.findPostIdsByUserIdAndPostIdsIn(currentUserId, postIds); - - return PageResponse.of(posts.map(p-> UserPagePostsDto.of(p, currentUserId, - getOrCreatePostCountInfoProcessor.execute(p.getId()), - myLikedPostIds.contains(p.getId())))); - } -} diff --git a/likelion-client/src/main/java/likelion/univ/user/usecase/GetUserProjectsUseCase.java b/likelion-client/src/main/java/likelion/univ/user/usecase/GetUserProjectsUseCase.java deleted file mode 100644 index 859f11ad..00000000 --- a/likelion-client/src/main/java/likelion/univ/user/usecase/GetUserProjectsUseCase.java +++ /dev/null @@ -1,21 +0,0 @@ -package likelion.univ.user.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.common.response.PageResponse; -import likelion.univ.domain.project.adapter.ProjectAdaptor; -import likelion.univ.domain.project.entity.Project; -import likelion.univ.user.dto.response.UserPageProjectsDto; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; - -@UseCase -@RequiredArgsConstructor -public class GetUserProjectsUseCase { - private final ProjectAdaptor projectAdaptor; - - public PageResponse execute(Long userId, Pageable pageable){ - Page projects = projectAdaptor.findByProjectMember(userId, pageable); - return PageResponse.of(projects.map(p -> UserPageProjectsDto.of(p))); - } -} diff --git a/likelion-client/src/main/java/likelion/univ/user/usecase/SearchUserByNameUseCase.java b/likelion-client/src/main/java/likelion/univ/user/usecase/SearchUserByNameUseCase.java deleted file mode 100644 index aeb7ca6f..00000000 --- a/likelion-client/src/main/java/likelion/univ/user/usecase/SearchUserByNameUseCase.java +++ /dev/null @@ -1,21 +0,0 @@ -package likelion.univ.user.usecase; - -import likelion.univ.annotation.UseCase; -import likelion.univ.common.response.SliceResponse; -import likelion.univ.domain.user.adaptor.UserAdaptor; -import likelion.univ.domain.user.entity.User; -import likelion.univ.user.dto.response.UserSearchResultDto; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; - -@UseCase -@RequiredArgsConstructor -public class SearchUserByNameUseCase { - private final UserAdaptor userAdaptor; - - public SliceResponse execute(String name, Pageable pageable){ - Slice userSlice = userAdaptor.searchByName(name, pageable); - return SliceResponse.of(userSlice.map(u -> UserSearchResultDto.of(u))); - } -} diff --git a/likelion-client/src/main/java/likelion/univ/utils/AuthenticatedUserUtils.java b/likelion-client/src/main/java/likelion/univ/utils/AuthenticatedUserUtils.java index 826fcd58..d6f182e3 100644 --- a/likelion-client/src/main/java/likelion/univ/utils/AuthenticatedUserUtils.java +++ b/likelion-client/src/main/java/likelion/univ/utils/AuthenticatedUserUtils.java @@ -1,27 +1,30 @@ package likelion.univ.utils; -import likelion.univ.domain.user.adaptor.UserAdaptor; import likelion.univ.domain.user.entity.User; import likelion.univ.domain.user.exception.UserNotMatchException; +import likelion.univ.domain.user.repository.UserRepository; import likelion.univ.security.SecurityUtils; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; +// TODO 이것도 반드시 제거.. @Component @RequiredArgsConstructor public class AuthenticatedUserUtils { - private final UserAdaptor userAdaptor; + + private final UserRepository userRepository; public Long getCurrentUserId() { return SecurityUtils.getCurrentUserId(); } public User getCurrentUser() { - return userAdaptor.findById(getCurrentUserId()); + return userRepository.getById(getCurrentUserId()); } - public void checkidentification(Long userId){ - if(!SecurityUtils.getCurrentUserId().equals(userId)) + public void checkIdentification(Long userId) { + if (!SecurityUtils.getCurrentUserId().equals(userId)) { throw new UserNotMatchException(); + } } -} \ No newline at end of file +} diff --git a/likelion-client/src/test/resources/application.yml b/likelion-client/src/test/resources/application.yml index 7b41e9fd..a4f27424 100644 --- a/likelion-client/src/test/resources/application.yml +++ b/likelion-client/src/test/resources/application.yml @@ -1,12 +1,12 @@ -## 공통 설정 spring: profiles: include: - - common - - core - - infrastructure - - security - - redis + - common-test + - core-test + - infrastructure-test + - security-test + - redis-test + active: test data: web: pageable: ##페이징 diff --git a/likelion-common/src/main/java/likelion/univ/LikelionCommonApplication.java b/likelion-common/src/main/java/likelion/univ/LikelionCommonApplication.java index 736f50da..435d2224 100644 --- a/likelion-common/src/main/java/likelion/univ/LikelionCommonApplication.java +++ b/likelion-common/src/main/java/likelion/univ/LikelionCommonApplication.java @@ -1,4 +1,5 @@ package likelion.univ; + import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.properties.ConfigurationPropertiesScan; diff --git a/likelion-common/src/main/java/likelion/univ/annotation/Adaptor.java b/likelion-common/src/main/java/likelion/univ/annotation/Adaptor.java index 34391a50..22f3b3eb 100644 --- a/likelion-common/src/main/java/likelion/univ/annotation/Adaptor.java +++ b/likelion-common/src/main/java/likelion/univ/annotation/Adaptor.java @@ -1,15 +1,15 @@ package likelion.univ.annotation; -import org.springframework.stereotype.Component; - import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.springframework.stereotype.Component; @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Component public @interface Adaptor { + String value() default ""; } diff --git a/likelion-common/src/main/java/likelion/univ/annotation/Processor.java b/likelion-common/src/main/java/likelion/univ/annotation/Processor.java index db99b153..30194528 100644 --- a/likelion-common/src/main/java/likelion/univ/annotation/Processor.java +++ b/likelion-common/src/main/java/likelion/univ/annotation/Processor.java @@ -1,15 +1,15 @@ package likelion.univ.annotation; -import org.springframework.stereotype.Component; - import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.springframework.stereotype.Component; @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Component public @interface Processor { + String value() default ""; } diff --git a/likelion-common/src/main/java/likelion/univ/annotation/RedisRepository.java b/likelion-common/src/main/java/likelion/univ/annotation/RedisRepository.java index b0ac7d99..9692ed02 100644 --- a/likelion-common/src/main/java/likelion/univ/annotation/RedisRepository.java +++ b/likelion-common/src/main/java/likelion/univ/annotation/RedisRepository.java @@ -1,15 +1,15 @@ package likelion.univ.annotation; -import org.springframework.stereotype.Component; - import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.springframework.stereotype.Component; @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Component public @interface RedisRepository { + String value() default ""; } diff --git a/likelion-common/src/main/java/likelion/univ/annotation/UseCase.java b/likelion-common/src/main/java/likelion/univ/annotation/UseCase.java index ce0f85c8..bd750279 100644 --- a/likelion-common/src/main/java/likelion/univ/annotation/UseCase.java +++ b/likelion-common/src/main/java/likelion/univ/annotation/UseCase.java @@ -1,15 +1,15 @@ package likelion.univ.annotation; -import org.springframework.stereotype.Component; - import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.springframework.stereotype.Component; @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Component public @interface UseCase { + String value() default ""; } diff --git a/likelion-common/src/main/java/likelion/univ/constant/StaticValue.java b/likelion-common/src/main/java/likelion/univ/constant/StaticValue.java index 5f114947..2350305d 100644 --- a/likelion-common/src/main/java/likelion/univ/constant/StaticValue.java +++ b/likelion-common/src/main/java/likelion/univ/constant/StaticValue.java @@ -1,6 +1,7 @@ package likelion.univ.constant; public class StaticValue { + /* 에러 코드 static 값 */ public static final int BAD_REQUEST = 400; public static final int UNAUTHORIZED = 401; diff --git a/likelion-common/src/main/java/likelion/univ/environment/ProfileProcessor.java b/likelion-common/src/main/java/likelion/univ/environment/ProfileProcessor.java index 0d15600b..d3fe4a5b 100644 --- a/likelion-common/src/main/java/likelion/univ/environment/ProfileProcessor.java +++ b/likelion-common/src/main/java/likelion/univ/environment/ProfileProcessor.java @@ -1,27 +1,28 @@ package likelion.univ.environment; +import java.util.Arrays; import likelion.univ.annotation.Processor; import lombok.RequiredArgsConstructor; import org.springframework.core.env.Environment; -import java.lang.reflect.Array; -import java.util.Arrays; - @Processor @RequiredArgsConstructor public class ProfileProcessor { + private final Environment environment; - public Boolean isDev(){ + public Boolean isDev() { String[] activeProfiles = environment.getActiveProfiles(); - return Arrays.stream(activeProfiles).anyMatch(env -> (env.equalsIgnoreCase("dev") )); + return Arrays.stream(activeProfiles).anyMatch(env -> (env.equalsIgnoreCase("dev"))); } - public Boolean isStag(){ + + public Boolean isStag() { String[] activeProfiles = environment.getActiveProfiles(); - return Arrays.stream(activeProfiles).anyMatch(env -> (env.equalsIgnoreCase("stag") )); + return Arrays.stream(activeProfiles).anyMatch(env -> (env.equalsIgnoreCase("stag"))); } - public Boolean isProd(){ + + public Boolean isProd() { String[] activeProfiles = environment.getActiveProfiles(); - return Arrays.stream(activeProfiles).anyMatch(env -> (env.equalsIgnoreCase("prod") )); + return Arrays.stream(activeProfiles).anyMatch(env -> (env.equalsIgnoreCase("prod"))); } } diff --git a/likelion-common/src/main/java/likelion/univ/exception/GlobalErrorCode.java b/likelion-common/src/main/java/likelion/univ/exception/GlobalErrorCode.java index 165d2b24..b60337b1 100644 --- a/likelion-common/src/main/java/likelion/univ/exception/GlobalErrorCode.java +++ b/likelion-common/src/main/java/likelion/univ/exception/GlobalErrorCode.java @@ -1,29 +1,30 @@ package likelion.univ.exception; +import static likelion.univ.constant.StaticValue.BAD_REQUEST; +import static likelion.univ.constant.StaticValue.FORBIDDEN; +import static likelion.univ.constant.StaticValue.INTERNAL_SERVER_ERROR; +import static likelion.univ.constant.StaticValue.METHOD_NOT_ALLOWED; + import likelion.univ.exception.base.BaseErrorCode; import lombok.AllArgsConstructor; import lombok.Getter; - -import static likelion.univ.constant.StaticValue.*; - @Getter @AllArgsConstructor public enum GlobalErrorCode implements BaseErrorCode { - BAD_REQUEST_ERROR(BAD_REQUEST, "GLOBAL_400_1", "잘못된 요청입니다."), - INVALID_HTTP_MESSAGE_BODY(BAD_REQUEST, "GLOBAL_400_2","HTTP 요청 바디의 형식이 잘못되었습니다."), - ACCESS_DENIED_REQUEST(FORBIDDEN,"GLOBAL_403","해당 요청에 접근 권한이 없습니다."), - UNSUPPORTED_HTTP_METHOD(METHOD_NOT_ALLOWED, "GLOBAL_405","지원하지 않는 HTTP 메서드입니다."), - SERVER_ERROR(INTERNAL_SERVER_ERROR,"GLOBAL_500","서버 내부에서 알 수 없는 오류가 발생했습니다."), - PUBKEY_GENERATION_FAILED(BAD_REQUEST,"PUBLIC_KEY_400_1","공개키를 생성하는데 실패했습니다."), + BAD_REQUEST_ERROR(BAD_REQUEST, "GLOBAL_400_1", "잘못된 요청입니다."), + INVALID_HTTP_MESSAGE_BODY(BAD_REQUEST, "GLOBAL_400_2", "HTTP 요청 바디의 형식이 잘못되었습니다."), + ACCESS_DENIED_REQUEST(FORBIDDEN, "GLOBAL_403", "해당 요청에 접근 권한이 없습니다."), + UNSUPPORTED_HTTP_METHOD(METHOD_NOT_ALLOWED, "GLOBAL_405", "지원하지 않는 HTTP 메서드입니다."), + SERVER_ERROR(INTERNAL_SERVER_ERROR, "GLOBAL_500", "서버 내부에서 알 수 없는 오류가 발생했습니다."), + PUBKEY_GENERATION_FAILED(BAD_REQUEST, "PUBLIC_KEY_400_1", "공개키를 생성하는데 실패했습니다."), SORT_TYPE_NOT_MATCHED(BAD_REQUEST, "SORT_400", "해당 조건으로 정렬할 수 없습니다."); - private final int httpStatus; private final String code; private final String message; -} \ No newline at end of file +} diff --git a/likelion-common/src/main/java/likelion/univ/exception/PublicKeyGenerationException.java b/likelion-common/src/main/java/likelion/univ/exception/PublicKeyGenerationException.java index a31385f1..18684363 100644 --- a/likelion-common/src/main/java/likelion/univ/exception/PublicKeyGenerationException.java +++ b/likelion-common/src/main/java/likelion/univ/exception/PublicKeyGenerationException.java @@ -1,11 +1,9 @@ package likelion.univ.exception; -import likelion.univ.exception.base.BaseErrorCode; import likelion.univ.exception.base.BaseException; public class PublicKeyGenerationException extends BaseException { - public PublicKeyGenerationException() { super(GlobalErrorCode.PUBKEY_GENERATION_FAILED); } diff --git a/likelion-common/src/main/java/likelion/univ/exception/SortTypeNotMatchedException.java b/likelion-common/src/main/java/likelion/univ/exception/SortTypeNotMatchedException.java index 45a8ab61..883bd9d6 100644 --- a/likelion-common/src/main/java/likelion/univ/exception/SortTypeNotMatchedException.java +++ b/likelion-common/src/main/java/likelion/univ/exception/SortTypeNotMatchedException.java @@ -3,6 +3,7 @@ import likelion.univ.exception.base.BaseException; public class SortTypeNotMatchedException extends BaseException { + public SortTypeNotMatchedException() { super(GlobalErrorCode.SORT_TYPE_NOT_MATCHED); } diff --git a/likelion-common/src/main/java/likelion/univ/exception/base/BaseErrorCode.java b/likelion-common/src/main/java/likelion/univ/exception/base/BaseErrorCode.java index c978e3ea..34907619 100644 --- a/likelion-common/src/main/java/likelion/univ/exception/base/BaseErrorCode.java +++ b/likelion-common/src/main/java/likelion/univ/exception/base/BaseErrorCode.java @@ -1,6 +1,10 @@ package likelion.univ.exception.base; + public interface BaseErrorCode { - public String getCode(); - public String getMessage(); - public int getHttpStatus(); -} \ No newline at end of file + + String getCode(); + + String getMessage(); + + int getHttpStatus(); +} diff --git a/likelion-common/src/main/java/likelion/univ/exception/base/BaseException.java b/likelion-common/src/main/java/likelion/univ/exception/base/BaseException.java index fd25df00..aaef5ac4 100644 --- a/likelion-common/src/main/java/likelion/univ/exception/base/BaseException.java +++ b/likelion-common/src/main/java/likelion/univ/exception/base/BaseException.java @@ -5,7 +5,8 @@ @Getter @AllArgsConstructor -public class BaseException extends RuntimeException{ +public class BaseException extends RuntimeException { + private final BaseErrorCode errorCode; } diff --git a/likelion-common/src/main/java/likelion/univ/response/BaseResponse.java b/likelion-common/src/main/java/likelion/univ/response/BaseResponse.java index be475d01..2e744eee 100644 --- a/likelion-common/src/main/java/likelion/univ/response/BaseResponse.java +++ b/likelion-common/src/main/java/likelion/univ/response/BaseResponse.java @@ -1,13 +1,12 @@ package likelion.univ.response; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; import likelion.univ.exception.base.BaseErrorCode; import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.ToString; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; - @Getter @ToString @RequiredArgsConstructor @@ -25,9 +24,11 @@ public static BaseResponse of(Boolean isSuccess, BaseErrorCode code) { public static BaseResponse of(Boolean isSuccess, BaseErrorCode errorCode, String message) { return new BaseResponse(isSuccess, errorCode.getCode(), message); } + public static BaseResponse of(Boolean isSuccess, String code, String message) { return new BaseResponse(isSuccess, code, message); } + public static BaseResponse success() { return new BaseResponse(true, "200", "호출에 성공하셨습니다."); } diff --git a/likelion-common/src/main/java/likelion/univ/response/ErrorResponse.java b/likelion-common/src/main/java/likelion/univ/response/ErrorResponse.java index d1508b52..1c967eb7 100644 --- a/likelion-common/src/main/java/likelion/univ/response/ErrorResponse.java +++ b/likelion-common/src/main/java/likelion/univ/response/ErrorResponse.java @@ -1,19 +1,23 @@ package likelion.univ.response; import likelion.univ.exception.base.BaseErrorCode; -import lombok.*; +import lombok.Builder; +import lombok.Getter; +import lombok.ToString; @Getter @ToString public class ErrorResponse extends BaseResponse { + private final int httpStatus; @Builder - public ErrorResponse(String code, String message, int httpStatus){ + public ErrorResponse(String code, String message, int httpStatus) { super(false, code, message); this.httpStatus = httpStatus; } + public static ErrorResponse of(BaseErrorCode errorCode) { return ErrorResponse.builder() .code(errorCode.getCode()) @@ -21,6 +25,7 @@ public static ErrorResponse of(BaseErrorCode errorCode) { .httpStatus(errorCode.getHttpStatus()) .build(); } + public static ErrorResponse of(BaseErrorCode errorCode, String message) { return ErrorResponse.builder() .code(errorCode.getCode()) @@ -36,4 +41,4 @@ public static ErrorResponse of(String code, String message, int httpStatus) { .httpStatus(httpStatus) .build(); } -} \ No newline at end of file +} diff --git a/likelion-common/src/main/java/likelion/univ/response/SuccessResponse.java b/likelion-common/src/main/java/likelion/univ/response/SuccessResponse.java index 27eb5916..5bcf4e5f 100644 --- a/likelion-common/src/main/java/likelion/univ/response/SuccessResponse.java +++ b/likelion-common/src/main/java/likelion/univ/response/SuccessResponse.java @@ -6,6 +6,7 @@ @Getter @ToString public class SuccessResponse extends BaseResponse { + private final T data; public SuccessResponse(T data) { @@ -26,5 +27,7 @@ public static SuccessResponse of(T data, String code) { return new SuccessResponse<>(code, data); } - public static SuccessResponse empty() { return new SuccessResponse<>(null); } + public static SuccessResponse empty() { + return new SuccessResponse<>(null); + } } diff --git a/likelion-common/src/main/java/likelion/univ/utils/PublicKeyGenerator.java b/likelion-common/src/main/java/likelion/univ/utils/PublicKeyGenerator.java index e5749636..e8002e60 100644 --- a/likelion-common/src/main/java/likelion/univ/utils/PublicKeyGenerator.java +++ b/likelion-common/src/main/java/likelion/univ/utils/PublicKeyGenerator.java @@ -1,7 +1,5 @@ package likelion.univ.utils; -import likelion.univ.exception.PublicKeyGenerationException; - import java.math.BigInteger; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; @@ -9,18 +7,20 @@ import java.security.spec.InvalidKeySpecException; import java.security.spec.RSAPublicKeySpec; import java.util.Base64; +import likelion.univ.exception.PublicKeyGenerationException; public class PublicKeyGenerator { - public static RSAPublicKey excute(String kty, String n, String e) { + + public static RSAPublicKey execute(String kty, String n, String e) { BigInteger modulus = new BigInteger(1, Base64.getUrlDecoder().decode(n)); - BigInteger exponent = new BigInteger(1,Base64.getUrlDecoder().decode(e)); + BigInteger exponent = new BigInteger(1, Base64.getUrlDecoder().decode(e)); - try{ + try { KeyFactory keyFactory = KeyFactory.getInstance(kty); RSAPublicKeySpec keySpec = new RSAPublicKeySpec(modulus, exponent); return (RSAPublicKey) keyFactory.generatePublic(keySpec); - } catch (NoSuchAlgorithmException | InvalidKeySpecException exception){ + } catch (NoSuchAlgorithmException | InvalidKeySpecException exception) { throw new PublicKeyGenerationException(); } } diff --git a/likelion-common/src/main/java/likelion/univ/validator/EmailValidator.java b/likelion-common/src/main/java/likelion/univ/validator/EmailValidator.java index 2d5fba7f..617e32e6 100644 --- a/likelion-common/src/main/java/likelion/univ/validator/EmailValidator.java +++ b/likelion-common/src/main/java/likelion/univ/validator/EmailValidator.java @@ -1,8 +1,5 @@ package likelion.univ.validator; -import javax.validation.ConstraintValidator; -import javax.validation.ConstraintValidatorContext; - //public class EmailValidator implements ConstraintValidator { // @Override // boolean isValid(String value, ConstraintValidatorContext context){ diff --git a/likelion-common/src/main/resources/application-common-test.yml b/likelion-common/src/main/resources/application-common-test.yml new file mode 100644 index 00000000..e69de29b diff --git a/likelion-core/src/main/java/likelion/univ/LikelionCoreApplication.java b/likelion-core/src/main/java/likelion/univ/LikelionCoreApplication.java index c0e2a6da..4db2d352 100644 --- a/likelion-core/src/main/java/likelion/univ/LikelionCoreApplication.java +++ b/likelion-core/src/main/java/likelion/univ/LikelionCoreApplication.java @@ -1,6 +1,7 @@ package likelion.univ; import org.springframework.boot.autoconfigure.SpringBootApplication; + @SpringBootApplication public class LikelionCoreApplication { } diff --git a/likelion-core/src/main/java/likelion/univ/common/entity/BaseTimeEntity.java b/likelion-core/src/main/java/likelion/univ/common/entity/BaseTimeEntity.java index 9e6d11c6..e3c697e0 100644 --- a/likelion-core/src/main/java/likelion/univ/common/entity/BaseTimeEntity.java +++ b/likelion-core/src/main/java/likelion/univ/common/entity/BaseTimeEntity.java @@ -1,14 +1,13 @@ package likelion.univ.common.entity; +import java.time.LocalDateTime; +import javax.persistence.EntityListeners; +import javax.persistence.MappedSuperclass; import lombok.Getter; import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; -import javax.persistence.EntityListeners; -import javax.persistence.MappedSuperclass; -import java.time.LocalDateTime; - @Getter @MappedSuperclass @EntityListeners(AuditingEntityListener.class) @@ -19,5 +18,4 @@ public abstract class BaseTimeEntity { @LastModifiedDate private LocalDateTime modifiedDate; - } diff --git a/likelion-core/src/main/java/likelion/univ/common/processor/ConvertSliceProcessor.java b/likelion-core/src/main/java/likelion/univ/common/processor/ConvertSliceProcessor.java index 8e273610..3d96e6ab 100644 --- a/likelion-core/src/main/java/likelion/univ/common/processor/ConvertSliceProcessor.java +++ b/likelion-core/src/main/java/likelion/univ/common/processor/ConvertSliceProcessor.java @@ -1,24 +1,26 @@ package likelion.univ.common.processor; +import java.util.List; import likelion.univ.annotation.Processor; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; import org.springframework.data.domain.SliceImpl; -import java.util.List; - @Processor public class ConvertSliceProcessor { public Slice execute(List contents, Pageable pageable) { - if (hasNext(contents, pageable)) + if (hasNext(contents, pageable)) { return new SliceImpl<>(subContentOne(contents, pageable), pageable, true); - else return new SliceImpl<>(contents, pageable, false); + } else { + return new SliceImpl<>(contents, pageable, false); + } } private Boolean hasNext(List content, Pageable pageable) { return pageable.isPaged() && content.size() > pageable.getPageSize(); } + private List subContentOne(List content, Pageable pageable) { return content.subList(0, pageable.getPageSize()); } diff --git a/likelion-core/src/main/java/likelion/univ/common/processor/DateCustomFormatter.java b/likelion-core/src/main/java/likelion/univ/common/processor/DateCustomFormatter.java index 28860e61..0335626f 100644 --- a/likelion-core/src/main/java/likelion/univ/common/processor/DateCustomFormatter.java +++ b/likelion-core/src/main/java/likelion/univ/common/processor/DateCustomFormatter.java @@ -4,6 +4,7 @@ import java.time.format.DateTimeFormatter; public class DateCustomFormatter { + public static String format(LocalDateTime dateTime, String pattern) { return dateTime.format(DateTimeFormatter.ofPattern(pattern)); } diff --git a/likelion-core/src/main/java/likelion/univ/common/query/BaseQueryDslRepository.java b/likelion-core/src/main/java/likelion/univ/common/query/BaseQueryDslRepository.java index 517bbd01..ab60cd83 100644 --- a/likelion-core/src/main/java/likelion/univ/common/query/BaseQueryDslRepository.java +++ b/likelion-core/src/main/java/likelion/univ/common/query/BaseQueryDslRepository.java @@ -1,46 +1,51 @@ package likelion.univ.common.query; +import static com.querydsl.core.types.Order.ASC; + import com.querydsl.core.types.Order; import com.querydsl.core.types.OrderSpecifier; import com.querydsl.core.types.Path; import com.querydsl.core.types.dsl.EntityPathBase; import com.querydsl.core.types.dsl.Expressions; import com.querydsl.core.types.dsl.PathBuilder; -import org.springframework.data.domain.Sort; - import java.lang.reflect.Field; import java.util.Arrays; import java.util.Map; import java.util.stream.Collectors; - -import static com.querydsl.core.types.Order.ASC; +import org.springframework.data.domain.Sort; public interface BaseQueryDslRepository { + default OrderSpecifier[] getOrdersBySort(EntityPathBase qEntity, Sort sort) { return sort.stream() .map(order -> createOrderSpecifier(qEntity, order)) .collect(Collectors.toList()).toArray(new OrderSpecifier[0]); } - private OrderSpecifier createOrderSpecifier(EntityPathBase qEntity, Sort.Order order){ + + private OrderSpecifier createOrderSpecifier(EntityPathBase qEntity, Sort.Order order) { PathBuilder pathBuilder = new PathBuilder(qEntity.getClass(), qEntity.getMetadata().getName()); Path propertyPath = pathBuilder.get(order.getProperty()); if (isCollectionType(propertyPath)) { // 속성이 컬렉션인 경우, size() 메서드를 사용하여 크기를 얻음 - return new OrderSpecifier<>(toQueryDslOrder(order), Expressions.numberTemplate(Integer.class, "{0}.size()", propertyPath)); + return new OrderSpecifier<>(toQueryDslOrder(order), + Expressions.numberTemplate(Integer.class, "{0}.size()", propertyPath)); } else { // 컬렉션이 아닌 경우 기존의 경로를 사용 return new OrderSpecifier<>(toQueryDslOrder(order), pathBuilder.get(order.getProperty())); } } + private boolean isFieldExists(EntityPathBase qEntity, String fieldName) { Field[] fields = qEntity.getClass().getDeclaredFields(); return Arrays.stream(fields).anyMatch(field -> field.getName().equals(fieldName)); } + private boolean isCollectionType(Path path) { Class type = path.getType(); // 여기에서 컬렉션 또는 맵인지 확인합니다. return Iterable.class.isAssignableFrom(type) || Map.class.isAssignableFrom(type); } + private Order toQueryDslOrder(Sort.Order order) { return order.isAscending() ? ASC : Order.DESC; } diff --git a/likelion-core/src/main/java/likelion/univ/common/response/PageResponse.java b/likelion-core/src/main/java/likelion/univ/common/response/PageResponse.java index 07e35a10..d93a3e25 100644 --- a/likelion-core/src/main/java/likelion/univ/common/response/PageResponse.java +++ b/likelion-core/src/main/java/likelion/univ/common/response/PageResponse.java @@ -1,14 +1,14 @@ package likelion.univ.common.response; +import java.util.List; import lombok.Builder; import lombok.Getter; import org.springframework.data.domain.Page; -import java.util.List; - @Getter @Builder public class PageResponse { + private int totalPage; private Long totalElements; private int pagingSize; @@ -18,17 +18,16 @@ public class PageResponse { private Boolean isEmpty; private List data; - public static PageResponse of(Page page) { return PageResponse.builder() .totalPage(page.getTotalPages()) .totalElements(page.getTotalElements()) .pagingSize(page.getSize()) - .currentPage(page.getNumber()+1) + .currentPage(page.getNumber() + 1) .isFirst(page.isFirst()) .isLast(page.isLast()) .isEmpty(page.isEmpty()) .data(page.getContent()) .build(); } -} \ No newline at end of file +} diff --git a/likelion-core/src/main/java/likelion/univ/common/response/SliceResponse.java b/likelion-core/src/main/java/likelion/univ/common/response/SliceResponse.java index 3869e0b3..d4f68749 100644 --- a/likelion-core/src/main/java/likelion/univ/common/response/SliceResponse.java +++ b/likelion-core/src/main/java/likelion/univ/common/response/SliceResponse.java @@ -1,11 +1,10 @@ package likelion.univ.common.response; +import java.util.List; import lombok.Builder; import lombok.Getter; import org.springframework.data.domain.Slice; -import java.util.List; - @Getter @Builder public class SliceResponse { @@ -17,7 +16,7 @@ public class SliceResponse { public static SliceResponse of(Slice slice) { return SliceResponse.builder() - .currentPage(slice.getNumber()+1) + .currentPage(slice.getNumber() + 1) .size(slice.getNumberOfElements()) .hasNext(slice.hasNext()) .data(slice.getContent()) diff --git a/likelion-core/src/main/java/likelion/univ/config/JpaConfig.java b/likelion-core/src/main/java/likelion/univ/config/JpaConfig.java new file mode 100644 index 00000000..ff5e7593 --- /dev/null +++ b/likelion-core/src/main/java/likelion/univ/config/JpaConfig.java @@ -0,0 +1,9 @@ +package likelion.univ.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.data.jpa.repository.config.EnableJpaAuditing; + +@EnableJpaAuditing +@Configuration +public class JpaConfig { +} diff --git a/likelion-core/src/main/java/likelion/univ/config/QueryDslConfig.java b/likelion-core/src/main/java/likelion/univ/config/QueryDslConfig.java index 3f7d8d3e..b7292a1f 100644 --- a/likelion-core/src/main/java/likelion/univ/config/QueryDslConfig.java +++ b/likelion-core/src/main/java/likelion/univ/config/QueryDslConfig.java @@ -1,13 +1,13 @@ package likelion.univ.config; import com.querydsl.jpa.impl.JPAQueryFactory; +import javax.persistence.EntityManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import javax.persistence.EntityManager; - @Configuration public class QueryDslConfig { + @Bean public JPAQueryFactory jpaQueryFactory(EntityManager entityManager) { return new JPAQueryFactory(entityManager); diff --git a/likelion-core/src/main/java/likelion/univ/domain/alarm/adaptor/AlarmAdaptor.java b/likelion-core/src/main/java/likelion/univ/domain/alarm/adaptor/AlarmAdaptor.java deleted file mode 100644 index ad04eea7..00000000 --- a/likelion-core/src/main/java/likelion/univ/domain/alarm/adaptor/AlarmAdaptor.java +++ /dev/null @@ -1,20 +0,0 @@ -package likelion.univ.domain.alarm.adaptor; - -import likelion.univ.annotation.Adaptor; -import likelion.univ.domain.alarm.entity.Alarm; -import likelion.univ.domain.alarm.exception.EmailAlreadyRegisteredAsAlarmException; -import likelion.univ.domain.alarm.repository.AlarmRepository; -import lombok.RequiredArgsConstructor; - -@Adaptor -@RequiredArgsConstructor -public class AlarmAdaptor { - private final AlarmRepository alarmRepository; - - public Alarm save(Alarm alarm){ return alarmRepository.save(alarm);} - - public void existsByOrdinalAndEmailAndAlarmType(Long ordinal, String email) { - if (alarmRepository.existsByOrdinalAndEmail(ordinal, email)) - throw new EmailAlreadyRegisteredAsAlarmException(); - } -} diff --git a/likelion-core/src/main/java/likelion/univ/domain/alarm/entity/Alarm.java b/likelion-core/src/main/java/likelion/univ/domain/alarm/entity/Alarm.java index 6616d806..ce8cf3c6 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/alarm/entity/Alarm.java +++ b/likelion-core/src/main/java/likelion/univ/domain/alarm/entity/Alarm.java @@ -1,10 +1,17 @@ package likelion.univ.domain.alarm.entity; -import likelion.univ.common.entity.BaseTimeEntity; -import lombok.*; - -import javax.persistence.*; -import static likelion.univ.domain.alarm.entity.SendStatus.NOT_SENT; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import likelion.univ.common.entity.BaseTimeEntity; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -12,10 +19,10 @@ @AllArgsConstructor @Entity public class Alarm extends BaseTimeEntity { + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - private Long ordinal; private String email; diff --git a/likelion-core/src/main/java/likelion/univ/domain/alarm/entity/SendStatus.java b/likelion-core/src/main/java/likelion/univ/domain/alarm/entity/SendStatus.java index 889b5e8c..58ea8598 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/alarm/entity/SendStatus.java +++ b/likelion-core/src/main/java/likelion/univ/domain/alarm/entity/SendStatus.java @@ -6,6 +6,7 @@ @Getter @AllArgsConstructor public enum SendStatus { + NOT_SENT("NOT_SENT"), RESERVED("RESERVED"), SENT("SENT"); diff --git a/likelion-core/src/main/java/likelion/univ/domain/alarm/exception/AlarmErrorCode.java b/likelion-core/src/main/java/likelion/univ/domain/alarm/exception/AlarmErrorCode.java index beaabada..725fed94 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/alarm/exception/AlarmErrorCode.java +++ b/likelion-core/src/main/java/likelion/univ/domain/alarm/exception/AlarmErrorCode.java @@ -1,16 +1,16 @@ package likelion.univ.domain.alarm.exception; +import static likelion.univ.constant.StaticValue.BAD_REQUEST; + import likelion.univ.exception.base.BaseErrorCode; import lombok.AllArgsConstructor; import lombok.Getter; -import static likelion.univ.constant.StaticValue.*; - @Getter @AllArgsConstructor public enum AlarmErrorCode implements BaseErrorCode { - EMAIL_ALREADY_REGISTERED_AS_ALARM(BAD_REQUEST, "ALARM_409", "해당 이메일은 이미 신청되어 있습니다."); + EMAIL_ALREADY_REGISTERED_AS_ALARM(BAD_REQUEST, "ALARM_409", "해당 이메일은 이미 신청되어 있습니다."); private final int httpStatus; private final String code; diff --git a/likelion-core/src/main/java/likelion/univ/domain/alarm/exception/EmailAlreadyRegisteredAsAlarmException.java b/likelion-core/src/main/java/likelion/univ/domain/alarm/exception/EmailAlreadyRegisteredAsAlarmException.java index 5478c7a1..b76ae157 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/alarm/exception/EmailAlreadyRegisteredAsAlarmException.java +++ b/likelion-core/src/main/java/likelion/univ/domain/alarm/exception/EmailAlreadyRegisteredAsAlarmException.java @@ -3,6 +3,7 @@ import likelion.univ.exception.base.BaseException; public class EmailAlreadyRegisteredAsAlarmException extends BaseException { + public EmailAlreadyRegisteredAsAlarmException() { super(AlarmErrorCode.EMAIL_ALREADY_REGISTERED_AS_ALARM); } diff --git a/likelion-core/src/main/java/likelion/univ/domain/alarm/repository/AlarmRepository.java b/likelion-core/src/main/java/likelion/univ/domain/alarm/repository/AlarmRepository.java index 8d431fe3..c6a33d57 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/alarm/repository/AlarmRepository.java +++ b/likelion-core/src/main/java/likelion/univ/domain/alarm/repository/AlarmRepository.java @@ -1,11 +1,12 @@ package likelion.univ.domain.alarm.repository; +import java.util.List; import likelion.univ.domain.alarm.entity.Alarm; import org.springframework.data.jpa.repository.JpaRepository; -import java.util.List; - public interface AlarmRepository extends JpaRepository { + boolean existsByOrdinalAndEmail(Long ordinal, String email); + List findAllByOrdinal(Long ordinal); } diff --git a/likelion-core/src/main/java/likelion/univ/domain/alarm/service/AlarmDomainService.java b/likelion-core/src/main/java/likelion/univ/domain/alarm/service/AlarmService.java similarity index 75% rename from likelion-core/src/main/java/likelion/univ/domain/alarm/service/AlarmDomainService.java rename to likelion-core/src/main/java/likelion/univ/domain/alarm/service/AlarmService.java index ea036772..de44e567 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/alarm/service/AlarmDomainService.java +++ b/likelion-core/src/main/java/likelion/univ/domain/alarm/service/AlarmService.java @@ -1,24 +1,22 @@ package likelion.univ.domain.alarm.service; -import likelion.univ.domain.alarm.adaptor.AlarmAdaptor; +import java.util.List; import likelion.univ.domain.alarm.entity.Alarm; import likelion.univ.domain.alarm.repository.AlarmRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.List; - @Service @Transactional(readOnly = true) @RequiredArgsConstructor -public class AlarmDomainService { - private final AlarmAdaptor alarmAdaptor; +public class AlarmService { + private final AlarmRepository alarmRepository; @Transactional - public Alarm createAlarm(Alarm alarm){ - return alarmAdaptor.save(alarm); + public Alarm createAlarm(Alarm alarm) { + return alarmRepository.save(alarm); } public List findAllByOrdinal(Long ordinal) { diff --git a/likelion-core/src/main/java/likelion/univ/domain/comment/adaptor/CommentAdaptor.java b/likelion-core/src/main/java/likelion/univ/domain/comment/adaptor/CommentAdaptor.java deleted file mode 100644 index 12b11d22..00000000 --- a/likelion-core/src/main/java/likelion/univ/domain/comment/adaptor/CommentAdaptor.java +++ /dev/null @@ -1,51 +0,0 @@ -package likelion.univ.domain.comment.adaptor; - -import likelion.univ.annotation.Adaptor; -import likelion.univ.domain.comment.dto.response.ChildCommentData; -import likelion.univ.domain.comment.dto.response.ParentCommentData; -import likelion.univ.domain.comment.entity.Comment; -import likelion.univ.domain.comment.exception.CommentNotFoundException; -import likelion.univ.domain.comment.repository.CommentRepository; -import likelion.univ.domain.user.repository.UserRepository; -import lombok.RequiredArgsConstructor; - -import java.util.List; - - -@Adaptor -@RequiredArgsConstructor -public class CommentAdaptor { - private final CommentRepository commentRepository; - private final UserRepository userRepository; - - public Long save(Comment comment) { - return commentRepository.save(comment).getId(); - } - - public Comment findById(Long id) { - return commentRepository.findById(id) - .orElseThrow(CommentNotFoundException::new); - } - public void delete(Comment comment) { - commentRepository.delete(comment); - } - - public List findParentCommentsByPostId(Long postId) { - return commentRepository.findParentCommentsByPostId(postId); - } - - public List findChildCommentsByPostId(Long postId) { - return commentRepository.findChildCommentsByPostId(postId); - } - - public Long countByPostId(Long postId){ - return commentRepository.countByPostId(postId); - } - - public Long countByPostIdAndIsDeletedEquals(Long postId, Boolean isDeleted) { - return commentRepository.countByPostIdAndIsDeletedEquals(postId, isDeleted); - } - public Comment findByPostId(Long postId) { - return commentRepository.findByPostId(postId); - } -} diff --git a/likelion-core/src/main/java/likelion/univ/domain/comment/dto/request/CreateChildCommentCommand.java b/likelion-core/src/main/java/likelion/univ/domain/comment/dto/request/CreateChildCommentCommand.java index f5009332..ac78eb07 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/comment/dto/request/CreateChildCommentCommand.java +++ b/likelion-core/src/main/java/likelion/univ/domain/comment/dto/request/CreateChildCommentCommand.java @@ -8,8 +8,8 @@ @Builder @AllArgsConstructor public class CreateChildCommentCommand { + private Long parentCommentId; -// private Long postId; private Long loginUserId; private String body; } diff --git a/likelion-core/src/main/java/likelion/univ/domain/comment/dto/request/CreateParentCommentCommand.java b/likelion-core/src/main/java/likelion/univ/domain/comment/dto/request/CreateParentCommentCommand.java index 2d989eaf..595114db 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/comment/dto/request/CreateParentCommentCommand.java +++ b/likelion-core/src/main/java/likelion/univ/domain/comment/dto/request/CreateParentCommentCommand.java @@ -1,8 +1,6 @@ package likelion.univ.domain.comment.dto.request; -import lombok.AllArgsConstructor; import lombok.Builder; -import lombok.Data; @Builder public record CreateParentCommentCommand( diff --git a/likelion-core/src/main/java/likelion/univ/domain/comment/dto/request/DeleteCommentCommand.java b/likelion-core/src/main/java/likelion/univ/domain/comment/dto/request/DeleteCommentCommand.java index 9582ccda..0349f223 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/comment/dto/request/DeleteCommentCommand.java +++ b/likelion-core/src/main/java/likelion/univ/domain/comment/dto/request/DeleteCommentCommand.java @@ -1,14 +1,13 @@ package likelion.univ.domain.comment.dto.request; -import lombok.AllArgsConstructor; import lombok.Builder; -import lombok.Data; @Builder public record DeleteCommentCommand( - Long commentId, - Long loginUserId + Long commentId, + Long loginUserId ) { + public static DeleteCommentCommand of(Long commentId, Long loginUserId) { return new DeleteCommentCommand(commentId, loginUserId); } diff --git a/likelion-core/src/main/java/likelion/univ/domain/comment/dto/request/UpdateCommentCommand.java b/likelion-core/src/main/java/likelion/univ/domain/comment/dto/request/UpdateCommentCommand.java index 1e589b03..bff01041 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/comment/dto/request/UpdateCommentCommand.java +++ b/likelion-core/src/main/java/likelion/univ/domain/comment/dto/request/UpdateCommentCommand.java @@ -8,6 +8,7 @@ @Builder @AllArgsConstructor public class UpdateCommentCommand { + private Long commentId; private Long loginUserId; private String body; diff --git a/likelion-core/src/main/java/likelion/univ/domain/comment/dto/response/ChildCommentData.java b/likelion-core/src/main/java/likelion/univ/domain/comment/dto/response/ChildCommentData.java index d41d5273..54e88858 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/comment/dto/response/ChildCommentData.java +++ b/likelion-core/src/main/java/likelion/univ/domain/comment/dto/response/ChildCommentData.java @@ -1,12 +1,11 @@ package likelion.univ.domain.comment.dto.response; import com.querydsl.core.annotations.QueryProjection; +import java.time.LocalDateTime; import likelion.univ.common.processor.DateCustomFormatter; import likelion.univ.domain.comment.entity.Comment; import lombok.Builder; -import java.time.LocalDateTime; - public record ChildCommentData( Long commentId, Long parentId, @@ -19,10 +18,11 @@ public record ChildCommentData( Boolean isDeleted, LocalDateTime createdDate ) { + @Builder @QueryProjection - public ChildCommentData {} - + public ChildCommentData { + } public static ChildCommentData of(Comment comment, Boolean isLikedByLoginUser) { return ChildCommentData.builder() @@ -46,5 +46,4 @@ private static Integer getLikeCount(Comment comment) { public String getFormattedDate() { return DateCustomFormatter.format(this.createdDate); } - } diff --git a/likelion-core/src/main/java/likelion/univ/domain/comment/dto/response/ChildCommentWithLikeData.java b/likelion-core/src/main/java/likelion/univ/domain/comment/dto/response/ChildCommentWithLikeData.java index a39eab2c..fd007146 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/comment/dto/response/ChildCommentWithLikeData.java +++ b/likelion-core/src/main/java/likelion/univ/domain/comment/dto/response/ChildCommentWithLikeData.java @@ -1,10 +1,9 @@ package likelion.univ.domain.comment.dto.response; +import java.time.LocalDateTime; import likelion.univ.domain.comment.entity.Comment; import lombok.Builder; -import java.time.LocalDateTime; - @Builder public record ChildCommentWithLikeData( Long commentId, @@ -18,6 +17,7 @@ public record ChildCommentWithLikeData( Boolean isDeleted, LocalDateTime createdDate ) { + public static ChildCommentWithLikeData of(Comment comment, Boolean isLikedByLoginUser) { return ChildCommentWithLikeData.builder() .commentId(comment.getId()) @@ -36,6 +36,5 @@ public static ChildCommentWithLikeData of(Comment comment, Boolean isLikedByLogi private static Integer getLikeCount(Comment comment) { return Math.toIntExact(comment.getCommentLikes().size()); } - } diff --git a/likelion-core/src/main/java/likelion/univ/domain/comment/dto/response/CommentData.java b/likelion-core/src/main/java/likelion/univ/domain/comment/dto/response/CommentData.java index 6e37ebb9..ba731578 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/comment/dto/response/CommentData.java +++ b/likelion-core/src/main/java/likelion/univ/domain/comment/dto/response/CommentData.java @@ -1,13 +1,12 @@ package likelion.univ.domain.comment.dto.response; +import java.util.List; import lombok.Builder; -import java.time.LocalDateTime; -import java.util.List; @Builder public record CommentData( - Long postAuthorId, - List parentComments, - List childComments + Long postAuthorId, + List parentComments, + List childComments ) { } diff --git a/likelion-core/src/main/java/likelion/univ/domain/comment/dto/response/ParentCommentData.java b/likelion-core/src/main/java/likelion/univ/domain/comment/dto/response/ParentCommentData.java index f9cd938f..bfd610fa 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/comment/dto/response/ParentCommentData.java +++ b/likelion-core/src/main/java/likelion/univ/domain/comment/dto/response/ParentCommentData.java @@ -1,13 +1,11 @@ package likelion.univ.domain.comment.dto.response; import com.querydsl.core.annotations.QueryProjection; +import java.time.LocalDateTime; import likelion.univ.common.processor.DateCustomFormatter; import likelion.univ.domain.comment.entity.Comment; import lombok.Builder; - -import java.time.LocalDateTime; - public record ParentCommentData( Long commentId, Long userId, @@ -19,9 +17,11 @@ public record ParentCommentData( Boolean isDeleted, LocalDateTime createdDate ) { + @Builder @QueryProjection - public ParentCommentData {} + public ParentCommentData { + } public static ParentCommentData of(Comment parentComment, Boolean isLikedByLoginUser) { return ParentCommentData.builder() @@ -44,5 +44,4 @@ private static Integer getLikeCount(Comment comment) { public String getFormattedDate() { return DateCustomFormatter.format(this.createdDate); } - } diff --git a/likelion-core/src/main/java/likelion/univ/domain/comment/dto/response/ParentCommentWithLikeData.java b/likelion-core/src/main/java/likelion/univ/domain/comment/dto/response/ParentCommentWithLikeData.java index 9fbfa4e3..8d06ba1f 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/comment/dto/response/ParentCommentWithLikeData.java +++ b/likelion-core/src/main/java/likelion/univ/domain/comment/dto/response/ParentCommentWithLikeData.java @@ -1,10 +1,9 @@ package likelion.univ.domain.comment.dto.response; +import java.time.LocalDateTime; import likelion.univ.domain.comment.entity.Comment; import lombok.Builder; -import java.time.LocalDateTime; - @Builder public record ParentCommentWithLikeData( Long commentId, @@ -17,6 +16,7 @@ public record ParentCommentWithLikeData( Boolean isDeleted, LocalDateTime createdDate ) { + public static ParentCommentWithLikeData of(Comment parentComment, Boolean isLikedByLoginUser) { return ParentCommentWithLikeData.builder() .commentId(parentComment.getId()) diff --git a/likelion-core/src/main/java/likelion/univ/domain/comment/dto/response/SimpleCommentData.java b/likelion-core/src/main/java/likelion/univ/domain/comment/dto/response/SimpleCommentData.java index 60cc0bcb..92def534 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/comment/dto/response/SimpleCommentData.java +++ b/likelion-core/src/main/java/likelion/univ/domain/comment/dto/response/SimpleCommentData.java @@ -8,6 +8,7 @@ @Builder @AllArgsConstructor public class SimpleCommentData { + private Long commentId; private Long postId; diff --git a/likelion-core/src/main/java/likelion/univ/domain/comment/entity/Comment.java b/likelion-core/src/main/java/likelion/univ/domain/comment/entity/Comment.java index 2845a3d9..6b41819d 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/comment/entity/Comment.java +++ b/likelion-core/src/main/java/likelion/univ/domain/comment/entity/Comment.java @@ -1,5 +1,18 @@ package likelion.univ.domain.comment.entity; +import java.util.ArrayList; +import java.util.List; +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; import likelion.univ.common.entity.BaseTimeEntity; import likelion.univ.domain.like.commentlike.entity.CommentLike; import likelion.univ.domain.post.entity.Post; @@ -9,15 +22,12 @@ import lombok.Getter; import lombok.NoArgsConstructor; -import javax.persistence.*; -import java.util.ArrayList; -import java.util.List; - @Getter @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @Table(name = "comment") public class Comment extends BaseTimeEntity { + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @@ -62,6 +72,7 @@ public Long updateBody(String body) { this.body = body; return this.id; } + public Boolean softDelete() { if (this.getIsDeleted()) { return false; diff --git a/likelion-core/src/main/java/likelion/univ/domain/comment/exception/CommentAlreadyDeletedException.java b/likelion-core/src/main/java/likelion/univ/domain/comment/exception/CommentAlreadyDeletedException.java index c444d8bd..4f8207e6 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/comment/exception/CommentAlreadyDeletedException.java +++ b/likelion-core/src/main/java/likelion/univ/domain/comment/exception/CommentAlreadyDeletedException.java @@ -3,6 +3,7 @@ import likelion.univ.exception.base.BaseException; public class CommentAlreadyDeletedException extends BaseException { + public CommentAlreadyDeletedException() { super(CommentErrorCode.COMMENT_ALREADY_DELETED); } diff --git a/likelion-core/src/main/java/likelion/univ/domain/comment/exception/CommentErrorCode.java b/likelion-core/src/main/java/likelion/univ/domain/comment/exception/CommentErrorCode.java index 198a8c9d..d6c3e5ac 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/comment/exception/CommentErrorCode.java +++ b/likelion-core/src/main/java/likelion/univ/domain/comment/exception/CommentErrorCode.java @@ -1,14 +1,16 @@ package likelion.univ.domain.comment.exception; +import static likelion.univ.constant.StaticValue.BAD_REQUEST; +import static likelion.univ.constant.StaticValue.NOT_FOUND; + import likelion.univ.exception.base.BaseErrorCode; import lombok.Getter; import lombok.RequiredArgsConstructor; -import static likelion.univ.constant.StaticValue.BAD_REQUEST; -import static likelion.univ.constant.StaticValue.NOT_FOUND; @Getter @RequiredArgsConstructor public enum CommentErrorCode implements BaseErrorCode { + CREATE_COMMENT_BAD_REQUEST(BAD_REQUEST, "COMMENT_400", "댓글을 생성하는 데 잘못된 요청을 하였습니다."), AUTHOR_NOT_DETECTED(BAD_REQUEST, "COMMENT_400", "작성자가 아닙니다."), COMMENT_NOT_FOUND(NOT_FOUND, "COMMENT_404", "댓글이 존재하지 않습니다."), diff --git a/likelion-core/src/main/java/likelion/univ/domain/comment/exception/CommentNotFoundException.java b/likelion-core/src/main/java/likelion/univ/domain/comment/exception/CommentNotFoundException.java index 13fcace6..2f756cac 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/comment/exception/CommentNotFoundException.java +++ b/likelion-core/src/main/java/likelion/univ/domain/comment/exception/CommentNotFoundException.java @@ -3,6 +3,7 @@ import likelion.univ.exception.base.BaseException; public class CommentNotFoundException extends BaseException { + public CommentNotFoundException() { super(CommentErrorCode.COMMENT_NOT_FOUND); } diff --git a/likelion-core/src/main/java/likelion/univ/domain/comment/exception/CreateCommentBadRequestException.java b/likelion-core/src/main/java/likelion/univ/domain/comment/exception/CreateCommentBadRequestException.java index 9da61014..5330b106 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/comment/exception/CreateCommentBadRequestException.java +++ b/likelion-core/src/main/java/likelion/univ/domain/comment/exception/CreateCommentBadRequestException.java @@ -3,6 +3,8 @@ import likelion.univ.exception.base.BaseException; public class CreateCommentBadRequestException extends BaseException { + public CreateCommentBadRequestException() { - super(CommentErrorCode.CREATE_COMMENT_BAD_REQUEST);} + super(CommentErrorCode.CREATE_COMMENT_BAD_REQUEST); + } } diff --git a/likelion-core/src/main/java/likelion/univ/domain/comment/exception/NotAuthorizedException.java b/likelion-core/src/main/java/likelion/univ/domain/comment/exception/NotAuthorizedException.java index 86bd2c96..33c5ee4c 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/comment/exception/NotAuthorizedException.java +++ b/likelion-core/src/main/java/likelion/univ/domain/comment/exception/NotAuthorizedException.java @@ -3,6 +3,7 @@ import likelion.univ.exception.base.BaseException; public class NotAuthorizedException extends BaseException { + public NotAuthorizedException() { super(CommentErrorCode.AUTHOR_NOT_DETECTED); } diff --git a/likelion-core/src/main/java/likelion/univ/domain/comment/repository/CommentRepository.java b/likelion-core/src/main/java/likelion/univ/domain/comment/repository/CommentRepository.java index 3675e430..69aba324 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/comment/repository/CommentRepository.java +++ b/likelion-core/src/main/java/likelion/univ/domain/comment/repository/CommentRepository.java @@ -1,10 +1,14 @@ package likelion.univ.domain.comment.repository; import likelion.univ.domain.comment.entity.Comment; +import likelion.univ.domain.comment.exception.CommentNotFoundException; import org.springframework.data.jpa.repository.JpaRepository; public interface CommentRepository extends JpaRepository, CommentRepositoryCustom { - Long countByPostId(Long postId); - Comment findByPostId(Long postId); + default Comment getById(Long id) { + return findById(id).orElseThrow(CommentNotFoundException::new); + } + + Long countByPostId(Long postId); } diff --git a/likelion-core/src/main/java/likelion/univ/domain/comment/repository/CommentRepositoryCustom.java b/likelion-core/src/main/java/likelion/univ/domain/comment/repository/CommentRepositoryCustom.java index 8586a187..6cc3b7dc 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/comment/repository/CommentRepositoryCustom.java +++ b/likelion-core/src/main/java/likelion/univ/domain/comment/repository/CommentRepositoryCustom.java @@ -1,16 +1,13 @@ package likelion.univ.domain.comment.repository; -import likelion.univ.domain.comment.dto.response.ChildCommentData; -import likelion.univ.domain.comment.dto.response.ParentCommentData; -import likelion.univ.domain.comment.entity.Comment; - import java.util.List; +import likelion.univ.domain.comment.entity.Comment; public interface CommentRepositoryCustom { -// List findParentCommentsByPostId(Long postId); -// List findChildCommentsByPostId(Long postId); + List findParentCommentsByPostId(Long postId); + List findChildCommentsByPostId(Long postId); - Long countByPostIdAndIsDeletedEquals(Long postId, Boolean isDeleted); + Long countByPostIdAndIsDeletedEquals(Long postId, Boolean isDeleted); } diff --git a/likelion-core/src/main/java/likelion/univ/domain/comment/repository/impl/CommentRepositoryCustomImpl.java b/likelion-core/src/main/java/likelion/univ/domain/comment/repository/impl/CommentRepositoryCustomImpl.java index 99ceee39..ea0cb800 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/comment/repository/impl/CommentRepositoryCustomImpl.java +++ b/likelion-core/src/main/java/likelion/univ/domain/comment/repository/impl/CommentRepositoryCustomImpl.java @@ -1,106 +1,73 @@ package likelion.univ.domain.comment.repository.impl; +import static likelion.univ.domain.comment.entity.QComment.comment; +import static likelion.univ.domain.like.commentlike.entity.QCommentLike.commentLike; +import static likelion.univ.domain.post.entity.QPost.post; +import static likelion.univ.domain.user.entity.QUser.user; + import com.querydsl.jpa.impl.JPAQueryFactory; -import likelion.univ.domain.comment.dto.response.ChildCommentData; -import likelion.univ.domain.comment.dto.response.ParentCommentData; -import likelion.univ.domain.comment.dto.response.QChildCommentData; -import likelion.univ.domain.comment.dto.response.QParentCommentData; +import java.util.List; import likelion.univ.domain.comment.entity.Comment; import likelion.univ.domain.comment.repository.CommentRepositoryCustom; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Repository; -import java.util.List; - -import static likelion.univ.domain.comment.entity.QComment.comment; -import static likelion.univ.domain.like.commentlike.entity.QCommentLike.commentLike; -import static likelion.univ.domain.post.entity.QPost.post; -import static likelion.univ.domain.user.entity.QUser.user; - @Repository @RequiredArgsConstructor public class CommentRepositoryCustomImpl implements CommentRepositoryCustom { - private final JPAQueryFactory queryFactory; - - @Override - public List findChildCommentsByPostId(Long postId) { - List parentCommentsIds = getParentCommentsIds(postId); - return queryFactory -// .select(childCommentData()) - .select(comment) - .from(comment) - .where(comment.parentComment.id.in(parentCommentsIds)) - .join(comment.author, user) - .leftJoin(comment.commentLikes, commentLike) - .distinct() - .fetch(); - } + private final JPAQueryFactory queryFactory; - @Override - public Long countByPostIdAndIsDeletedEquals(Long postId, Boolean isDeleted) { - Long commentCount = queryFactory - .select(comment.id.count()) - .from(comment) - .join(comment.post, post) - .on(comment.post.id.eq(postId)) - .where(comment.isDeleted.eq(isDeleted)) - .fetchFirst(); - return commentCount; - } + @Override + public List findChildCommentsByPostId(Long postId) { + List parentCommentsIds = getParentCommentsIds(postId); - @Override - public List findParentCommentsByPostId(Long postId) { - List parentCommentsIds = getParentCommentsIds(postId); + return queryFactory + .select(comment) + .from(comment) + .where(comment.parentComment.id.in(parentCommentsIds)) + .join(comment.author, user) + .leftJoin(comment.commentLikes, commentLike) + .distinct() + .fetch(); + } - return queryFactory -// .select(parentCommentData()) - .select(comment) - .from(comment) - .where(comment.id.in(parentCommentsIds)) - .join(comment.author, user) - .leftJoin(comment.commentLikes, commentLike) - .orderBy(comment.createdDate.asc()) - .distinct() - .fetch(); - } + @Override + public Long countByPostIdAndIsDeletedEquals(Long postId, Boolean isDeleted) { + Long commentCount = queryFactory + .select(comment.id.count()) + .from(comment) + .join(comment.post, post) + .on(comment.post.id.eq(postId)) + .where(comment.isDeleted.eq(isDeleted)) + .fetchFirst(); + return commentCount; + } - private List getParentCommentsIds(Long postId) { - return queryFactory - .select(comment.id) - .from(comment) - .where(comment.post.id.eq(postId)) - .where(comment.parentComment.isNull()) - .fetch(); - } + @Override + public List findParentCommentsByPostId(Long postId) { + List parentCommentsIds = getParentCommentsIds(postId); -// private static QParentCommentData parentCommentData() { -// return new QParentCommentData( -// comment.id, -// comment.author.id, -// comment.author.profile.name, -// comment.author.profile.profileImage, -// comment.commentLikes.size(), -// comment.body, -// comment.isDeleted, -// comment.createdDate -// ); -// } -// -// private static QChildCommentData childCommentData() { -// return new QChildCommentData( -// comment.id, -// comment.parentComment.id, -// comment.author.id, -// comment.author.profile.name, -// comment.author.profile.profileImage, -// comment.commentLikes.size(), -// comment.body, -// comment.isDeleted, -// comment.createdDate -// ); -// } + return queryFactory +// .select(parentCommentData()) + .select(comment) + .from(comment) + .where(comment.id.in(parentCommentsIds)) + .join(comment.author, user) + .leftJoin(comment.commentLikes, commentLike) + .orderBy(comment.createdDate.asc()) + .distinct() + .fetch(); + } + private List getParentCommentsIds(Long postId) { + return queryFactory + .select(comment.id) + .from(comment) + .where(comment.post.id.eq(postId)) + .where(comment.parentComment.isNull()) + .fetch(); + } } diff --git a/likelion-core/src/main/java/likelion/univ/domain/comment/service/CommentDomainService.java b/likelion-core/src/main/java/likelion/univ/domain/comment/service/CommentService.java similarity index 55% rename from likelion-core/src/main/java/likelion/univ/domain/comment/service/CommentDomainService.java rename to likelion-core/src/main/java/likelion/univ/domain/comment/service/CommentService.java index c18cbb0a..34a50cd3 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/comment/service/CommentDomainService.java +++ b/likelion-core/src/main/java/likelion/univ/domain/comment/service/CommentService.java @@ -1,62 +1,70 @@ package likelion.univ.domain.comment.service; -import likelion.univ.domain.comment.adaptor.CommentAdaptor; -import likelion.univ.domain.comment.dto.request.*; -import likelion.univ.domain.comment.dto.response.*; +import java.util.List; +import likelion.univ.domain.comment.dto.request.CreateChildCommentCommand; +import likelion.univ.domain.comment.dto.request.CreateParentCommentCommand; +import likelion.univ.domain.comment.dto.request.DeleteCommentCommand; +import likelion.univ.domain.comment.dto.request.GetCommentCommand; +import likelion.univ.domain.comment.dto.request.UpdateCommentCommand; +import likelion.univ.domain.comment.dto.response.ChildCommentData; +import likelion.univ.domain.comment.dto.response.CommentData; +import likelion.univ.domain.comment.dto.response.DeleteCommentData; +import likelion.univ.domain.comment.dto.response.ParentCommentData; import likelion.univ.domain.comment.entity.Comment; import likelion.univ.domain.comment.exception.NotAuthorizedException; -import likelion.univ.domain.like.commentlike.adaptor.CommentLikeAdaptor; -import likelion.univ.domain.post.adaptor.PostAdaptor; +import likelion.univ.domain.comment.repository.CommentRepository; +import likelion.univ.domain.like.commentlike.repository.CommentLikeRepository; import likelion.univ.domain.post.entity.Post; -import likelion.univ.domain.user.adaptor.UserAdaptor; +import likelion.univ.domain.post.repository.PostRepository; +import likelion.univ.domain.user.repository.UserRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.List; - @Service @Transactional @RequiredArgsConstructor -public class CommentDomainService { - private final CommentAdaptor commentAdaptor; - private final PostAdaptor postAdaptor; - private final UserAdaptor userAdaptor; - private final CommentLikeAdaptor commentLikeAdaptor; +public class CommentService { + + private final CommentRepository commentRepository; + private final PostRepository postRepository; + private final UserRepository userRepository; + private final CommentLikeRepository commentLikeRepository; public CommentData getComment(GetCommentCommand command) { Long postId = command.postId(); Long loginUserId = command.loginUserId(); - Long authorId = postAdaptor.findById(postId).getAuthor().getId(); + Long authorId = postRepository.getById(postId).getAuthor().getId(); // comment entity data - List parentComments = commentAdaptor.findParentCommentsByPostId(postId); - List childComments = commentAdaptor.findChildCommentsByPostId(postId); + List parentComments = commentRepository.findParentCommentsByPostId(postId); + List childComments = commentRepository.findChildCommentsByPostId(postId); - List parentCommentData = parentComments.stream().map(i -> ParentCommentData.of(i, commentLikeAdaptor.existsByCommentIdAndUserId(i.getId(), loginUserId))).toList(); - List childCommentData = childComments.stream().map(i -> ChildCommentData.of(i, commentLikeAdaptor.existsByCommentIdAndUserId(i.getId(), loginUserId))).toList(); + List parentCommentData = parentComments.stream().map(i -> ParentCommentData.of(i, + commentLikeRepository.existsByCommentIdAndUserId(i.getId(), loginUserId))).toList(); + List childCommentData = childComments.stream() + .map(i -> ChildCommentData.of(i, + commentLikeRepository.existsByCommentIdAndUserId(i.getId(), loginUserId))) + .toList(); return new CommentData(authorId, parentCommentData, childCommentData); } - public void createParentComment(CreateParentCommentCommand request) { Comment parentComment = parentCommentBy(request); - commentAdaptor.save(parentComment); + commentRepository.save(parentComment); } - public Long createChildComment(CreateChildCommentCommand request) { Comment childComment = childCommentBy(request); Long postId = childComment.getPost().getId(); - commentAdaptor.save(childComment); + commentRepository.save(childComment); return postId; } - public Long updateCommentBody(UpdateCommentCommand request) { if (isAuthorized(request)) { - Comment findComment = commentAdaptor.findById(request.getCommentId()); + Comment findComment = commentRepository.getById(request.getCommentId()); Long updatedCommentId = findComment.updateBody(request.getBody()); return updatedCommentId; } @@ -65,7 +73,7 @@ public Long updateCommentBody(UpdateCommentCommand request) { public DeleteCommentData deleteCommentSoft(DeleteCommentCommand request) { if (isAuthorized(request)) { - Comment findComment = commentAdaptor.findById(request.commentId()); + Comment findComment = commentRepository.getById(request.commentId()); Boolean isDeleted = findComment.softDelete(); Long postId = findComment.getPost().getId(); return new DeleteCommentData(isDeleted, postId); @@ -74,33 +82,33 @@ public DeleteCommentData deleteCommentSoft(DeleteCommentCommand request) { } public void deleteCommentHard(DeleteCommentCommand request) { - Comment findComment = commentAdaptor.findById(request.commentId()); - commentAdaptor.delete(findComment); + Comment findComment = commentRepository.getById(request.commentId()); + commentRepository.delete(findComment); } - /* --------------- 내부 편의 메서드 --------------- */ private Comment parentCommentBy(CreateParentCommentCommand request) { return Comment.builder() - .post(postAdaptor.findById(request.postId())) - .author(userAdaptor.findById(request.loginUserId())) + .post(postRepository.getById(request.postId())) + .author(userRepository.getById(request.loginUserId())) .body(request.body()) .build(); } + private Comment childCommentBy(CreateChildCommentCommand request) { Comment comment = Comment.builder() .post(getPostFromParentComment(request)) - .author(userAdaptor.findById(request.getLoginUserId())) + .author(userRepository.getById(request.getLoginUserId())) .body(request.getBody()) .build(); - comment.setParent(commentAdaptor.findById(request.getParentCommentId())); + comment.setParent(commentRepository.getById(request.getParentCommentId())); return comment; } private Post getPostFromParentComment(CreateChildCommentCommand request) { Long parentCommentId = request.getParentCommentId(); - Post post = commentAdaptor.findById(parentCommentId).getPost(); + Post post = commentRepository.getById(parentCommentId).getPost(); return post; } @@ -120,7 +128,6 @@ private boolean isAuthorized(DeleteCommentCommand request) { } private Long getAuthorId(Long commentId) { - return commentAdaptor.findById(commentId).getAuthor().getId(); + return commentRepository.getById(commentId).getAuthor().getId(); } - } diff --git a/likelion-core/src/main/java/likelion/univ/domain/donation_history/adaptor/DonationHistoryAdaptor.java b/likelion-core/src/main/java/likelion/univ/domain/donation_history/adaptor/DonationHistoryAdaptor.java deleted file mode 100644 index 3abd0669..00000000 --- a/likelion-core/src/main/java/likelion/univ/domain/donation_history/adaptor/DonationHistoryAdaptor.java +++ /dev/null @@ -1,22 +0,0 @@ -package likelion.univ.domain.donation_history.adaptor; - -import likelion.univ.annotation.Adaptor; -import likelion.univ.domain.donation_history.entity.DonationHistory; -import likelion.univ.domain.donation_history.exception.DonationHistoryNotFoundException; -import likelion.univ.domain.donation_history.repository.DonationHistoryRepository; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; - -@Adaptor -@RequiredArgsConstructor -public class DonationHistoryAdaptor { - private final DonationHistoryRepository donationHistoryRepository; - - public DonationHistory findById(Long id){ - return donationHistoryRepository.findById(id).orElseThrow(()-> new DonationHistoryNotFoundException()); - } - public Page searchDonationHistoryWithSort(Pageable pageable, String sort, String search){ - return donationHistoryRepository.searchDonationHistoryWithSort(pageable, sort, search); - } -} diff --git a/likelion-core/src/main/java/likelion/univ/domain/donation_history/repository/DonationHistoryRepository.java b/likelion-core/src/main/java/likelion/univ/domain/donation_history/repository/DonationHistoryRepository.java deleted file mode 100644 index e0ac86b7..00000000 --- a/likelion-core/src/main/java/likelion/univ/domain/donation_history/repository/DonationHistoryRepository.java +++ /dev/null @@ -1,12 +0,0 @@ -package likelion.univ.domain.donation_history.repository; - -import likelion.univ.domain.donation_history.entity.DonationHistory; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; - -import java.util.Optional; - -public interface DonationHistoryRepository extends JpaRepository, DonationHistoryCustomRepository { - @Query("select distinct d from DonationHistory d join fetch d.author join fetch d.attachments where d.id = :id") - Optional findById(Long id); -} diff --git a/likelion-core/src/main/java/likelion/univ/domain/donation_history/service/DonationHistoryDomainService.java b/likelion-core/src/main/java/likelion/univ/domain/donation_history/service/DonationHistoryDomainService.java deleted file mode 100644 index c072849b..00000000 --- a/likelion-core/src/main/java/likelion/univ/domain/donation_history/service/DonationHistoryDomainService.java +++ /dev/null @@ -1,21 +0,0 @@ -package likelion.univ.domain.donation_history.service; - -import likelion.univ.domain.donation_history.adaptor.DonationHistoryAdaptor; -import likelion.univ.domain.donation_history.entity.DonationHistory; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@Transactional(readOnly = true) -@RequiredArgsConstructor -public class DonationHistoryDomainService { - private final DonationHistoryAdaptor donationHistoryAdaptor; - - @Transactional - public DonationHistory getAndViewCountUp(Long donationHistoryId){ - DonationHistory donationHistory = donationHistoryAdaptor.findById(donationHistoryId); - donationHistory.viewCountUp(); - return donationHistory; - } -} diff --git a/likelion-core/src/main/java/likelion/univ/domain/donation_history/entity/DonationHistory.java b/likelion-core/src/main/java/likelion/univ/domain/donationhistory/entity/DonationHistory.java similarity index 58% rename from likelion-core/src/main/java/likelion/univ/domain/donation_history/entity/DonationHistory.java rename to likelion-core/src/main/java/likelion/univ/domain/donationhistory/entity/DonationHistory.java index 14040c24..3d4f4769 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/donation_history/entity/DonationHistory.java +++ b/likelion-core/src/main/java/likelion/univ/domain/donationhistory/entity/DonationHistory.java @@ -1,17 +1,23 @@ -package likelion.univ.domain.donation_history.entity; +package likelion.univ.domain.donationhistory.entity; +import java.util.ArrayList; +import java.util.List; +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; import likelion.univ.common.entity.BaseTimeEntity; -import likelion.univ.domain.project.entity.ProjectMember; import likelion.univ.domain.user.entity.User; import lombok.AccessLevel; -import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import javax.persistence.*; -import java.util.ArrayList; -import java.util.List; - @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -27,16 +33,16 @@ public class DonationHistory extends BaseTimeEntity { private String title; - @Column(columnDefinition="TEXT") + @Column(columnDefinition = "TEXT") private String body; private Long viewCount = Long.valueOf(0); @OneToMany(cascade = CascadeType.ALL) - @JoinColumn(name="donation_history_id", insertable = false, updatable = false) + @JoinColumn(name = "donation_history_id", insertable = false, updatable = false) private List attachments = new ArrayList<>(); - public void viewCountUp(){ + public void viewCountUp() { this.viewCount += 1; } -} \ No newline at end of file +} diff --git a/likelion-core/src/main/java/likelion/univ/domain/donation_history/entity/DonationHistoryAttachment.java b/likelion-core/src/main/java/likelion/univ/domain/donationhistory/entity/DonationHistoryAttachment.java similarity index 58% rename from likelion-core/src/main/java/likelion/univ/domain/donation_history/entity/DonationHistoryAttachment.java rename to likelion-core/src/main/java/likelion/univ/domain/donationhistory/entity/DonationHistoryAttachment.java index 27859511..8ea77889 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/donation_history/entity/DonationHistoryAttachment.java +++ b/likelion-core/src/main/java/likelion/univ/domain/donationhistory/entity/DonationHistoryAttachment.java @@ -1,15 +1,19 @@ -package likelion.univ.domain.donation_history.entity; +package likelion.univ.domain.donationhistory.entity; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; -import javax.persistence.*; - @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class DonationHistoryAttachment { + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private long id; @@ -17,6 +21,6 @@ public class DonationHistoryAttachment { private String fileName; private String fileExtension; - @Column(columnDefinition="TEXT") + @Column(columnDefinition = "TEXT") private String fileUrl; } diff --git a/likelion-core/src/main/java/likelion/univ/domain/donation_history/exception/DonationHistoryErrorCode.java b/likelion-core/src/main/java/likelion/univ/domain/donationhistory/exception/DonationHistoryErrorCode.java similarity index 78% rename from likelion-core/src/main/java/likelion/univ/domain/donation_history/exception/DonationHistoryErrorCode.java rename to likelion-core/src/main/java/likelion/univ/domain/donationhistory/exception/DonationHistoryErrorCode.java index 93a23c3e..d756787f 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/donation_history/exception/DonationHistoryErrorCode.java +++ b/likelion-core/src/main/java/likelion/univ/domain/donationhistory/exception/DonationHistoryErrorCode.java @@ -1,16 +1,16 @@ -package likelion.univ.domain.donation_history.exception; +package likelion.univ.domain.donationhistory.exception; + +import static likelion.univ.constant.StaticValue.NOT_FOUND; import likelion.univ.exception.base.BaseErrorCode; import lombok.AllArgsConstructor; import lombok.Getter; -import static likelion.univ.constant.StaticValue.*; - @Getter @AllArgsConstructor public enum DonationHistoryErrorCode implements BaseErrorCode { - DONATION_HISTORY_NOT_FOUND(NOT_FOUND, "DONATION_HISTORY_404", "기부금 내역 게시글을 찾을 수 없습니다."); + DONATION_HISTORY_NOT_FOUND(NOT_FOUND, "DONATION_HISTORY_404", "기부금 내역 게시글을 찾을 수 없습니다."); private final int httpStatus; private final String code; diff --git a/likelion-core/src/main/java/likelion/univ/domain/donation_history/exception/DonationHistoryNotFoundException.java b/likelion-core/src/main/java/likelion/univ/domain/donationhistory/exception/DonationHistoryNotFoundException.java similarity index 81% rename from likelion-core/src/main/java/likelion/univ/domain/donation_history/exception/DonationHistoryNotFoundException.java rename to likelion-core/src/main/java/likelion/univ/domain/donationhistory/exception/DonationHistoryNotFoundException.java index 1f00c2df..7eb9cdd0 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/donation_history/exception/DonationHistoryNotFoundException.java +++ b/likelion-core/src/main/java/likelion/univ/domain/donationhistory/exception/DonationHistoryNotFoundException.java @@ -1,8 +1,9 @@ -package likelion.univ.domain.donation_history.exception; +package likelion.univ.domain.donationhistory.exception; import likelion.univ.exception.base.BaseException; public class DonationHistoryNotFoundException extends BaseException { + public DonationHistoryNotFoundException() { super(DonationHistoryErrorCode.DONATION_HISTORY_NOT_FOUND); } diff --git a/likelion-core/src/main/java/likelion/univ/domain/donation_history/repository/DonationHistoryCustomRepository.java b/likelion-core/src/main/java/likelion/univ/domain/donationhistory/repository/DonationHistoryCustomRepository.java similarity index 66% rename from likelion-core/src/main/java/likelion/univ/domain/donation_history/repository/DonationHistoryCustomRepository.java rename to likelion-core/src/main/java/likelion/univ/domain/donationhistory/repository/DonationHistoryCustomRepository.java index 12f62a43..cf90c827 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/donation_history/repository/DonationHistoryCustomRepository.java +++ b/likelion-core/src/main/java/likelion/univ/domain/donationhistory/repository/DonationHistoryCustomRepository.java @@ -1,9 +1,10 @@ -package likelion.univ.domain.donation_history.repository; +package likelion.univ.domain.donationhistory.repository; -import likelion.univ.domain.donation_history.entity.DonationHistory; +import likelion.univ.domain.donationhistory.entity.DonationHistory; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; public interface DonationHistoryCustomRepository { + Page searchDonationHistoryWithSort(Pageable pageable, String sort, String search); } diff --git a/likelion-core/src/main/java/likelion/univ/domain/donationhistory/repository/DonationHistoryRepository.java b/likelion-core/src/main/java/likelion/univ/domain/donationhistory/repository/DonationHistoryRepository.java new file mode 100644 index 00000000..14a3b84d --- /dev/null +++ b/likelion-core/src/main/java/likelion/univ/domain/donationhistory/repository/DonationHistoryRepository.java @@ -0,0 +1,14 @@ +package likelion.univ.domain.donationhistory.repository; + +import likelion.univ.domain.donationhistory.entity.DonationHistory; +import likelion.univ.domain.donationhistory.exception.DonationHistoryNotFoundException; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface DonationHistoryRepository extends + JpaRepository, + DonationHistoryCustomRepository { + + default DonationHistory getById(Long id) { + return findById(id).orElseThrow(DonationHistoryNotFoundException::new); + } +} diff --git a/likelion-core/src/main/java/likelion/univ/domain/donation_history/repository/impl/DonationHistoryCustomRepositoryImpl.java b/likelion-core/src/main/java/likelion/univ/domain/donationhistory/repository/impl/DonationHistoryCustomRepositoryImpl.java similarity index 70% rename from likelion-core/src/main/java/likelion/univ/domain/donation_history/repository/impl/DonationHistoryCustomRepositoryImpl.java rename to likelion-core/src/main/java/likelion/univ/domain/donationhistory/repository/impl/DonationHistoryCustomRepositoryImpl.java index 4db1b034..d0f0505d 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/donation_history/repository/impl/DonationHistoryCustomRepositoryImpl.java +++ b/likelion-core/src/main/java/likelion/univ/domain/donationhistory/repository/impl/DonationHistoryCustomRepositoryImpl.java @@ -1,30 +1,29 @@ -package likelion.univ.domain.donation_history.repository.impl; +package likelion.univ.domain.donationhistory.repository.impl; + +import static likelion.univ.domain.donationhistory.entity.QDonationHistory.donationHistory; +import static likelion.univ.domain.user.entity.QUser.user; import com.querydsl.core.types.OrderSpecifier; import com.querydsl.core.types.Predicate; import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.jpa.impl.JPAQueryFactory; -import likelion.univ.domain.donation_history.entity.DonationHistory; -import likelion.univ.domain.donation_history.repository.DonationHistoryCustomRepository; -import likelion.univ.domain.donation_history.repository.impl.condition.DonationSortType; +import java.util.List; +import likelion.univ.domain.donationhistory.entity.DonationHistory; +import likelion.univ.domain.donationhistory.repository.DonationHistoryCustomRepository; +import likelion.univ.domain.donationhistory.repository.impl.condition.DonationSortType; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; import org.springframework.util.StringUtils; -import java.util.List; - -import static likelion.univ.domain.donation_history.entity.QDonationHistory.donationHistory; -import static likelion.univ.domain.donation_history.entity.QDonationHistoryAttachment.donationHistoryAttachment; -import static likelion.univ.domain.user.entity.QUser.user; - @RequiredArgsConstructor public class DonationHistoryCustomRepositoryImpl implements DonationHistoryCustomRepository { + private final JPAQueryFactory queryFactory; @Override - public Page searchDonationHistoryWithSort(Pageable pageable, String sort, String search){ + public Page searchDonationHistoryWithSort(Pageable pageable, String sort, String search) { List ids = getCoveringIndex(searchCondition(search)); return findDonationHistoryWithSort(ids, pageable, DonationSortType.toOrderSpecifier(sort)); } @@ -34,10 +33,11 @@ private List getCoveringIndex(Predicate predicate) { } private BooleanExpression searchCondition(String search) { - return StringUtils.hasText(search) ? donationHistory.body.contains(search).or(donationHistory.title.contains(search)) : null; + return StringUtils.hasText(search) ? donationHistory.body.contains(search) + .or(donationHistory.title.contains(search)) : null; } - private Page findDonationHistoryWithSort(List ids, Pageable pageable, OrderSpecifier sort){ + private Page findDonationHistoryWithSort(List ids, Pageable pageable, OrderSpecifier sort) { List donationHistories = queryFactory .select(donationHistory) diff --git a/likelion-core/src/main/java/likelion/univ/domain/donation_history/repository/impl/condition/DonationSortType.java b/likelion-core/src/main/java/likelion/univ/domain/donationhistory/repository/impl/condition/DonationSortType.java similarity index 73% rename from likelion-core/src/main/java/likelion/univ/domain/donation_history/repository/impl/condition/DonationSortType.java rename to likelion-core/src/main/java/likelion/univ/domain/donationhistory/repository/impl/condition/DonationSortType.java index e1fd54cb..efb0557f 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/donation_history/repository/impl/condition/DonationSortType.java +++ b/likelion-core/src/main/java/likelion/univ/domain/donationhistory/repository/impl/condition/DonationSortType.java @@ -1,16 +1,17 @@ -package likelion.univ.domain.donation_history.repository.impl.condition; +package likelion.univ.domain.donationhistory.repository.impl.condition; + +import static likelion.univ.domain.donationhistory.entity.QDonationHistory.donationHistory; import com.querydsl.core.types.OrderSpecifier; import likelion.univ.exception.SortTypeNotMatchedException; import lombok.AllArgsConstructor; import lombok.Getter; -import static likelion.univ.domain.donation_history.entity.QDonationHistory.donationHistory; - @Getter @AllArgsConstructor public enum DonationSortType { + CREATED_DATE("created_date"), VIEW_COUNT("view_count"); @@ -24,8 +25,9 @@ public static DonationSortType fromValue(String value) { } throw new SortTypeNotMatchedException(); } - public static OrderSpecifier toOrderSpecifier(String value){ - switch (DonationSortType.fromValue(value)){ + + public static OrderSpecifier toOrderSpecifier(String value) { + switch (DonationSortType.fromValue(value)) { case VIEW_COUNT: return donationHistory.viewCount.desc(); default: diff --git a/likelion-core/src/main/java/likelion/univ/domain/donationhistory/service/DonationHistoryService.java b/likelion-core/src/main/java/likelion/univ/domain/donationhistory/service/DonationHistoryService.java new file mode 100644 index 00000000..f9508cfa --- /dev/null +++ b/likelion-core/src/main/java/likelion/univ/domain/donationhistory/service/DonationHistoryService.java @@ -0,0 +1,22 @@ +package likelion.univ.domain.donationhistory.service; + +import likelion.univ.domain.donationhistory.entity.DonationHistory; +import likelion.univ.domain.donationhistory.repository.DonationHistoryRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional(readOnly = true) +@RequiredArgsConstructor +public class DonationHistoryService { + + private final DonationHistoryRepository donationHistoryRepository; + + @Transactional + public DonationHistory getAndViewCountUp(Long donationHistoryId) { + DonationHistory donationHistory = donationHistoryRepository.getById(donationHistoryId); + donationHistory.viewCountUp(); + return donationHistory; + } +} diff --git a/likelion-core/src/main/java/likelion/univ/domain/example/adaptor/ExampleAdaptor.java b/likelion-core/src/main/java/likelion/univ/domain/example/adaptor/ExampleAdaptor.java deleted file mode 100644 index f13c217e..00000000 --- a/likelion-core/src/main/java/likelion/univ/domain/example/adaptor/ExampleAdaptor.java +++ /dev/null @@ -1,23 +0,0 @@ -package likelion.univ.domain.example.adaptor; - -import likelion.univ.annotation.Adaptor; -import likelion.univ.domain.example.entity.Example; -import likelion.univ.domain.example.exception.ExampleNotFoundException; -import likelion.univ.domain.example.repository.ExampleRepository; -import lombok.RequiredArgsConstructor; - -@Adaptor -@RequiredArgsConstructor -public class ExampleAdaptor { - private final ExampleRepository exampleRepository; - - public void save(Example example) { - exampleRepository.save(example); - } - public Example findById(Long id){ - return exampleRepository.findById(id) - .orElseThrow(() -> new ExampleNotFoundException()); - } - public void delete(Example example) {exampleRepository.delete(example); - } -} diff --git a/likelion-core/src/main/java/likelion/univ/domain/example/entity/Example.java b/likelion-core/src/main/java/likelion/univ/domain/example/entity/Example.java index 6f671abe..0f6c49e3 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/example/entity/Example.java +++ b/likelion-core/src/main/java/likelion/univ/domain/example/entity/Example.java @@ -1,13 +1,15 @@ package likelion.univ.domain.example.entity; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; import likelion.univ.common.entity.BaseTimeEntity; import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import javax.persistence.*; - @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @Entity @@ -17,24 +19,20 @@ public class Example extends BaseTimeEntity { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @Column(nullable = false) -//<<<<<<< HEAD private String columns; private String body; + @Builder public Example(String column, String body) { this.columns = column; this.body = body; } - public void updateColumn(String column){ - this.columns = column;} - //======= -// @Builder -// public Example(String body) { -// this.body = body; -// } - public void editBody(String body){ + + public void updateColumn(String column) { + this.columns = column; + } + + public void editBody(String body) { this.body = body; -//>>>>>>> main } } diff --git a/likelion-core/src/main/java/likelion/univ/domain/example/exception/CreateExampleBadRequestException.java b/likelion-core/src/main/java/likelion/univ/domain/example/exception/CreateExampleBadRequestException.java index 7059088e..b335abf8 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/example/exception/CreateExampleBadRequestException.java +++ b/likelion-core/src/main/java/likelion/univ/domain/example/exception/CreateExampleBadRequestException.java @@ -1,11 +1,9 @@ package likelion.univ.domain.example.exception; -import likelion.univ.exception.base.BaseErrorCode; import likelion.univ.exception.base.BaseException; public class CreateExampleBadRequestException extends BaseException { - public CreateExampleBadRequestException() { super(ExampleErrorCode.CREATE_EXAMPLE_BAD_REQUEST); } diff --git a/likelion-core/src/main/java/likelion/univ/domain/example/exception/ExampleErrorCode.java b/likelion-core/src/main/java/likelion/univ/domain/example/exception/ExampleErrorCode.java index c3b43433..57045924 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/example/exception/ExampleErrorCode.java +++ b/likelion-core/src/main/java/likelion/univ/domain/example/exception/ExampleErrorCode.java @@ -1,15 +1,16 @@ package likelion.univ.domain.example.exception; +import static likelion.univ.constant.StaticValue.BAD_REQUEST; +import static likelion.univ.constant.StaticValue.NOT_FOUND; + import likelion.univ.exception.base.BaseErrorCode; import lombok.AllArgsConstructor; import lombok.Getter; -import static likelion.univ.constant.StaticValue.BAD_REQUEST; -import static likelion.univ.constant.StaticValue.NOT_FOUND; - @Getter @AllArgsConstructor public enum ExampleErrorCode implements BaseErrorCode { + CREATE_EXAMPLE_BAD_REQUEST(BAD_REQUEST, "EXAMPLE_400", "example을 생성하는 데 잘못된 요청을 하였습니다."), EXAMPLE_NOT_FOUND(NOT_FOUND, "EXAMPLE_404", "예시가 존재하지 않습니다."); diff --git a/likelion-core/src/main/java/likelion/univ/domain/example/exception/ExampleNotFoundException.java b/likelion-core/src/main/java/likelion/univ/domain/example/exception/ExampleNotFoundException.java index 7b5057e9..b86c9ec9 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/example/exception/ExampleNotFoundException.java +++ b/likelion-core/src/main/java/likelion/univ/domain/example/exception/ExampleNotFoundException.java @@ -1,6 +1,5 @@ package likelion.univ.domain.example.exception; -import likelion.univ.exception.base.BaseErrorCode; import likelion.univ.exception.base.BaseException; public class ExampleNotFoundException extends BaseException { diff --git a/likelion-core/src/main/java/likelion/univ/domain/example/repository/ExampleRepository.java b/likelion-core/src/main/java/likelion/univ/domain/example/repository/ExampleRepository.java index bd66e704..d28f77cf 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/example/repository/ExampleRepository.java +++ b/likelion-core/src/main/java/likelion/univ/domain/example/repository/ExampleRepository.java @@ -1,7 +1,12 @@ package likelion.univ.domain.example.repository; import likelion.univ.domain.example.entity.Example; +import likelion.univ.domain.example.exception.ExampleNotFoundException; import org.springframework.data.jpa.repository.JpaRepository; -public interface ExampleRepository extends JpaRepository { +public interface ExampleRepository extends JpaRepository { + + default Example getById(Long id) { + return findById(id).orElseThrow(ExampleNotFoundException::new); + } } diff --git a/likelion-core/src/main/java/likelion/univ/domain/example/service/ExampleDomainService.java b/likelion-core/src/main/java/likelion/univ/domain/example/service/ExampleService.java similarity index 52% rename from likelion-core/src/main/java/likelion/univ/domain/example/service/ExampleDomainService.java rename to likelion-core/src/main/java/likelion/univ/domain/example/service/ExampleService.java index 36b879c3..e4e20d62 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/example/service/ExampleDomainService.java +++ b/likelion-core/src/main/java/likelion/univ/domain/example/service/ExampleService.java @@ -1,33 +1,36 @@ package likelion.univ.domain.example.service; -import likelion.univ.domain.example.adaptor.ExampleAdaptor; import likelion.univ.domain.example.entity.Example; +import likelion.univ.domain.example.repository.ExampleRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; + @Service @Transactional(readOnly = true) @RequiredArgsConstructor -public class ExampleDomainService { - private final ExampleAdaptor exampleAdaptor; +public class ExampleService { + + private final ExampleRepository exampleRepository; @Transactional - public Example createExample(String body){ + public Example createExample(String body) { Example example = Example.builder() .body(body) .build(); - exampleAdaptor.save(example); + exampleRepository.save(example); return example; } + @Transactional - public void editExample(Long id, String body){ - Example example = exampleAdaptor.findById(id); + public void editExample(Long id, String body) { + Example example = exampleRepository.getById(id); example.editBody(body); } @Transactional - public void deleteExample(Long id){ - Example example = exampleAdaptor.findById(id); - exampleAdaptor.delete(example); + public void deleteExample(Long id) { + Example example = exampleRepository.getById(id); + exampleRepository.delete(example); } } diff --git a/likelion-core/src/main/java/likelion/univ/domain/follow/adaptor/FollowAdaptor.java b/likelion-core/src/main/java/likelion/univ/domain/follow/adaptor/FollowAdaptor.java deleted file mode 100644 index 89c2b000..00000000 --- a/likelion-core/src/main/java/likelion/univ/domain/follow/adaptor/FollowAdaptor.java +++ /dev/null @@ -1,28 +0,0 @@ -package likelion.univ.domain.follow.adaptor; - -import likelion.univ.annotation.Adaptor; -import likelion.univ.domain.follow.exception.AlreadyFollowingUserException; -import likelion.univ.domain.follow.repository.FollowRepository; -import lombok.RequiredArgsConstructor; - -@Adaptor -@RequiredArgsConstructor -public class FollowAdaptor { - private final FollowRepository followRepository; - - public Boolean hasFollowedUser(Long followerId, Long folloingId) { - return followRepository.existsByFollowerIdAndFollowingId(followerId, folloingId); - } - - public Long countByFollowerId(Long followerId){ - return followRepository.countByFollowerId(followerId); - } - public Long countByFollowingId(Long followingId){ - return followRepository.countByFollowingId(followingId); - } - public void save(Long currentUserId, Long userId) { - try { followRepository.save(currentUserId,userId);} - catch(Exception e) { throw new AlreadyFollowingUserException(); } - } - public void delete(Long currentUserId, Long userId) { followRepository.delete(currentUserId,userId);} -} diff --git a/likelion-core/src/main/java/likelion/univ/domain/follow/entity/Follow.java b/likelion-core/src/main/java/likelion/univ/domain/follow/entity/Follow.java index f1b6f5b4..ec49945c 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/follow/entity/Follow.java +++ b/likelion-core/src/main/java/likelion/univ/domain/follow/entity/Follow.java @@ -1,13 +1,20 @@ package likelion.univ.domain.follow.entity; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.UniqueConstraint; import likelion.univ.common.entity.BaseTimeEntity; import likelion.univ.domain.user.entity.User; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; -import javax.persistence.*; - @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @Entity @@ -25,6 +32,4 @@ public class Follow extends BaseTimeEntity { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "following_id") private User following; - - } diff --git a/likelion-core/src/main/java/likelion/univ/domain/follow/exception/AlreadyFollowingUserException.java b/likelion-core/src/main/java/likelion/univ/domain/follow/exception/AlreadyFollowingUserException.java index aa42d0c0..a4ce6f97 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/follow/exception/AlreadyFollowingUserException.java +++ b/likelion-core/src/main/java/likelion/univ/domain/follow/exception/AlreadyFollowingUserException.java @@ -3,6 +3,7 @@ import likelion.univ.exception.base.BaseException; public class AlreadyFollowingUserException extends BaseException { + public AlreadyFollowingUserException() { super(FollowErrorCode.ALREADY_FOLLOWING_USER); } diff --git a/likelion-core/src/main/java/likelion/univ/domain/follow/exception/FollowErrorCode.java b/likelion-core/src/main/java/likelion/univ/domain/follow/exception/FollowErrorCode.java index 5cbfce87..82370974 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/follow/exception/FollowErrorCode.java +++ b/likelion-core/src/main/java/likelion/univ/domain/follow/exception/FollowErrorCode.java @@ -1,16 +1,16 @@ package likelion.univ.domain.follow.exception; +import static likelion.univ.constant.StaticValue.BAD_REQUEST; + import likelion.univ.exception.base.BaseErrorCode; import lombok.AllArgsConstructor; import lombok.Getter; -import static likelion.univ.constant.StaticValue.*; - @Getter @AllArgsConstructor public enum FollowErrorCode implements BaseErrorCode { - ALREADY_FOLLOWING_USER(BAD_REQUEST, "FOLLOW_400_1", "이미 팔로우하고 있습니다."); + ALREADY_FOLLOWING_USER(BAD_REQUEST, "FOLLOW_400_1", "이미 팔로우하고 있습니다."); private final int httpStatus; private final String code; diff --git a/likelion-core/src/main/java/likelion/univ/domain/follow/repository/FollowRepository.java b/likelion-core/src/main/java/likelion/univ/domain/follow/repository/FollowRepository.java index d3c8ca0c..fa5c534a 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/follow/repository/FollowRepository.java +++ b/likelion-core/src/main/java/likelion/univ/domain/follow/repository/FollowRepository.java @@ -7,13 +7,17 @@ import org.springframework.transaction.annotation.Transactional; -public interface FollowRepository extends JpaRepository { +public interface FollowRepository extends JpaRepository { + Long countByFollowerId(Long followerId); + Long countByFollowingId(Long followingId); + + // TODO 제거 @Modifying @Transactional @Query(value = "insert into follow(created_date, modified_date, follower_id, following_id)" - + "values (now(), now(), :currentId , :userId)", nativeQuery = true) + + "values (now(), now(), :currentId , :userId)", nativeQuery = true) void save(Long currentId, Long userId); boolean existsByFollowerIdAndFollowingId(Long followerId, Long followingId); diff --git a/likelion-core/src/main/java/likelion/univ/domain/hackathon/entity/HackathonForm.java b/likelion-core/src/main/java/likelion/univ/domain/hackathon/entity/HackathonForm.java new file mode 100644 index 00000000..5e900c9f --- /dev/null +++ b/likelion-core/src/main/java/likelion/univ/domain/hackathon/entity/HackathonForm.java @@ -0,0 +1,132 @@ +package likelion.univ.domain.hackathon.entity; + +import static javax.persistence.EnumType.STRING; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Enumerated; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import likelion.univ.common.entity.BaseTimeEntity; +import likelion.univ.domain.hackathon.exception.HackathonFormNotEditableException; +import likelion.univ.domain.hackathon.exception.NoAuthorityGuestApplyHackathon; +import likelion.univ.domain.hackathon.exception.NoAuthorityOrdinalApplyHackathon; +import likelion.univ.domain.hackathon.exception.ReasonForNotOfflineException; +import likelion.univ.domain.university.entity.University; +import likelion.univ.domain.user.entity.Role; +import likelion.univ.domain.user.entity.User; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Entity +public class HackathonForm extends BaseTimeEntity { + + public static final Long HACKATHON_ORDINAL = 12L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id") + private User user; + + @Column(nullable = false) + private String name; + + @Column(nullable = false) + private String email; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "university_id", nullable = false) + private University university; + + @Column(nullable = false) + private String major; + + @Column(nullable = false) + private String phone; + + @Enumerated(STRING) + @Column(nullable = false) + private HackathonPart hackathonPart; + + @Column(length = 10, nullable = false) + private String teamName; + + private boolean offlineParticipation; + + @Column(length = 100) + private String reasonForNotOffline; + + public HackathonForm( + User user, + String name, + String email, + University university, + String major, + String phone, + HackathonPart hackathonPart, + String teamName, + boolean offlineParticipation, + String reasonForNotOffline + ) { + this.user = user; + this.name = name; + this.email = email; + this.university = university; + this.major = major; + this.phone = phone; + this.hackathonPart = hackathonPart; + this.teamName = teamName; + this.offlineParticipation = offlineParticipation; + setReasonForNotOffline(offlineParticipation, reasonForNotOffline); + } + + public void apply() { + if (user.getAuthInfo().getRole().equals(Role.GUEST)) { + throw new NoAuthorityGuestApplyHackathon(); + } + if (!user.getUniversityInfo().getOrdinal().equals(HACKATHON_ORDINAL)) { + throw new NoAuthorityOrdinalApplyHackathon(); + } + + setReasonForNotOffline(offlineParticipation, reasonForNotOffline); + } + + public void modify(String phone, HackathonPart hackathonPart, String teamName, boolean offlineParticipation, String reasonForNotOffline) { + this.phone = phone; + this.hackathonPart = hackathonPart; + this.teamName = teamName; + this.offlineParticipation = offlineParticipation; + setReasonForNotOffline(offlineParticipation, reasonForNotOffline); + } + + public void validateUser(User user) { + if (!this.user.equals(user)) { + throw new HackathonFormNotEditableException(); + } + } + + private void setReasonForNotOffline(boolean offlineParticipation, String reasonForNotOffline) { + if (offlineParticipation) { + this.reasonForNotOffline = null; + } else { + validReasonForNotOffline(offlineParticipation, reasonForNotOffline); + this.reasonForNotOffline = reasonForNotOffline; + } + } + private void validReasonForNotOffline(boolean offlineParticipation, String reasonForNotOffline) { + if (!offlineParticipation && (reasonForNotOffline == null || reasonForNotOffline.isEmpty())) + throw new ReasonForNotOfflineException(); + } + +} + diff --git a/likelion-core/src/main/java/likelion/univ/domain/hackathon/entity/HackathonPart.java b/likelion-core/src/main/java/likelion/univ/domain/hackathon/entity/HackathonPart.java new file mode 100644 index 00000000..37b9b305 --- /dev/null +++ b/likelion-core/src/main/java/likelion/univ/domain/hackathon/entity/HackathonPart.java @@ -0,0 +1,16 @@ +package likelion.univ.domain.hackathon.entity; + +public enum HackathonPart { + + PM("기획"), + DESIGNER("디자인"), + FRONTEND("프론트엔드"), + BACKEND("백엔드"), + ; + + private final String name; + + HackathonPart(String name) { + this.name = name; + } +} diff --git a/likelion-core/src/main/java/likelion/univ/domain/hackathon/exception/HackathonErrorCode.java b/likelion-core/src/main/java/likelion/univ/domain/hackathon/exception/HackathonErrorCode.java new file mode 100644 index 00000000..db9ed0c2 --- /dev/null +++ b/likelion-core/src/main/java/likelion/univ/domain/hackathon/exception/HackathonErrorCode.java @@ -0,0 +1,45 @@ +package likelion.univ.domain.hackathon.exception; + +import static likelion.univ.constant.StaticValue.BAD_REQUEST; +import static likelion.univ.constant.StaticValue.FORBIDDEN; +import static likelion.univ.constant.StaticValue.NOT_FOUND; +import static likelion.univ.domain.hackathon.entity.HackathonForm.HACKATHON_ORDINAL; + +import likelion.univ.exception.base.BaseErrorCode; + +public enum HackathonErrorCode implements BaseErrorCode { + REASON_FOR_NOT_OFFLINE_NECESSARY(BAD_REQUEST, "HACKATHON_400_1", "오프라인 해커톤에 불참하는 경우, 불참 사유 작성은 필수입니다."), + HACKATHON_FORM_NOT_FOUND(NOT_FOUND, "HACKATHON_404_1", "해커톤 신청서를 찾을 수 없습니다."), + NO_AUTHORITY_GUEST_APPLY_HACKATHON(FORBIDDEN, "HACKATHON_403_1", "회원가입이 완료된 회원만 신청할 수 있습니다."), + HACKATHON_FORM_NOT_EDITABLE(FORBIDDEN, "HACKATHON_403_2", "사용자가 작성한 해커톤 신청서가 아닙니다."), + NO_AUTHORITY_ORDINAL_APPLY_HACKATHON( + FORBIDDEN, + "HACKATHON_403_2", + "본 중앙 해커톤은 %d기 아기사자 및 운영진 참가 대상입니다".formatted(HACKATHON_ORDINAL) + ); + + private final int httpStatus; + private final String code; + private final String message; + + HackathonErrorCode(int httpStatus, String code, String message) { + this.httpStatus = httpStatus; + this.code = code; + this.message = message; + } + + @Override + public String getCode() { + return this.code; + } + + @Override + public String getMessage() { + return this.message; + } + + @Override + public int getHttpStatus() { + return this.httpStatus; + } +} diff --git a/likelion-core/src/main/java/likelion/univ/domain/hackathon/exception/HackathonFormNotEditableException.java b/likelion-core/src/main/java/likelion/univ/domain/hackathon/exception/HackathonFormNotEditableException.java new file mode 100644 index 00000000..d6f18198 --- /dev/null +++ b/likelion-core/src/main/java/likelion/univ/domain/hackathon/exception/HackathonFormNotEditableException.java @@ -0,0 +1,13 @@ +package likelion.univ.domain.hackathon.exception; + +import static likelion.univ.domain.hackathon.exception.HackathonErrorCode.HACKATHON_FORM_NOT_EDITABLE; +import static likelion.univ.domain.hackathon.exception.HackathonErrorCode.HACKATHON_FORM_NOT_FOUND; + +import likelion.univ.exception.base.BaseException; + +public class HackathonFormNotEditableException extends BaseException { + + public HackathonFormNotEditableException() { + super(HACKATHON_FORM_NOT_EDITABLE); + } +} diff --git a/likelion-core/src/main/java/likelion/univ/domain/hackathon/exception/HackathonFormNotFoundException.java b/likelion-core/src/main/java/likelion/univ/domain/hackathon/exception/HackathonFormNotFoundException.java new file mode 100644 index 00000000..d40feb50 --- /dev/null +++ b/likelion-core/src/main/java/likelion/univ/domain/hackathon/exception/HackathonFormNotFoundException.java @@ -0,0 +1,12 @@ +package likelion.univ.domain.hackathon.exception; + +import static likelion.univ.domain.hackathon.exception.HackathonErrorCode.HACKATHON_FORM_NOT_FOUND; + +import likelion.univ.exception.base.BaseException; + +public class HackathonFormNotFoundException extends BaseException { + + public HackathonFormNotFoundException() { + super(HACKATHON_FORM_NOT_FOUND); + } +} diff --git a/likelion-core/src/main/java/likelion/univ/domain/hackathon/exception/NoAuthorityGuestApplyHackathon.java b/likelion-core/src/main/java/likelion/univ/domain/hackathon/exception/NoAuthorityGuestApplyHackathon.java new file mode 100644 index 00000000..f1eaaeb0 --- /dev/null +++ b/likelion-core/src/main/java/likelion/univ/domain/hackathon/exception/NoAuthorityGuestApplyHackathon.java @@ -0,0 +1,10 @@ +package likelion.univ.domain.hackathon.exception; + +import likelion.univ.exception.base.BaseException; + +public class NoAuthorityGuestApplyHackathon extends BaseException { + + public NoAuthorityGuestApplyHackathon() { + super(HackathonErrorCode.NO_AUTHORITY_GUEST_APPLY_HACKATHON); + } +} diff --git a/likelion-core/src/main/java/likelion/univ/domain/hackathon/exception/NoAuthorityOrdinalApplyHackathon.java b/likelion-core/src/main/java/likelion/univ/domain/hackathon/exception/NoAuthorityOrdinalApplyHackathon.java new file mode 100644 index 00000000..64b99293 --- /dev/null +++ b/likelion-core/src/main/java/likelion/univ/domain/hackathon/exception/NoAuthorityOrdinalApplyHackathon.java @@ -0,0 +1,12 @@ +package likelion.univ.domain.hackathon.exception; + +import static likelion.univ.domain.hackathon.exception.HackathonErrorCode.NO_AUTHORITY_ORDINAL_APPLY_HACKATHON; + +import likelion.univ.exception.base.BaseException; + +public class NoAuthorityOrdinalApplyHackathon extends BaseException { + + public NoAuthorityOrdinalApplyHackathon() { + super(NO_AUTHORITY_ORDINAL_APPLY_HACKATHON); + } +} diff --git a/likelion-core/src/main/java/likelion/univ/domain/hackathon/exception/ReasonForNotOfflineException.java b/likelion-core/src/main/java/likelion/univ/domain/hackathon/exception/ReasonForNotOfflineException.java new file mode 100644 index 00000000..2fda22dd --- /dev/null +++ b/likelion-core/src/main/java/likelion/univ/domain/hackathon/exception/ReasonForNotOfflineException.java @@ -0,0 +1,12 @@ +package likelion.univ.domain.hackathon.exception; + +import static likelion.univ.domain.hackathon.exception.HackathonErrorCode.REASON_FOR_NOT_OFFLINE_NECESSARY; + +import likelion.univ.exception.base.BaseException; + +public class ReasonForNotOfflineException extends BaseException { + + public ReasonForNotOfflineException() { + super(REASON_FOR_NOT_OFFLINE_NECESSARY); + } +} diff --git a/likelion-core/src/main/java/likelion/univ/domain/hackathon/repository/HackathonFormCustomRepository.java b/likelion-core/src/main/java/likelion/univ/domain/hackathon/repository/HackathonFormCustomRepository.java new file mode 100644 index 00000000..4be93f95 --- /dev/null +++ b/likelion-core/src/main/java/likelion/univ/domain/hackathon/repository/HackathonFormCustomRepository.java @@ -0,0 +1,11 @@ +package likelion.univ.domain.hackathon.repository; + +import likelion.univ.domain.hackathon.entity.HackathonForm; +import likelion.univ.domain.hackathon.repository.condition.HackathonFormSearchCondition; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +public interface HackathonFormCustomRepository { + + Page search(HackathonFormSearchCondition condition, Pageable pageable); +} diff --git a/likelion-core/src/main/java/likelion/univ/domain/hackathon/repository/HackathonFormRepository.java b/likelion-core/src/main/java/likelion/univ/domain/hackathon/repository/HackathonFormRepository.java new file mode 100644 index 00000000..3806c2db --- /dev/null +++ b/likelion-core/src/main/java/likelion/univ/domain/hackathon/repository/HackathonFormRepository.java @@ -0,0 +1,12 @@ +package likelion.univ.domain.hackathon.repository; + +import likelion.univ.domain.hackathon.entity.HackathonForm; +import likelion.univ.domain.hackathon.exception.HackathonFormNotFoundException; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface HackathonFormRepository extends JpaRepository, HackathonFormCustomRepository { + + default HackathonForm getById(Long id) { + return findById(id).orElseThrow(HackathonFormNotFoundException::new); + } +} diff --git a/likelion-core/src/main/java/likelion/univ/domain/hackathon/repository/condition/HackathonFormSearchCondition.java b/likelion-core/src/main/java/likelion/univ/domain/hackathon/repository/condition/HackathonFormSearchCondition.java new file mode 100644 index 00000000..db086fc7 --- /dev/null +++ b/likelion-core/src/main/java/likelion/univ/domain/hackathon/repository/condition/HackathonFormSearchCondition.java @@ -0,0 +1,7 @@ +package likelion.univ.domain.hackathon.repository.condition; + +public record HackathonFormSearchCondition( + String keyword, + boolean isExcelData +) { +} diff --git a/likelion-core/src/main/java/likelion/univ/domain/hackathon/repository/impl/HackathonFormCustomRepositoryImpl.java b/likelion-core/src/main/java/likelion/univ/domain/hackathon/repository/impl/HackathonFormCustomRepositoryImpl.java new file mode 100644 index 00000000..98ac3ae1 --- /dev/null +++ b/likelion-core/src/main/java/likelion/univ/domain/hackathon/repository/impl/HackathonFormCustomRepositoryImpl.java @@ -0,0 +1,64 @@ +package likelion.univ.domain.hackathon.repository.impl; + +import static likelion.univ.domain.hackathon.entity.QHackathonForm.hackathonForm; + +import com.querydsl.core.types.Predicate; +import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.jpa.impl.JPAQueryFactory; +import java.util.List; +import likelion.univ.domain.hackathon.entity.HackathonForm; +import likelion.univ.domain.hackathon.repository.HackathonFormCustomRepository; +import likelion.univ.domain.hackathon.repository.condition.HackathonFormSearchCondition; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.support.PageableExecutionUtils; + +@RequiredArgsConstructor +public class HackathonFormCustomRepositoryImpl implements HackathonFormCustomRepository { + private final JPAQueryFactory queryFactory; + + @Override + public Page search(HackathonFormSearchCondition condition, Pageable pageable) { + List ids = getCoveringIndex(keywordContains(condition.keyword())); + + List result = queryFactory.select(hackathonForm) + .from(hackathonForm) + .leftJoin(hackathonForm.university) + .fetchJoin() + .where(hackathonForm.id.in(ids)) + .orderBy(hackathonForm.createdDate.desc()) + .offset(condition.isExcelData() ? 0 : pageable.getOffset()) + .limit( + condition.isExcelData() + ? ids.size() + 1 + : pageable.getPageSize()) + .fetch(); + + return condition.isExcelData() + ? PageableExecutionUtils.getPage( + result, PageRequest.of(0, ids.size() + 1), ids::size) + : PageableExecutionUtils.getPage(result, pageable, ids::size); + } + + /** + * Page 기반 페이지네이션을 위한 커버링인덱스 구하는 함수 + * + * @param predicate 탐색 조건 + * @return 커버링 인덱스 + */ + private List getCoveringIndex(Predicate predicate) { + return queryFactory.select(hackathonForm.id).from(hackathonForm).where(predicate).fetch(); + } + + /** + * 검색어 + */ + private BooleanExpression keywordContains(String keyword) { + return keyword != null + ? hackathonForm.name.contains(keyword) + .or(hackathonForm.university.name.contains(keyword)) + : null; + } +} diff --git a/likelion-core/src/main/java/likelion/univ/domain/hackathon/response/HackathonFindResponse.java b/likelion-core/src/main/java/likelion/univ/domain/hackathon/response/HackathonFindResponse.java new file mode 100644 index 00000000..739fdb2e --- /dev/null +++ b/likelion-core/src/main/java/likelion/univ/domain/hackathon/response/HackathonFindResponse.java @@ -0,0 +1,35 @@ +package likelion.univ.domain.hackathon.response; + +import likelion.univ.domain.hackathon.entity.HackathonForm; +import likelion.univ.domain.hackathon.entity.HackathonPart; +import lombok.Builder; + +@Builder +public record HackathonFindResponse( + Long hackathonFormId, + String name, + String email, + String universityName, + String major, + String phone, + HackathonPart hackathonPart, + String teamName, + boolean offlineParticipation, + String reasonForNotOffline +) { + + public static HackathonFindResponse from(HackathonForm hackathonForm) { + return new HackathonFindResponse( + hackathonForm.getId(), + hackathonForm.getName(), + hackathonForm.getEmail(), + hackathonForm.getUniversity().getName(), + hackathonForm.getMajor(), + hackathonForm.getPhone(), + hackathonForm.getHackathonPart(), + hackathonForm.getTeamName(), + hackathonForm.isOfflineParticipation(), + hackathonForm.getReasonForNotOffline() + ); + } +} diff --git a/likelion-core/src/main/java/likelion/univ/domain/hackathon/service/HackathonService.java b/likelion-core/src/main/java/likelion/univ/domain/hackathon/service/HackathonService.java new file mode 100644 index 00000000..dde95179 --- /dev/null +++ b/likelion-core/src/main/java/likelion/univ/domain/hackathon/service/HackathonService.java @@ -0,0 +1,60 @@ +package likelion.univ.domain.hackathon.service; + +import likelion.univ.domain.hackathon.entity.HackathonForm; +import likelion.univ.domain.hackathon.repository.HackathonFormRepository; +import likelion.univ.domain.hackathon.repository.condition.HackathonFormSearchCondition; +import likelion.univ.domain.hackathon.response.HackathonFindResponse; +import likelion.univ.domain.hackathon.service.command.HackathonApplyCommand; +import likelion.univ.domain.hackathon.service.command.HackathonModifyCommand; +import likelion.univ.domain.university.entity.University; +import likelion.univ.domain.university.repository.UniversityRepository; +import likelion.univ.domain.user.entity.User; +import likelion.univ.domain.user.repository.UserRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional +@RequiredArgsConstructor +public class HackathonService { + + private final HackathonFormRepository hackathonFormRepository; + private final UserRepository userRepository; + private final UniversityRepository universityRepository; + + public Long apply(HackathonApplyCommand command) { + User user = userRepository.getById(command.userId()); + University university = universityRepository.getByName(command.universityName()); + HackathonForm hackathonForm = command.toHackathonForm(user, university); + hackathonForm.apply(); + return hackathonFormRepository.save(hackathonForm).getId(); + } + + public HackathonFindResponse find(Long userId, Long hackathonFormId) { + HackathonForm hackathonForm = hackathonFormRepository.getById(hackathonFormId); + User user = userRepository.getById(userId); + hackathonForm.validateUser(user); + return HackathonFindResponse.from(hackathonForm); + } + + public void modify(HackathonModifyCommand command) { + HackathonForm hackathonForm = hackathonFormRepository.getById(command.hackathonFormId()); + User user = userRepository.getById(command.userId()); + hackathonForm.validateUser(user); + hackathonForm.modify( + command.phone(), + command.hackathonPart(), + command.teamName(), + command.offlineParticipation(), + command.reasonForNotOffline() + ); + } + + public Page search(HackathonFormSearchCondition condition, Pageable pageable) { + Page result = hackathonFormRepository.search(condition, pageable); + return result; + } +} diff --git a/likelion-core/src/main/java/likelion/univ/domain/hackathon/service/command/HackathonApplyCommand.java b/likelion-core/src/main/java/likelion/univ/domain/hackathon/service/command/HackathonApplyCommand.java new file mode 100644 index 00000000..9e965a7a --- /dev/null +++ b/likelion-core/src/main/java/likelion/univ/domain/hackathon/service/command/HackathonApplyCommand.java @@ -0,0 +1,35 @@ +package likelion.univ.domain.hackathon.service.command; + + +import likelion.univ.domain.hackathon.entity.HackathonForm; +import likelion.univ.domain.hackathon.entity.HackathonPart; +import likelion.univ.domain.university.entity.University; +import likelion.univ.domain.user.entity.User; + +public record HackathonApplyCommand( + Long userId, + String name, + String email, + String universityName, + String major, + String phone, + HackathonPart hackathonPart, + String teamName, + boolean offlineParticipation, + String reasonForNotOffline +) { + public HackathonForm toHackathonForm(User user, University university) { + return new HackathonForm( + user, + name, + email, + university, + major, + phone, + hackathonPart, + teamName, + offlineParticipation, + reasonForNotOffline + ); + } +} diff --git a/likelion-core/src/main/java/likelion/univ/domain/hackathon/service/command/HackathonModifyCommand.java b/likelion-core/src/main/java/likelion/univ/domain/hackathon/service/command/HackathonModifyCommand.java new file mode 100644 index 00000000..b74a2b4a --- /dev/null +++ b/likelion-core/src/main/java/likelion/univ/domain/hackathon/service/command/HackathonModifyCommand.java @@ -0,0 +1,15 @@ +package likelion.univ.domain.hackathon.service.command; + + +import likelion.univ.domain.hackathon.entity.HackathonPart; + +public record HackathonModifyCommand( + Long hackathonFormId, + Long userId, + String phone, + HackathonPart hackathonPart, + String teamName, + boolean offlineParticipation, + String reasonForNotOffline +) { +} diff --git a/likelion-core/src/main/java/likelion/univ/domain/like/commentlike/adaptor/CommentLikeAdaptor.java b/likelion-core/src/main/java/likelion/univ/domain/like/commentlike/adaptor/CommentLikeAdaptor.java deleted file mode 100644 index 2f38641a..00000000 --- a/likelion-core/src/main/java/likelion/univ/domain/like/commentlike/adaptor/CommentLikeAdaptor.java +++ /dev/null @@ -1,41 +0,0 @@ -package likelion.univ.domain.like.commentlike.adaptor; - -import likelion.univ.annotation.Adaptor; -import likelion.univ.domain.like.commentlike.entity.CommentLike; -import likelion.univ.domain.like.commentlike.exception.CommentLikeNotFoundException; -import likelion.univ.domain.like.commentlike.repository.CommentLikeRepository; -import likelion.univ.domain.user.entity.User; -import lombok.RequiredArgsConstructor; - -import java.util.List; - -@Adaptor -@RequiredArgsConstructor -public class CommentLikeAdaptor { - private final CommentLikeRepository commentLikeRepository; - - public Long save(CommentLike commentLike) { - return commentLikeRepository.save(commentLike).getId(); - } - - public CommentLike findById(Long id) { - return commentLikeRepository.findById(id) - .orElseThrow(CommentLikeNotFoundException::new); - } - public void delete(CommentLike commentLike) { - commentLikeRepository.delete(commentLike); - } - - public List findAllByUser(User user) { - return commentLikeRepository.findByUser(user); - } - - public CommentLike findByCommentIdAndUserId(Long commentId, Long userId) { - return commentLikeRepository.findByCommentIdAndUserId(commentId, userId).orElseThrow(() -> new CommentLikeNotFoundException()); - } - - public Boolean existsByCommentIdAndUserId(Long commentId, Long userId) { - return commentLikeRepository.existsByCommentIdAndUserId(commentId, userId); - } - -} diff --git a/likelion-core/src/main/java/likelion/univ/domain/like/commentlike/dto/request/CommentLikeCommand.java b/likelion-core/src/main/java/likelion/univ/domain/like/commentlike/dto/request/CommentLikeCommand.java index c31a4601..42765ede 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/like/commentlike/dto/request/CommentLikeCommand.java +++ b/likelion-core/src/main/java/likelion/univ/domain/like/commentlike/dto/request/CommentLikeCommand.java @@ -6,5 +6,5 @@ public record CommentLikeCommand( Long loginUserId, Long commentId -){ +) { } diff --git a/likelion-core/src/main/java/likelion/univ/domain/like/commentlike/dto/request/CommentLikeDeleteCommand.java b/likelion-core/src/main/java/likelion/univ/domain/like/commentlike/dto/request/CommentLikeDeleteCommand.java index f2a41488..05d0bb58 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/like/commentlike/dto/request/CommentLikeDeleteCommand.java +++ b/likelion-core/src/main/java/likelion/univ/domain/like/commentlike/dto/request/CommentLikeDeleteCommand.java @@ -7,5 +7,4 @@ public record CommentLikeDeleteCommand( Long commentId, Long loginUserId ) { - } diff --git a/likelion-core/src/main/java/likelion/univ/domain/like/commentlike/dto/response/CommentLikeDeleteData.java b/likelion-core/src/main/java/likelion/univ/domain/like/commentlike/dto/response/CommentLikeDeleteData.java deleted file mode 100644 index bcad9c33..00000000 --- a/likelion-core/src/main/java/likelion/univ/domain/like/commentlike/dto/response/CommentLikeDeleteData.java +++ /dev/null @@ -1,5 +0,0 @@ -package likelion.univ.domain.like.commentlike.dto.response; - -public class CommentLikeDeleteData { - -} diff --git a/likelion-core/src/main/java/likelion/univ/domain/like/commentlike/dto/response/CommentLikeIdData.java b/likelion-core/src/main/java/likelion/univ/domain/like/commentlike/dto/response/CommentLikeIdData.java index 9db84a07..21f3810d 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/like/commentlike/dto/response/CommentLikeIdData.java +++ b/likelion-core/src/main/java/likelion/univ/domain/like/commentlike/dto/response/CommentLikeIdData.java @@ -1,14 +1,13 @@ package likelion.univ.domain.like.commentlike.dto.response; import likelion.univ.domain.like.commentlike.entity.CommentLike; -import lombok.AllArgsConstructor; import lombok.Builder; -import lombok.Data; @Builder public record CommentLikeIdData( Long commentLikeId ) { + public static CommentLikeIdData of(Long commentLikeId) { return CommentLikeIdData.builder() .commentLikeId(commentLikeId) diff --git a/likelion-core/src/main/java/likelion/univ/domain/like/commentlike/entity/CommentLike.java b/likelion-core/src/main/java/likelion/univ/domain/like/commentlike/entity/CommentLike.java index e47813eb..f5834ef8 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/like/commentlike/entity/CommentLike.java +++ b/likelion-core/src/main/java/likelion/univ/domain/like/commentlike/entity/CommentLike.java @@ -1,5 +1,12 @@ package likelion.univ.domain.like.commentlike.entity; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; import likelion.univ.common.entity.BaseTimeEntity; import likelion.univ.domain.comment.entity.Comment; import likelion.univ.domain.user.entity.User; @@ -8,13 +15,13 @@ import lombok.Getter; import lombok.NoArgsConstructor; -import javax.persistence.*; - @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class CommentLike extends BaseTimeEntity { - @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @ManyToOne(fetch = FetchType.LAZY) diff --git a/likelion-core/src/main/java/likelion/univ/domain/like/commentlike/exception/CommentLikeErrorCode.java b/likelion-core/src/main/java/likelion/univ/domain/like/commentlike/exception/CommentLikeErrorCode.java index 76000504..d178a6fa 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/like/commentlike/exception/CommentLikeErrorCode.java +++ b/likelion-core/src/main/java/likelion/univ/domain/like/commentlike/exception/CommentLikeErrorCode.java @@ -1,14 +1,15 @@ package likelion.univ.domain.like.commentlike.exception; +import static likelion.univ.constant.StaticValue.BAD_REQUEST; + import likelion.univ.exception.base.BaseErrorCode; import lombok.Getter; import lombok.RequiredArgsConstructor; -import static likelion.univ.constant.StaticValue.BAD_REQUEST; - @Getter @RequiredArgsConstructor public enum CommentLikeErrorCode implements BaseErrorCode { + CREATE_LIKECOMMENT_BAD_REQUEST(BAD_REQUEST, "COMMENT_400", "댓글 좋아요를 생성하는 데 잘못된 요청을 하였습니다."); private final int httpStatus; diff --git a/likelion-core/src/main/java/likelion/univ/domain/like/commentlike/exception/CommentLikeNotFoundException.java b/likelion-core/src/main/java/likelion/univ/domain/like/commentlike/exception/CommentLikeNotFoundException.java index 9f513b6a..03903492 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/like/commentlike/exception/CommentLikeNotFoundException.java +++ b/likelion-core/src/main/java/likelion/univ/domain/like/commentlike/exception/CommentLikeNotFoundException.java @@ -3,6 +3,7 @@ import likelion.univ.exception.base.BaseException; public class CommentLikeNotFoundException extends BaseException { + public CommentLikeNotFoundException() { super(CommentLikeErrorCode.CREATE_LIKECOMMENT_BAD_REQUEST); } diff --git a/likelion-core/src/main/java/likelion/univ/domain/like/commentlike/repository/CommentLikeRepository.java b/likelion-core/src/main/java/likelion/univ/domain/like/commentlike/repository/CommentLikeRepository.java index 10a8943f..dac2ef91 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/like/commentlike/repository/CommentLikeRepository.java +++ b/likelion-core/src/main/java/likelion/univ/domain/like/commentlike/repository/CommentLikeRepository.java @@ -1,17 +1,26 @@ package likelion.univ.domain.like.commentlike.repository; -import likelion.univ.domain.comment.entity.Comment; +import java.util.List; +import java.util.Optional; import likelion.univ.domain.like.commentlike.entity.CommentLike; +import likelion.univ.domain.like.commentlike.exception.CommentLikeNotFoundException; import likelion.univ.domain.user.entity.User; import org.springframework.data.jpa.repository.JpaRepository; -import java.util.List; -import java.util.Optional; +public interface CommentLikeRepository extends JpaRepository { -public interface CommentLikeRepository extends JpaRepository, CommentLikeRepositoryCustom { + default CommentLike getById(Long id) { + return findById(id).orElseThrow(CommentLikeNotFoundException::new); + } List findByUser(User user); + Boolean existsByCommentIdAndUserId(Long commentId, Long userId); - Optional findByCommentIdAndUserId(Long commentId, Long userId); + default CommentLike getByCommentIdAndUserId(Long commentId, Long userId) { + return findByCommentIdAndUserId(commentId, userId) + .orElseThrow(CommentLikeNotFoundException::new); + } + + Optional findByCommentIdAndUserId(Long commentId, Long userId); } diff --git a/likelion-core/src/main/java/likelion/univ/domain/like/commentlike/repository/CommentLikeRepositoryCustom.java b/likelion-core/src/main/java/likelion/univ/domain/like/commentlike/repository/CommentLikeRepositoryCustom.java deleted file mode 100644 index b8357198..00000000 --- a/likelion-core/src/main/java/likelion/univ/domain/like/commentlike/repository/CommentLikeRepositoryCustom.java +++ /dev/null @@ -1,6 +0,0 @@ -package likelion.univ.domain.like.commentlike.repository; - -import likelion.univ.domain.like.commentlike.entity.CommentLike; - -public interface CommentLikeRepositoryCustom { -} diff --git a/likelion-core/src/main/java/likelion/univ/domain/like/commentlike/service/CommentLikeDomainService.java b/likelion-core/src/main/java/likelion/univ/domain/like/commentlike/service/CommentLikeService.java similarity index 59% rename from likelion-core/src/main/java/likelion/univ/domain/like/commentlike/service/CommentLikeDomainService.java rename to likelion-core/src/main/java/likelion/univ/domain/like/commentlike/service/CommentLikeService.java index 70996487..df614a78 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/like/commentlike/service/CommentLikeDomainService.java +++ b/likelion-core/src/main/java/likelion/univ/domain/like/commentlike/service/CommentLikeService.java @@ -1,13 +1,11 @@ package likelion.univ.domain.like.commentlike.service; -import likelion.univ.domain.comment.adaptor.CommentAdaptor; -import likelion.univ.domain.comment.entity.Comment; import likelion.univ.domain.comment.exception.NotAuthorizedException; -import likelion.univ.domain.like.commentlike.adaptor.CommentLikeAdaptor; +import likelion.univ.domain.comment.repository.CommentRepository; import likelion.univ.domain.like.commentlike.dto.request.CommentLikeCommand; import likelion.univ.domain.like.commentlike.entity.CommentLike; -import likelion.univ.domain.user.adaptor.UserAdaptor; -import likelion.univ.domain.user.entity.User; +import likelion.univ.domain.like.commentlike.repository.CommentLikeRepository; +import likelion.univ.domain.user.repository.UserRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -15,42 +13,41 @@ @Service @Transactional @RequiredArgsConstructor -public class CommentLikeDomainService { - private final UserAdaptor userAdaptor; - private final CommentAdaptor commentAdaptor; - private final CommentLikeAdaptor commentLikeAdaptor; +public class CommentLikeService { + + private final UserRepository userRepository; + private final CommentRepository commentRepository; + private final CommentLikeRepository commentLikeRepository; public boolean createOrDeleteCommentLike(CommentLikeCommand request) throws NotAuthorizedException { Long commentId = request.commentId(); Long loginUserId = request.loginUserId(); -// Comment comment = commentAdaptor.findById(commentId); -// User user = userAdaptor.findById(loginUserId); // 이미 좋아요 했으면 취소 if (existsCommentLike(commentId, loginUserId)) { - CommentLike commentLike = commentLikeAdaptor.findByCommentIdAndUserId(commentId, loginUserId); + CommentLike commentLike = commentLikeRepository.getByCommentIdAndUserId(commentId, loginUserId); if (isAuthorized(commentLike.getUser().getId(), loginUserId)) { - commentLikeAdaptor.delete(commentLike); + commentLikeRepository.delete(commentLike); return false; } throw new NotAuthorizedException(); } // 좋아요 없으면 새로 생성 CommentLike newLike = getCommentLike(request); - commentLikeAdaptor.save(newLike); + commentLikeRepository.save(newLike); return true; } /* ----- 내부 편의 메서드 ------ */ private Boolean existsCommentLike(Long commentId, Long userId) { - return commentLikeAdaptor.existsByCommentIdAndUserId(commentId, userId); + return commentLikeRepository.existsByCommentIdAndUserId(commentId, userId); } private CommentLike getCommentLike(CommentLikeCommand request) { return CommentLike.builder() - .user(userAdaptor.findById(request.loginUserId())) - .comment(commentAdaptor.findById(request.commentId())) + .user(userRepository.getById(request.loginUserId())) + .comment(commentRepository.getById(request.commentId())) .build(); } diff --git a/likelion-core/src/main/java/likelion/univ/domain/like/postlike/adaptor/PostLikeAdaptor.java b/likelion-core/src/main/java/likelion/univ/domain/like/postlike/adaptor/PostLikeAdaptor.java deleted file mode 100644 index ae33fc10..00000000 --- a/likelion-core/src/main/java/likelion/univ/domain/like/postlike/adaptor/PostLikeAdaptor.java +++ /dev/null @@ -1,48 +0,0 @@ -package likelion.univ.domain.like.postlike.adaptor; - -import likelion.univ.annotation.Adaptor; -import likelion.univ.domain.like.commentlike.exception.CommentLikeNotFoundException; -import likelion.univ.domain.like.postlike.entity.PostLike; -import likelion.univ.domain.like.postlike.exception.PostLikeNotFoundException; -import likelion.univ.domain.like.postlike.repository.PostLikeRepository; -import likelion.univ.domain.post.entity.Post; -import likelion.univ.domain.user.entity.User; -import lombok.RequiredArgsConstructor; - -import java.util.List; - -import static likelion.univ.domain.like.postlike.entity.QPostLike.postLike; - -@Adaptor -@RequiredArgsConstructor -public class PostLikeAdaptor { - private final PostLikeRepository postLikeRepository; - - public Boolean existsByPostIdAndAuthorId(Long postId, long userId) { - return postLikeRepository.existsByPostIdAndUserId(postId, userId); - } - - public Long save(PostLike postLike) { - PostLike savedLike = postLikeRepository.save(postLike); - return savedLike.getId(); - } - public void delete(PostLike postLike) { - postLikeRepository.delete(postLike); - } - - public PostLike findById(Long postLikeId) { - return postLikeRepository.findById(postLikeId).orElseThrow(() -> new PostLikeNotFoundException()); - } - public Long countByPostId(Long postId){ - return postLikeRepository.countByPostId(postId); - } - - public PostLike findByPostAndUser(Post post, User user) { - return postLikeRepository.findByPostAndUser(post, user).orElseThrow(() -> new CommentLikeNotFoundException()); - } - - public List findPostIdsByUserIdAndPostIdsIn(Long userId, List postIds){ - return postLikeRepository.findPostIdsByUserIdAndPostIdsIn(userId, postIds); - } -} - diff --git a/likelion-core/src/main/java/likelion/univ/domain/like/postlike/dto/PostLikeCommand.java b/likelion-core/src/main/java/likelion/univ/domain/like/postlike/dto/PostLikeCommand.java index 09ae03bb..a663b89a 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/like/postlike/dto/PostLikeCommand.java +++ b/likelion-core/src/main/java/likelion/univ/domain/like/postlike/dto/PostLikeCommand.java @@ -1,12 +1,7 @@ package likelion.univ.domain.like.postlike.dto; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; - public record PostLikeCommand( Long postId, Long loginUserId ) { - } diff --git a/likelion-core/src/main/java/likelion/univ/domain/like/postlike/dto/PostLikeDeleteServiceDto.java b/likelion-core/src/main/java/likelion/univ/domain/like/postlike/dto/PostLikeDeleteServiceDto.java index 0ae77580..7a7adecf 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/like/postlike/dto/PostLikeDeleteServiceDto.java +++ b/likelion-core/src/main/java/likelion/univ/domain/like/postlike/dto/PostLikeDeleteServiceDto.java @@ -1,9 +1,5 @@ package likelion.univ.domain.like.postlike.dto; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; - public record PostLikeDeleteServiceDto( Long postId, Long loginUserId diff --git a/likelion-core/src/main/java/likelion/univ/domain/like/postlike/entity/PostLike.java b/likelion-core/src/main/java/likelion/univ/domain/like/postlike/entity/PostLike.java index 63f0b049..1e3f28ac 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/like/postlike/entity/PostLike.java +++ b/likelion-core/src/main/java/likelion/univ/domain/like/postlike/entity/PostLike.java @@ -1,25 +1,35 @@ package likelion.univ.domain.like.postlike.entity; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; import likelion.univ.common.entity.BaseTimeEntity; import likelion.univ.domain.post.entity.Post; import likelion.univ.domain.user.entity.User; -import lombok.*; - -import javax.persistence.*; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class PostLike extends BaseTimeEntity { - @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "user_id", nullable = false) private User user; - @ManyToOne(fetch = FetchType.LAZY ) - @JoinColumn(name = "post_id" ) + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "post_id") private Post post; @Builder diff --git a/likelion-core/src/main/java/likelion/univ/domain/like/postlike/exception/PostLikeErrorCode.java b/likelion-core/src/main/java/likelion/univ/domain/like/postlike/exception/PostLikeErrorCode.java index 52b8020c..cfc12f33 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/like/postlike/exception/PostLikeErrorCode.java +++ b/likelion-core/src/main/java/likelion/univ/domain/like/postlike/exception/PostLikeErrorCode.java @@ -1,14 +1,15 @@ package likelion.univ.domain.like.postlike.exception; +import static likelion.univ.constant.StaticValue.NOT_FOUND; + import likelion.univ.exception.base.BaseErrorCode; import lombok.AllArgsConstructor; import lombok.Getter; -import static likelion.univ.constant.StaticValue.NOT_FOUND; - @Getter @AllArgsConstructor public enum PostLikeErrorCode implements BaseErrorCode { + LIKEPOST_NOT_FOUND(NOT_FOUND, "LIKEPOST_404", "LikePost가 존재하지 않습니다."); private final int httpStatus; diff --git a/likelion-core/src/main/java/likelion/univ/domain/like/postlike/repository/PostLikeCustomRepository.java b/likelion-core/src/main/java/likelion/univ/domain/like/postlike/repository/PostLikeCustomRepository.java index 05b57dde..1d5c5984 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/like/postlike/repository/PostLikeCustomRepository.java +++ b/likelion-core/src/main/java/likelion/univ/domain/like/postlike/repository/PostLikeCustomRepository.java @@ -3,5 +3,6 @@ import java.util.List; public interface PostLikeCustomRepository { + List findPostIdsByUserIdAndPostIdsIn(Long userId, List postIds); } diff --git a/likelion-core/src/main/java/likelion/univ/domain/like/postlike/repository/PostLikeRepository.java b/likelion-core/src/main/java/likelion/univ/domain/like/postlike/repository/PostLikeRepository.java index c1116ec4..5a2f796e 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/like/postlike/repository/PostLikeRepository.java +++ b/likelion-core/src/main/java/likelion/univ/domain/like/postlike/repository/PostLikeRepository.java @@ -1,14 +1,26 @@ package likelion.univ.domain.like.postlike.repository; +import java.util.Optional; +import likelion.univ.domain.like.commentlike.exception.CommentLikeNotFoundException; import likelion.univ.domain.like.postlike.entity.PostLike; +import likelion.univ.domain.like.postlike.exception.PostLikeNotFoundException; import likelion.univ.domain.post.entity.Post; import likelion.univ.domain.user.entity.User; import org.springframework.data.jpa.repository.JpaRepository; -import java.util.Optional; +public interface PostLikeRepository extends JpaRepository, PostLikeCustomRepository { + + default PostLike getById(Long postLikeId) { + return findById(postLikeId).orElseThrow(PostLikeNotFoundException::new); + } + + default PostLike getByPostAndUser(Post post, User user) { + return findByPostAndUser(post, user).orElseThrow(CommentLikeNotFoundException::new); + } -public interface PostLikeRepository extends JpaRepository, PostLikeCustomRepository { Optional findByPostAndUser(Post post, User user); + Long countByPostId(Long postId); + Boolean existsByPostIdAndUserId(Long postId, Long userId); } diff --git a/likelion-core/src/main/java/likelion/univ/domain/like/postlike/repository/impl/PostLikeCustomRepositoryImpl.java b/likelion-core/src/main/java/likelion/univ/domain/like/postlike/repository/impl/PostLikeCustomRepositoryImpl.java index f7c70988..f832a4b0 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/like/postlike/repository/impl/PostLikeCustomRepositoryImpl.java +++ b/likelion-core/src/main/java/likelion/univ/domain/like/postlike/repository/impl/PostLikeCustomRepositoryImpl.java @@ -1,19 +1,19 @@ package likelion.univ.domain.like.postlike.repository.impl; +import static likelion.univ.domain.like.postlike.entity.QPostLike.postLike; + import com.querydsl.jpa.impl.JPAQueryFactory; +import java.util.List; import likelion.univ.domain.like.postlike.repository.PostLikeCustomRepository; import lombok.RequiredArgsConstructor; -import java.util.List; - -import static likelion.univ.domain.like.postlike.entity.QPostLike.postLike; - @RequiredArgsConstructor -public class PostLikeCustomRepositoryImpl implements PostLikeCustomRepository{ +public class PostLikeCustomRepositoryImpl implements PostLikeCustomRepository { + private final JPAQueryFactory queryFactory; @Override - public List findPostIdsByUserIdAndPostIdsIn(Long userId, List postIds){ + public List findPostIdsByUserIdAndPostIdsIn(Long userId, List postIds) { List ids = queryFactory.select(postLike.post.id) .from(postLike) .where(postLike.user.id.eq(userId), postLike.post.id.in(postIds)) diff --git a/likelion-core/src/main/java/likelion/univ/domain/like/postlike/service/PostLikeDomainService.java b/likelion-core/src/main/java/likelion/univ/domain/like/postlike/service/PostLikeService.java similarity index 62% rename from likelion-core/src/main/java/likelion/univ/domain/like/postlike/service/PostLikeDomainService.java rename to likelion-core/src/main/java/likelion/univ/domain/like/postlike/service/PostLikeService.java index ea82430b..85c0a4d3 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/like/postlike/service/PostLikeDomainService.java +++ b/likelion-core/src/main/java/likelion/univ/domain/like/postlike/service/PostLikeService.java @@ -1,48 +1,47 @@ package likelion.univ.domain.like.postlike.service; import likelion.univ.domain.comment.exception.NotAuthorizedException; -import likelion.univ.domain.like.postlike.adaptor.PostLikeAdaptor; +import likelion.univ.domain.like.postlike.dto.PostLikeCommand; import likelion.univ.domain.like.postlike.entity.PostLike; -import likelion.univ.domain.post.adaptor.PostAdaptor; +import likelion.univ.domain.like.postlike.repository.PostLikeRepository; import likelion.univ.domain.post.entity.Post; -import likelion.univ.domain.like.postlike.dto.PostLikeCommand; -import likelion.univ.domain.user.adaptor.UserAdaptor; +import likelion.univ.domain.post.repository.PostRepository; import likelion.univ.domain.user.entity.User; +import likelion.univ.domain.user.repository.UserRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @Service @RequiredArgsConstructor -public class PostLikeDomainService { +public class PostLikeService { - private final PostLikeAdaptor postLikeAdaptor; - private final PostAdaptor postAdaptor; - private final UserAdaptor userAdaptor; + private final PostLikeRepository postLikeRepository; + private final PostRepository postRepository; + private final UserRepository userRepository; public boolean createOrDeletePostLike(PostLikeCommand request) { Long postId = request.postId(); Long loginUserId = request.loginUserId(); - Post post = postAdaptor.findById(postId); - User user = userAdaptor.findById(loginUserId); + Post post = postRepository.getById(postId); + User user = userRepository.getById(loginUserId); if (existsPostLike(postId, loginUserId)) { - PostLike postLike = postLikeAdaptor.findByPostAndUser(post, user); + PostLike postLike = postLikeRepository.getByPostAndUser(post, user); if (isAuthorized(postLike, loginUserId)) { - postLikeAdaptor.delete(postLike); + postLikeRepository.delete(postLike); return false; } throw new NotAuthorizedException(); } PostLike newPostLike = newPostLikeBy(request); - postLikeAdaptor.save(newPostLike); + postLikeRepository.save(newPostLike); return true; } private Boolean existsPostLike(Long postId, Long loginUserId) { - return postLikeAdaptor.existsByPostIdAndAuthorId(postId, loginUserId); + return postLikeRepository.existsByPostIdAndUserId(postId, loginUserId); } - private boolean isAuthorized(PostLike findPostLike, Long loginUserId) { Long authorId = findPostLike.getUser().getId(); return loginUserId.equals(authorId); @@ -51,13 +50,11 @@ private boolean isAuthorized(PostLike findPostLike, Long loginUserId) { private PostLike newPostLikeBy(PostLikeCommand request) { Long postId = request.postId(); Long loginUserId = request.loginUserId(); - Post findPost = postAdaptor.findById(postId); - User findUser = userAdaptor.findById(loginUserId); + Post findPost = postRepository.getById(postId); + User findUser = userRepository.getById(loginUserId); return PostLike.builder() .post(findPost) .user(findUser) .build(); } - - } diff --git a/likelion-core/src/main/java/likelion/univ/domain/post/adaptor/PostAdaptor.java b/likelion-core/src/main/java/likelion/univ/domain/post/adaptor/PostAdaptor.java deleted file mode 100644 index 52cd3f7c..00000000 --- a/likelion-core/src/main/java/likelion/univ/domain/post/adaptor/PostAdaptor.java +++ /dev/null @@ -1,90 +0,0 @@ -package likelion.univ.domain.post.adaptor; - -import likelion.univ.annotation.Adaptor; -import likelion.univ.domain.post.dto.response.PostEditData; -import likelion.univ.domain.post.dto.response.PostSimpleData; -import likelion.univ.domain.post.entity.Post; -import likelion.univ.domain.post.dto.enums.MainCategory; -import likelion.univ.domain.post.dto.enums.SubCategory; -import likelion.univ.domain.post.repository.PostRepository; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import likelion.univ.domain.post.exception.PostNotFoudException; - -import java.util.List; - -@Adaptor -@RequiredArgsConstructor -public class PostAdaptor { - private final PostRepository postRepository; - - public Post findById(Long postId) { - return postRepository.findById(postId).orElseThrow(PostNotFoudException::new); - } - - public PostEditData findPostEditByPostId(Long postId) { - return postRepository.findPostEditByPostId(postId); - } - - public Long save(Post post) { - Post savedPost = postRepository.save(post); - return savedPost.getId(); - } - - public void delete(Post post) { - postRepository.delete(post); - } - public void deleteAllByIdInBatch(List ids){ - postRepository.deleteAllByIdInBatch(ids); - } - - public Page findAllByAuthor_Id(Long userId, Pageable pageable){ - return postRepository.findAllByAuthor_Id(userId,pageable); - } - - public Page findByCommentAuthorId(Long userId, Pageable pageable){ - return postRepository.findByCommentAuthorId(userId,pageable); - } - - public Page findByPostLikeAuthorId(Long userId, Pageable pageable, String sort, String search){ - return postRepository.findByPostLikeAuthorId(userId,pageable,sort,search); - } - - public Page findByCategoriesOrderByCreatedDate(MainCategory mainCategory, SubCategory subCategory, Pageable pageable) { - return postRepository.findByCategoriesOrderByCreatedDate(mainCategory, subCategory, pageable); - } - - public Page findByCategoriesOrderByLikeCount(MainCategory mainCategory, SubCategory subCategory, Pageable pageable) { - return postRepository.findByCategoriesOrderByLikeCount(mainCategory, subCategory, pageable); - } - - public Page findByCategoriesOrderByCommentCount(MainCategory mainCategory, SubCategory subCategory, Pageable pageable) { - return postRepository.findByCategoriesOrderByCommentCount(mainCategory, subCategory, pageable); - } - - public Page findByCategoriesAndSearchTitleOrderByCreatedDate(String searchTitle, MainCategory mainCategory, SubCategory subCategory, Pageable pageable) { - return postRepository.findByCategoriesAndSearchTitleOrderByCreatedDate(searchTitle, mainCategory, subCategory, pageable); - } - public Page findByCategoriesAndSearchTitleOrderByCommentCount(String searchTitle, MainCategory mainCategory, SubCategory subCategory, Pageable pageable) { - return postRepository.findByCategoriesAndSearchTitleOrderByCommentCount(searchTitle, mainCategory, subCategory, pageable); - } - public Page findByCategoriesAndSearchTitleOrderByLikeCount(String searchTitle, MainCategory mainCategory, SubCategory subCategory, Pageable pageable) { - return postRepository.findByCategoriesAndSearchTitleOrderByLikeCount(searchTitle, mainCategory, subCategory, pageable); - } - public Page findBySearchTitleOrderByCreatedDate(String searchTitle, Pageable pageable) { - return postRepository.findBySearchTitleOrderByCreatedDate(searchTitle, pageable); - } - public Page findBySearchTitleOrderByCommentCount(String searchTitle, Pageable pageable) { - return postRepository.findBySearchTitleOrderByCommentCount(searchTitle, pageable); - } - public Page findBySearchTitleOrderByLikeCount(String searchTitle, Pageable pageable) { - return postRepository.findBySearchTitleOrderByLikeCount(searchTitle, pageable); - } - - public Page findPostsByCategoriesAndUniversityOrderByCreatedDate( - MainCategory mainCategory, SubCategory subCategory, Long universityId, Pageable pageable){ - return postRepository.findByCategoriesAndUniversityOrderByCreatedDate( - mainCategory, subCategory, universityId, pageable); - } -} diff --git a/likelion-core/src/main/java/likelion/univ/domain/post/dto/enums/MainCategory.java b/likelion-core/src/main/java/likelion/univ/domain/post/dto/enums/MainCategory.java index 2bc18b5d..0d2038c5 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/post/dto/enums/MainCategory.java +++ b/likelion-core/src/main/java/likelion/univ/domain/post/dto/enums/MainCategory.java @@ -3,15 +3,17 @@ import likelion.univ.domain.post.exception.NoSuchCategoryException; import lombok.Getter; import lombok.RequiredArgsConstructor; -import org.jboss.jandex.Main; @Getter @RequiredArgsConstructor public enum MainCategory { + HQ_BOARD("멋쟁이사자처럼"), FREE_BOARD("자유게시판"), OVERFLOW("트랙별 소통 채널"); + private final String title; + public static MainCategory findByTitle(String title) { if (title.equals(HQ_BOARD.title)) { return HQ_BOARD; diff --git a/likelion-core/src/main/java/likelion/univ/domain/post/dto/enums/PostOrderCondition.java b/likelion-core/src/main/java/likelion/univ/domain/post/dto/enums/PostOrderCondition.java index f6a435df..d04f460d 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/post/dto/enums/PostOrderCondition.java +++ b/likelion-core/src/main/java/likelion/univ/domain/post/dto/enums/PostOrderCondition.java @@ -6,6 +6,7 @@ @Getter @RequiredArgsConstructor public enum PostOrderCondition { + CREATED_DATE_ORDER("최신순"), LIKE_COUNT_ORDER("좋아요순"), COMMENT_COUNT_ORDER("댓글순"); diff --git a/likelion-core/src/main/java/likelion/univ/domain/post/dto/enums/SubCategory.java b/likelion-core/src/main/java/likelion/univ/domain/post/dto/enums/SubCategory.java index 4e7249b7..aa9b72c1 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/post/dto/enums/SubCategory.java +++ b/likelion-core/src/main/java/likelion/univ/domain/post/dto/enums/SubCategory.java @@ -1,7 +1,6 @@ package likelion.univ.domain.post.dto.enums; - import likelion.univ.domain.post.exception.NoSuchCategoryException; import lombok.Getter; import lombok.RequiredArgsConstructor; @@ -9,50 +8,52 @@ @Getter @RequiredArgsConstructor public enum SubCategory { - // HQ - NOTICE("공지사항"), - - // board - INFO("정보공유"), - GET_MEMBER("프로젝트 팀원 모집"), - SHOWOFF("프로젝트 자랑"), - - // overflow - FRONTEND("프론트엔드"), - BACKEND("백엔드"), - PM("기획"), - DESIGN("디자인"), - ETC("기타"); - - private final String title; - - public static SubCategory findByTitle(String title) { - if (title.equals(NOTICE.title)) { - return NOTICE; - } else if (title.equals(INFO.title)) { - return INFO; - } else if (title.equals(GET_MEMBER.title)) { - return GET_MEMBER; - } else if (title.equals(SHOWOFF.title)) { - return SHOWOFF; - } else if (title.equals(FRONTEND.title)) { - return FRONTEND; - } else if (title.equals(BACKEND.title)) { - return BACKEND; - } else if (title.equals(PM.title)) { - return PM; - } else if (title.equals(DESIGN.title)) { - return DESIGN; - } else if (title.equals(ETC.title)) { - return ETC; - } - throw new NoSuchCategoryException(); - } - public static boolean isValid(String title) { - if (SubCategory.findByTitle(title) == null) { - return false; - } - return true; - } + + // HQ + NOTICE("공지사항"), + + // board + INFO("정보공유"), + GET_MEMBER("프로젝트 팀원 모집"), + SHOWOFF("프로젝트 자랑"), + + // overflow + FRONTEND("프론트엔드"), + BACKEND("백엔드"), + PM("기획"), + DESIGN("디자인"), + ETC("기타"); + + private final String title; + + public static SubCategory findByTitle(String title) { + if (title.equals(NOTICE.title)) { + return NOTICE; + } else if (title.equals(INFO.title)) { + return INFO; + } else if (title.equals(GET_MEMBER.title)) { + return GET_MEMBER; + } else if (title.equals(SHOWOFF.title)) { + return SHOWOFF; + } else if (title.equals(FRONTEND.title)) { + return FRONTEND; + } else if (title.equals(BACKEND.title)) { + return BACKEND; + } else if (title.equals(PM.title)) { + return PM; + } else if (title.equals(DESIGN.title)) { + return DESIGN; + } else if (title.equals(ETC.title)) { + return ETC; + } + throw new NoSuchCategoryException(); + } + + public static boolean isValid(String title) { + if (SubCategory.findByTitle(title) == null) { + return false; + } + return true; + } } diff --git a/likelion-core/src/main/java/likelion/univ/domain/post/dto/request/CreatePostCommand.java b/likelion-core/src/main/java/likelion/univ/domain/post/dto/request/CreatePostCommand.java index e7a7f67b..b4500619 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/post/dto/request/CreatePostCommand.java +++ b/likelion-core/src/main/java/likelion/univ/domain/post/dto/request/CreatePostCommand.java @@ -2,9 +2,7 @@ import likelion.univ.domain.post.dto.enums.MainCategory; import likelion.univ.domain.post.dto.enums.SubCategory; -import lombok.AllArgsConstructor; import lombok.Builder; -import lombok.Data; @Builder public record CreatePostCommand( @@ -15,5 +13,4 @@ public record CreatePostCommand( MainCategory mainCategory, SubCategory subCategory ) { - } diff --git a/likelion-core/src/main/java/likelion/univ/domain/post/dto/request/DeletePostCommand.java b/likelion-core/src/main/java/likelion/univ/domain/post/dto/request/DeletePostCommand.java index 0599f936..f5aa2323 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/post/dto/request/DeletePostCommand.java +++ b/likelion-core/src/main/java/likelion/univ/domain/post/dto/request/DeletePostCommand.java @@ -1,8 +1,6 @@ package likelion.univ.domain.post.dto.request; -import lombok.AllArgsConstructor; import lombok.Builder; -import lombok.Data; @Builder public record DeletePostCommand( diff --git a/likelion-core/src/main/java/likelion/univ/domain/post/dto/request/GetPostDetailCommand.java b/likelion-core/src/main/java/likelion/univ/domain/post/dto/request/GetPostDetailCommand.java index f38ae92f..58ef4b7b 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/post/dto/request/GetPostDetailCommand.java +++ b/likelion-core/src/main/java/likelion/univ/domain/post/dto/request/GetPostDetailCommand.java @@ -4,5 +4,4 @@ public record GetPostDetailCommand( Long postId, Long loginUserId ) { - } diff --git a/likelion-core/src/main/java/likelion/univ/domain/post/dto/request/GetPostsByCategoriesCommand.java b/likelion-core/src/main/java/likelion/univ/domain/post/dto/request/GetPostsByCategoriesCommand.java index 9692c4d1..5e23bd57 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/post/dto/request/GetPostsByCategoriesCommand.java +++ b/likelion-core/src/main/java/likelion/univ/domain/post/dto/request/GetPostsByCategoriesCommand.java @@ -1,9 +1,7 @@ package likelion.univ.domain.post.dto.request; import likelion.univ.domain.post.dto.enums.MainCategory; -import likelion.univ.domain.post.dto.enums.PostOrderCondition; import likelion.univ.domain.post.dto.enums.SubCategory; -import org.springframework.data.domain.Pageable; public record GetPostsByCategoriesCommand( MainCategory mainCategory, diff --git a/likelion-core/src/main/java/likelion/univ/domain/post/dto/request/GetPostsByCategorySearchCommand.java b/likelion-core/src/main/java/likelion/univ/domain/post/dto/request/GetPostsByCategorySearchCommand.java index 62672932..5eef92b3 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/post/dto/request/GetPostsByCategorySearchCommand.java +++ b/likelion-core/src/main/java/likelion/univ/domain/post/dto/request/GetPostsByCategorySearchCommand.java @@ -4,7 +4,6 @@ import likelion.univ.domain.post.dto.enums.MainCategory; import likelion.univ.domain.post.dto.enums.PostOrderCondition; import likelion.univ.domain.post.dto.enums.SubCategory; -import org.springframework.data.domain.Pageable; public record GetPostsByCategorySearchCommand( @@ -13,7 +12,16 @@ public record GetPostsByCategorySearchCommand( MainCategory mainCategory, SubCategory subCategory ) { - public GetPostsByCategorySearchCommand(PostOrderCondition orderCondition, String searchTitle, String mainCategory, String subCategory) { - this(orderCondition, searchTitle, MainCategory.findByTitle(mainCategory), SubCategory.findByTitle(subCategory)); + + public GetPostsByCategorySearchCommand( + PostOrderCondition orderCondition, + String searchTitle, + String mainCategory, + String subCategory + ) { + this(orderCondition, + searchTitle, + MainCategory.findByTitle(mainCategory), + SubCategory.findByTitle(subCategory)); } } diff --git a/likelion-core/src/main/java/likelion/univ/domain/post/dto/request/GetPostsBySearchTitleCommand.java b/likelion-core/src/main/java/likelion/univ/domain/post/dto/request/GetPostsBySearchTitleCommand.java index e9f74e8b..d1000177 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/post/dto/request/GetPostsBySearchTitleCommand.java +++ b/likelion-core/src/main/java/likelion/univ/domain/post/dto/request/GetPostsBySearchTitleCommand.java @@ -1,7 +1,6 @@ package likelion.univ.domain.post.dto.request; import likelion.univ.domain.post.dto.enums.PostOrderCondition; -import org.springframework.data.domain.Pageable; public record GetPostsBySearchTitleCommand( PostOrderCondition orderCondition, diff --git a/likelion-core/src/main/java/likelion/univ/domain/post/dto/request/UpdatePostCommand.java b/likelion-core/src/main/java/likelion/univ/domain/post/dto/request/UpdatePostCommand.java index bd096a60..668f6833 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/post/dto/request/UpdatePostCommand.java +++ b/likelion-core/src/main/java/likelion/univ/domain/post/dto/request/UpdatePostCommand.java @@ -1,8 +1,6 @@ package likelion.univ.domain.post.dto.request; -import lombok.AllArgsConstructor; import lombok.Builder; -import lombok.Data; @Builder public record UpdatePostCommand( diff --git a/likelion-core/src/main/java/likelion/univ/domain/post/dto/response/PostData.java b/likelion-core/src/main/java/likelion/univ/domain/post/dto/response/PostData.java index a96c942f..fee1e5bc 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/post/dto/response/PostData.java +++ b/likelion-core/src/main/java/likelion/univ/domain/post/dto/response/PostData.java @@ -1,9 +1,7 @@ package likelion.univ.domain.post.dto.response; -import likelion.univ.common.processor.DateCustomFormatter; - import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; +import likelion.univ.common.processor.DateCustomFormatter; public record PostData( Long postId, @@ -17,6 +15,7 @@ public record PostData( Long commentCount, LocalDateTime createdDate ) { + public static PostData getInstance(PostSimpleData post, Long likeCount, Long commentCount) { return new PostData( post.postId(), @@ -31,8 +30,8 @@ public static PostData getInstance(PostSimpleData post, Long likeCount, Long com post.createdDate() ); } + public String getFormattedDate() { return DateCustomFormatter.format(this.createdDate); } - } diff --git a/likelion-core/src/main/java/likelion/univ/domain/post/dto/response/PostDetailData.java b/likelion-core/src/main/java/likelion/univ/domain/post/dto/response/PostDetailData.java index 3f5e2bf2..cb1dcb62 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/post/dto/response/PostDetailData.java +++ b/likelion-core/src/main/java/likelion/univ/domain/post/dto/response/PostDetailData.java @@ -1,17 +1,11 @@ package likelion.univ.domain.post.dto.response; +import java.time.LocalDateTime; import likelion.univ.common.processor.DateCustomFormatter; -import likelion.univ.domain.comment.dto.response.ChildCommentData; -import likelion.univ.domain.comment.dto.response.ParentCommentData; import likelion.univ.domain.post.dto.enums.MainCategory; import likelion.univ.domain.post.dto.enums.SubCategory; import lombok.Builder; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.time.format.FormatStyle; -import java.util.List; - @Builder public record PostDetailData( Long postId, @@ -29,8 +23,8 @@ public record PostDetailData( String body, LocalDateTime createdDate ) { + public String getFormattedDate() { return DateCustomFormatter.format(this.createdDate); } - } diff --git a/likelion-core/src/main/java/likelion/univ/domain/post/dto/response/PostEditData.java b/likelion-core/src/main/java/likelion/univ/domain/post/dto/response/PostEditData.java index bb01f50f..a9c64137 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/post/dto/response/PostEditData.java +++ b/likelion-core/src/main/java/likelion/univ/domain/post/dto/response/PostEditData.java @@ -12,8 +12,16 @@ public record PostEditData( MainCategory mainCategory, SubCategory subCategory ) { + @QueryProjection - public PostEditData(Long postId, String title, String body, String thumbnail, MainCategory mainCategory, SubCategory subCategory) { + public PostEditData( + Long postId, + String title, + String body, + String thumbnail, + MainCategory mainCategory, + SubCategory subCategory + ) { this.postId = postId; this.title = title; this.body = body; diff --git a/likelion-core/src/main/java/likelion/univ/domain/post/dto/response/PostSimpleData.java b/likelion-core/src/main/java/likelion/univ/domain/post/dto/response/PostSimpleData.java index 4a0d0ad1..e6dc462c 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/post/dto/response/PostSimpleData.java +++ b/likelion-core/src/main/java/likelion/univ/domain/post/dto/response/PostSimpleData.java @@ -1,31 +1,32 @@ package likelion.univ.domain.post.dto.response; import com.querydsl.core.annotations.QueryProjection; +import java.time.LocalDateTime; import likelion.univ.common.processor.DateCustomFormatter; import likelion.univ.domain.post.dto.enums.MainCategory; import likelion.univ.domain.post.dto.enums.SubCategory; import likelion.univ.domain.post.entity.Post; import lombok.Builder; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; - @Builder public record PostSimpleData( - Long postId, - Long authorId, - MainCategory mainCategory, - SubCategory subCategory, - String authorName, - String authorProfileImageUrl, - String title, - String body, - String thumbnailUrl, - LocalDateTime createdDate + Long postId, + Long authorId, + MainCategory mainCategory, + SubCategory subCategory, + String authorName, + String authorProfileImageUrl, + String title, + String body, + String thumbnailUrl, + LocalDateTime createdDate ) { + @QueryProjection - public PostSimpleData(Long postId, Long authorId, MainCategory mainCategory, SubCategory subCategory, String authorName, String authorProfileImageUrl, String title, String body, String thumbnailUrl, LocalDateTime createdDate) { + public PostSimpleData(Long postId, Long authorId, MainCategory mainCategory, SubCategory subCategory, + String authorName, String authorProfileImageUrl, String title, String body, + String thumbnailUrl, LocalDateTime createdDate) { this.postId = postId; this.authorId = authorId; this.mainCategory = mainCategory; @@ -57,12 +58,14 @@ public String getParsedBody() { String noImgBody = this.removeImageTag(this.body); return this.shortenString(noImgBody); } + private String removeImageTag(String imageIncluded) { String imageExcluded = imageIncluded .replaceAll("", "") .replaceAll("

<\\/p>", ""); return imageExcluded; } + private String shortenString(String longString) { if (longString.length() < 300) { return longString; @@ -73,6 +76,4 @@ private String shortenString(String longString) { public String getFormattedDate() { return DateCustomFormatter.format(this.createdDate); } - - } diff --git a/likelion-core/src/main/java/likelion/univ/domain/post/entity/Post.java b/likelion-core/src/main/java/likelion/univ/domain/post/entity/Post.java index 17486639..1de4d3bb 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/post/entity/Post.java +++ b/likelion-core/src/main/java/likelion/univ/domain/post/entity/Post.java @@ -1,17 +1,31 @@ package likelion.univ.domain.post.entity; +import java.util.ArrayList; +import java.util.List; +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; import likelion.univ.common.entity.BaseTimeEntity; import likelion.univ.domain.comment.entity.Comment; import likelion.univ.domain.like.postlike.entity.PostLike; -import likelion.univ.domain.post.dto.request.UpdatePostCommand; import likelion.univ.domain.post.dto.enums.MainCategory; import likelion.univ.domain.post.dto.enums.SubCategory; +import likelion.univ.domain.post.dto.request.UpdatePostCommand; import likelion.univ.domain.user.entity.User; -import lombok.*; - -import javax.persistence.*; -import java.util.ArrayList; -import java.util.List; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -19,6 +33,7 @@ @AllArgsConstructor @Entity public class Post extends BaseTimeEntity { + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @@ -30,17 +45,17 @@ public class Post extends BaseTimeEntity { @Column(length = 100) private String title; - @Column(columnDefinition="TEXT") + @Column(columnDefinition = "TEXT") private String body; private String thumbnail; @OneToMany(cascade = {CascadeType.PERSIST, CascadeType.REMOVE}, orphanRemoval = true) - @JoinColumn(name="post_id", insertable = false, updatable = false) + @JoinColumn(name = "post_id", insertable = false, updatable = false) private List postLikes = new ArrayList(); @OneToMany(cascade = CascadeType.ALL) - @JoinColumn(name="post_id", insertable = false, updatable = false) + @JoinColumn(name = "post_id", insertable = false, updatable = false) private List comments = new ArrayList<>(); @Enumerated(EnumType.STRING) @@ -68,5 +83,4 @@ public void edit(UpdatePostCommand request) { this.subCategory = SubCategory.findByTitle(request.subCategory()); } } - } diff --git a/likelion-core/src/main/java/likelion/univ/domain/post/exception/NoSuchCategoryException.java b/likelion-core/src/main/java/likelion/univ/domain/post/exception/NoSuchCategoryException.java index 6c838b86..30123580 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/post/exception/NoSuchCategoryException.java +++ b/likelion-core/src/main/java/likelion/univ/domain/post/exception/NoSuchCategoryException.java @@ -1,9 +1,9 @@ package likelion.univ.domain.post.exception; import likelion.univ.exception.base.BaseException; -import lombok.Getter; public class NoSuchCategoryException extends BaseException { + public NoSuchCategoryException() { super(PostErrorCode.CATEGORY_NOT_FOUND); } diff --git a/likelion-core/src/main/java/likelion/univ/domain/post/exception/PostErrorCode.java b/likelion-core/src/main/java/likelion/univ/domain/post/exception/PostErrorCode.java index db7f0eff..57f1ff40 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/post/exception/PostErrorCode.java +++ b/likelion-core/src/main/java/likelion/univ/domain/post/exception/PostErrorCode.java @@ -1,15 +1,16 @@ package likelion.univ.domain.post.exception; +import static likelion.univ.constant.StaticValue.BAD_REQUEST; +import static likelion.univ.constant.StaticValue.NOT_FOUND; + import likelion.univ.exception.base.BaseErrorCode; import lombok.AllArgsConstructor; import lombok.Getter; -import static likelion.univ.constant.StaticValue.BAD_REQUEST; -import static likelion.univ.constant.StaticValue.NOT_FOUND; - @Getter @AllArgsConstructor public enum PostErrorCode implements BaseErrorCode { + POST_NOT_FOUND(NOT_FOUND, "POST_404", "Post가 존재하지 않습니다."), AUTHOR_NOT_AUTHORIZED(BAD_REQUEST, "POST_401", "Post의 작성자가 아닙니다."), CATEGORY_NOT_FOUND(NOT_FOUND, "POST_400", "잘못된 Category 요청입니다."); diff --git a/likelion-core/src/main/java/likelion/univ/domain/post/exception/PostNoAuthorizationException.java b/likelion-core/src/main/java/likelion/univ/domain/post/exception/PostNoAuthorizationException.java index 332f29f5..1d89685b 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/post/exception/PostNoAuthorizationException.java +++ b/likelion-core/src/main/java/likelion/univ/domain/post/exception/PostNoAuthorizationException.java @@ -3,6 +3,7 @@ import likelion.univ.exception.base.BaseException; public class PostNoAuthorizationException extends BaseException { + public PostNoAuthorizationException() { super(PostErrorCode.AUTHOR_NOT_AUTHORIZED); } diff --git a/likelion-core/src/main/java/likelion/univ/domain/post/exception/PostNotFoudException.java b/likelion-core/src/main/java/likelion/univ/domain/post/exception/PostNotFoundException.java similarity index 61% rename from likelion-core/src/main/java/likelion/univ/domain/post/exception/PostNotFoudException.java rename to likelion-core/src/main/java/likelion/univ/domain/post/exception/PostNotFoundException.java index 00ce1367..b16f9941 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/post/exception/PostNotFoudException.java +++ b/likelion-core/src/main/java/likelion/univ/domain/post/exception/PostNotFoundException.java @@ -2,9 +2,9 @@ import likelion.univ.exception.base.BaseException; -public class PostNotFoudException extends BaseException { +public class PostNotFoundException extends BaseException { - public PostNotFoudException() { + public PostNotFoundException() { super(PostErrorCode.POST_NOT_FOUND); } } diff --git a/likelion-core/src/main/java/likelion/univ/domain/post/repository/PostCommandCustomRepository.java b/likelion-core/src/main/java/likelion/univ/domain/post/repository/PostCommandCustomRepository.java index 3cd1ff42..7df358c4 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/post/repository/PostCommandCustomRepository.java +++ b/likelion-core/src/main/java/likelion/univ/domain/post/repository/PostCommandCustomRepository.java @@ -2,7 +2,4 @@ public interface PostCommandCustomRepository { - - - } diff --git a/likelion-core/src/main/java/likelion/univ/domain/post/repository/PostCommandCustomRepositoryImpl.java b/likelion-core/src/main/java/likelion/univ/domain/post/repository/PostCommandCustomRepositoryImpl.java index e6a32b85..11378ab8 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/post/repository/PostCommandCustomRepositoryImpl.java +++ b/likelion-core/src/main/java/likelion/univ/domain/post/repository/PostCommandCustomRepositoryImpl.java @@ -1,18 +1,7 @@ package likelion.univ.domain.post.repository; -import likelion.univ.domain.post.entity.Post; -import likelion.univ.domain.user.entity.User; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Repository; -import java.util.List; - -import static likelion.univ.domain.post.entity.QPost.post; -import static likelion.univ.domain.user.entity.QUser.user; - @Repository public class PostCommandCustomRepositoryImpl implements PostCommandCustomRepository { - } diff --git a/likelion-core/src/main/java/likelion/univ/domain/post/repository/PostCustomRepository.java b/likelion-core/src/main/java/likelion/univ/domain/post/repository/PostCustomRepository.java index c858eb25..3550ac74 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/post/repository/PostCustomRepository.java +++ b/likelion-core/src/main/java/likelion/univ/domain/post/repository/PostCustomRepository.java @@ -1,35 +1,67 @@ package likelion.univ.domain.post.repository; import likelion.univ.common.query.BaseQueryDslRepository; +import likelion.univ.domain.post.dto.enums.MainCategory; +import likelion.univ.domain.post.dto.enums.SubCategory; import likelion.univ.domain.post.dto.response.PostEditData; import likelion.univ.domain.post.dto.response.PostSimpleData; import likelion.univ.domain.post.entity.Post; -import likelion.univ.domain.post.dto.enums.MainCategory; -import likelion.univ.domain.post.dto.enums.SubCategory; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; public interface PostCustomRepository extends BaseQueryDslRepository { + PostEditData findPostEditByPostId(Long postId); + Page findByCommentAuthorId(Long userId, Pageable pageable); Page findByPostLikeAuthorId(Long userId, Pageable pageable); - Page findByCategoriesOrderByCreatedDate(MainCategory mainCategory, SubCategory subCategory, Pageable pageable); + + Page findByCategoriesOrderByCreatedDate( + MainCategory mainCategory, + SubCategory subCategory, + Pageable pageable + ); Page findByCategoriesOrderByLikeCount(MainCategory mainCategory, SubCategory subCategory, Pageable pageable); - Page findByCategoriesOrderByCommentCount(MainCategory mainCategory, SubCategory subCategory, Pageable pageable); + Page findByCategoriesOrderByCommentCount( + MainCategory mainCategory, + SubCategory subCategory, + Pageable pageable + ); - Page findByCategoriesAndSearchTitleOrderByCommentCount(String searchTitle, MainCategory mainCategory, SubCategory subCategory, Pageable pageable); + Page findByCategoriesAndSearchTitleOrderByCommentCount( + String searchTitle, + MainCategory mainCategory, + SubCategory subCategory, + Pageable pageable + ); - Page findByCategoriesAndSearchTitleOrderByLikeCount(String searchTitle, MainCategory mainCategory, SubCategory subCategory, Pageable pageable); + Page findByCategoriesAndSearchTitleOrderByLikeCount( + String searchTitle, + MainCategory mainCategory, + SubCategory subCategory, + Pageable pageable + ); - Page findByCategoriesAndSearchTitleOrderByCreatedDate(String searchTitle, MainCategory mainCategory, SubCategory subCategory, Pageable pageable); + Page findByCategoriesAndSearchTitleOrderByCreatedDate( + String searchTitle, + MainCategory mainCategory, + SubCategory subCategory, + Pageable pageable + ); Page findBySearchTitleOrderByCreatedDate(String searchTitle, Pageable pageable); + Page findByPostLikeAuthorId(Long userId, Pageable pageable, String sort, String search); + Page findByCategoriesAndUniversityOrderByCreatedDate( - MainCategory mainCategory, SubCategory subCategory, Long universityId, Pageable pageable); + MainCategory mainCategory, + SubCategory subCategory, + Long universityId, + Pageable pageable + ); Page findBySearchTitleOrderByCommentCount(String searchTitle, Pageable pageable); diff --git a/likelion-core/src/main/java/likelion/univ/domain/post/repository/PostRepository.java b/likelion-core/src/main/java/likelion/univ/domain/post/repository/PostRepository.java index 4c7f06f8..3b1f2600 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/post/repository/PostRepository.java +++ b/likelion-core/src/main/java/likelion/univ/domain/post/repository/PostRepository.java @@ -1,12 +1,17 @@ package likelion.univ.domain.post.repository; import likelion.univ.domain.post.entity.Post; +import likelion.univ.domain.post.exception.PostNotFoundException; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; - public interface PostRepository extends JpaRepository, PostCustomRepository { - Page findAllByAuthor_Id(Long userId, Pageable pageable); + + default Post getById(Long postId) { + return findById(postId).orElseThrow(PostNotFoundException::new); + } + + Page findAllByAuthorId(Long userId, Pageable pageable); } diff --git a/likelion-core/src/main/java/likelion/univ/domain/post/repository/impl/PostCustomRepositoryImpl.java b/likelion-core/src/main/java/likelion/univ/domain/post/repository/impl/PostCustomRepositoryImpl.java index 5b4e8410..d6a88516 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/post/repository/impl/PostCustomRepositoryImpl.java +++ b/likelion-core/src/main/java/likelion/univ/domain/post/repository/impl/PostCustomRepositoryImpl.java @@ -1,16 +1,25 @@ package likelion.univ.domain.post.repository.impl; +import static likelion.univ.domain.comment.entity.QComment.comment; +import static likelion.univ.domain.like.postlike.entity.QPostLike.postLike; +import static likelion.univ.domain.post.entity.QPost.post; +import static likelion.univ.domain.university.entity.QUniversity.university; +import static likelion.univ.domain.user.entity.QUser.user; + import com.querydsl.core.types.OrderSpecifier; import com.querydsl.core.types.Predicate; import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.jpa.impl.JPAQueryFactory; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import likelion.univ.domain.post.dto.enums.MainCategory; +import likelion.univ.domain.post.dto.enums.SubCategory; import likelion.univ.domain.post.dto.response.PostEditData; import likelion.univ.domain.post.dto.response.PostSimpleData; import likelion.univ.domain.post.dto.response.QPostEditData; import likelion.univ.domain.post.dto.response.QPostSimpleData; import likelion.univ.domain.post.entity.Post; -import likelion.univ.domain.post.dto.enums.MainCategory; -import likelion.univ.domain.post.dto.enums.SubCategory; import likelion.univ.domain.post.repository.PostCustomRepository; import likelion.univ.domain.post.repository.impl.condition.PostSortType; import lombok.RequiredArgsConstructor; @@ -19,16 +28,6 @@ import org.springframework.data.domain.Pageable; import org.springframework.util.StringUtils; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; - -import static likelion.univ.domain.comment.entity.QComment.comment; -import static likelion.univ.domain.like.postlike.entity.QPostLike.postLike; -import static likelion.univ.domain.post.entity.QPost.post; -import static likelion.univ.domain.university.entity.QUniversity.university; -import static likelion.univ.domain.user.entity.QUser.user; - @RequiredArgsConstructor public class PostCustomRepositoryImpl implements PostCustomRepository { @@ -45,32 +44,36 @@ public PostEditData findPostEditByPostId(Long postId) { /* ----- 마이 페이지 ----- */ @Override - public Page findByCommentAuthorId(Long userId, Pageable pageable){ + public Page findByCommentAuthorId(Long userId, Pageable pageable) { List ids = getCoveringIndexByComment(comment.author.id.eq(userId) - .and(comment.isDeleted.isFalse())); + .and(comment.isDeleted.isFalse())); return findByCoveringIndexOrderByCreatedDate(ids, pageable); } + @Override - public Page findByPostLikeAuthorId(Long userId, Pageable pageable){ + public Page findByPostLikeAuthorId(Long userId, Pageable pageable) { List ids = getCoveringIndexByPostLike(postLike.user.id.eq(userId)); return findByCoveringIndexOrderByCreatedDate(ids, pageable); } /* ----- 커뮤니티 ----- */ @Override - public Page findByCategoriesOrderByCreatedDate(MainCategory mainCategory, SubCategory subCategory, Pageable pageable) { + public Page findByCategoriesOrderByCreatedDate(MainCategory mainCategory, SubCategory subCategory, + Pageable pageable) { List ids = getCoveringIndexByPost(post.mainCategory.eq(mainCategory) - .and(post.subCategory.eq(subCategory))); + .and(post.subCategory.eq(subCategory))); return findByCoveringIndexOrderByCreatedDate(ids, pageable); } @Override - public Page findByCategoriesOrderByLikeCount(MainCategory mainCategory, SubCategory subCategory, Pageable pageable) { + public Page findByCategoriesOrderByLikeCount(MainCategory mainCategory, SubCategory subCategory, + Pageable pageable) { List ids = getCoveringIndexByPost(post.mainCategory.eq(mainCategory) .and(post.subCategory.eq(subCategory))); return findByCoveringIndexOrderByLikeCount(ids, pageable); } - public Page findByPostLikeAuthorId(Long userId, Pageable pageable, String sort, String search){ + + public Page findByPostLikeAuthorId(Long userId, Pageable pageable, String sort, String search) { List ids = getCoveringIndexByPostLike(postLike.user.id.eq(userId)); return findByPostLikesWithSort(ids, pageable, PostSortType.toOrderSpecifier(sort), search); } @@ -80,7 +83,7 @@ public Page findByCategoriesAndUniversityOrderByCreatedDate( MainCategory mainCategory, SubCategory subCategory, Long universityId, Pageable pageable) { List ids = queryFactory - .select(post.id, post.createdDate,post.postLikes.size(), post.comments.size()) + .select(post.id, post.createdDate, post.postLikes.size(), post.comments.size()) .from(post) .join(post.author, user) .join(user.universityInfo.university, university) @@ -104,14 +107,18 @@ public Page findByCategoriesAndUniversityOrderByCreatedDate( } @Override - public Page findByCategoriesOrderByCommentCount(MainCategory mainCategory, SubCategory subCategory, Pageable pageable) { + public Page findByCategoriesOrderByCommentCount(MainCategory mainCategory, SubCategory subCategory, + Pageable pageable) { List ids = getCoveringIndexByPost(post.mainCategory.eq(mainCategory) .and(post.subCategory.eq(subCategory))); return findByCoveringIndexOrderByCommentCount(ids, pageable); } @Override - public Page findByCategoriesAndSearchTitleOrderByCommentCount(String searchTitle, MainCategory mainCategory, SubCategory subCategory, Pageable pageable) { + public Page findByCategoriesAndSearchTitleOrderByCommentCount(String searchTitle, + MainCategory mainCategory, + SubCategory subCategory, + Pageable pageable) { long totalSize = getCategorySearchResultSize(searchTitle, mainCategory, subCategory); List posts = queryFactory @@ -130,7 +137,10 @@ public Page findByCategoriesAndSearchTitleOrderByCommentCount(St } @Override - public Page findByCategoriesAndSearchTitleOrderByLikeCount(String searchTitle, MainCategory mainCategory, SubCategory subCategory, Pageable pageable) { + public Page findByCategoriesAndSearchTitleOrderByLikeCount(String searchTitle, + MainCategory mainCategory, + SubCategory subCategory, + Pageable pageable) { long totalSize = getCategorySearchResultSize(searchTitle, mainCategory, subCategory); List posts = queryFactory @@ -149,7 +159,10 @@ public Page findByCategoriesAndSearchTitleOrderByLikeCount(Strin } @Override - public Page findByCategoriesAndSearchTitleOrderByCreatedDate(String searchTitle, MainCategory mainCategory, SubCategory subCategory, Pageable pageable) { + public Page findByCategoriesAndSearchTitleOrderByCreatedDate(String searchTitle, + MainCategory mainCategory, + SubCategory subCategory, + Pageable pageable) { long totalSize = getCategorySearchResultSize(searchTitle, mainCategory, subCategory); List posts = queryFactory @@ -158,8 +171,8 @@ public Page findByCategoriesAndSearchTitleOrderByCreatedDate(Str .join(post.author, user) .where( post.title.containsIgnoreCase(searchTitle) - .and(post.mainCategory.eq(mainCategory) - .and(post.subCategory.eq(subCategory)))) + .and(post.mainCategory.eq(mainCategory) + .and(post.subCategory.eq(subCategory)))) .offset(pageable.getOffset()) .orderBy(post.createdDate.desc()) .limit(pageable.getPageSize()) @@ -220,6 +233,7 @@ public Page findBySearchTitleOrderByLikeCount(String searchTitle private List getCoveringIndexByComment(Predicate predicate) { return queryFactory.select(comment.post.id).from(comment).where(predicate).fetch(); } + private List getCoveringIndexByPostLike(Predicate predicate) { return queryFactory.select(postLike.post.id).from(postLike).where(predicate).fetch(); } @@ -227,6 +241,7 @@ private List getCoveringIndexByPostLike(Predicate predicate) { private BooleanExpression searchCondition(String search) { return StringUtils.hasText(search) ? post.body.contains(search).or(post.title.contains(search)) : null; } + private List getCoveringIndexByPost(Predicate predicate) { return queryFactory .select(post.id) @@ -235,7 +250,7 @@ private List getCoveringIndexByPost(Predicate predicate) { .fetch(); } - private Page findByCoveringIndexOrderByCreatedDate(List ids, Pageable pageable) { + private Page findByCoveringIndexOrderByCreatedDate(List ids, Pageable pageable) { List posts = queryFactory .select(post) @@ -249,8 +264,8 @@ private Page findByCoveringIndexOrderByCreatedDate(List ids, Pageab return new PageImpl<>(posts, pageable, ids.size()); } - private Page findByUniversityAndCoveringIndexOrderByCreatedDate(List ids, Pageable pageable, - Long universityId){ + private Page findByUniversityAndCoveringIndexOrderByCreatedDate(List ids, Pageable pageable, + Long universityId) { List posts = queryFactory .select(post) @@ -276,6 +291,7 @@ private Page findByCoveringIndexOrderByLikeCount(List ids, Pageable .fetch(); return new PageImpl<>(posts, pageable, ids.size()); } + private Page findByCoveringIndexOrderByCommentCount(List ids, Pageable pageable) { List posts = queryFactory .selectFrom(post) @@ -295,6 +311,7 @@ private int getSearchResultSize(String searchTitle) { .where(post.title.containsIgnoreCase(searchTitle)) .fetch().size(); } + private int getCategorySearchResultSize(String searchTitle, MainCategory mainCategory, SubCategory subCategory) { return queryFactory .select(post.id) @@ -304,6 +321,7 @@ private int getCategorySearchResultSize(String searchTitle, MainCategory mainCat .where(post.title.containsIgnoreCase(searchTitle)) .fetch().size(); } + private static QPostSimpleData postSimpleData() { return new QPostSimpleData( post.id, @@ -317,6 +335,7 @@ private static QPostSimpleData postSimpleData() { post.thumbnail, post.createdDate); } + private static QPostEditData postEditData() { return new QPostEditData( post.id, @@ -328,7 +347,7 @@ private static QPostEditData postEditData() { ); } - private Page findByPostLikesWithSort(List ids, Pageable pageable, OrderSpecifier sort, String search){ + private Page findByPostLikesWithSort(List ids, Pageable pageable, OrderSpecifier sort, String search) { List posts = queryFactory .selectDistinct(post) @@ -346,15 +365,16 @@ private Page findByPostLikesWithSort(List ids, Pageable pageable, O return new PageImpl<>(posts, pageable, ids.size()); } - private OrderSpecifier[] getOrderSpecifierByPageable(Pageable pageable){ + private OrderSpecifier[] getOrderSpecifierByPageable(Pageable pageable) { OrderSpecifier[] orderSpecifiers = getOrdersBySort(post, pageable.getSort()); return Arrays.stream(orderSpecifiers).map(orderSpecifier -> convertToPostOrderSpecifier(orderSpecifier)) .collect(Collectors.toList()).toArray(new OrderSpecifier[0]); } - private OrderSpecifier convertToPostOrderSpecifier(OrderSpecifier orderSpecifier){ - if(orderSpecifier.getTarget().equals(post.postLikes)){ + + private OrderSpecifier convertToPostOrderSpecifier(OrderSpecifier orderSpecifier) { + if (orderSpecifier.getTarget().equals(post.postLikes)) { return post.postLikes.size().desc(); - }else if(orderSpecifier.getTarget().equals(post.comments)){ + } else if (orderSpecifier.getTarget().equals(post.comments)) { return post.comments.size().desc(); } return orderSpecifier; diff --git a/likelion-core/src/main/java/likelion/univ/domain/post/repository/impl/condition/PostSortType.java b/likelion-core/src/main/java/likelion/univ/domain/post/repository/impl/condition/PostSortType.java index a26d181d..a8cd2997 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/post/repository/impl/condition/PostSortType.java +++ b/likelion-core/src/main/java/likelion/univ/domain/post/repository/impl/condition/PostSortType.java @@ -1,15 +1,16 @@ package likelion.univ.domain.post.repository.impl.condition; +import static likelion.univ.domain.post.entity.QPost.post; + import com.querydsl.core.types.OrderSpecifier; import likelion.univ.exception.SortTypeNotMatchedException; import lombok.AllArgsConstructor; import lombok.Getter; -import static likelion.univ.domain.post.entity.QPost.post; - @Getter @AllArgsConstructor public enum PostSortType { + CREATED_DATE("created_date"), LIKE("like"), COMMENT("comment"); @@ -24,8 +25,9 @@ public static PostSortType fromValue(String value) { } throw new SortTypeNotMatchedException(); } - public static OrderSpecifier toOrderSpecifier(String value){ - switch (PostSortType.fromValue(value)){ + + public static OrderSpecifier toOrderSpecifier(String value) { + switch (PostSortType.fromValue(value)) { case LIKE: return post.postLikes.size().desc(); case COMMENT: diff --git a/likelion-core/src/main/java/likelion/univ/domain/post/service/PostDomainService.java b/likelion-core/src/main/java/likelion/univ/domain/post/service/PostService.java similarity index 59% rename from likelion-core/src/main/java/likelion/univ/domain/post/service/PostDomainService.java rename to likelion-core/src/main/java/likelion/univ/domain/post/service/PostService.java index 4a68e2a4..ce124357 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/post/service/PostDomainService.java +++ b/likelion-core/src/main/java/likelion/univ/domain/post/service/PostService.java @@ -1,21 +1,29 @@ package likelion.univ.domain.post.service; -import likelion.univ.domain.comment.adaptor.CommentAdaptor; -import likelion.univ.domain.follow.adaptor.FollowAdaptor; -import likelion.univ.domain.like.postlike.adaptor.PostLikeAdaptor; -import likelion.univ.domain.post.adaptor.PostAdaptor; -import likelion.univ.domain.post.dto.enums.PostOrderCondition; -import likelion.univ.domain.post.dto.request.*; -import likelion.univ.domain.post.dto.response.*; -import likelion.univ.domain.post.entity.Post; +import java.util.List; +import likelion.univ.domain.follow.repository.FollowRepository; +import likelion.univ.domain.like.postlike.repository.PostLikeRepository; import likelion.univ.domain.post.dto.enums.MainCategory; +import likelion.univ.domain.post.dto.enums.PostOrderCondition; import likelion.univ.domain.post.dto.enums.SubCategory; +import likelion.univ.domain.post.dto.request.CreatePostCommand; +import likelion.univ.domain.post.dto.request.DeletePostCommand; +import likelion.univ.domain.post.dto.request.GetPostDetailCommand; +import likelion.univ.domain.post.dto.request.GetPostsByCategoriesCommand; +import likelion.univ.domain.post.dto.request.GetPostsByCategorySearchCommand; +import likelion.univ.domain.post.dto.request.GetPostsBySearchTitleCommand; +import likelion.univ.domain.post.dto.request.UpdatePostCommand; +import likelion.univ.domain.post.dto.response.PostDetailData; +import likelion.univ.domain.post.dto.response.PostEditData; +import likelion.univ.domain.post.dto.response.PostSimpleData; +import likelion.univ.domain.post.entity.Post; import likelion.univ.domain.post.exception.PostNoAuthorizationException; -import likelion.univ.domain.post.exception.PostNotFoudException; -import likelion.univ.domain.user.adaptor.UserAdaptor; +import likelion.univ.domain.post.exception.PostNotFoundException; +import likelion.univ.domain.post.repository.PostRepository; import likelion.univ.domain.user.entity.Profile; import likelion.univ.domain.user.entity.UniversityInfo; import likelion.univ.domain.user.entity.User; +import likelion.univ.domain.user.repository.UserRepository; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; @@ -23,35 +31,31 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.List; - @Service @Transactional(readOnly = true) @RequiredArgsConstructor -public class PostDomainService { - - private final PostAdaptor postAdaptor; - private final CommentAdaptor commentAdaptor; - private final UserAdaptor userAdaptor; - private final FollowAdaptor followAdaptor; - private final PostLikeAdaptor postLikeAdaptor; +public class PostService { + private final PostRepository postRepository; + private final UserRepository userRepository; + private final FollowRepository followRepository; + private final PostLikeRepository postLikeRepository; public PostDetailData getPostDetail(GetPostDetailCommand request) { Long postId = request.postId(); Long loginUserId = request.loginUserId(); // post entity data - Post post = postAdaptor.findById(postId); - Boolean isLikedPost = postLikeAdaptor.existsByPostIdAndAuthorId(postId, loginUserId); - Integer postLikeCount = Math.toIntExact(postLikeAdaptor.countByPostId(postId)); + Post post = postRepository.getById(postId); + Boolean isLikedPost = postLikeRepository.existsByPostIdAndUserId(postId, loginUserId); + Integer postLikeCount = Math.toIntExact(postLikeRepository.countByPostId(postId)); // user entity data User author = post.getAuthor(); Profile authorProfile = author.getProfile(); UniversityInfo authorUniversityInfo = author.getUniversityInfo(); String authorProfileImageUrl = authorProfile.getProfileImage(); - Boolean hasFollowedAuthor = followAdaptor.hasFollowedUser(loginUserId, author.getId()); + Boolean hasFollowedAuthor = followRepository.existsByFollowerIdAndFollowingId(loginUserId, author.getId()); return PostDetailData.builder() .postId(post.getId()) @@ -72,49 +76,58 @@ public PostDetailData getPostDetail(GetPostDetailCommand request) { } public PostEditData getPostEditById(Long postId) { - PostEditData postEdit = postAdaptor.findPostEditByPostId(postId); + PostEditData postEdit = postRepository.findPostEditByPostId(postId); if (postEdit == null) { - throw new PostNotFoudException(); + throw new PostNotFoundException(); } return postEdit; } - public Page getByCategoriesOrderByCreatedData(GetPostsByCategoriesCommand request, Pageable pageable) { + public Page getByCategoriesOrderByCreatedData(GetPostsByCategoriesCommand request, + Pageable pageable) { MainCategory mainCategory = request.mainCategory(); SubCategory subCategory = request.subCategory(); - Page posts = postAdaptor.findByCategoriesOrderByCreatedDate(mainCategory, subCategory, pageable); + Page posts = postRepository.findByCategoriesOrderByCreatedDate(mainCategory, subCategory, pageable); List postSimpleDataList = posts.stream().map(PostSimpleData::of).toList(); return new PageImpl<>(postSimpleDataList, pageable, posts.getTotalElements()); } - public Page getByCategoriesOrderByLikeCount(GetPostsByCategoriesCommand request, Pageable pageable) { + public Page getByCategoriesOrderByLikeCount(GetPostsByCategoriesCommand request, + Pageable pageable) { MainCategory mainCategory = request.mainCategory(); SubCategory subCategory = request.subCategory(); - Page posts = postAdaptor.findByCategoriesOrderByLikeCount(mainCategory, subCategory, pageable); + Page posts = postRepository.findByCategoriesOrderByLikeCount(mainCategory, subCategory, pageable); List postSimpleDataList = posts.stream().map(PostSimpleData::of).toList(); return new PageImpl<>(postSimpleDataList, pageable, posts.getTotalElements()); } - public Page getByCategoriesOrderByCommentCount(GetPostsByCategoriesCommand request, Pageable pageable) { + public Page getByCategoriesOrderByCommentCount(GetPostsByCategoriesCommand request, + Pageable pageable) { MainCategory mainCategory = request.mainCategory(); SubCategory subCategory = request.subCategory(); - Page posts = postAdaptor.findByCategoriesOrderByCommentCount(mainCategory, subCategory, pageable); + Page posts = postRepository.findByCategoriesOrderByCommentCount(mainCategory, subCategory, pageable); List postSimpleDataList = posts.stream().map(PostSimpleData::of).toList(); return new PageImpl<>(postSimpleDataList, pageable, posts.getTotalElements()); } - public Page getByCategoriesAndSearchTitle(GetPostsByCategorySearchCommand request, Pageable pageable) { + + public Page getByCategoriesAndSearchTitle(GetPostsByCategorySearchCommand request, + Pageable pageable) { PostOrderCondition orderCondition = request.orderCondition(); String searchTitle = request.searchTitle(); MainCategory mainCategory = request.mainCategory(); SubCategory subCategory = request.subCategory(); if (orderCondition.equals(PostOrderCondition.COMMENT_COUNT_ORDER)) { - return postAdaptor.findByCategoriesAndSearchTitleOrderByCommentCount(searchTitle, mainCategory, subCategory, pageable); + return postRepository.findByCategoriesAndSearchTitleOrderByCommentCount(searchTitle, mainCategory, + subCategory, + pageable); } else if (orderCondition.equals(PostOrderCondition.LIKE_COUNT_ORDER)) { - return postAdaptor.findByCategoriesAndSearchTitleOrderByLikeCount(searchTitle, mainCategory, subCategory, pageable); + return postRepository.findByCategoriesAndSearchTitleOrderByLikeCount(searchTitle, mainCategory, subCategory, + pageable); } // order by created date - return postAdaptor.findByCategoriesAndSearchTitleOrderByCreatedDate(searchTitle, mainCategory, subCategory, pageable); + return postRepository.findByCategoriesAndSearchTitleOrderByCreatedDate(searchTitle, mainCategory, subCategory, + pageable); } public Page getBySearchTitle(GetPostsBySearchTitleCommand request, Pageable pageable) { @@ -122,42 +135,41 @@ public Page getBySearchTitle(GetPostsBySearchTitleCommand reques String searchTitle = request.searchTitle(); if (orderCondition.equals(PostOrderCondition.LIKE_COUNT_ORDER)) { - return postAdaptor.findBySearchTitleOrderByLikeCount(searchTitle, pageable); + return postRepository.findBySearchTitleOrderByLikeCount(searchTitle, pageable); } else if (orderCondition.equals(PostOrderCondition.COMMENT_COUNT_ORDER)) { - return postAdaptor.findBySearchTitleOrderByCommentCount(searchTitle, pageable); + return postRepository.findBySearchTitleOrderByCommentCount(searchTitle, pageable); } - return postAdaptor.findBySearchTitleOrderByCreatedDate(searchTitle, pageable); + return postRepository.findBySearchTitleOrderByCreatedDate(searchTitle, pageable); } @Transactional public Long createPost(CreatePostCommand request) { Post post = createEntity(request); - Long savedId = postAdaptor.save(post); - return savedId; + return postRepository.save(post).getId(); } @Transactional public Long editPost(UpdatePostCommand request) { - Post post = postAdaptor.findById(request.postId()); + Post post = postRepository.getById(request.postId()); if (!(post.getAuthor().getId().equals(request.loginUserId()))) { throw new PostNoAuthorizationException(); } post.edit(request); - Long saveId = postAdaptor.save(post); - return saveId; + return postRepository.save(post).getId(); } + @Transactional public void deletePost(DeletePostCommand request) { - Post post = postAdaptor.findById(request.postId()); + Post post = postRepository.getById(request.postId()); if (!(post.getAuthor().getId().equals(request.loginUserId()))) { throw new PostNoAuthorizationException(); } - postAdaptor.delete(post); + postRepository.delete(post); } private Post createEntity(CreatePostCommand request) { - return Post.builder() - .author(userAdaptor.findById(request.authorId())) + return Post.builder() + .author(userRepository.getById(request.authorId())) .title(request.title()) .body(request.body()) .thumbnail(request.thumbnail()) @@ -165,15 +177,4 @@ private Post createEntity(CreatePostCommand request) { .subCategory(request.subCategory()) .build(); } - -// private Page addCountsData(Page posts, Pageable pageable) { -// List response = posts.stream().map(p -> { -// Long commentCount = commentAdaptor.countByPostId(p.postId()); -// Long likeCount = postLikeAdaptor.countByPostId(p.postId()); -// return PostData.getInstance(p, likeCount, commentCount); -// }).toList(); -// return new PageImpl<>(response, pageable, posts.getTotalPages()); -// } - - } diff --git a/likelion-core/src/main/java/likelion/univ/domain/project/adapter/ProjectAdaptor.java b/likelion-core/src/main/java/likelion/univ/domain/project/adapter/ProjectAdaptor.java deleted file mode 100644 index de04d0f2..00000000 --- a/likelion-core/src/main/java/likelion/univ/domain/project/adapter/ProjectAdaptor.java +++ /dev/null @@ -1,55 +0,0 @@ -package likelion.univ.domain.project.adapter; - -import likelion.univ.annotation.Adaptor; -import likelion.univ.domain.project.entity.Project; -import likelion.univ.domain.project.exception.CreateProjectBadRequestException; -import likelion.univ.domain.project.exception.ProjectNotFoundException; -import likelion.univ.domain.project.repository.ProjectRepository; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; - - -@Adaptor -@RequiredArgsConstructor -public class ProjectAdaptor { - - private final ProjectRepository projectRepository; - public Project findById(Long id){ - return projectRepository.findById(id).orElseThrow(() -> new ProjectNotFoundException()); - } - - public Project save(Project project){ - - try { - projectRepository.save(project); - }catch(Exception e) { - throw new CreateProjectBadRequestException(); - } - - return project; - } - - public void delete(Project project) { - projectRepository.delete(project); - } - - public Page findAll(Pageable pageable){ - return projectRepository.findAll(pageable); - } - public Page findProject(Long ordinal, Pageable pageable){ - return projectRepository.findByOrdinal(ordinal, pageable); - } - public Page findArchiveProject(Long ordinal, Pageable pageable){ - return projectRepository.findArchivePosts(ordinal, pageable); - } - public int getCurrentOrdinal(){ - return projectRepository.findLatestOrdinal(); - } - - public Page findByProjectMember(Long userId, Pageable pageable){ - return projectRepository.findByProjectMember(userId, pageable); - } - -} diff --git a/likelion-core/src/main/java/likelion/univ/domain/project/adapter/ProjectImageAdaptor.java b/likelion-core/src/main/java/likelion/univ/domain/project/adapter/ProjectImageAdaptor.java deleted file mode 100644 index 84c64aee..00000000 --- a/likelion-core/src/main/java/likelion/univ/domain/project/adapter/ProjectImageAdaptor.java +++ /dev/null @@ -1,32 +0,0 @@ -package likelion.univ.domain.project.adapter; - -import likelion.univ.annotation.Adaptor; -import likelion.univ.domain.project.entity.ProjectImage; -import likelion.univ.domain.project.entity.Project; -import likelion.univ.domain.project.repository.ProjectImageRepository; -import lombok.RequiredArgsConstructor; - -import java.util.List; - -@Adaptor -@RequiredArgsConstructor -public class ProjectImageAdaptor { - - private final ProjectImageRepository projectImageRepository; - - public List findByProject(Project project) { - return projectImageRepository.findByProject(project); - } - - public void saveAll(List projectImages) { - projectImageRepository.saveAll(projectImages); - } - - public void deleteByProject(Project project) { - projectImageRepository.deleteByProject(project); - } - - public void save(ProjectImage projectImage){ - projectImageRepository.save(projectImage); - } -} diff --git a/likelion-core/src/main/java/likelion/univ/domain/project/adapter/ProjectMemberAdaptor.java b/likelion-core/src/main/java/likelion/univ/domain/project/adapter/ProjectMemberAdaptor.java deleted file mode 100644 index a7d6fa8e..00000000 --- a/likelion-core/src/main/java/likelion/univ/domain/project/adapter/ProjectMemberAdaptor.java +++ /dev/null @@ -1,28 +0,0 @@ -package likelion.univ.domain.project.adapter; - -import likelion.univ.annotation.Adaptor; -import likelion.univ.domain.project.entity.Project; -import likelion.univ.domain.project.entity.ProjectMember; -import likelion.univ.domain.project.repository.ProjectMemberRepository; -import lombok.RequiredArgsConstructor; - -import java.util.List; - -@Adaptor -@RequiredArgsConstructor -public class ProjectMemberAdaptor { - - private final ProjectMemberRepository projectMemberRepository; - - public List findByProject(Project project) { - return projectMemberRepository.findByProject(project); - } - - public void saveAll(List projectMembers) { - projectMemberRepository.saveAll(projectMembers); - } - - public void deleteByProject(Project project) { - projectMemberRepository.deleteByProject(project); - } -} diff --git a/likelion-core/src/main/java/likelion/univ/domain/project/adapter/ProjectTechAdaptor.java b/likelion-core/src/main/java/likelion/univ/domain/project/adapter/ProjectTechAdaptor.java deleted file mode 100644 index fa3bc06f..00000000 --- a/likelion-core/src/main/java/likelion/univ/domain/project/adapter/ProjectTechAdaptor.java +++ /dev/null @@ -1,42 +0,0 @@ -package likelion.univ.domain.project.adapter; - -import likelion.univ.annotation.Adaptor; -import likelion.univ.domain.project.entity.Project; -import likelion.univ.domain.project.entity.ProjectTech; -import likelion.univ.domain.project.entity.Tech; -import likelion.univ.domain.project.exception.ProjectNotFoundException; -import likelion.univ.domain.project.repository.ProjectTechRepository; -import likelion.univ.domain.project.repository.TechRepository; - -import lombok.RequiredArgsConstructor; - -import java.util.List; - -@Adaptor -@RequiredArgsConstructor -public class ProjectTechAdaptor { - private final TechRepository techRepository; - private final ProjectTechRepository projectTechRepository; - - public void saveTech(Tech tech){techRepository.save(tech);} - public Tech findByName(String techName){ - return techRepository.findTechByTechName(techName); - } - public Tech findById(Long id){return techRepository.findById(id).orElseThrow(()-> new ProjectNotFoundException());} - public List findByProject(Project project) { - return projectTechRepository.findByProject(project); - } - - public void saveAll(List projectTechList) { - projectTechRepository.saveAll(projectTechList); - } - - public void deleteByProject(Project project) { - projectTechRepository.deleteByProject(project); - } - - public void save(ProjectTech projectTech){ - projectTechRepository.save(projectTech); - } - -} diff --git a/likelion-core/src/main/java/likelion/univ/domain/project/entity/Project.java b/likelion-core/src/main/java/likelion/univ/domain/project/entity/Project.java index 4fd6cd5c..772cde89 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/project/entity/Project.java +++ b/likelion-core/src/main/java/likelion/univ/domain/project/entity/Project.java @@ -1,5 +1,20 @@ package likelion.univ.domain.project.entity; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; import likelion.univ.common.entity.BaseTimeEntity; import likelion.univ.domain.project.entity.enums.Output; import likelion.univ.domain.university.entity.University; @@ -10,11 +25,6 @@ import lombok.NoArgsConstructor; import org.springframework.format.annotation.DateTimeFormat; -import javax.persistence.*; -import java.time.LocalDate; -import java.util.ArrayList; -import java.util.List; - @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -59,19 +69,20 @@ public class Project extends BaseTimeEntity { private String productionUrl; @OneToMany(cascade = CascadeType.ALL) - @JoinColumn(name="project_id", insertable = false, updatable = false) + @JoinColumn(name = "project_id", insertable = false, updatable = false) private List projectMembers = new ArrayList<>(); @OneToMany(cascade = CascadeType.ALL) - @JoinColumn(name="project_id", insertable = false, updatable = false) + @JoinColumn(name = "project_id", insertable = false, updatable = false) private List projectImages = new ArrayList<>(); @OneToMany(cascade = CascadeType.ALL) - @JoinColumn(name="project_id", insertable = false, updatable = false) + @JoinColumn(name = "project_id", insertable = false, updatable = false) private List teches = new ArrayList<>(); @Builder - public Project(String activity, Output outPut, String serviceName, long ordinal, University univ, LocalDate startDate, LocalDate endDate, String description, String content, String productionUrl) { + public Project(String activity, Output outPut, String serviceName, long ordinal, University univ, + LocalDate startDate, LocalDate endDate, String description, String content, String productionUrl) { this.activity = activity; this.outPut = outPut; this.serviceName = serviceName; diff --git a/likelion-core/src/main/java/likelion/univ/domain/project/entity/ProjectImage.java b/likelion-core/src/main/java/likelion/univ/domain/project/entity/ProjectImage.java index 0a369020..f624d4f4 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/project/entity/ProjectImage.java +++ b/likelion-core/src/main/java/likelion/univ/domain/project/entity/ProjectImage.java @@ -1,15 +1,20 @@ package likelion.univ.domain.project.entity; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import javax.persistence.*; - @Entity @Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) +@NoArgsConstructor(access = AccessLevel.PROTECTED) public class ProjectImage { @Id diff --git a/likelion-core/src/main/java/likelion/univ/domain/project/entity/ProjectMember.java b/likelion-core/src/main/java/likelion/univ/domain/project/entity/ProjectMember.java index 7e103059..003170a3 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/project/entity/ProjectMember.java +++ b/likelion-core/src/main/java/likelion/univ/domain/project/entity/ProjectMember.java @@ -1,5 +1,14 @@ package likelion.univ.domain.project.entity; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; import likelion.univ.domain.user.entity.Part; import likelion.univ.domain.user.entity.User; import lombok.AccessLevel; @@ -7,8 +16,6 @@ import lombok.Getter; import lombok.NoArgsConstructor; -import javax.persistence.*; - @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -36,5 +43,7 @@ public ProjectMember(Project project, User user, Part part) { this.part = part; } - public void updateProject(){this.project = project;} + public void updateProject() { + this.project = project; + } } diff --git a/likelion-core/src/main/java/likelion/univ/domain/project/entity/ProjectTech.java b/likelion-core/src/main/java/likelion/univ/domain/project/entity/ProjectTech.java index f3c39c3b..8587a6eb 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/project/entity/ProjectTech.java +++ b/likelion-core/src/main/java/likelion/univ/domain/project/entity/ProjectTech.java @@ -1,16 +1,22 @@ package likelion.univ.domain.project.entity; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import javax.persistence.*; - @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class ProjectTech { + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; diff --git a/likelion-core/src/main/java/likelion/univ/domain/project/entity/Tech.java b/likelion-core/src/main/java/likelion/univ/domain/project/entity/Tech.java index 22102a92..bc91d6d6 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/project/entity/Tech.java +++ b/likelion-core/src/main/java/likelion/univ/domain/project/entity/Tech.java @@ -1,14 +1,13 @@ package likelion.univ.domain.project.entity; -import lombok.AccessLevel; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; - import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; @Entity @Getter @@ -22,8 +21,7 @@ public class Tech { private String techName; @Builder - public Tech(String techName){ + public Tech(String techName) { this.techName = techName; - } } \ No newline at end of file diff --git a/likelion-core/src/main/java/likelion/univ/domain/project/entity/enums/Output.java b/likelion-core/src/main/java/likelion/univ/domain/project/entity/enums/Output.java index a2630406..c3ada5ad 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/project/entity/enums/Output.java +++ b/likelion-core/src/main/java/likelion/univ/domain/project/entity/enums/Output.java @@ -6,11 +6,11 @@ @Getter @RequiredArgsConstructor public enum Output { - WEB("OUTPUT_WEB","웹"), - ANDROID("OUTPUT_AND","안드로이드"), - IOS("OUTPUT_IOS","아이폰"); + + WEB("OUTPUT_WEB", "웹"), + ANDROID("OUTPUT_AND", "안드로이드"), + IOS("OUTPUT_IOS", "아이폰"); private final String key; private final String title; - } diff --git a/likelion-core/src/main/java/likelion/univ/domain/project/exception/CreateProjectBadRequestException.java b/likelion-core/src/main/java/likelion/univ/domain/project/exception/CreateProjectBadRequestException.java index d4358fc4..5e9455f9 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/project/exception/CreateProjectBadRequestException.java +++ b/likelion-core/src/main/java/likelion/univ/domain/project/exception/CreateProjectBadRequestException.java @@ -3,6 +3,7 @@ import likelion.univ.exception.base.BaseException; public class CreateProjectBadRequestException extends BaseException { + public CreateProjectBadRequestException() { super(ProjectErrorCode.CREATE_PROJECT_BAD_REQUEST); } diff --git a/likelion-core/src/main/java/likelion/univ/domain/project/exception/ProjectErrorCode.java b/likelion-core/src/main/java/likelion/univ/domain/project/exception/ProjectErrorCode.java index 8a525662..4dc96a8d 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/project/exception/ProjectErrorCode.java +++ b/likelion-core/src/main/java/likelion/univ/domain/project/exception/ProjectErrorCode.java @@ -1,15 +1,16 @@ package likelion.univ.domain.project.exception; +import static likelion.univ.constant.StaticValue.BAD_REQUEST; +import static likelion.univ.constant.StaticValue.NOT_FOUND; + import likelion.univ.exception.base.BaseErrorCode; import lombok.AllArgsConstructor; import lombok.Getter; -import static likelion.univ.constant.StaticValue.BAD_REQUEST; -import static likelion.univ.constant.StaticValue.NOT_FOUND; - @Getter @AllArgsConstructor public enum ProjectErrorCode implements BaseErrorCode { + CREATE_PROJECT_BAD_REQUEST(BAD_REQUEST, "PROJECT_400", "프로젝트를 등록하는 데 잘못된 요청을 하였습니다."), PROJECT_NOT_FOUND(NOT_FOUND, "PROJECT_404", "프로젝트가 존재하지 않습니다."); diff --git a/likelion-core/src/main/java/likelion/univ/domain/project/exception/ProjectNotFoundException.java b/likelion-core/src/main/java/likelion/univ/domain/project/exception/ProjectNotFoundException.java index a7f5acf4..809e5b55 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/project/exception/ProjectNotFoundException.java +++ b/likelion-core/src/main/java/likelion/univ/domain/project/exception/ProjectNotFoundException.java @@ -3,6 +3,7 @@ import likelion.univ.exception.base.BaseException; public class ProjectNotFoundException extends BaseException { + public ProjectNotFoundException() { super(ProjectErrorCode.PROJECT_NOT_FOUND); } diff --git a/likelion-core/src/main/java/likelion/univ/domain/project/repository/ProjectCustomRepository.java b/likelion-core/src/main/java/likelion/univ/domain/project/repository/ProjectCustomRepository.java index bc97ed82..81daa2c5 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/project/repository/ProjectCustomRepository.java +++ b/likelion-core/src/main/java/likelion/univ/domain/project/repository/ProjectCustomRepository.java @@ -6,5 +6,6 @@ import org.springframework.data.domain.Pageable; public interface ProjectCustomRepository { + Page findByProjectMember(Long userId, Pageable pageable); } diff --git a/likelion-core/src/main/java/likelion/univ/domain/project/repository/ProjectImageRepository.java b/likelion-core/src/main/java/likelion/univ/domain/project/repository/ProjectImageRepository.java index 7126861a..0023524d 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/project/repository/ProjectImageRepository.java +++ b/likelion-core/src/main/java/likelion/univ/domain/project/repository/ProjectImageRepository.java @@ -1,13 +1,13 @@ package likelion.univ.domain.project.repository; -import likelion.univ.domain.project.entity.ProjectImage; +import java.util.List; import likelion.univ.domain.project.entity.Project; +import likelion.univ.domain.project.entity.ProjectImage; import org.springframework.data.jpa.repository.JpaRepository; -import java.util.List; - public interface ProjectImageRepository extends JpaRepository { - public List findByProject(Project project); - public void deleteByProject(Project project); + List findByProject(Project project); + + void deleteByProject(Project project); } diff --git a/likelion-core/src/main/java/likelion/univ/domain/project/repository/ProjectMemberRepository.java b/likelion-core/src/main/java/likelion/univ/domain/project/repository/ProjectMemberRepository.java index b7ec112b..121ee72e 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/project/repository/ProjectMemberRepository.java +++ b/likelion-core/src/main/java/likelion/univ/domain/project/repository/ProjectMemberRepository.java @@ -1,14 +1,15 @@ package likelion.univ.domain.project.repository; +import java.util.List; import likelion.univ.domain.project.entity.Project; import likelion.univ.domain.project.entity.ProjectMember; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; -import java.util.List; - public interface ProjectMemberRepository extends JpaRepository { + @Query("SELECT m FROM ProjectMember m join fetch m.user where m.project = :project") - public List findByProject(Project project); - public void deleteByProject(Project project); + List findByProject(Project project); + + void deleteByProject(Project project); } diff --git a/likelion-core/src/main/java/likelion/univ/domain/project/repository/ProjectRepository.java b/likelion-core/src/main/java/likelion/univ/domain/project/repository/ProjectRepository.java index 348ae85d..ef6f8465 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/project/repository/ProjectRepository.java +++ b/likelion-core/src/main/java/likelion/univ/domain/project/repository/ProjectRepository.java @@ -1,6 +1,7 @@ package likelion.univ.domain.project.repository; import likelion.univ.domain.project.entity.Project; +import likelion.univ.domain.project.exception.ProjectNotFoundException; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; @@ -9,12 +10,16 @@ public interface ProjectRepository extends JpaRepository, ProjectCustomRepository { + + default Project getById(Long id) { + return findById(id).orElseThrow(ProjectNotFoundException::new); + } + Page findByOrdinal(Long ordinal, Pageable pageable); @Query("SELECT p FROM Project p WHERE p.ordinal <= :ordinal ORDER BY p.ordinal DESC") - Page findArchivePosts(@Param("ordinal") Long ordinal, Pageable pageable); + Page findArchiveProject(@Param("ordinal") Long ordinal, Pageable pageable); @Query("SELECT MAX(p.ordinal) FROM Project p") int findLatestOrdinal(); - -} \ No newline at end of file +} diff --git a/likelion-core/src/main/java/likelion/univ/domain/project/repository/ProjectTechRepository.java b/likelion-core/src/main/java/likelion/univ/domain/project/repository/ProjectTechRepository.java index a2d5fbde..2b3302f7 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/project/repository/ProjectTechRepository.java +++ b/likelion-core/src/main/java/likelion/univ/domain/project/repository/ProjectTechRepository.java @@ -1,13 +1,13 @@ package likelion.univ.domain.project.repository; +import java.util.List; import likelion.univ.domain.project.entity.Project; import likelion.univ.domain.project.entity.ProjectTech; import org.springframework.data.jpa.repository.JpaRepository; -import java.util.List; - public interface ProjectTechRepository extends JpaRepository { - public List findByProject(Project project); - public void deleteByProject(Project project); + List findByProject(Project project); + + void deleteByProject(Project project); } diff --git a/likelion-core/src/main/java/likelion/univ/domain/project/repository/TechRepository.java b/likelion-core/src/main/java/likelion/univ/domain/project/repository/TechRepository.java index a5c94b30..16e9a7f6 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/project/repository/TechRepository.java +++ b/likelion-core/src/main/java/likelion/univ/domain/project/repository/TechRepository.java @@ -1,10 +1,14 @@ package likelion.univ.domain.project.repository; import likelion.univ.domain.project.entity.Tech; +import likelion.univ.domain.project.exception.ProjectNotFoundException; import org.springframework.data.jpa.repository.JpaRepository; -import java.util.List; - public interface TechRepository extends JpaRepository { - Tech findTechByTechName(String techName); + + default Tech getById(Long id) { + return findById(id).orElseThrow(ProjectNotFoundException::new); + } + + Tech findByTechName(String techName); } diff --git a/likelion-core/src/main/java/likelion/univ/domain/project/repository/impl/ProjectCustomRepositoryImpl.java b/likelion-core/src/main/java/likelion/univ/domain/project/repository/impl/ProjectCustomRepositoryImpl.java index f382d124..84a0311c 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/project/repository/impl/ProjectCustomRepositoryImpl.java +++ b/likelion-core/src/main/java/likelion/univ/domain/project/repository/impl/ProjectCustomRepositoryImpl.java @@ -1,7 +1,13 @@ package likelion.univ.domain.project.repository.impl; +import static likelion.univ.domain.project.entity.QProject.project; +import static likelion.univ.domain.project.entity.QProjectImage.projectImage; +import static likelion.univ.domain.project.entity.QProjectMember.projectMember; +import static likelion.univ.domain.university.entity.QUniversity.university; + import com.querydsl.core.types.Predicate; import com.querydsl.jpa.impl.JPAQueryFactory; +import java.util.List; import likelion.univ.domain.project.entity.Project; import likelion.univ.domain.project.repository.ProjectCustomRepository; import lombok.RequiredArgsConstructor; @@ -9,21 +15,14 @@ import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; -import java.util.List; -import java.util.Optional; - -import static likelion.univ.domain.project.entity.QProject.project; -import static likelion.univ.domain.project.entity.QProjectImage.projectImage; -import static likelion.univ.domain.project.entity.QProjectMember.projectMember; -import static likelion.univ.domain.university.entity.QUniversity.university; - @RequiredArgsConstructor public class ProjectCustomRepositoryImpl implements ProjectCustomRepository { private final JPAQueryFactory queryFactory; + @Override - public Page findByProjectMember(Long userId, Pageable pageable){ + public Page findByProjectMember(Long userId, Pageable pageable) { List ids = getCoveringIndexByProjectMember(projectMember.user.id.eq(userId)); return queryBasicByCoveringIndex(ids, pageable); } @@ -32,7 +31,7 @@ private List getCoveringIndexByProjectMember(Predicate predicate) { return queryFactory.select(projectMember.project.id).from(projectMember).where(predicate).fetch(); } - private Page queryBasicByCoveringIndex(List ids, Pageable pageable){ + private Page queryBasicByCoveringIndex(List ids, Pageable pageable) { List projects = queryFactory .selectDistinct(project) diff --git a/likelion-core/src/main/java/likelion/univ/domain/project/service/ProjectImageService.java b/likelion-core/src/main/java/likelion/univ/domain/project/service/ProjectImageService.java index 57daa473..0b7e7962 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/project/service/ProjectImageService.java +++ b/likelion-core/src/main/java/likelion/univ/domain/project/service/ProjectImageService.java @@ -1,41 +1,40 @@ package likelion.univ.domain.project.service; -import likelion.univ.domain.project.adapter.ProjectImageAdaptor; -import likelion.univ.domain.project.adapter.ProjectAdaptor; -import likelion.univ.domain.project.entity.ProjectImage; +import java.util.List; import likelion.univ.domain.project.entity.Project; +import likelion.univ.domain.project.entity.ProjectImage; +import likelion.univ.domain.project.repository.ProjectImageRepository; +import likelion.univ.domain.project.repository.ProjectRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.List; - @Service @Transactional(readOnly = true) //읽기 전용 모드 @RequiredArgsConstructor public class ProjectImageService { - private final ProjectAdaptor projectAdaptor; - private final ProjectImageAdaptor projectImageAdaptor; + private final ProjectRepository projectRepository; + private final ProjectImageRepository projectImageRepository; @Transactional public void addImage(List projectImages) { if (projectImages != null) { - projectImageAdaptor.saveAll(projectImages); + projectImageRepository.saveAll(projectImages); } } @Transactional public void updateImage(Project project, List projectImages) { - projectImageAdaptor.deleteByProject(project); //기존 사진 모두 삭제 - if(projectImages != null) { - projectImageAdaptor.saveAll(projectImages); + projectImageRepository.deleteByProject(project); //기존 사진 모두 삭제 + if (projectImages != null) { + projectImageRepository.saveAll(projectImages); } } @Transactional public void deleteImage(Long id) { - Project project = projectAdaptor.findById(id); - projectImageAdaptor.deleteByProject(project); + Project project = projectRepository.getById(id); + projectImageRepository.deleteByProject(project); } } diff --git a/likelion-core/src/main/java/likelion/univ/domain/project/service/ProjectMemberService.java b/likelion-core/src/main/java/likelion/univ/domain/project/service/ProjectMemberService.java index 6201bf64..a67d7ac2 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/project/service/ProjectMemberService.java +++ b/likelion-core/src/main/java/likelion/univ/domain/project/service/ProjectMemberService.java @@ -1,49 +1,33 @@ package likelion.univ.domain.project.service; -import likelion.univ.domain.project.adapter.ProjectAdaptor; -import likelion.univ.domain.project.adapter.ProjectMemberAdaptor; +import java.util.List; import likelion.univ.domain.project.entity.Project; import likelion.univ.domain.project.entity.ProjectMember; -import likelion.univ.domain.user.entity.User; +import likelion.univ.domain.project.repository.ProjectMemberRepository; +import likelion.univ.domain.project.repository.ProjectRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.List; -import java.util.stream.Collectors; - @Service @Transactional(readOnly = true) //읽기 전용 모드 @RequiredArgsConstructor public class ProjectMemberService { - private final ProjectAdaptor projectAdaptor; - private final ProjectMemberAdaptor projectMemberAdaptor; - -// @Transactional -// public void addMembers(Project project, List users){ -// List members = users.stream() -// .map(user -> new ProjectMember(project, user)) -// .collect(Collectors.toList()); -// projectMemberAdaptor.saveAll(members); -// } + private final ProjectRepository projectRepository; + private final ProjectMemberRepository projectMemberRepository; @Transactional public void updateProjectMember(Project project, List projectMembers) { - projectMemberAdaptor.deleteByProject(project); //기존 멤버 모두 삭제 - if(projectMembers != null) { - projectMemberAdaptor.saveAll(projectMembers); + projectMemberRepository.deleteByProject(project); //기존 멤버 모두 삭제 + if (projectMembers != null) { + projectMemberRepository.saveAll(projectMembers); } } @Transactional public void deleteProjectMember(Long id) { - Project project = projectAdaptor.findById(id); - projectMemberAdaptor.deleteByProject(project); + Project project = projectRepository.getById(id); + projectMemberRepository.deleteByProject(project); } - -// public List getProjectMember(Long id) { -// Project project = projectRepository.findById(id).get(); -// return projectMemberRepository.findByProject(project); -// } } diff --git a/likelion-core/src/main/java/likelion/univ/domain/project/service/ProjectService.java b/likelion-core/src/main/java/likelion/univ/domain/project/service/ProjectService.java index 93f044a5..c101264f 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/project/service/ProjectService.java +++ b/likelion-core/src/main/java/likelion/univ/domain/project/service/ProjectService.java @@ -1,41 +1,43 @@ package likelion.univ.domain.project.service; -import likelion.univ.domain.project.adapter.ProjectAdaptor; +import java.time.LocalDate; import likelion.univ.domain.project.entity.Project; import likelion.univ.domain.project.exception.CreateProjectBadRequestException; +import likelion.univ.domain.project.repository.ProjectRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.time.LocalDate; - @Service @Transactional @RequiredArgsConstructor public class ProjectService { - private final ProjectAdaptor projectAdaptor; + private final ProjectRepository projectRepository; - public Project createProject(Project project) - { + public Project createProject(Project project) { LocalDate startDate = project.getStartDate(); LocalDate endDate = project.getEndDate(); - if(startDate.isEqual(endDate) || startDate.isAfter(endDate)){ + if (startDate.isEqual(endDate) || startDate.isAfter(endDate)) { + throw new CreateProjectBadRequestException(); + } + try { + Project savedProject = projectRepository.save(project); + return savedProject; + } catch (Exception e) { throw new CreateProjectBadRequestException(); } - Project savedProject = projectAdaptor.save(project); - return savedProject; } public void updateProject(Long id, Project updateProject) { - Project project = projectAdaptor.findById(id); + Project project = projectRepository.getById(id); project.update(updateProject); - projectAdaptor.save(project); + projectRepository.save(project); } public void deleteProject(Long id) { - Project project = projectAdaptor.findById(id); - projectAdaptor.delete(project); + Project project = projectRepository.getById(id); + projectRepository.delete(project); } } diff --git a/likelion-core/src/main/java/likelion/univ/domain/project/service/ProjectTechService.java b/likelion-core/src/main/java/likelion/univ/domain/project/service/ProjectTechService.java index 31e106be..ad6bf73b 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/project/service/ProjectTechService.java +++ b/likelion-core/src/main/java/likelion/univ/domain/project/service/ProjectTechService.java @@ -1,36 +1,37 @@ package likelion.univ.domain.project.service; -import likelion.univ.domain.project.adapter.ProjectAdaptor; -import likelion.univ.domain.project.adapter.ProjectTechAdaptor; +import java.util.ArrayList; +import java.util.List; import likelion.univ.domain.project.entity.Project; import likelion.univ.domain.project.entity.ProjectTech; import likelion.univ.domain.project.entity.Tech; +import likelion.univ.domain.project.repository.ProjectRepository; +import likelion.univ.domain.project.repository.ProjectTechRepository; +import likelion.univ.domain.project.repository.TechRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.ArrayList; -import java.util.List; - @Service @Transactional(readOnly = true) @RequiredArgsConstructor public class ProjectTechService { - private final ProjectAdaptor projectAdaptor; - private final ProjectTechAdaptor projectTechAdaptor; + private final TechRepository techRepository; + private final ProjectRepository projectRepository; + private final ProjectTechRepository projectTechRepository; @Transactional public void addProjectTech(Project project, List techNames) { List projectTeches = new ArrayList<>(); for (String techName : techNames) { - Tech existingTech = projectTechAdaptor.findByName(techName); + Tech existingTech = techRepository.findByTechName(techName); Tech tech; if (existingTech != null) { tech = existingTech; } else { Tech newTech = Tech.builder().techName(techName).build(); - projectTechAdaptor.saveTech(newTech); + techRepository.save(newTech); tech = newTech; } ProjectTech projectTech = ProjectTech.builder() @@ -39,35 +40,37 @@ public void addProjectTech(Project project, List techNames) { .build(); projectTeches.add(projectTech); } - projectTechAdaptor.saveAll(projectTeches); + projectTechRepository.saveAll(projectTeches); } + @Transactional public void updateProjectTech(Project project, List teches) { - projectTechAdaptor.deleteByProject(project); + projectTechRepository.deleteByProject(project); if (teches != null && !teches.isEmpty()) { List projectTeches = new ArrayList<>(); for (String techName : teches) { - Tech tech = projectTechAdaptor.findByName(techName.toUpperCase()); + Tech tech = techRepository.findByTechName(techName.toUpperCase()); Tech persistedTech; - if(tech == null) { + if (tech == null) { Tech newTech = Tech.builder().techName(techName.toUpperCase()).build(); - projectTechAdaptor.saveTech(newTech); + techRepository.save(newTech); persistedTech = newTech; - } else + } else { persistedTech = tech; + } ProjectTech projectTech = new ProjectTech(project, persistedTech); projectTeches.add(projectTech); } - projectTechAdaptor.saveAll(projectTeches); + projectTechRepository.saveAll(projectTeches); } } @Transactional public void deleteProjectTech(Long id) { - Project project = projectAdaptor.findById(id); - projectTechAdaptor.deleteByProject(project); + Project project = projectRepository.getById(id); + projectTechRepository.deleteByProject(project); } } diff --git a/likelion-core/src/main/java/likelion/univ/domain/recruit/adopter/RecruitAdopter.java b/likelion-core/src/main/java/likelion/univ/domain/recruit/adopter/RecruitAdopter.java deleted file mode 100644 index e017dfd6..00000000 --- a/likelion-core/src/main/java/likelion/univ/domain/recruit/adopter/RecruitAdopter.java +++ /dev/null @@ -1,23 +0,0 @@ -package likelion.univ.domain.recruit.adopter; - -import likelion.univ.annotation.Adaptor; -import likelion.univ.domain.recruit.entity.Recruit; -import likelion.univ.domain.recruit.exception.RecruitNotFound; -import likelion.univ.domain.recruit.repository.RecruitRepository; -import lombok.RequiredArgsConstructor; - -@Adaptor -@RequiredArgsConstructor -public class RecruitAdopter { - - private final RecruitRepository recruitRepository; - - public Long save(Recruit recruit) { - return recruitRepository.save(recruit).getId(); - } - - public Recruit findById(Long id) { - return recruitRepository.findById(id) - .orElseThrow(RecruitNotFound::new); - } -} diff --git a/likelion-core/src/main/java/likelion/univ/domain/recruit/entity/Recruit.java b/likelion-core/src/main/java/likelion/univ/domain/recruit/entity/Recruit.java index caf7e8c8..c7d0ad32 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/recruit/entity/Recruit.java +++ b/likelion-core/src/main/java/likelion/univ/domain/recruit/entity/Recruit.java @@ -1,5 +1,12 @@ package likelion.univ.domain.recruit.entity; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; import likelion.univ.common.entity.BaseTimeEntity; import likelion.univ.domain.university.entity.University; import lombok.AccessLevel; @@ -7,8 +14,6 @@ import lombok.Getter; import lombok.NoArgsConstructor; -import javax.persistence.*; - @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) diff --git a/likelion-core/src/main/java/likelion/univ/domain/recruit/exception/EmailAlreadyRegistered.java b/likelion-core/src/main/java/likelion/univ/domain/recruit/exception/EmailAlreadyRegistered.java index c94ba7ae..a20c5a09 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/recruit/exception/EmailAlreadyRegistered.java +++ b/likelion-core/src/main/java/likelion/univ/domain/recruit/exception/EmailAlreadyRegistered.java @@ -3,6 +3,7 @@ import likelion.univ.exception.base.BaseException; public class EmailAlreadyRegistered extends BaseException { + public EmailAlreadyRegistered() { super(RecruitErrorCode.EMAIL_ALREADY_REGISTERED); } diff --git a/likelion-core/src/main/java/likelion/univ/domain/recruit/exception/RecruitErrorCode.java b/likelion-core/src/main/java/likelion/univ/domain/recruit/exception/RecruitErrorCode.java index 55f7bbd6..5f30a019 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/recruit/exception/RecruitErrorCode.java +++ b/likelion-core/src/main/java/likelion/univ/domain/recruit/exception/RecruitErrorCode.java @@ -1,17 +1,17 @@ package likelion.univ.domain.recruit.exception; +import static likelion.univ.constant.StaticValue.BAD_REQUEST; + import likelion.univ.exception.base.BaseErrorCode; import lombok.AllArgsConstructor; import lombok.Getter; -import static likelion.univ.constant.StaticValue.BAD_REQUEST; - @Getter @AllArgsConstructor public enum RecruitErrorCode implements BaseErrorCode { - EMAIL_ALREADY_REGISTERED(BAD_REQUEST, "ALARM_400","이번 기수에 이미 등록된 이메일입니다."), - RECRUIT_NOT_FOUND(BAD_REQUEST, "ALARM_400_1","등록된 리크루팅이 없습니다."); + EMAIL_ALREADY_REGISTERED(BAD_REQUEST, "ALARM_400", "이번 기수에 이미 등록된 이메일입니다."), + RECRUIT_NOT_FOUND(BAD_REQUEST, "ALARM_400_1", "등록된 리크루팅이 없습니다."); private final int httpStatus; private final String code; diff --git a/likelion-core/src/main/java/likelion/univ/domain/recruit/repository/RecruitRepository.java b/likelion-core/src/main/java/likelion/univ/domain/recruit/repository/RecruitRepository.java index 93e09106..ae70a290 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/recruit/repository/RecruitRepository.java +++ b/likelion-core/src/main/java/likelion/univ/domain/recruit/repository/RecruitRepository.java @@ -1,13 +1,19 @@ package likelion.univ.domain.recruit.repository; +import java.util.List; import likelion.univ.domain.recruit.entity.Recruit; +import likelion.univ.domain.recruit.exception.RecruitNotFound; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; -import java.util.List; - @Repository public interface RecruitRepository extends JpaRepository { + + default Recruit getById(Long id) { + return findById(id).orElseThrow(RecruitNotFound::new); + } + List findAllByGenerationAndUniversityName(Integer generation, String universityName); - Boolean existsByEmailAndGeneration(String email, Integer generation); + + boolean existsByEmailAndGeneration(String email, Integer generation); } diff --git a/likelion-core/src/main/java/likelion/univ/domain/recruit/service/RecruitQueryService.java b/likelion-core/src/main/java/likelion/univ/domain/recruit/service/RecruitQueryService.java index 639da07d..1658b803 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/recruit/service/RecruitQueryService.java +++ b/likelion-core/src/main/java/likelion/univ/domain/recruit/service/RecruitQueryService.java @@ -1,14 +1,12 @@ package likelion.univ.domain.recruit.service; -import likelion.univ.domain.recruit.adopter.RecruitAdopter; +import java.util.List; import likelion.univ.domain.recruit.entity.Recruit; import likelion.univ.domain.recruit.repository.RecruitRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.List; - @Service @Transactional(readOnly = true) @RequiredArgsConstructor diff --git a/likelion-core/src/main/java/likelion/univ/domain/recruit/service/RecruitService.java b/likelion-core/src/main/java/likelion/univ/domain/recruit/service/RecruitService.java index 526e8f39..75d53985 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/recruit/service/RecruitService.java +++ b/likelion-core/src/main/java/likelion/univ/domain/recruit/service/RecruitService.java @@ -1,6 +1,5 @@ package likelion.univ.domain.recruit.service; -import likelion.univ.domain.recruit.adopter.RecruitAdopter; import likelion.univ.domain.recruit.entity.Recruit; import likelion.univ.domain.recruit.exception.EmailAlreadyRegistered; import likelion.univ.domain.recruit.repository.RecruitRepository; @@ -13,14 +12,13 @@ @RequiredArgsConstructor public class RecruitService { - private final RecruitAdopter recruitAdopter; private final RecruitRepository recruitRepository; public Long register(Recruit recruit) { if (recruitRepository.existsByEmailAndGeneration(recruit.getEmail(), recruit.getGeneration())) { throw new EmailAlreadyRegistered(); } - return recruitAdopter.save(recruit); + return recruitRepository.save(recruit).getId(); } public void delete(long recruitId) { diff --git a/likelion-core/src/main/java/likelion/univ/domain/university/adaptor/UniversityAdaptor.java b/likelion-core/src/main/java/likelion/univ/domain/university/adaptor/UniversityAdaptor.java deleted file mode 100644 index 562c2fb9..00000000 --- a/likelion-core/src/main/java/likelion/univ/domain/university/adaptor/UniversityAdaptor.java +++ /dev/null @@ -1,32 +0,0 @@ -package likelion.univ.domain.university.adaptor; - -import likelion.univ.annotation.Adaptor; -import likelion.univ.domain.university.entity.University; -import likelion.univ.domain.university.entity.UniversityStatus; -import likelion.univ.domain.university.exception.UniversityNotFoundException; -import likelion.univ.domain.university.repository.UniversityRepository; -import lombok.RequiredArgsConstructor; - -import java.util.List; - -@Adaptor -@RequiredArgsConstructor -public class UniversityAdaptor { - private final UniversityRepository universityRepository; - - public University findByName(String name){ - return universityRepository.findByName(name) - .orElseThrow(() -> new UniversityNotFoundException()); - } - - public List findAll() { - return universityRepository.findAllByUniversityStatus(UniversityStatus.ACTIVE); - } - public List findByLocation(String location) { - return universityRepository.findByLocationAndUniversityStatus(location, UniversityStatus.ACTIVE); - } - - public University findById(Long id) { - return universityRepository.findById(id).get(); - } -} diff --git a/likelion-core/src/main/java/likelion/univ/domain/university/entity/University.java b/likelion-core/src/main/java/likelion/univ/domain/university/entity/University.java index 101972d0..270a78ef 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/university/entity/University.java +++ b/likelion-core/src/main/java/likelion/univ/domain/university/entity/University.java @@ -1,13 +1,16 @@ package likelion.univ.domain.university.entity; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; import likelion.univ.common.entity.BaseTimeEntity; -import likelion.univ.domain.user.entity.Part; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; -import net.bytebuddy.dynamic.TypeResolutionStrategy; - -import javax.persistence.*; @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -17,12 +20,16 @@ public class University extends BaseTimeEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; + @Column(unique = true) private String name; + private String location; + private String image; - private String recruiteUrl; + + private String recruitUrl; + @Enumerated(EnumType.STRING) private UniversityStatus universityStatus = UniversityStatus.ACTIVE; - } diff --git a/likelion-core/src/main/java/likelion/univ/domain/university/entity/UniversityStatus.java b/likelion-core/src/main/java/likelion/univ/domain/university/entity/UniversityStatus.java index a0120683..26eb7a1e 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/university/entity/UniversityStatus.java +++ b/likelion-core/src/main/java/likelion/univ/domain/university/entity/UniversityStatus.java @@ -6,6 +6,7 @@ @AllArgsConstructor @Getter public enum UniversityStatus { + ACTIVE("ACTIVE"), DEACTIVE("DEACTIVE"); diff --git a/likelion-core/src/main/java/likelion/univ/domain/university/exception/UniversityErrorCode.java b/likelion-core/src/main/java/likelion/univ/domain/university/exception/UniversityErrorCode.java index 3db348e4..58755c61 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/university/exception/UniversityErrorCode.java +++ b/likelion-core/src/main/java/likelion/univ/domain/university/exception/UniversityErrorCode.java @@ -1,20 +1,18 @@ package likelion.univ.domain.university.exception; +import static likelion.univ.constant.StaticValue.NOT_FOUND; + import likelion.univ.exception.base.BaseErrorCode; import lombok.AllArgsConstructor; import lombok.Getter; -import static likelion.univ.constant.StaticValue.BAD_REQUEST; -import static likelion.univ.constant.StaticValue.NOT_FOUND; - @Getter @AllArgsConstructor public enum UniversityErrorCode implements BaseErrorCode { - UNIVERSITY_NOT_FOUND(NOT_FOUND, "UNIVERSITY_404", "해당 대학을 찾을 수 없습니다."); + UNIVERSITY_NOT_FOUND(NOT_FOUND, "UNIVERSITY_404", "해당 대학을 찾을 수 없습니다."); private final int httpStatus; private final String code; private final String message; - } diff --git a/likelion-core/src/main/java/likelion/univ/domain/university/exception/UniversityNotFoundException.java b/likelion-core/src/main/java/likelion/univ/domain/university/exception/UniversityNotFoundException.java index 8a51fbde..84198d72 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/university/exception/UniversityNotFoundException.java +++ b/likelion-core/src/main/java/likelion/univ/domain/university/exception/UniversityNotFoundException.java @@ -1,9 +1,9 @@ package likelion.univ.domain.university.exception; -import likelion.univ.exception.base.BaseErrorCode; import likelion.univ.exception.base.BaseException; public class UniversityNotFoundException extends BaseException { + public UniversityNotFoundException() { super(UniversityErrorCode.UNIVERSITY_NOT_FOUND); } diff --git a/likelion-core/src/main/java/likelion/univ/domain/university/repository/UniversityRepository.java b/likelion-core/src/main/java/likelion/univ/domain/university/repository/UniversityRepository.java index e83644ec..98eb102b 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/university/repository/UniversityRepository.java +++ b/likelion-core/src/main/java/likelion/univ/domain/university/repository/UniversityRepository.java @@ -1,14 +1,33 @@ package likelion.univ.domain.university.repository; +import java.util.List; +import java.util.Optional; import likelion.univ.domain.university.entity.University; import likelion.univ.domain.university.entity.UniversityStatus; +import likelion.univ.domain.university.exception.UniversityNotFoundException; import org.springframework.data.jpa.repository.JpaRepository; -import java.util.List; -import java.util.Optional; +public interface UniversityRepository extends JpaRepository { + + default University getById(Long id) { + return findById(id).orElseThrow(UniversityNotFoundException::new); + } + + default University getByName(String name) { + return findByName(name).orElseThrow(UniversityNotFoundException::new); + } -public interface UniversityRepository extends JpaRepository { Optional findByName(String name); + + default List findByLocationAndStatusIsActive(String location) { + return findByLocationAndUniversityStatus(location, UniversityStatus.ACTIVE); + } + List findByLocationAndUniversityStatus(String location, UniversityStatus status); + + default List findAllByStatusIsActive() { + return findAllByUniversityStatus(UniversityStatus.ACTIVE); + } + List findAllByUniversityStatus(UniversityStatus status); } diff --git a/likelion-core/src/main/java/likelion/univ/domain/university/service/UniversityService.java b/likelion-core/src/main/java/likelion/univ/domain/university/service/UniversityService.java index b23b70b3..5dd68572 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/university/service/UniversityService.java +++ b/likelion-core/src/main/java/likelion/univ/domain/university/service/UniversityService.java @@ -1,7 +1,7 @@ package likelion.univ.domain.university.service; -import likelion.univ.domain.university.adaptor.UniversityAdaptor; import likelion.univ.domain.university.entity.University; +import likelion.univ.domain.university.repository.UniversityRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -11,9 +11,9 @@ @RequiredArgsConstructor public class UniversityService { - private final UniversityAdaptor universityAdaptor; + private final UniversityRepository universityRepository; public University findByName(String name) { - return universityAdaptor.findByName(name); + return universityRepository.getByName(name); } } diff --git a/likelion-core/src/main/java/likelion/univ/domain/user/adaptor/UserAdaptor.java b/likelion-core/src/main/java/likelion/univ/domain/user/adaptor/UserAdaptor.java deleted file mode 100644 index c7509e7f..00000000 --- a/likelion-core/src/main/java/likelion/univ/domain/user/adaptor/UserAdaptor.java +++ /dev/null @@ -1,74 +0,0 @@ -package likelion.univ.domain.user.adaptor; - -import likelion.univ.annotation.Adaptor; -import likelion.univ.domain.user.entity.Role; -import likelion.univ.domain.user.entity.User; -import likelion.univ.domain.user.exception.UserNotFoundException; -import likelion.univ.domain.user.repository.UserRepository; -import likelion.univ.domain.user.repository.searchcondition.UserSearchCondition; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; - -import java.util.List; - -@Adaptor -@RequiredArgsConstructor -public class UserAdaptor { - private final UserRepository userRepository; - - public User findById(Long id){ - return userRepository.findById(id) - .orElseThrow(()-> new UserNotFoundException()); - } - public User findByIdWithUniversity(Long id){ - return userRepository.findByIdWithUniversity(id) - .orElseThrow(() -> new UserNotFoundException()); - } - public User findByEmail(String email){ - return userRepository.findByAuthInfoEmail(email) - .orElseThrow(() -> new UserNotFoundException()); - } - public Boolean checkEmail(String email){ - return userRepository.existsByAuthInfoEmail(email); - } - public User save(User user){ - return userRepository.save(user); - } - - public Page findByUniversityInfoUniversityId(Long id, Pageable pageable) { - return userRepository.findByUniversityInfoUniversityId(id, pageable); - } - - public Page findByUnivNameAndRole(Role role, String univName, Pageable pageable) { - return userRepository.findByUnivNameAndRole(role, univName, pageable); - } - - public List findDynamicUsers(UserSearchCondition condition) { - return userRepository.findDynamicUsers(condition); - } - public Slice findFollowingUsersByFollowerID(Long userId, Pageable pageable){ - return userRepository.findFollowingUsersByFollowerID(userId, pageable); - } - public Slice findFollowerUsersByFollowingID(Long userId, Pageable pageable){ - return userRepository.findFollowerUsersByFollowingID(userId, pageable); - } - public List findMyFollowingUsersByFollowingIdIn(Long follwerId, List followingIdList){ - return userRepository.findMyFollowingUsersByFollowingIdIn(follwerId, followingIdList); - } - public Slice searchByName(String name, Pageable pageable){ - return userRepository.searchByName(name, pageable); - } - public List findAllByIdIn(List ids) { - List users = userRepository.findAllByIdIn(ids); - if (users.size() != ids.size()) { - throw new UserNotFoundException(); - } - return users; - } - - public Page findAllWithUniversity(Pageable pageable){ - return userRepository.findAllWithUniversity(pageable); - } -} diff --git a/likelion-core/src/main/java/likelion/univ/domain/user/entity/AccountStatus.java b/likelion-core/src/main/java/likelion/univ/domain/user/entity/AccountStatus.java index 6471a4e9..d98c87c2 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/user/entity/AccountStatus.java +++ b/likelion-core/src/main/java/likelion/univ/domain/user/entity/AccountStatus.java @@ -6,6 +6,7 @@ @AllArgsConstructor @Getter public enum AccountStatus { + ACTIVE("ACTIVE"), Deleted("DELETED"); diff --git a/likelion-core/src/main/java/likelion/univ/domain/user/entity/AuthInfo.java b/likelion-core/src/main/java/likelion/univ/domain/user/entity/AuthInfo.java index 9e5fd0eb..1703fa06 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/user/entity/AuthInfo.java +++ b/likelion-core/src/main/java/likelion/univ/domain/user/entity/AuthInfo.java @@ -1,12 +1,18 @@ package likelion.univ.domain.user.entity; -import lombok.*; - -import javax.persistence.*; - import static likelion.univ.domain.user.entity.AccountStatus.ACTIVE; import static likelion.univ.domain.user.entity.Role.GUEST; +import javax.persistence.Column; +import javax.persistence.Embeddable; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + @Embeddable @AllArgsConstructor @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -16,10 +22,13 @@ public class AuthInfo { @Enumerated(EnumType.STRING) private LoginType loginType; + @Column(unique = true) private String email; + @Enumerated(EnumType.STRING) private AccountStatus accountStatus; + // 01000000000 형태로 private String phoneNumber; @@ -35,10 +44,11 @@ public static AuthInfo authInfoForSignUp(LoginType loginType, String email) { .build(); } - public void updateRole(Role role){ + public void updateRole(Role role) { this.role = role; } - public void delete(){ + + public void delete() { this.accountStatus = AccountStatus.Deleted; this.email = null; } diff --git a/likelion-core/src/main/java/likelion/univ/domain/user/entity/LoginType.java b/likelion-core/src/main/java/likelion/univ/domain/user/entity/LoginType.java index 3877a4e9..d81657e9 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/user/entity/LoginType.java +++ b/likelion-core/src/main/java/likelion/univ/domain/user/entity/LoginType.java @@ -7,6 +7,7 @@ @AllArgsConstructor @Getter public enum LoginType { + KAKAO("kakao"), GOOGLE("google"); diff --git a/likelion-core/src/main/java/likelion/univ/domain/user/entity/Part.java b/likelion-core/src/main/java/likelion/univ/domain/user/entity/Part.java index 7b26b108..4f674626 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/user/entity/Part.java +++ b/likelion-core/src/main/java/likelion/univ/domain/user/entity/Part.java @@ -6,6 +6,7 @@ @AllArgsConstructor @Getter public enum Part { + ADMIN("관리자"), PM("기획"), DESIGNER("디자인"), @@ -13,5 +14,6 @@ public enum Part { FRONTEND("프론트엔드"), BACKEND("백엔드"), NO_PART("NO_PART"); + private String value; } diff --git a/likelion-core/src/main/java/likelion/univ/domain/user/entity/Profile.java b/likelion-core/src/main/java/likelion/univ/domain/user/entity/Profile.java index bca7c846..6e24eab5 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/user/entity/Profile.java +++ b/likelion-core/src/main/java/likelion/univ/domain/user/entity/Profile.java @@ -1,11 +1,14 @@ package likelion.univ.domain.user.entity; -import lombok.*; - import javax.persistence.Column; import javax.persistence.Embeddable; import javax.persistence.EnumType; import javax.persistence.Enumerated; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; @Embeddable @Getter @@ -28,14 +31,14 @@ public void updateProfile(String name, Part part) { this.part = part; } - public static Profile fromName(String name){ + public static Profile fromName(String name) { return Profile.builder() .name(name) .part(Part.NO_PART) .build(); } - public void delete(){ + public void delete() { this.name = "알수없음"; } } \ No newline at end of file diff --git a/likelion-core/src/main/java/likelion/univ/domain/user/entity/UniversityInfo.java b/likelion-core/src/main/java/likelion/univ/domain/user/entity/UniversityInfo.java index c23f6de3..2d0cc5cd 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/user/entity/UniversityInfo.java +++ b/likelion-core/src/main/java/likelion/univ/domain/user/entity/UniversityInfo.java @@ -1,12 +1,15 @@ package likelion.univ.domain.user.entity; -import likelion.univ.domain.university.entity.University; -import lombok.*; - import javax.persistence.Embeddable; import javax.persistence.FetchType; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; +import likelion.univ.domain.university.entity.University; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; @Embeddable @Getter @@ -14,18 +17,19 @@ @AllArgsConstructor @Builder public class UniversityInfo { + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "university_id") private University university; private String major; private Long ordinal; - public void updateUniversityInfo(String major, Long ordinal){ - this.major=major; - this.ordinal=ordinal; + public void updateUniversityInfo(String major, Long ordinal) { + this.major = major; + this.ordinal = ordinal; } - public static UniversityInfo universityInfoForSignUp(University university, String major){ + public static UniversityInfo universityInfoForSignUp(University university, String major) { return UniversityInfo.builder() .university(university) .major(major) diff --git a/likelion-core/src/main/java/likelion/univ/domain/user/entity/User.java b/likelion-core/src/main/java/likelion/univ/domain/user/entity/User.java index bc917f20..3b3c8023 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/user/entity/User.java +++ b/likelion-core/src/main/java/likelion/univ/domain/user/entity/User.java @@ -1,8 +1,18 @@ package likelion.univ.domain.user.entity; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.UniqueConstraint; import likelion.univ.common.entity.BaseTimeEntity; -import lombok.*; -import javax.persistence.*; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -10,7 +20,7 @@ @AllArgsConstructor @Entity @Table(uniqueConstraints = {@UniqueConstraint(columnNames = {"email", "loginType"})}) -public class User extends BaseTimeEntity{ +public class User extends BaseTimeEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -25,7 +35,7 @@ public class User extends BaseTimeEntity{ @Embedded private AuthInfo authInfo; - public void editProfile(Profile profile){ + public void editProfile(Profile profile) { this.profile = profile; } } diff --git a/likelion-core/src/main/java/likelion/univ/domain/user/exception/EmailAlreadyRegistered.java b/likelion-core/src/main/java/likelion/univ/domain/user/exception/EmailAlreadyRegistered.java index 9426ef98..6271260f 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/user/exception/EmailAlreadyRegistered.java +++ b/likelion-core/src/main/java/likelion/univ/domain/user/exception/EmailAlreadyRegistered.java @@ -3,6 +3,7 @@ import likelion.univ.exception.base.BaseException; public class EmailAlreadyRegistered extends BaseException { + public EmailAlreadyRegistered() { super(UserErrorCode.EMAIL_ALREADY_REGISTERED); } diff --git a/likelion-core/src/main/java/likelion/univ/domain/user/exception/NotSupportedLoginTypeException.java b/likelion-core/src/main/java/likelion/univ/domain/user/exception/NotSupportedLoginTypeException.java index d9d624e1..8b814489 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/user/exception/NotSupportedLoginTypeException.java +++ b/likelion-core/src/main/java/likelion/univ/domain/user/exception/NotSupportedLoginTypeException.java @@ -3,6 +3,7 @@ import likelion.univ.exception.base.BaseException; public class NotSupportedLoginTypeException extends BaseException { + public NotSupportedLoginTypeException() { super(UserErrorCode.NOT_SUPPORTED_LOGIN_TYPE); } diff --git a/likelion-core/src/main/java/likelion/univ/domain/user/exception/UserErrorCode.java b/likelion-core/src/main/java/likelion/univ/domain/user/exception/UserErrorCode.java index 4bd6e166..1aa6050c 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/user/exception/UserErrorCode.java +++ b/likelion-core/src/main/java/likelion/univ/domain/user/exception/UserErrorCode.java @@ -1,20 +1,22 @@ package likelion.univ.domain.user.exception; +import static likelion.univ.constant.StaticValue.BAD_REQUEST; +import static likelion.univ.constant.StaticValue.FORBIDDEN; +import static likelion.univ.constant.StaticValue.NOT_FOUND; + import likelion.univ.exception.base.BaseErrorCode; import lombok.AllArgsConstructor; import lombok.Getter; -import static likelion.univ.constant.StaticValue.*; - @Getter @AllArgsConstructor -public enum UserErrorCode implements BaseErrorCode{ +public enum UserErrorCode implements BaseErrorCode { + NOT_SUPPORTED_LOGIN_TYPE(BAD_REQUEST, "LOGIN_TYPE_400", "해당 방식은 지원하지않는 로그인 방식입니다."), USER_NOT_MATCH(FORBIDDEN, "USER_403", "사용자가 일치하지 않습니다."), USER_NOT_FOUND(NOT_FOUND, "USER_404", "유저를 찾을 수 없습니다."), EMAIL_ALREADY_REGISTERED(NOT_FOUND, "USER_409", "같은 이메일로 회원가입된 계정이 있습니다."); - private final int httpStatus; private final String code; private final String message; diff --git a/likelion-core/src/main/java/likelion/univ/domain/user/exception/UserNotFoundException.java b/likelion-core/src/main/java/likelion/univ/domain/user/exception/UserNotFoundException.java index 603ae59b..0e5bd1ef 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/user/exception/UserNotFoundException.java +++ b/likelion-core/src/main/java/likelion/univ/domain/user/exception/UserNotFoundException.java @@ -3,6 +3,7 @@ import likelion.univ.exception.base.BaseException; public class UserNotFoundException extends BaseException { + public UserNotFoundException() { super(UserErrorCode.USER_NOT_FOUND); } diff --git a/likelion-core/src/main/java/likelion/univ/domain/user/exception/UserNotMatchException.java b/likelion-core/src/main/java/likelion/univ/domain/user/exception/UserNotMatchException.java index 64525922..cf44aed0 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/user/exception/UserNotMatchException.java +++ b/likelion-core/src/main/java/likelion/univ/domain/user/exception/UserNotMatchException.java @@ -1,9 +1,9 @@ package likelion.univ.domain.user.exception; -import likelion.univ.exception.base.BaseErrorCode; import likelion.univ.exception.base.BaseException; public class UserNotMatchException extends BaseException { + public UserNotMatchException() { super(UserErrorCode.USER_NOT_MATCH); } diff --git a/likelion-core/src/main/java/likelion/univ/domain/user/repository/UserCustomRepository.java b/likelion-core/src/main/java/likelion/univ/domain/user/repository/UserCustomRepository.java index bbcbbf4f..25476f4c 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/user/repository/UserCustomRepository.java +++ b/likelion-core/src/main/java/likelion/univ/domain/user/repository/UserCustomRepository.java @@ -1,5 +1,6 @@ package likelion.univ.domain.user.repository; +import java.util.List; import likelion.univ.domain.user.entity.Role; import likelion.univ.domain.user.entity.User; import likelion.univ.domain.user.repository.searchcondition.UserSearchCondition; @@ -7,15 +8,21 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; -import java.util.List; - public interface UserCustomRepository { - List findDynamicUsers(UserSearchCondition condition); - Slice findFollowingUsersByFollowerID(Long userId, Pageable pageable); - Slice findFollowerUsersByFollowingID(Long userId, Pageable pageable); + + List search(UserSearchCondition condition); + + Slice findFollowingUsersByFollowerId(Long userId, Pageable pageable); + + Slice findFollowerUsersByFollowingId(Long userId, Pageable pageable); + Slice searchByName(String name, Pageable pageable); + List findMyFollowingUsersByFollowingIdIn(Long followerId, List followingIdList); + Page findAllWithUniversity(Pageable pageable); + Page findByUnivNameAndRole(Role role, String univName, Pageable pageable); + Page findByUniversityInfoUniversityId(Long univId, Pageable pageable); } diff --git a/likelion-core/src/main/java/likelion/univ/domain/user/repository/UserRepository.java b/likelion-core/src/main/java/likelion/univ/domain/user/repository/UserRepository.java index fb67c356..531ba295 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/user/repository/UserRepository.java +++ b/likelion-core/src/main/java/likelion/univ/domain/user/repository/UserRepository.java @@ -1,21 +1,43 @@ package likelion.univ.domain.user.repository; +import java.util.List; +import java.util.Optional; import likelion.univ.domain.user.entity.Role; import likelion.univ.domain.user.entity.User; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; +import likelion.univ.domain.user.exception.UserNotFoundException; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; -import java.util.List; -import java.util.Optional; +public interface UserRepository extends JpaRepository, UserCustomRepository { + + default User getById(Long id) { + return findById(id).orElseThrow(UserNotFoundException::new); + } + + default User getByIdWithUniversity(Long id) { + return findByIdWithUniversity(id).orElseThrow(UserNotFoundException::new); + } + + default User getByEmail(String email) { + return findByAuthInfoEmail(email).orElseThrow(UserNotFoundException::new); + } -public interface UserRepository extends JpaRepository, UserCustomRepository { Optional findByAuthInfoEmail(String email); - Boolean existsByAuthInfoEmail(String email); + + boolean existsByAuthInfoEmail(String email); + @Query(value = "SELECT u FROM User u join fetch u.universityInfo.university where u.id = :id ") Optional findByIdWithUniversity(Long id); List findByAuthInfoRoleIn(List roles); + + default List findAllByIdsExactly(List ids) { + List users = findAllByIdIn(ids); + if (users.size() != ids.size()) { + throw new UserNotFoundException(); + } + return users; + } + List findAllByIdIn(List ids); } diff --git a/likelion-core/src/main/java/likelion/univ/domain/user/repository/impl/UserCustomRepositoryImpl.java b/likelion-core/src/main/java/likelion/univ/domain/user/repository/impl/UserCustomRepositoryImpl.java index 077a5a1e..acd3e702 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/user/repository/impl/UserCustomRepositoryImpl.java +++ b/likelion-core/src/main/java/likelion/univ/domain/user/repository/impl/UserCustomRepositoryImpl.java @@ -32,225 +32,224 @@ @RequiredArgsConstructor public class UserCustomRepositoryImpl implements UserCustomRepository { - private final JPAQueryFactory queryFactory; - private final ConvertSliceProcessor convertSliceProcessor; - - @Override - public List findDynamicUsers(UserSearchCondition condition) { - return queryFactory - .selectFrom(user) - .where( - containsName(condition.getName()), - eqUniversity(condition.getUniversity()), - eqPart(condition.getPart()) - ) - .fetch(); - } - - private BooleanExpression containsName(String searchName) { - return StringUtils.hasText(searchName) ? user.profile.name.contains(searchName) : null; - } - - private BooleanExpression eqUniversity(String searchUniversity) { - return searchUniversity != null ? user.universityInfo.university.name.eq(searchUniversity) : null; - } - - private BooleanExpression startsWithUniversity(String searchUniversity) { - return StringUtils.hasText(searchUniversity) ? - user.universityInfo.university.name.startsWith(searchUniversity) : null; - } - - private BooleanExpression eqPart(String searchPart) { - return searchPart != null ? user.profile.part.eq(Part.valueOf(searchPart)) : null; - } - - private BooleanExpression eqUnivId(Long univId) { - return univId != null ? user.universityInfo.university.id.eq(univId) : null; - } - - private BooleanExpression eqRole(Role role) { - return role != null ? - switch (role) { - case GUEST -> user.authInfo.role.eq(Role.GUEST); - case USER -> user.authInfo.role.eq(Role.USER); - case MANAGER -> user.authInfo.role.eq(Role.MANAGER); - case UNIVERSITY_ADMIN -> user.authInfo.role.eq(Role.UNIVERSITY_ADMIN); - case SUPER_ADMIN -> user.authInfo.role.eq(Role.SUPER_ADMIN); - } - : null; - } - - @Override - public Page findByUniversityInfoUniversityId(Long univId, Pageable pageable) { - List ids = getCoveringIndexByUniversityId(univId); - NumberExpression partOrder = new CaseBuilder() - .when(user.profile.part.eq(Part.PM)).then(1) - .when(user.profile.part.eq(Part.DESIGNER)).then(2) - .when(user.profile.part.eq(Part.PM_DESIGNER)).then(3) - .when(user.profile.part.eq(Part.FRONTEND)).then(4) - .when(user.profile.part.eq(Part.BACKEND)).then(5) - .otherwise(6); - List users = - queryFactory - .select(user) - .from(user) - .innerJoin(user.universityInfo.university, university).fetchJoin() - .where(user.id.in(ids)) - .offset(pageable.getOffset()) - .orderBy(user.universityInfo.ordinal.desc(), - user.universityInfo.university.name.asc(), - partOrder.asc(), - user.profile.name.asc()) - .limit(pageable.getPageSize()) - .fetch(); - - return PageableExecutionUtils.getPage(users, pageable, ids::size); - } - - @Override - public Page findByUnivNameAndRole(Role role, String univName, Pageable pageable) { - List ids = queryFactory - .select(user.id) - .from(user) - .where(startsWithUniversity(univName), eqRole(role), user.authInfo.accountStatus.eq(ACTIVE)) - .fetch(); - NumberExpression partOrder = new CaseBuilder() - .when(user.profile.part.eq(Part.PM)).then(1) - .when(user.profile.part.eq(Part.DESIGNER)).then(2) - .when(user.profile.part.eq(Part.PM_DESIGNER)).then(3) - .when(user.profile.part.eq(Part.FRONTEND)).then(4) - .when(user.profile.part.eq(Part.BACKEND)).then(5) - .otherwise(6); - - List users = - queryFactory - .select(user) - .from(user) - .innerJoin(user.universityInfo.university, university).fetchJoin() - .where(startsWithUniversity(univName), - eqRole(role), - user.authInfo.accountStatus.eq(ACTIVE)) - .offset(pageable.getOffset()) - .orderBy(user.universityInfo.ordinal.desc(), - user.universityInfo.university.name.asc(), - partOrder.asc(), - user.profile.name.asc()) - .limit(pageable.getPageSize()) - .fetch(); - - return PageableExecutionUtils.getPage(users, pageable, ids::size); - } - - - @Override - public Slice findFollowingUsersByFollowerID(Long followerId, Pageable pageable) { - List users = - queryFactory - .select(follow.following) - .from(follow) - .innerJoin(follow.following, user) - .where(follow.follower.id.eq(followerId)) - .offset(pageable.getOffset()) - .orderBy(user.createdDate.desc()) - .limit(pageable.getPageSize() + 1) - .fetch(); - - return convertSliceProcessor.execute(users, pageable); - } - - @Override - public Slice findFollowerUsersByFollowingID(Long followingId, Pageable pageable) { - List users = - queryFactory - .select(user) - .from(follow) - .innerJoin(follow.follower, user) - .where(follow.following.id.eq(followingId)) - .offset(pageable.getOffset()) - .orderBy(user.createdDate.desc()) - .limit(pageable.getPageSize() + 1) - .fetch(); - - return convertSliceProcessor.execute(users, pageable); - } - - @Override - public List findMyFollowingUsersByFollowingIdIn(Long followerId, List followingIdList) { - List users = - queryFactory - .select(user) - .from(follow) - .innerJoin(follow.following, user) - .where(follow.follower.id.eq(followerId) - .and(follow.following.id.in(followingIdList))) - .fetch(); - return users; - } - - @Override - public Slice searchByName(String name, Pageable pageable) { - NumberExpression partOrder = new CaseBuilder() - .when(user.profile.part.eq(Part.PM)).then(1) - .when(user.profile.part.eq(Part.DESIGNER)).then(2) - .when(user.profile.part.eq(Part.PM_DESIGNER)).then(3) - .when(user.profile.part.eq(Part.FRONTEND)).then(4) - .when(user.profile.part.eq(Part.BACKEND)).then(5) - .otherwise(6); - - List users = - queryFactory - .select(user) - .from(user) - .innerJoin(user.universityInfo.university, university).fetchJoin() - .where(containsName(name)) - .offset(pageable.getOffset()) - .orderBy(partOrder.asc(), user.profile.name.asc()) - .limit(pageable.getPageSize() + 1) - .fetch(); - - return convertSliceProcessor.execute(users, pageable); - } - - @Override - public Page findAllWithUniversity(Pageable pageable) { - List ids = getCoveringIndex(null); - List result = queryFactory.select(user) - .from(user) - .leftJoin(user.universityInfo.university, university).fetchJoin() - .where(user.id.in(ids)) - .orderBy(getOrders(user, pageable.getSort())) - .offset(pageable.getOffset()) - .limit(pageable.getPageSize()) - .fetch(); - return PageableExecutionUtils.getPage(result, pageable, ids::size); - } - - private List getCoveringIndex(Predicate predicate) { - return queryFactory - .select(user.id) - .from(user) - .where(predicate, user.authInfo.accountStatus.eq(ACTIVE)) - .fetch(); - } - - private List getCoveringIndexByUniversityId(Long univId) { - return queryFactory - .select(user.id) - .from(user) - .where(user.authInfo.accountStatus.eq(ACTIVE), - eqUnivId(univId)) - .fetch(); - } - - private OrderSpecifier[] getOrders(EntityPath qEntity, Sort sort) { - return sort.stream().map(it -> getOrder(qEntity, it)).toArray(OrderSpecifier[]::new); - } - - private OrderSpecifier getOrder(EntityPath qEntity, Sort.Order order) { - final Order direction = order.isAscending() ? Order.ASC : Order.DESC; - final String property = order.getProperty(); - PathBuilder pathBuilder = - new PathBuilder<>(qEntity.getType(), qEntity.getMetadata().getName()); - return new OrderSpecifier(direction, pathBuilder.get(property)); - } + private final JPAQueryFactory queryFactory; + private final ConvertSliceProcessor convertSliceProcessor; + + @Override + public List search(UserSearchCondition condition) { + return queryFactory + .selectFrom(user) + .where( + containsName(condition.getName()), + eqUniversity(condition.getUniversity()), + eqPart(condition.getPart()) + ) + .fetch(); + } + + private BooleanExpression containsName(String searchName) { + return StringUtils.hasText(searchName) ? user.profile.name.contains(searchName) : null; + } + + private BooleanExpression eqUniversity(String searchUniversity) { + return searchUniversity != null ? user.universityInfo.university.name.eq(searchUniversity) : null; + } + + private BooleanExpression startsWithUniversity(String searchUniversity) { + return StringUtils.hasText(searchUniversity) ? + user.universityInfo.university.name.startsWith(searchUniversity) : null; + } + + private BooleanExpression eqPart(String searchPart) { + return searchPart != null ? user.profile.part.eq(Part.valueOf(searchPart)) : null; + } + + private BooleanExpression eqUnivId(Long univId) { + return univId != null ? user.universityInfo.university.id.eq(univId) : null; + } + + private BooleanExpression eqRole(Role role) { + return role != null ? + switch (role) { + case GUEST -> user.authInfo.role.eq(Role.GUEST); + case USER -> user.authInfo.role.eq(Role.USER); + case MANAGER -> user.authInfo.role.eq(Role.MANAGER); + case UNIVERSITY_ADMIN -> user.authInfo.role.eq(Role.UNIVERSITY_ADMIN); + case SUPER_ADMIN -> user.authInfo.role.eq(Role.SUPER_ADMIN); + } + : null; + } + + @Override + public Page findByUniversityInfoUniversityId(Long univId, Pageable pageable) { + List ids = getCoveringIndexByUniversityId(univId); + NumberExpression partOrder = new CaseBuilder() + .when(user.profile.part.eq(Part.PM)).then(1) + .when(user.profile.part.eq(Part.DESIGNER)).then(2) + .when(user.profile.part.eq(Part.PM_DESIGNER)).then(3) + .when(user.profile.part.eq(Part.FRONTEND)).then(4) + .when(user.profile.part.eq(Part.BACKEND)).then(5) + .otherwise(6); + List users = + queryFactory + .select(user) + .from(user) + .innerJoin(user.universityInfo.university, university).fetchJoin() + .where(user.id.in(ids)) + .offset(pageable.getOffset()) + .orderBy(user.universityInfo.ordinal.desc(), + user.universityInfo.university.name.asc(), + partOrder.asc(), + user.profile.name.asc()) + .limit(pageable.getPageSize()) + .fetch(); + + return PageableExecutionUtils.getPage(users, pageable, ids::size); + } + + @Override + public Page findByUnivNameAndRole(Role role, String univName, Pageable pageable) { + List ids = queryFactory + .select(user.id) + .from(user) + .where(startsWithUniversity(univName), eqRole(role), user.authInfo.accountStatus.eq(ACTIVE)) + .fetch(); + NumberExpression partOrder = new CaseBuilder() + .when(user.profile.part.eq(Part.PM)).then(1) + .when(user.profile.part.eq(Part.DESIGNER)).then(2) + .when(user.profile.part.eq(Part.PM_DESIGNER)).then(3) + .when(user.profile.part.eq(Part.FRONTEND)).then(4) + .when(user.profile.part.eq(Part.BACKEND)).then(5) + .otherwise(6); + + List users = + queryFactory + .select(user) + .from(user) + .innerJoin(user.universityInfo.university, university).fetchJoin() + .where(startsWithUniversity(univName), + eqRole(role), + user.authInfo.accountStatus.eq(ACTIVE)) + .offset(pageable.getOffset()) + .orderBy(user.universityInfo.ordinal.desc(), + user.universityInfo.university.name.asc(), + partOrder.asc(), + user.profile.name.asc()) + .limit(pageable.getPageSize()) + .fetch(); + + return PageableExecutionUtils.getPage(users, pageable, ids::size); + } + + @Override + public Slice findFollowingUsersByFollowerId(Long followerId, Pageable pageable) { + List users = + queryFactory + .select(follow.following) + .from(follow) + .innerJoin(follow.following, user) + .where(follow.follower.id.eq(followerId)) + .offset(pageable.getOffset()) + .orderBy(user.createdDate.desc()) + .limit(pageable.getPageSize() + 1) + .fetch(); + + return convertSliceProcessor.execute(users, pageable); + } + + @Override + public Slice findFollowerUsersByFollowingId(Long followingId, Pageable pageable) { + List users = + queryFactory + .select(user) + .from(follow) + .innerJoin(follow.follower, user) + .where(follow.following.id.eq(followingId)) + .offset(pageable.getOffset()) + .orderBy(user.createdDate.desc()) + .limit(pageable.getPageSize() + 1) + .fetch(); + + return convertSliceProcessor.execute(users, pageable); + } + + @Override + public List findMyFollowingUsersByFollowingIdIn(Long followerId, List followingIdList) { + List users = + queryFactory + .select(user) + .from(follow) + .innerJoin(follow.following, user) + .where(follow.follower.id.eq(followerId) + .and(follow.following.id.in(followingIdList))) + .fetch(); + return users; + } + + @Override + public Slice searchByName(String name, Pageable pageable) { + NumberExpression partOrder = new CaseBuilder() + .when(user.profile.part.eq(Part.PM)).then(1) + .when(user.profile.part.eq(Part.DESIGNER)).then(2) + .when(user.profile.part.eq(Part.PM_DESIGNER)).then(3) + .when(user.profile.part.eq(Part.FRONTEND)).then(4) + .when(user.profile.part.eq(Part.BACKEND)).then(5) + .otherwise(6); + + List users = + queryFactory + .select(user) + .from(user) + .innerJoin(user.universityInfo.university, university).fetchJoin() + .where(containsName(name)) + .offset(pageable.getOffset()) + .orderBy(partOrder.asc(), user.profile.name.asc()) + .limit(pageable.getPageSize() + 1) + .fetch(); + + return convertSliceProcessor.execute(users, pageable); + } + + @Override + public Page findAllWithUniversity(Pageable pageable) { + List ids = getCoveringIndex(null); + List result = queryFactory.select(user) + .from(user) + .leftJoin(user.universityInfo.university, university).fetchJoin() + .where(user.id.in(ids)) + .orderBy(getOrders(user, pageable.getSort())) + .offset(pageable.getOffset()) + .limit(pageable.getPageSize()) + .fetch(); + return PageableExecutionUtils.getPage(result, pageable, ids::size); + } + + private List getCoveringIndex(Predicate predicate) { + return queryFactory + .select(user.id) + .from(user) + .where(predicate, user.authInfo.accountStatus.eq(ACTIVE)) + .fetch(); + } + + private List getCoveringIndexByUniversityId(Long univId) { + return queryFactory + .select(user.id) + .from(user) + .where(user.authInfo.accountStatus.eq(ACTIVE), + eqUnivId(univId)) + .fetch(); + } + + private OrderSpecifier[] getOrders(EntityPath qEntity, Sort sort) { + return sort.stream().map(it -> getOrder(qEntity, it)).toArray(OrderSpecifier[]::new); + } + + private OrderSpecifier getOrder(EntityPath qEntity, Sort.Order order) { + final Order direction = order.isAscending() ? Order.ASC : Order.DESC; + final String property = order.getProperty(); + PathBuilder pathBuilder = + new PathBuilder<>(qEntity.getType(), qEntity.getMetadata().getName()); + return new OrderSpecifier(direction, pathBuilder.get(property)); + } } \ No newline at end of file diff --git a/likelion-core/src/main/java/likelion/univ/domain/user/repository/searchcondition/UserSearchCondition.java b/likelion-core/src/main/java/likelion/univ/domain/user/repository/searchcondition/UserSearchCondition.java index c711354c..c7642498 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/user/repository/searchcondition/UserSearchCondition.java +++ b/likelion-core/src/main/java/likelion/univ/domain/user/repository/searchcondition/UserSearchCondition.java @@ -1,7 +1,5 @@ package likelion.univ.domain.user.repository.searchcondition; -import likelion.univ.domain.university.entity.University; -import likelion.univ.domain.user.entity.Part; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; @@ -10,6 +8,7 @@ @Builder @AllArgsConstructor public class UserSearchCondition { + private String name; private String university; private String part; diff --git a/likelion-core/src/main/java/likelion/univ/domain/user/service/UserDomainService.java b/likelion-core/src/main/java/likelion/univ/domain/user/service/UserService.java similarity index 55% rename from likelion-core/src/main/java/likelion/univ/domain/user/service/UserDomainService.java rename to likelion-core/src/main/java/likelion/univ/domain/user/service/UserService.java index bfde77ae..4547d201 100644 --- a/likelion-core/src/main/java/likelion/univ/domain/user/service/UserDomainService.java +++ b/likelion-core/src/main/java/likelion/univ/domain/user/service/UserService.java @@ -1,8 +1,13 @@ package likelion.univ.domain.user.service; -import likelion.univ.domain.university.adaptor.UniversityAdaptor; -import likelion.univ.domain.user.adaptor.UserAdaptor; -import likelion.univ.domain.user.entity.*; +import java.util.List; +import likelion.univ.domain.user.entity.AuthInfo; +import likelion.univ.domain.user.entity.LoginType; +import likelion.univ.domain.user.entity.Part; +import likelion.univ.domain.user.entity.Profile; +import likelion.univ.domain.user.entity.Role; +import likelion.univ.domain.user.entity.UniversityInfo; +import likelion.univ.domain.user.entity.User; import likelion.univ.domain.user.exception.EmailAlreadyRegistered; import likelion.univ.domain.user.repository.UserRepository; import likelion.univ.domain.user.repository.searchcondition.UserSearchCondition; @@ -10,73 +15,69 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.List; - @Service @Transactional(readOnly = true) @RequiredArgsConstructor -public class UserDomainService { - private final UserAdaptor userAdaptor; +public class UserService { private final UserRepository userRepository; - private final UniversityAdaptor universityAdaptor; - - public User login(LoginType loginType, String email){ - User user = userAdaptor.findByEmail(email); - if(user.getAuthInfo().getLoginType().equals(loginType)){ + public User login(LoginType loginType, String email) { + User user = userRepository.getByEmail(email); + if (user.getAuthInfo().getLoginType().equals(loginType)) { return user; - }else throw new EmailAlreadyRegistered(); + } else { + throw new EmailAlreadyRegistered(); + } } @Transactional - public User signUp(Profile profile, AuthInfo authInfo, UniversityInfo universityInfo){ + public User signUp(Profile profile, AuthInfo authInfo, UniversityInfo universityInfo) { User user = User.builder() .profile(profile) .authInfo(authInfo) .universityInfo(universityInfo) .build(); - return userAdaptor.save(user); + return userRepository.save(user); } + @Transactional - public User editProfile(Long userId, Profile profile){ - User user = userAdaptor.findById(userId); + public User editProfile(Long userId, Profile profile) { + User user = userRepository.getById(userId); user.editProfile(profile); return user; } - @Transactional public void updateUser(User user, String name, String part, - String major, Long ordinal, Role role){ + String major, Long ordinal, Role role) { - user.getProfile().updateProfile(name,Part.valueOf(part)); - user.getUniversityInfo().updateUniversityInfo(major,ordinal); + user.getProfile().updateProfile(name, Part.valueOf(part)); + user.getUniversityInfo().updateUniversityInfo(major, ordinal); user.getAuthInfo().updateRole(role); - userAdaptor.save(user); + userRepository.save(user); } @Transactional - public void deleteUser(User user){ + public void deleteUser(User user) { user.getAuthInfo().delete(); user.getProfile().delete(); - userAdaptor.save(user); + userRepository.save(user); } @Transactional - public void deleteAll(List users){ - users.stream().forEach(user ->{ + public void deleteAll(List users) { + users.stream().forEach(user -> { user.getAuthInfo().delete(); user.getProfile().delete(); - userAdaptor.save(user); + userRepository.save(user); }); } - public List findDynamicUsers(UserSearchCondition condition) { - return userAdaptor.findDynamicUsers(condition); + return userRepository.search(condition); } public List findByRoleIn(List roles) { diff --git a/likelion-core/src/main/resources/application-core-test.yml b/likelion-core/src/main/resources/application-core-test.yml new file mode 100644 index 00000000..83e924e0 --- /dev/null +++ b/likelion-core/src/main/resources/application-core-test.yml @@ -0,0 +1,23 @@ +## test 설정 +spring: + datasource: + driver-class-name: org.h2.Driver + url: jdbc:h2:mem:testdb + username: sa + password: + jpa: + show-sql: true + open-in-view: false + hibernate: + ddl-auto: create-drop + properties: + hibernate: + default_batch_fetch_size: 1000 + database: h2 + +logging: + level: + org.springframework.orm.jpa: DEBUG + org.springframework.transaction: DEBUG + pattern: + console: "%d{yyyy-MM-dd HH:mm:ss} - %msg%n" diff --git a/likelion-core/src/main/resources/application-core.yml b/likelion-core/src/main/resources/application-core.yml index 38abf933..c6499f9a 100644 --- a/likelion-core/src/main/resources/application-core.yml +++ b/likelion-core/src/main/resources/application-core.yml @@ -23,6 +23,36 @@ spring: format_sql: true +--- ## local 환경 설정 +spring: + config: + activate: + on-profile: local + + jpa: + show-sql: true + database: mysql + open-in-view: false + hibernate: + ddl-auto: create + properties: + hibernate: + format_sql: true + use_sql_comments: true + highlight_sql: true + +logging: + level: + org.springframework.orm.jpa: DEBUG + org.springframework.transaction: DEBUG + org: + hibernate: + type: + descriptor: + sql: trace + pattern: + console: "%d{yyyy-MM-dd HH:mm:ss} - %msg%n" + --- ## dev 환경 설정 spring: config: diff --git a/likelion-core/src/test/java/likelion/univ/domain/hackathon/entity/HackathonFormTest.java b/likelion-core/src/test/java/likelion/univ/domain/hackathon/entity/HackathonFormTest.java new file mode 100644 index 00000000..8d563eab --- /dev/null +++ b/likelion-core/src/test/java/likelion/univ/domain/hackathon/entity/HackathonFormTest.java @@ -0,0 +1,109 @@ +package likelion.univ.domain.hackathon.entity; + +import static likelion.univ.domain.user.entity.Role.GUEST; +import static likelion.univ.domain.user.entity.Role.USER; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import likelion.univ.domain.hackathon.exception.NoAuthorityGuestApplyHackathon; +import likelion.univ.domain.hackathon.exception.NoAuthorityOrdinalApplyHackathon; +import likelion.univ.domain.university.entity.University; +import likelion.univ.domain.user.entity.AuthInfo; +import likelion.univ.domain.user.entity.UniversityInfo; +import likelion.univ.domain.user.entity.User; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; +import org.junit.jupiter.api.Test; + +@DisplayName("해커톤 신청서 (HackathonForm) 은(는)") +@SuppressWarnings("NonAsciiCharacters") +@DisplayNameGeneration(ReplaceUnderscores.class) +class HackathonFormTest { + + @Test + void GUEST_회원이_참여신청_시_예외() { + // given + User user = mock(User.class); + AuthInfo geustAuthInfo = mock(AuthInfo.class); + when(geustAuthInfo.getRole()).thenReturn(GUEST); + when(user.getAuthInfo()).thenReturn(geustAuthInfo); + HackathonForm hackathonForm = new HackathonForm( + user, + "name", + "email", + mock(University.class), + "major", + "01011112222", + HackathonPart.PM, + "team", + false, + "개인 사정으로 불참합니다." + ); + + // when & then + assertThrows( + NoAuthorityGuestApplyHackathon.class, + hackathonForm::apply + ); + } + + @Test + void 기수가_12기_외_회원이_참여신청시_예외() { + // given + User user = mock(User.class); + AuthInfo geustAuthInfo = mock(AuthInfo.class); + when(geustAuthInfo.getRole()).thenReturn(USER); + when(user.getUniversityInfo()).thenReturn( + new UniversityInfo(mock(University.class), "major", 11L) + ); + when(user.getAuthInfo()).thenReturn(geustAuthInfo); + HackathonForm hackathonForm = new HackathonForm( + user, + "name", + "email", + mock(University.class), + "major", + "01011112222", + HackathonPart.PM, + "team", + false, + "개인 사정으로 불참합니다." + ); + + // when & then + assertThrows( + NoAuthorityOrdinalApplyHackathon.class, + hackathonForm::apply + ); + } + + @Test + void 기수가_12기이며_GUEST_가_아닌_회원이_참여신청_가능() { + // given + User user = mock(User.class); + AuthInfo geustAuthInfo = mock(AuthInfo.class); + when(geustAuthInfo.getRole()).thenReturn(USER); + when(user.getUniversityInfo()).thenReturn( + new UniversityInfo(mock(University.class), "major", 12L) + ); + when(user.getAuthInfo()).thenReturn(geustAuthInfo); + HackathonForm hackathonForm = new HackathonForm( + user, + "name", + "email", + mock(University.class), + "major", + "01011112222", + HackathonPart.PM, + "team", + false, + "개인 사정으로 불참합니다." + ); + + // when & then + assertDoesNotThrow(hackathonForm::apply); + } +} diff --git a/likelion-core/src/test/resources/application.yml b/likelion-core/src/test/resources/application.yml index e450d2c5..03c30d37 100644 --- a/likelion-core/src/test/resources/application.yml +++ b/likelion-core/src/test/resources/application.yml @@ -1,24 +1,3 @@ -## test 설정 spring: - datasource: - driver-class-name: org.h2.Driver - url: jdbc:h2:tcp://localhost/~/test - username: sa - password: - jpa: - show-sql: true - open-in-view: false - hibernate: - ddl-auto: create-drop - properties: - hibernate: - default_batch_fetch_size: 1000 - -logging: - level: - org.springframework.orm.jpa: DEBUG - org.springframework.transaction: DEBUG - pattern: - console: "%d{yyyy-MM-dd HH:mm:ss} - %msg%n" - - + profiles: + active: test diff --git a/likelion-infrastructure/src/main/java/likelion/univ/email/ContentsType.java b/likelion-infrastructure/src/main/java/likelion/univ/email/ContentsType.java index a6fdca66..906dc7ca 100644 --- a/likelion-infrastructure/src/main/java/likelion/univ/email/ContentsType.java +++ b/likelion-infrastructure/src/main/java/likelion/univ/email/ContentsType.java @@ -1,10 +1,9 @@ package likelion.univ.email; import com.azure.communication.email.models.EmailMessage; -import lombok.RequiredArgsConstructor; - import java.util.Arrays; import java.util.function.Function; +import lombok.RequiredArgsConstructor; @RequiredArgsConstructor public enum ContentsType { diff --git a/likelion-infrastructure/src/main/java/likelion/univ/email/exception/EmailErrorCode.java b/likelion-infrastructure/src/main/java/likelion/univ/email/exception/EmailErrorCode.java index 904a8b35..cbc6d234 100644 --- a/likelion-infrastructure/src/main/java/likelion/univ/email/exception/EmailErrorCode.java +++ b/likelion-infrastructure/src/main/java/likelion/univ/email/exception/EmailErrorCode.java @@ -1,17 +1,17 @@ package likelion.univ.email.exception; +import static likelion.univ.constant.StaticValue.BAD_REQUEST; + import likelion.univ.exception.base.BaseErrorCode; import lombok.AllArgsConstructor; import lombok.Getter; -import static likelion.univ.constant.StaticValue.BAD_REQUEST; - @Getter @AllArgsConstructor public enum EmailErrorCode implements BaseErrorCode { - EMAIL_SEND_FAILED(BAD_REQUEST, "EMAIL_400","이메일 전송에 실패하였습니다."), - INVALID_ATTACHMENT(BAD_REQUEST, "EMAIL_401","올바르지 않은 이메일 첨부파일 입니다."); + EMAIL_SEND_FAILED(BAD_REQUEST, "EMAIL_400", "이메일 전송에 실패하였습니다."), + INVALID_ATTACHMENT(BAD_REQUEST, "EMAIL_401", "올바르지 않은 이메일 첨부파일 입니다."); private final int httpStatus; private final String code; diff --git a/likelion-infrastructure/src/main/java/likelion/univ/email/exception/InvalidAttachment.java b/likelion-infrastructure/src/main/java/likelion/univ/email/exception/InvalidAttachment.java index ac19c3aa..c104ced6 100644 --- a/likelion-infrastructure/src/main/java/likelion/univ/email/exception/InvalidAttachment.java +++ b/likelion-infrastructure/src/main/java/likelion/univ/email/exception/InvalidAttachment.java @@ -1,9 +1,9 @@ package likelion.univ.email.exception; -import likelion.univ.exception.base.BaseErrorCode; import likelion.univ.exception.base.BaseException; public class InvalidAttachment extends BaseException { + public InvalidAttachment() { super(EmailErrorCode.INVALID_ATTACHMENT); } diff --git a/likelion-infrastructure/src/main/java/likelion/univ/email/sender/EmailContent.java b/likelion-infrastructure/src/main/java/likelion/univ/email/sender/EmailContent.java index da169589..73ce899b 100644 --- a/likelion-infrastructure/src/main/java/likelion/univ/email/sender/EmailContent.java +++ b/likelion-infrastructure/src/main/java/likelion/univ/email/sender/EmailContent.java @@ -1,13 +1,12 @@ package likelion.univ.email.sender; +import java.util.List; import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import org.springframework.web.multipart.MultipartFile; -import java.util.List; - @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class EmailContent { diff --git a/likelion-infrastructure/src/main/java/likelion/univ/email/sender/azure/AzureEmailSender.java b/likelion-infrastructure/src/main/java/likelion/univ/email/sender/azure/AzureEmailSender.java index f3ed80d4..c3e13b39 100644 --- a/likelion-infrastructure/src/main/java/likelion/univ/email/sender/azure/AzureEmailSender.java +++ b/likelion-infrastructure/src/main/java/likelion/univ/email/sender/azure/AzureEmailSender.java @@ -2,11 +2,17 @@ import com.azure.communication.email.EmailClient; import com.azure.communication.email.EmailClientBuilder; -import com.azure.communication.email.models.*; +import com.azure.communication.email.models.EmailAddress; +import com.azure.communication.email.models.EmailAttachment; +import com.azure.communication.email.models.EmailMessage; +import com.azure.communication.email.models.EmailSendResult; +import com.azure.communication.email.models.EmailSendStatus; import com.azure.core.credential.AzureKeyCredential; import com.azure.core.util.BinaryData; import com.azure.core.util.polling.PollResponse; import com.azure.core.util.polling.SyncPoller; +import java.io.IOException; +import java.util.List; import likelion.univ.email.exception.EmailSendFailed; import likelion.univ.email.exception.InvalidAttachment; import likelion.univ.email.sender.EmailContent; @@ -15,9 +21,6 @@ import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; -import java.io.IOException; -import java.util.List; - @Component @RequiredArgsConstructor public class AzureEmailSender implements EmailSender { @@ -66,11 +69,9 @@ private void sendEmail(EmailClient emailClient, EmailMessage message) { } private List getAttachments(List attachments) { - if (attachments == null || attachments.size() == 0) { return null; } - return attachments.stream() .map(attachment -> new EmailAttachment( attachment.getOriginalFilename(), diff --git a/likelion-infrastructure/src/main/java/likelion/univ/feign/FeignClientConfig.java b/likelion-infrastructure/src/main/java/likelion/univ/feign/FeignClientConfig.java index 4b4df0fb..9a0077c2 100644 --- a/likelion-infrastructure/src/main/java/likelion/univ/feign/FeignClientConfig.java +++ b/likelion-infrastructure/src/main/java/likelion/univ/feign/FeignClientConfig.java @@ -6,13 +6,13 @@ import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import feign.codec.Decoder; import feign.jackson.JacksonDecoder; -import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class FeignClientConfig { + @Bean public Decoder feignDecoder() { return new JacksonDecoder(customObjectMapper()); @@ -26,5 +26,4 @@ private ObjectMapper customObjectMapper() { objectMapper.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false); return objectMapper; } - } diff --git a/likelion-infrastructure/src/main/java/likelion/univ/feign/exception/FeignClientException.java b/likelion-infrastructure/src/main/java/likelion/univ/feign/exception/FeignClientException.java index 674ef955..29a1dd62 100644 --- a/likelion-infrastructure/src/main/java/likelion/univ/feign/exception/FeignClientException.java +++ b/likelion-infrastructure/src/main/java/likelion/univ/feign/exception/FeignClientException.java @@ -5,7 +5,8 @@ @Getter @AllArgsConstructor -public class FeignClientException extends RuntimeException{ +public class FeignClientException extends RuntimeException { + private int httpStatus; private String methodKey; private String code; diff --git a/likelion-infrastructure/src/main/java/likelion/univ/feign/oauth/google/RequestGooglePublicKeysClient.java b/likelion-infrastructure/src/main/java/likelion/univ/feign/oauth/google/RequestGooglePublicKeysClient.java index 114091a9..8c0f01db 100644 --- a/likelion-infrastructure/src/main/java/likelion/univ/feign/oauth/google/RequestGooglePublicKeysClient.java +++ b/likelion-infrastructure/src/main/java/likelion/univ/feign/oauth/google/RequestGooglePublicKeysClient.java @@ -1,6 +1,5 @@ package likelion.univ.feign.oauth.google; -import likelion.univ.feign.oauth.google.errordecoder.RequestGoogleTokenErrorDecode; import likelion.univ.feign.oauth.oidc.PublicKeysDto; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; @@ -9,7 +8,7 @@ name = "RequestGooglePublicKeysClient", url = "https://www.googleapis.com/oauth2/v3/certs") public interface RequestGooglePublicKeysClient { + @GetMapping PublicKeysDto getPublicKeys(); - } diff --git a/likelion-infrastructure/src/main/java/likelion/univ/feign/oauth/google/RequestGoogleTokenClient.java b/likelion-infrastructure/src/main/java/likelion/univ/feign/oauth/google/RequestGoogleTokenClient.java index 6883bcb5..2971c87d 100644 --- a/likelion-infrastructure/src/main/java/likelion/univ/feign/oauth/google/RequestGoogleTokenClient.java +++ b/likelion-infrastructure/src/main/java/likelion/univ/feign/oauth/google/RequestGoogleTokenClient.java @@ -9,13 +9,15 @@ @FeignClient( name = "RequestGoogleTokenClient", url = "https://oauth2.googleapis.com", - configuration = RequestGoogleTokenErrorDecode.class) + configuration = RequestGoogleTokenErrorDecode.class +) public interface RequestGoogleTokenClient { - @PostMapping( - "/token?grant_type=authorization_code") + + @PostMapping("/token?grant_type=authorization_code") GoogleTokenInfoDto getToken( @RequestParam("client_id") String clientId, @RequestParam("client_secret") String clientSecret, @RequestParam("code") String code, - @RequestParam("redirect_uri") String redirectUri); + @RequestParam("redirect_uri") String redirectUri + ); } diff --git a/likelion-infrastructure/src/main/java/likelion/univ/feign/oauth/google/dto/GoogleErrorResponseDto.java b/likelion-infrastructure/src/main/java/likelion/univ/feign/oauth/google/dto/GoogleErrorResponseDto.java index 74cfc150..7d178482 100644 --- a/likelion-infrastructure/src/main/java/likelion/univ/feign/oauth/google/dto/GoogleErrorResponseDto.java +++ b/likelion-infrastructure/src/main/java/likelion/univ/feign/oauth/google/dto/GoogleErrorResponseDto.java @@ -5,12 +5,13 @@ import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; + @Getter @NoArgsConstructor @AllArgsConstructor @JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) public class GoogleErrorResponseDto { + private String error; private String errorDescription; - -} \ No newline at end of file +} diff --git a/likelion-infrastructure/src/main/java/likelion/univ/feign/oauth/google/dto/GoogleTokenInfoDto.java b/likelion-infrastructure/src/main/java/likelion/univ/feign/oauth/google/dto/GoogleTokenInfoDto.java index bf978c0f..bd74511b 100644 --- a/likelion-infrastructure/src/main/java/likelion/univ/feign/oauth/google/dto/GoogleTokenInfoDto.java +++ b/likelion-infrastructure/src/main/java/likelion/univ/feign/oauth/google/dto/GoogleTokenInfoDto.java @@ -9,6 +9,7 @@ @NoArgsConstructor @JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) public class GoogleTokenInfoDto { + private String accessToken; private String idToken; private String refreshToken; diff --git a/likelion-infrastructure/src/main/java/likelion/univ/feign/oauth/google/errordecoder/RequestGoogleTokenErrorDecode.java b/likelion-infrastructure/src/main/java/likelion/univ/feign/oauth/google/errordecoder/RequestGoogleTokenErrorDecode.java index 09951b98..b13c926c 100644 --- a/likelion-infrastructure/src/main/java/likelion/univ/feign/oauth/google/errordecoder/RequestGoogleTokenErrorDecode.java +++ b/likelion-infrastructure/src/main/java/likelion/univ/feign/oauth/google/errordecoder/RequestGoogleTokenErrorDecode.java @@ -2,33 +2,37 @@ import com.fasterxml.jackson.databind.ObjectMapper; import feign.Response; -import feign.RetryableException; import feign.Util; import feign.codec.ErrorDecoder; +import java.io.IOException; import likelion.univ.feign.exception.FeignClientException; import likelion.univ.feign.oauth.google.dto.GoogleErrorResponseDto; -import likelion.univ.feign.oauth.kakao.dto.KakaoErrorResponseDto; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import java.io.IOException; - @RequiredArgsConstructor @Slf4j -public class RequestGoogleTokenErrorDecode implements ErrorDecoder{ +public class RequestGoogleTokenErrorDecode implements ErrorDecoder { + private final ObjectMapper objectMapper; + @Override public Exception decode(String methodKey, Response response) { if (response.body() != null) { try { String message = Util.toString(response.body().asReader(Util.UTF_8)); - GoogleErrorResponseDto errorResponseForm= objectMapper.readValue(message, GoogleErrorResponseDto.class); - return new FeignClientException(response.status(), methodKey, - errorResponseForm.getError(), errorResponseForm.getErrorDescription()); + GoogleErrorResponseDto errorResponseForm = + objectMapper.readValue(message, GoogleErrorResponseDto.class); + return new FeignClientException( + response.status(), + methodKey, + errorResponseForm.getError(), + errorResponseForm.getErrorDescription() + ); } catch (IOException e) { log.error(methodKey + "Error Deserializing response body from failed feign request response.", e); } } return new FeignClientException(response.status(), methodKey, "GOOGLE_SERVER_ERROR", null); } -} \ No newline at end of file +} diff --git a/likelion-infrastructure/src/main/java/likelion/univ/feign/oauth/kakao/RequestKakaoTokenClient.java b/likelion-infrastructure/src/main/java/likelion/univ/feign/oauth/kakao/RequestKakaoTokenClient.java index 2215e409..685291e7 100644 --- a/likelion-infrastructure/src/main/java/likelion/univ/feign/oauth/kakao/RequestKakaoTokenClient.java +++ b/likelion-infrastructure/src/main/java/likelion/univ/feign/oauth/kakao/RequestKakaoTokenClient.java @@ -5,7 +5,6 @@ import likelion.univ.feign.oauth.oidc.PublicKeysDto; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -13,14 +12,17 @@ @FeignClient( name = "RequestKakaoTokenClient", url = "https://kauth.kakao.com", - configuration = RequestKakaoTokenErrorDecoder.class) + configuration = RequestKakaoTokenErrorDecoder.class +) public interface RequestKakaoTokenClient { + @PostMapping("/oauth/token?grant_type=authorization_code") KakaoTokenInfoDto getToken( @RequestParam("client_id") String clientId, @RequestParam("redirect_uri") String redirectUri, @RequestParam("code") String code, - @RequestParam("client_secret") String clientSecret); + @RequestParam("client_secret") String clientSecret + ); @GetMapping("/.well-known/jwks.json") PublicKeysDto getPublicKeys(); diff --git a/likelion-infrastructure/src/main/java/likelion/univ/feign/oauth/kakao/dto/KakaoErrorResponseDto.java b/likelion-infrastructure/src/main/java/likelion/univ/feign/oauth/kakao/dto/KakaoErrorResponseDto.java index ee4543fa..c9b37ab8 100644 --- a/likelion-infrastructure/src/main/java/likelion/univ/feign/oauth/kakao/dto/KakaoErrorResponseDto.java +++ b/likelion-infrastructure/src/main/java/likelion/univ/feign/oauth/kakao/dto/KakaoErrorResponseDto.java @@ -1,6 +1,5 @@ package likelion.univ.feign.oauth.kakao.dto; -import com.fasterxml.jackson.databind.PropertyNamingStrategies; import com.fasterxml.jackson.databind.PropertyNamingStrategy; import com.fasterxml.jackson.databind.annotation.JsonNaming; import lombok.AllArgsConstructor; @@ -12,7 +11,7 @@ @AllArgsConstructor @JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) public class KakaoErrorResponseDto { + private String errorCode; private String errorDescription; - -} \ No newline at end of file +} diff --git a/likelion-infrastructure/src/main/java/likelion/univ/feign/oauth/kakao/dto/KakaoTokenInfoDto.java b/likelion-infrastructure/src/main/java/likelion/univ/feign/oauth/kakao/dto/KakaoTokenInfoDto.java index 24911db8..01e38556 100644 --- a/likelion-infrastructure/src/main/java/likelion/univ/feign/oauth/kakao/dto/KakaoTokenInfoDto.java +++ b/likelion-infrastructure/src/main/java/likelion/univ/feign/oauth/kakao/dto/KakaoTokenInfoDto.java @@ -9,7 +9,8 @@ @NoArgsConstructor @JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) public class KakaoTokenInfoDto { + private String accessToken; private String refreshToken; private String idToken; -} \ No newline at end of file +} diff --git a/likelion-infrastructure/src/main/java/likelion/univ/feign/oauth/kakao/errordecoder/RequestKakaoTokenErrorDecoder.java b/likelion-infrastructure/src/main/java/likelion/univ/feign/oauth/kakao/errordecoder/RequestKakaoTokenErrorDecoder.java index 5b612114..a8c478ae 100644 --- a/likelion-infrastructure/src/main/java/likelion/univ/feign/oauth/kakao/errordecoder/RequestKakaoTokenErrorDecoder.java +++ b/likelion-infrastructure/src/main/java/likelion/univ/feign/oauth/kakao/errordecoder/RequestKakaoTokenErrorDecoder.java @@ -4,26 +4,32 @@ import feign.Response; import feign.Util; import feign.codec.ErrorDecoder; +import java.io.IOException; import likelion.univ.feign.exception.FeignClientException; import likelion.univ.feign.oauth.kakao.dto.KakaoErrorResponseDto; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import java.io.IOException; - @RequiredArgsConstructor @Slf4j -public class RequestKakaoTokenErrorDecoder implements ErrorDecoder{ +public class RequestKakaoTokenErrorDecoder implements ErrorDecoder { + private final ObjectMapper objectMapper; + @Override public Exception decode(String methodKey, Response response) { if (response.body() != null) { try { String message = Util.toString(response.body().asReader(Util.UTF_8)); - KakaoErrorResponseDto errorResponseForm= objectMapper.readValue(message, KakaoErrorResponseDto.class); - return new FeignClientException(response.status(), methodKey, - errorResponseForm.getErrorCode(), errorResponseForm.getErrorDescription()); + KakaoErrorResponseDto errorResponseForm = + objectMapper.readValue(message, KakaoErrorResponseDto.class); + return new FeignClientException( + response.status(), + methodKey, + errorResponseForm.getErrorCode(), + errorResponseForm.getErrorDescription() + ); } catch (IOException e) { log.error(methodKey + "Error Deserializing response body from failed feign request response.", e); } diff --git a/likelion-infrastructure/src/main/java/likelion/univ/feign/oauth/oidc/PublicKeyDto.java b/likelion-infrastructure/src/main/java/likelion/univ/feign/oauth/oidc/PublicKeyDto.java index 4489b905..88ae8ddf 100644 --- a/likelion-infrastructure/src/main/java/likelion/univ/feign/oauth/oidc/PublicKeyDto.java +++ b/likelion-infrastructure/src/main/java/likelion/univ/feign/oauth/oidc/PublicKeyDto.java @@ -9,6 +9,7 @@ @NoArgsConstructor @JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) public class PublicKeyDto { + private String kid; private String kty; private String alg; diff --git a/likelion-infrastructure/src/main/java/likelion/univ/feign/oauth/oidc/PublicKeysDto.java b/likelion-infrastructure/src/main/java/likelion/univ/feign/oauth/oidc/PublicKeysDto.java index c18c0117..64734f17 100644 --- a/likelion-infrastructure/src/main/java/likelion/univ/feign/oauth/oidc/PublicKeysDto.java +++ b/likelion-infrastructure/src/main/java/likelion/univ/feign/oauth/oidc/PublicKeysDto.java @@ -2,14 +2,14 @@ import com.fasterxml.jackson.databind.PropertyNamingStrategy; import com.fasterxml.jackson.databind.annotation.JsonNaming; +import java.util.List; import lombok.Getter; import lombok.NoArgsConstructor; -import java.util.List; - @Getter @NoArgsConstructor @JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) public class PublicKeysDto { + private List keys; -} \ No newline at end of file +} diff --git a/likelion-infrastructure/src/main/java/likelion/univ/properties/GoogleProperties.java b/likelion-infrastructure/src/main/java/likelion/univ/properties/GoogleProperties.java index 34e0e5c1..bc66ad65 100644 --- a/likelion-infrastructure/src/main/java/likelion/univ/properties/GoogleProperties.java +++ b/likelion-infrastructure/src/main/java/likelion/univ/properties/GoogleProperties.java @@ -10,6 +10,7 @@ @ConfigurationProperties(prefix = "google") @ConstructorBinding public class GoogleProperties { + private String iss; private String clientId; private String clientSecret; diff --git a/likelion-infrastructure/src/main/java/likelion/univ/properties/KakaoProperties.java b/likelion-infrastructure/src/main/java/likelion/univ/properties/KakaoProperties.java index cc41d244..1bab64dc 100644 --- a/likelion-infrastructure/src/main/java/likelion/univ/properties/KakaoProperties.java +++ b/likelion-infrastructure/src/main/java/likelion/univ/properties/KakaoProperties.java @@ -10,6 +10,7 @@ @ConfigurationProperties(prefix = "kakao") @ConstructorBinding public class KakaoProperties { + private String iss; private String clientId; private String clientSecret; diff --git a/likelion-infrastructure/src/main/java/likelion/univ/s3/GeneratePresignedUrlProcessor.java b/likelion-infrastructure/src/main/java/likelion/univ/s3/GeneratePresignedUrlProcessor.java index 1f6562f1..62fbb7e0 100644 --- a/likelion-infrastructure/src/main/java/likelion/univ/s3/GeneratePresignedUrlProcessor.java +++ b/likelion-infrastructure/src/main/java/likelion/univ/s3/GeneratePresignedUrlProcessor.java @@ -5,26 +5,29 @@ import com.amazonaws.services.s3.Headers; import com.amazonaws.services.s3.model.CannedAccessControlList; import com.amazonaws.services.s3.model.GeneratePresignedUrlRequest; -import likelion.univ.annotation.Processor; -import lombok.RequiredArgsConstructor; - import java.net.URL; import java.util.Date; +import likelion.univ.annotation.Processor; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Profile; +@Profile("!test") @Processor @RequiredArgsConstructor public class GeneratePresignedUrlProcessor { + private final AmazonS3 amazonS3; private final S3Properties s3Properties; public String execute(String fileName) { GeneratePresignedUrlRequest generatePresignedUrlRequest = - new GeneratePresignedUrlRequest(s3Properties.getBucket(), fileName) - .withMethod(HttpMethod.PUT) - .withExpiration(getPreSignedUrlExpiration()); + new GeneratePresignedUrlRequest(s3Properties.getBucket(), fileName) + .withMethod(HttpMethod.PUT) + .withExpiration(getPreSignedUrlExpiration()); generatePresignedUrlRequest.addRequestParameter( Headers.S3_CANNED_ACL, - CannedAccessControlList.PublicRead.toString()); + CannedAccessControlList.PublicRead.toString() + ); URL presignedUrl = amazonS3.generatePresignedUrl(generatePresignedUrlRequest); return presignedUrl.toString(); } @@ -36,4 +39,4 @@ private Date getPreSignedUrlExpiration() { expiration.setTime(expTimeMillis); return expiration; } -} \ No newline at end of file +} diff --git a/likelion-infrastructure/src/main/java/likelion/univ/s3/S3Config.java b/likelion-infrastructure/src/main/java/likelion/univ/s3/S3Config.java index f3db911a..ebc1c7bd 100644 --- a/likelion-infrastructure/src/main/java/likelion/univ/s3/S3Config.java +++ b/likelion-infrastructure/src/main/java/likelion/univ/s3/S3Config.java @@ -8,25 +8,26 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; +import org.springframework.context.annotation.Profile; +@Profile("!test") @Configuration @RequiredArgsConstructor public class S3Config { + private final S3Properties s3Properties; + @Bean @Primary - public BasicAWSCredentials awsCredentialsProvider(){ - BasicAWSCredentials basicAWSCredentials = new BasicAWSCredentials(s3Properties.getAccessKey(), s3Properties.getSecretKey()); - return basicAWSCredentials; + public BasicAWSCredentials awsCredentialsProvider() { + return new BasicAWSCredentials(s3Properties.getAccessKey(), s3Properties.getSecretKey()); } @Bean public AmazonS3 amazonS3() { - AmazonS3 s3Builder = AmazonS3ClientBuilder.standard() + return AmazonS3ClientBuilder.standard() .withRegion(s3Properties.getRegion()) .withCredentials(new AWSStaticCredentialsProvider(awsCredentialsProvider())) .build(); - return s3Builder; } - -} \ No newline at end of file +} diff --git a/likelion-infrastructure/src/main/java/likelion/univ/s3/S3Properties.java b/likelion-infrastructure/src/main/java/likelion/univ/s3/S3Properties.java index 198a4a68..ca3a1b29 100644 --- a/likelion-infrastructure/src/main/java/likelion/univ/s3/S3Properties.java +++ b/likelion-infrastructure/src/main/java/likelion/univ/s3/S3Properties.java @@ -10,6 +10,7 @@ @ConfigurationProperties(prefix = "cloud.aws.s3") @ConstructorBinding public class S3Properties { + private String bucket; private String accessKey; private String secretKey; diff --git a/likelion-infrastructure/src/main/java/likelion/univ/sms/SmsContent.java b/likelion-infrastructure/src/main/java/likelion/univ/sms/SmsContent.java deleted file mode 100644 index 2fbce47f..00000000 --- a/likelion-infrastructure/src/main/java/likelion/univ/sms/SmsContent.java +++ /dev/null @@ -1,30 +0,0 @@ -//package likelion.univ.sms; -// -//import lombok.AccessLevel; -//import lombok.Builder; -//import lombok.Getter; -//import lombok.NoArgsConstructor; -// -//import java.util.List; -//import java.util.stream.Collectors; -// -//@Getter -//@NoArgsConstructor(access = AccessLevel.PROTECTED) -//public class SmsContent { -// -// private String contents; -// -// private List receivers; -// -// @Builder -// public SmsContent(String contents, List receivers) { -// this.contents = contents; -// this.receivers = formatPhones(receivers); -// } -// -// private List formatPhones(List phones) { -// return phones.stream() -// .map(phone -> phone.replaceAll("-", "")) -// .collect(Collectors.toList()); -// } -//} diff --git a/likelion-infrastructure/src/main/java/likelion/univ/sms/SmsSender.java b/likelion-infrastructure/src/main/java/likelion/univ/sms/SmsSender.java deleted file mode 100644 index 8683aa3f..00000000 --- a/likelion-infrastructure/src/main/java/likelion/univ/sms/SmsSender.java +++ /dev/null @@ -1,60 +0,0 @@ -//package likelion.univ.sms; -// -//import net.nurigo.sdk.NurigoApp; -//import net.nurigo.sdk.message.exception.NurigoEmptyResponseException; -//import net.nurigo.sdk.message.exception.NurigoMessageNotReceivedException; -//import net.nurigo.sdk.message.exception.NurigoUnknownException; -//import net.nurigo.sdk.message.model.Message; -//import net.nurigo.sdk.message.service.DefaultMessageService; -//import org.springframework.beans.factory.annotation.Value; -//import org.springframework.stereotype.Component; -// -//import javax.annotation.PostConstruct; -//import java.util.ArrayList; -//import java.util.HashMap; -//import java.util.List; -// -//@Component -//public class SmsSender { -// -// private final String API_KEY; -// private final String API_SECRET; -// private final String SENDING_NUMBER; -// -// public SmsSender( -// @Value("${alarm.sms.api-key}") String apiKey, -// @Value("${alarm.sms.api-secret}") String apiSecret, -// @Value("${alarm.sms.sending-number}") String sendingNumber) { -// this.API_KEY = apiKey; -// this.API_SECRET = apiSecret; -// this.SENDING_NUMBER = sendingNumber; -// } -// -// public void send(SmsContent smsContent) { -// DefaultMessageService messageService = NurigoApp.INSTANCE.initialize(API_KEY, API_SECRET, "https://api.solapi.com"); -// -// List messages = new ArrayList<>(); -// for (String receiver : smsContent.getReceivers()) { -// Message message = new Message(); -// message.setFrom(SENDING_NUMBER); -// message.setTo(receiver); -// message.setText(smsContent.getContents()); -// messages.add(message); -// } -// -// try { -// messageService.send(messages); -// } catch (NurigoMessageNotReceivedException e) { -// e.printStackTrace(); -// } catch (Exception e) { -// throw new RuntimeException(e); -// } -// } -// -// /** -// * TODO -// * https://msg.nurigo.co.kr -// * 아래 콘솔에서 API KEY, SECRET 발급, 발신번호 추가 절차 필요 -// * 이후 application.yml 에 설정 -// */ -//} diff --git a/likelion-infrastructure/src/main/resources/application-infrastructure-test.yml b/likelion-infrastructure/src/main/resources/application-infrastructure-test.yml new file mode 100644 index 00000000..e69de29b diff --git a/likelion-redis/src/main/java/likelion/univ/LikelionRedisApplication.java b/likelion-redis/src/main/java/likelion/univ/LikelionRedisApplication.java index c230e2d5..359f97ed 100644 --- a/likelion-redis/src/main/java/likelion/univ/LikelionRedisApplication.java +++ b/likelion-redis/src/main/java/likelion/univ/LikelionRedisApplication.java @@ -1,9 +1,6 @@ package likelion.univ; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.cache.annotation.EnableCaching; - @SpringBootApplication public class LikelionRedisApplication { diff --git a/likelion-redis/src/main/java/likelion/univ/common/base/BaseRedisRepository.java b/likelion-redis/src/main/java/likelion/univ/common/base/BaseRedisRepository.java index 736cee12..f6795a42 100644 --- a/likelion-redis/src/main/java/likelion/univ/common/base/BaseRedisRepository.java +++ b/likelion-redis/src/main/java/likelion/univ/common/base/BaseRedisRepository.java @@ -1,35 +1,32 @@ package likelion.univ.common.base; -import lombok.extern.slf4j.Slf4j; -import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.data.redis.core.StringRedisTemplate; - import java.util.Optional; import java.util.concurrent.TimeUnit; - +import org.springframework.data.redis.core.RedisTemplate; public abstract class BaseRedisRepository { + protected RedisTemplate redisTemplate; protected String prefix; protected Long ttl; public void save(Long id, T data) { - redisTemplate.opsForValue().set(generateKeyfromId(id), data, ttl, TimeUnit.SECONDS); + redisTemplate.opsForValue().set(generateKeyFromId(id), data, ttl, TimeUnit.SECONDS); } public Optional findById(Long id) { - try{ - return Optional.of(redisTemplate.opsForValue().get(generateKeyfromId(id))); - }catch (NullPointerException e){ + try { + return Optional.of(redisTemplate.opsForValue().get(generateKeyFromId(id))); + } catch (NullPointerException e) { return Optional.empty(); } } + public Boolean delete(Long id) { - return redisTemplate.delete(generateKeyfromId(id)); + return redisTemplate.delete(generateKeyFromId(id)); } - public String generateKeyfromId(Long id){ + public String generateKeyFromId(Long id) { return prefix + id.toString(); } - } diff --git a/likelion-redis/src/main/java/likelion/univ/common/config/RedisCacheManagerConfig.java b/likelion-redis/src/main/java/likelion/univ/common/config/RedisCacheManagerConfig.java index 1ab852f4..3ebdce57 100644 --- a/likelion-redis/src/main/java/likelion/univ/common/config/RedisCacheManagerConfig.java +++ b/likelion-redis/src/main/java/likelion/univ/common/config/RedisCacheManagerConfig.java @@ -1,24 +1,25 @@ package likelion.univ.common.config; -import likelion.univ.common.constant.RedisKey; +import static likelion.univ.common.constant.RedisKey.GOOGLE_PUBLIC_KEYS; +import static likelion.univ.common.constant.RedisKey.KAKAO_PUBLIC_KEYS; +import static org.springframework.data.redis.serializer.RedisSerializationContext.SerializationPair; + +import java.time.Duration; +import java.util.HashMap; +import java.util.Map; import lombok.RequiredArgsConstructor; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; import org.springframework.data.redis.cache.RedisCacheConfiguration; import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; -import org.springframework.data.redis.serializer.RedisSerializationContext; import org.springframework.data.redis.serializer.StringRedisSerializer; -import java.time.Duration; -import java.util.HashMap; -import java.util.Map; - -import static likelion.univ.common.constant.RedisKey.*; - +@Profile("!test") @RequiredArgsConstructor @EnableCaching @Configuration @@ -29,20 +30,22 @@ public class RedisCacheManagerConfig { @Bean public CacheManager redisCacheManager() { RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig() - .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())) - .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer())) - .entryTtl(Duration.ofDays(1L)); - - RedisCacheManager redisCacheManager = RedisCacheManager.RedisCacheManagerBuilder + .serializeKeysWith( + SerializationPair.fromSerializer(new StringRedisSerializer()) + ).serializeValuesWith( + SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()) + ).entryTtl(Duration.ofDays(1L)); + return RedisCacheManager.RedisCacheManagerBuilder .fromConnectionFactory(redisConnectionFactory) .cacheDefaults(redisCacheConfiguration) .withInitialCacheConfigurations(customConfigurationMap(redisCacheConfiguration)) .build(); - return redisCacheManager; } /* 커스텀하여 만료기간 설정 */ - private Map customConfigurationMap(RedisCacheConfiguration redisCacheConfiguration) { + private Map customConfigurationMap( + RedisCacheConfiguration redisCacheConfiguration + ) { Map customConfigurationMap = new HashMap<>(); customConfigurationMap.put(KAKAO_PUBLIC_KEYS, redisCacheConfiguration.entryTtl(Duration.ofDays(1L))); customConfigurationMap.put(GOOGLE_PUBLIC_KEYS, redisCacheConfiguration.entryTtl(Duration.ofDays(1L))); diff --git a/likelion-redis/src/main/java/likelion/univ/common/config/RedisConfig.java b/likelion-redis/src/main/java/likelion/univ/common/config/RedisConfig.java index aeb7b22b..5cfe300f 100644 --- a/likelion-redis/src/main/java/likelion/univ/common/config/RedisConfig.java +++ b/likelion-redis/src/main/java/likelion/univ/common/config/RedisConfig.java @@ -10,6 +10,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.RedisStandaloneConfiguration; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; @@ -18,6 +19,7 @@ import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; +@Profile("!test") @Configuration @RequiredArgsConstructor public class RedisConfig { @@ -31,7 +33,6 @@ public class RedisConfig { @Value("${redis.password}") private String password; - public ObjectMapper redisObjectMapper() { PolymorphicTypeValidator typeValidator = BasicPolymorphicTypeValidator.builder() .allowIfSubType(Object.class) @@ -47,9 +48,9 @@ public ObjectMapper redisObjectMapper() { public RedisConnectionFactory redisConnectionFactory() { RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration(host, port); redisStandaloneConfiguration.setPassword(password); - LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(redisStandaloneConfiguration); - return connectionFactory; + return new LettuceConnectionFactory(redisStandaloneConfiguration); } + @Bean public RedisMessageListenerContainer redisMessageListener(RedisConnectionFactory connectionFactory) { RedisMessageListenerContainer container = new RedisMessageListenerContainer(); diff --git a/likelion-redis/src/main/java/likelion/univ/common/constant/RedisKey.java b/likelion-redis/src/main/java/likelion/univ/common/constant/RedisKey.java index 3f4f8298..856a5b66 100644 --- a/likelion-redis/src/main/java/likelion/univ/common/constant/RedisKey.java +++ b/likelion-redis/src/main/java/likelion/univ/common/constant/RedisKey.java @@ -1,6 +1,7 @@ package likelion.univ.common.constant; public class RedisKey { + public static final int DEFAULT_EXPIRE_DAY = 1; public static final String KAKAO_PUBLIC_KEYS = "kakaoPublicKeys"; diff --git a/likelion-redis/src/main/java/likelion/univ/follow/dao/FollowNumRedisDao.java b/likelion-redis/src/main/java/likelion/univ/follow/dao/FollowNumRedisDao.java index a8297c35..2fc5c072 100644 --- a/likelion-redis/src/main/java/likelion/univ/follow/dao/FollowNumRedisDao.java +++ b/likelion-redis/src/main/java/likelion/univ/follow/dao/FollowNumRedisDao.java @@ -1,13 +1,13 @@ package likelion.univ.follow.dao; +import static likelion.univ.common.constant.RedisKey.USER_FOLLOW_NUM; +import static likelion.univ.common.constant.RedisKey.USER_FOLLOW_NUM_EXPIRE_SEC; + import likelion.univ.annotation.RedisRepository; import likelion.univ.common.base.BaseRedisRepository; import likelion.univ.follow.entity.FollowNum; import org.springframework.data.redis.core.RedisTemplate; -import static likelion.univ.common.constant.RedisKey.USER_FOLLOW_NUM; -import static likelion.univ.common.constant.RedisKey.USER_FOLLOW_NUM_EXPIRE_SEC; - @RedisRepository public class FollowNumRedisDao extends BaseRedisRepository { @@ -16,4 +16,4 @@ public FollowNumRedisDao(RedisTemplate redisTemplate) { this.ttl = USER_FOLLOW_NUM_EXPIRE_SEC; this.redisTemplate = redisTemplate; } -} \ No newline at end of file +} diff --git a/likelion-redis/src/main/java/likelion/univ/follow/entity/FollowNum.java b/likelion-redis/src/main/java/likelion/univ/follow/entity/FollowNum.java index 7c88387a..1183b8b9 100644 --- a/likelion-redis/src/main/java/likelion/univ/follow/entity/FollowNum.java +++ b/likelion-redis/src/main/java/likelion/univ/follow/entity/FollowNum.java @@ -10,6 +10,7 @@ @NoArgsConstructor @Builder public class FollowNum { + private Long followerNum; private Long followingNum; } diff --git a/likelion-redis/src/main/java/likelion/univ/follow/service/FollowNumRedisService.java b/likelion-redis/src/main/java/likelion/univ/follow/service/FollowNumRedisService.java index b0cb6d41..092a86df 100644 --- a/likelion-redis/src/main/java/likelion/univ/follow/service/FollowNumRedisService.java +++ b/likelion-redis/src/main/java/likelion/univ/follow/service/FollowNumRedisService.java @@ -8,9 +8,10 @@ @Service @RequiredArgsConstructor public class FollowNumRedisService { + private final FollowNumRedisDao followNumRedisDao; - public FollowNum save(Long userId, Long followerNum, Long followingNum){ + public FollowNum save(Long userId, Long followerNum, Long followingNum) { FollowNum followNum = FollowNum.builder() .followerNum(followerNum) .followingNum(followingNum) @@ -18,32 +19,36 @@ public FollowNum save(Long userId, Long followerNum, Long followingNum){ followNumRedisDao.save(userId, followNum); return followNum; } - public void followerUp(Long userId, FollowNum followNum){ + + public void followerUp(Long userId, FollowNum followNum) { FollowNum newFollowNum = FollowNum.builder() .followerNum(followNum.getFollowerNum() + 1) .followingNum(followNum.getFollowingNum()) .build(); followNumRedisDao.save(userId, newFollowNum); } - public void followerDown(Long userId, FollowNum followNum){ + + public void followerDown(Long userId, FollowNum followNum) { FollowNum newFollowNum = FollowNum.builder() .followerNum(followNum.getFollowerNum() - 1) .followingNum(followNum.getFollowingNum()) .build(); followNumRedisDao.save(userId, newFollowNum); } - public void followingUp(Long userId, FollowNum followNum){ + + public void followingUp(Long userId, FollowNum followNum) { FollowNum newFollowNum = FollowNum.builder() .followerNum(followNum.getFollowerNum()) .followingNum(followNum.getFollowingNum() + 1) .build(); followNumRedisDao.save(userId, newFollowNum); } - public void followingDown(Long userId, FollowNum followNum){ + + public void followingDown(Long userId, FollowNum followNum) { FollowNum newFollowNum = FollowNum.builder() .followerNum(followNum.getFollowerNum()) .followingNum(followNum.getFollowingNum() - 1) .build(); followNumRedisDao.save(userId, newFollowNum); } -} \ No newline at end of file +} diff --git a/likelion-redis/src/main/java/likelion/univ/post/dao/PostCountInfoRedisDao.java b/likelion-redis/src/main/java/likelion/univ/post/dao/PostCountInfoRedisDao.java index b9e9b6e5..c60e8662 100644 --- a/likelion-redis/src/main/java/likelion/univ/post/dao/PostCountInfoRedisDao.java +++ b/likelion-redis/src/main/java/likelion/univ/post/dao/PostCountInfoRedisDao.java @@ -1,13 +1,13 @@ package likelion.univ.post.dao; +import static likelion.univ.common.constant.RedisKey.POST_COUNT_INFO; +import static likelion.univ.common.constant.RedisKey.POST_COUNT_INFO_EXPIRE_SEC; + import likelion.univ.annotation.RedisRepository; import likelion.univ.common.base.BaseRedisRepository; import likelion.univ.post.entity.PostCountInfo; import org.springframework.data.redis.core.RedisTemplate; -import static likelion.univ.common.constant.RedisKey.POST_COUNT_INFO; -import static likelion.univ.common.constant.RedisKey.POST_COUNT_INFO_EXPIRE_SEC; - @RedisRepository public class PostCountInfoRedisDao extends BaseRedisRepository { diff --git a/likelion-redis/src/main/java/likelion/univ/post/entity/PostCountInfo.java b/likelion-redis/src/main/java/likelion/univ/post/entity/PostCountInfo.java index a7f2158f..e686875c 100644 --- a/likelion-redis/src/main/java/likelion/univ/post/entity/PostCountInfo.java +++ b/likelion-redis/src/main/java/likelion/univ/post/entity/PostCountInfo.java @@ -10,6 +10,7 @@ @NoArgsConstructor @Builder public class PostCountInfo { + private Long commentCount; private Long likeCount; } diff --git a/likelion-redis/src/main/java/likelion/univ/post/service/PostCountInfoRedisService.java b/likelion-redis/src/main/java/likelion/univ/post/service/PostCountInfoRedisService.java index 7c3f23a4..95cafbfc 100644 --- a/likelion-redis/src/main/java/likelion/univ/post/service/PostCountInfoRedisService.java +++ b/likelion-redis/src/main/java/likelion/univ/post/service/PostCountInfoRedisService.java @@ -8,9 +8,10 @@ @Service @RequiredArgsConstructor public class PostCountInfoRedisService { + private final PostCountInfoRedisDao postCountInfoRedisDao; - public PostCountInfo save(Long postId, Long commentCount, Long likeCount){ + public PostCountInfo save(Long postId, Long commentCount, Long likeCount) { PostCountInfo postCountInfo = PostCountInfo.builder() .commentCount(commentCount) .likeCount(likeCount) diff --git a/likelion-redis/src/main/java/likelion/univ/refreshtoken/dao/RefreshTokenRedisDao.java b/likelion-redis/src/main/java/likelion/univ/refreshtoken/dao/RefreshTokenRedisDao.java index 836be70f..baa8c1f6 100644 --- a/likelion-redis/src/main/java/likelion/univ/refreshtoken/dao/RefreshTokenRedisDao.java +++ b/likelion-redis/src/main/java/likelion/univ/refreshtoken/dao/RefreshTokenRedisDao.java @@ -1,13 +1,13 @@ package likelion.univ.refreshtoken.dao; +import static likelion.univ.common.constant.RedisKey.REFRESH_TOKEN; +import static likelion.univ.common.constant.RedisKey.REFRESH_TOKEN_EXPIRE_SEC; + import likelion.univ.annotation.RedisRepository; import likelion.univ.common.base.BaseRedisRepository; import likelion.univ.refreshtoken.entity.RefreshToken; import org.springframework.data.redis.core.RedisTemplate; -import static likelion.univ.common.constant.RedisKey.REFRESH_TOKEN; -import static likelion.univ.common.constant.RedisKey.REFRESH_TOKEN_EXPIRE_SEC; - @RedisRepository public class RefreshTokenRedisDao extends BaseRedisRepository { diff --git a/likelion-redis/src/main/java/likelion/univ/refreshtoken/entity/RefreshToken.java b/likelion-redis/src/main/java/likelion/univ/refreshtoken/entity/RefreshToken.java index a00e2d38..5c798642 100644 --- a/likelion-redis/src/main/java/likelion/univ/refreshtoken/entity/RefreshToken.java +++ b/likelion-redis/src/main/java/likelion/univ/refreshtoken/entity/RefreshToken.java @@ -1,11 +1,10 @@ package likelion.univ.refreshtoken.entity; -import likelion.univ.common.constant.RedisKey; -import lombok.*; -import org.springframework.data.annotation.Id; -import org.springframework.data.redis.core.RedisHash; -import javax.persistence.GeneratedValue; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; @Getter @AllArgsConstructor diff --git a/likelion-redis/src/main/java/likelion/univ/refreshtoken/exception/ExpiredRefreshTokenException.java b/likelion-redis/src/main/java/likelion/univ/refreshtoken/exception/ExpiredRefreshTokenException.java index 3bffd9d2..452ce502 100644 --- a/likelion-redis/src/main/java/likelion/univ/refreshtoken/exception/ExpiredRefreshTokenException.java +++ b/likelion-redis/src/main/java/likelion/univ/refreshtoken/exception/ExpiredRefreshTokenException.java @@ -1,9 +1,9 @@ package likelion.univ.refreshtoken.exception; -import likelion.univ.exception.base.BaseErrorCode; import likelion.univ.exception.base.BaseException; public class ExpiredRefreshTokenException extends BaseException { + public ExpiredRefreshTokenException() { super(RefreshTokenErrorCode.EXPIRED_REFRESH_TOKEN); } diff --git a/likelion-redis/src/main/java/likelion/univ/refreshtoken/exception/RefreshTokenErrorCode.java b/likelion-redis/src/main/java/likelion/univ/refreshtoken/exception/RefreshTokenErrorCode.java index d3366d2a..599266f0 100644 --- a/likelion-redis/src/main/java/likelion/univ/refreshtoken/exception/RefreshTokenErrorCode.java +++ b/likelion-redis/src/main/java/likelion/univ/refreshtoken/exception/RefreshTokenErrorCode.java @@ -1,16 +1,16 @@ package likelion.univ.refreshtoken.exception; +import static likelion.univ.constant.StaticValue.UNAUTHORIZED; + import likelion.univ.exception.base.BaseErrorCode; import lombok.AllArgsConstructor; import lombok.Getter; -import static likelion.univ.constant.StaticValue.*; - @Getter @AllArgsConstructor public enum RefreshTokenErrorCode implements BaseErrorCode { - EXPIRED_REFRESH_TOKEN(UNAUTHORIZED, "REFRESH_TOKEN_401", "해당 리프레쉬토큰은 만료되었습니다."); + EXPIRED_REFRESH_TOKEN(UNAUTHORIZED, "REFRESH_TOKEN_401", "해당 리프레쉬토큰은 만료되었습니다."); private final int httpStatus; private final String code; diff --git a/likelion-redis/src/main/java/likelion/univ/refreshtoken/service/RefreshTokenRedisService.java b/likelion-redis/src/main/java/likelion/univ/refreshtoken/service/RefreshTokenRedisService.java index 4545a42d..eefe3a3f 100644 --- a/likelion-redis/src/main/java/likelion/univ/refreshtoken/service/RefreshTokenRedisService.java +++ b/likelion-redis/src/main/java/likelion/univ/refreshtoken/service/RefreshTokenRedisService.java @@ -4,25 +4,29 @@ import likelion.univ.refreshtoken.entity.RefreshToken; import likelion.univ.refreshtoken.exception.ExpiredRefreshTokenException; import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @Service @RequiredArgsConstructor public class RefreshTokenRedisService { + private final RefreshTokenRedisDao refreshTokenRedisDao; - public void save(Long id, String token){ + public void save(Long id, String token) { RefreshToken refreshToken = RefreshToken.builder() .userId(id) .token(token) .build(); refreshTokenRedisDao.save(id, refreshToken); } - public Boolean checkToken(Long id, String token){ + + public Boolean checkToken(Long id, String token) { RefreshToken refreshToken = refreshTokenRedisDao.findById(id) .orElseThrow(() -> new ExpiredRefreshTokenException()); - if(token.equals(refreshToken.getToken())) return true; - else return false; + if (token.equals(refreshToken.getToken())) { + return true; + } else { + return false; + } } } diff --git a/likelion-redis/src/main/resources/application-redis-test.yml b/likelion-redis/src/main/resources/application-redis-test.yml new file mode 100644 index 00000000..40fabfc7 --- /dev/null +++ b/likelion-redis/src/main/resources/application-redis-test.yml @@ -0,0 +1,4 @@ +redis: + host: localhost + port: 11111 + password: 11111 diff --git a/likelion-security/src/main/java/likelion/univ/exception/ExpiredTokenException.java b/likelion-security/src/main/java/likelion/univ/exception/ExpiredTokenException.java index d143ffda..80607b7e 100644 --- a/likelion-security/src/main/java/likelion/univ/exception/ExpiredTokenException.java +++ b/likelion-security/src/main/java/likelion/univ/exception/ExpiredTokenException.java @@ -3,7 +3,8 @@ import likelion.univ.exception.base.BaseException; public class ExpiredTokenException extends BaseException { - public ExpiredTokenException(){ + + public ExpiredTokenException() { super(SecurityErrorCode.EXPIRED_TOKEN); } } diff --git a/likelion-security/src/main/java/likelion/univ/exception/IncorrectIssuerTokenException.java b/likelion-security/src/main/java/likelion/univ/exception/IncorrectIssuerTokenException.java index 13f51f12..334249ec 100644 --- a/likelion-security/src/main/java/likelion/univ/exception/IncorrectIssuerTokenException.java +++ b/likelion-security/src/main/java/likelion/univ/exception/IncorrectIssuerTokenException.java @@ -3,6 +3,7 @@ import likelion.univ.exception.base.BaseException; public class IncorrectIssuerTokenException extends BaseException { + public IncorrectIssuerTokenException() { super(SecurityErrorCode.INCORRECT_ISSUER_TOKEN); } diff --git a/likelion-security/src/main/java/likelion/univ/exception/InvalidSignatureTokenException.java b/likelion-security/src/main/java/likelion/univ/exception/InvalidSignatureTokenException.java index d1bd9154..16714d9d 100644 --- a/likelion-security/src/main/java/likelion/univ/exception/InvalidSignatureTokenException.java +++ b/likelion-security/src/main/java/likelion/univ/exception/InvalidSignatureTokenException.java @@ -3,7 +3,8 @@ import likelion.univ.exception.base.BaseException; public class InvalidSignatureTokenException extends BaseException { - public InvalidSignatureTokenException(){ + + public InvalidSignatureTokenException() { super(SecurityErrorCode.INVALID_SIGNATURE_TOKEN); } } diff --git a/likelion-security/src/main/java/likelion/univ/exception/InvalidTokenException.java b/likelion-security/src/main/java/likelion/univ/exception/InvalidTokenException.java index 3e826587..4caf7c32 100644 --- a/likelion-security/src/main/java/likelion/univ/exception/InvalidTokenException.java +++ b/likelion-security/src/main/java/likelion/univ/exception/InvalidTokenException.java @@ -3,7 +3,8 @@ import likelion.univ.exception.base.BaseException; public class InvalidTokenException extends BaseException { - public InvalidTokenException(){ + + public InvalidTokenException() { super(SecurityErrorCode.INVALID_TOKEN); } } diff --git a/likelion-security/src/main/java/likelion/univ/exception/NotAuthentiatedException.java b/likelion-security/src/main/java/likelion/univ/exception/NotAuthenticatedException.java similarity index 58% rename from likelion-security/src/main/java/likelion/univ/exception/NotAuthentiatedException.java rename to likelion-security/src/main/java/likelion/univ/exception/NotAuthenticatedException.java index 0aa7b5c2..4d2b294e 100644 --- a/likelion-security/src/main/java/likelion/univ/exception/NotAuthentiatedException.java +++ b/likelion-security/src/main/java/likelion/univ/exception/NotAuthenticatedException.java @@ -2,8 +2,9 @@ import likelion.univ.exception.base.BaseException; -public class NotAuthentiatedException extends BaseException { - public NotAuthentiatedException() { +public class NotAuthenticatedException extends BaseException { + + public NotAuthenticatedException() { super(SecurityErrorCode.NOT_AUTHENTIATED_ERROR); } } diff --git a/likelion-security/src/main/java/likelion/univ/exception/NotMatchedTokenTypeException.java b/likelion-security/src/main/java/likelion/univ/exception/NotMatchedTokenTypeException.java index ee32a465..a64bc91e 100644 --- a/likelion-security/src/main/java/likelion/univ/exception/NotMatchedTokenTypeException.java +++ b/likelion-security/src/main/java/likelion/univ/exception/NotMatchedTokenTypeException.java @@ -1,6 +1,5 @@ package likelion.univ.exception; -import likelion.univ.exception.base.BaseErrorCode; import likelion.univ.exception.base.BaseException; public class NotMatchedTokenTypeException extends BaseException { diff --git a/likelion-security/src/main/java/likelion/univ/exception/SecurityErrorCode.java b/likelion-security/src/main/java/likelion/univ/exception/SecurityErrorCode.java index 6b34bb3e..e0b435bb 100644 --- a/likelion-security/src/main/java/likelion/univ/exception/SecurityErrorCode.java +++ b/likelion-security/src/main/java/likelion/univ/exception/SecurityErrorCode.java @@ -1,21 +1,21 @@ package likelion.univ.exception; +import static likelion.univ.constant.StaticValue.UNAUTHORIZED; + import likelion.univ.exception.base.BaseErrorCode; import lombok.AllArgsConstructor; import lombok.Getter; -import static likelion.univ.constant.StaticValue.*; - @Getter @AllArgsConstructor public enum SecurityErrorCode implements BaseErrorCode { - NOT_AUTHENTIATED_ERROR(UNAUTHORIZED,"SECURITY_401","사용자가 인증되지 않았습니다."), - INVALID_TOKEN(UNAUTHORIZED,"TOKEN_401_1","토큰이 유효하지않습니다."), - INVALID_SIGNATURE_TOKEN(UNAUTHORIZED,"TOKEN_401_2","토큰의 Signature가 일치하지 않습니다."), - INCORRECT_ISSUER_TOKEN(UNAUTHORIZED,"TOKEN_401_3","토큰 발급처가 일치하지 않습니다."), - EXPIRED_TOKEN(UNAUTHORIZED,"TOKEN_401_4","토큰이 만료되었습니다."), - NOT_MATCHED_TOKEN_TYPE(UNAUTHORIZED,"TOKEN_401_5","토큰의 타입이 일치하지 않아 디코딩할 수 없습니다."); - + + NOT_AUTHENTIATED_ERROR(UNAUTHORIZED, "SECURITY_401", "사용자가 인증되지 않았습니다."), + INVALID_TOKEN(UNAUTHORIZED, "TOKEN_401_1", "토큰이 유효하지않습니다."), + INVALID_SIGNATURE_TOKEN(UNAUTHORIZED, "TOKEN_401_2", "토큰의 Signature가 일치하지 않습니다."), + INCORRECT_ISSUER_TOKEN(UNAUTHORIZED, "TOKEN_401_3", "토큰 발급처가 일치하지 않습니다."), + EXPIRED_TOKEN(UNAUTHORIZED, "TOKEN_401_4", "토큰이 만료되었습니다."), + NOT_MATCHED_TOKEN_TYPE(UNAUTHORIZED, "TOKEN_401_5", "토큰의 타입이 일치하지 않아 디코딩할 수 없습니다."); private final int httpStatus; diff --git a/likelion-security/src/main/java/likelion/univ/jwt/JwtIdTokenProvider.java b/likelion-security/src/main/java/likelion/univ/jwt/JwtIdTokenProvider.java index db560499..a55aeb1a 100644 --- a/likelion-security/src/main/java/likelion/univ/jwt/JwtIdTokenProvider.java +++ b/likelion-security/src/main/java/likelion/univ/jwt/JwtIdTokenProvider.java @@ -1,7 +1,15 @@ package likelion.univ.jwt; import com.fasterxml.jackson.databind.ObjectMapper; -import io.jsonwebtoken.*; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.ExpiredJwtException; +import io.jsonwebtoken.IncorrectClaimException; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureException; +import java.nio.charset.StandardCharsets; +import java.security.interfaces.RSAPublicKey; +import java.util.Base64; +import java.util.Map; import likelion.univ.exception.ExpiredTokenException; import likelion.univ.exception.IncorrectIssuerTokenException; import likelion.univ.exception.InvalidSignatureTokenException; @@ -10,24 +18,20 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; -import java.nio.charset.StandardCharsets; -import java.security.interfaces.RSAPublicKey; -import java.util.Base64; -import java.util.Map; - @RequiredArgsConstructor @Component public class JwtIdTokenProvider { + /* kid 서명검증없이 가져오기 */ - public String getKid(String idToken){ - try{ + public String getKid(String idToken) { + try { String[] idTokenParts = idToken.split("\\."); String encodedHeader = idTokenParts[0]; String decodedHeader = new String(Base64.getUrlDecoder().decode(encodedHeader), StandardCharsets.UTF_8); ObjectMapper objectMapper = new ObjectMapper(); Map map = objectMapper.readValue(decodedHeader, java.util.Map.class); return map.get("kid"); - } catch (Exception e){ + } catch (Exception e) { throw new InvalidTokenException(); } } @@ -45,18 +49,14 @@ public UserInfoFromIdToken getUserInfo(String idToken, RSAPublicKey publicKey, S return UserInfoFromIdToken.builder() .email(claims.get("email", String.class)) .build(); - } catch (SignatureException exception) { throw new InvalidSignatureTokenException(); - }catch (IncorrectClaimException exception){ + } catch (IncorrectClaimException exception) { throw new IncorrectIssuerTokenException(); - }catch (ExpiredJwtException exception) { + } catch (ExpiredJwtException exception) { throw new ExpiredTokenException(); - } catch (Exception exception){ + } catch (Exception exception) { throw new InvalidTokenException(); } } - - - -} \ No newline at end of file +} diff --git a/likelion-security/src/main/java/likelion/univ/jwt/JwtProvider.java b/likelion-security/src/main/java/likelion/univ/jwt/JwtProvider.java index 7b5c053c..702acbcc 100644 --- a/likelion-security/src/main/java/likelion/univ/jwt/JwtProvider.java +++ b/likelion-security/src/main/java/likelion/univ/jwt/JwtProvider.java @@ -1,31 +1,35 @@ package likelion.univ.jwt; -import io.jsonwebtoken.*; +import static likelion.univ.constant.StaticValue.ACCESS_TOKEN; +import static likelion.univ.constant.StaticValue.REFRESH_TOKEN; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.ExpiredJwtException; +import io.jsonwebtoken.Jws; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureException; import io.jsonwebtoken.security.Keys; +import java.security.Key; +import java.util.Date; import likelion.univ.exception.ExpiredTokenException; import likelion.univ.exception.InvalidSignatureTokenException; import likelion.univ.exception.InvalidTokenException; import likelion.univ.exception.NotMatchedTokenTypeException; import likelion.univ.jwt.dto.DecodedJwtToken; import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; -import java.security.Key; -import java.util.Date; - -import static likelion.univ.constant.StaticValue.*; - @RequiredArgsConstructor @Component public class JwtProvider { + private final JwtProperties jwtProperties; public Key getSecretKey() { return Keys.hmacShaKeyFor(jwtProperties.getSecretKey().getBytes()); } - public Jws getClaim(String token){ + public Jws getClaim(String token) { try { return Jwts.parserBuilder() .setSigningKey(getSecretKey()) @@ -35,43 +39,47 @@ public Jws getClaim(String token){ throw new InvalidSignatureTokenException(); } catch (ExpiredJwtException e) { throw new ExpiredTokenException(); - } catch (Exception e){ + } catch (Exception e) { throw new InvalidTokenException(); } } - private String issueToken(Long userId, String role, String type, Long time){ + private String issueToken(Long userId, String role, String type, Long time) { Date now = new Date(); return Jwts.builder() .setIssuer("LikelionUniv") .setSubject(userId.toString()) .setIssuedAt(now) .setExpiration(new Date(now.getTime() + time)) - .claim("type",type) + .claim("type", type) .claim("role", role) .signWith(getSecretKey()) .compact(); } - public String generateAccessToken(Long userId, String role){ - return issueToken(userId,role, ACCESS_TOKEN, jwtProperties.getAccessTokenExp()); + public String generateAccessToken(Long userId, String role) { + return issueToken(userId, role, ACCESS_TOKEN, jwtProperties.getAccessTokenExp()); } - public String generateRefreshToken(Long userId, String role){ - return issueToken(userId,role, REFRESH_TOKEN, jwtProperties.getRefreshTokenExp()); + + public String generateRefreshToken(Long userId, String role) { + return issueToken(userId, role, REFRESH_TOKEN, jwtProperties.getRefreshTokenExp()); } - public DecodedJwtToken decodeToken(String token, String type){ + public DecodedJwtToken decodeToken(String token, String type) { Claims claims = getClaim(token).getBody(); - checkType(claims,type); - DecodedJwtToken result = DecodedJwtToken.builder() + checkType(claims, type); + return DecodedJwtToken.builder() .userId(Long.valueOf(claims.getSubject())) .role(String.valueOf(claims.get("role"))) .type(String.valueOf(claims.get("type"))) .build(); - return result; } - private void checkType(Claims claims, String type){ - if(type.equals(String.valueOf(claims.get("type")))) return; - else throw new NotMatchedTokenTypeException(); + + private void checkType(Claims claims, String type) { + if (type.equals(String.valueOf(claims.get("type")))) { + return; + } else { + throw new NotMatchedTokenTypeException(); + } } -} \ No newline at end of file +} diff --git a/likelion-security/src/main/java/likelion/univ/security/CorsConfig.java b/likelion-security/src/main/java/likelion/univ/security/CorsConfig.java index b20f4d9b..a15e326c 100644 --- a/likelion-security/src/main/java/likelion/univ/security/CorsConfig.java +++ b/likelion-security/src/main/java/likelion/univ/security/CorsConfig.java @@ -1,17 +1,18 @@ package likelion.univ.security; +import java.util.ArrayList; import likelion.univ.environment.ProfileProcessor; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; -import java.util.ArrayList; - @Configuration @RequiredArgsConstructor public class CorsConfig implements WebMvcConfigurer { + private final ProfileProcessor profileProcessor; + @Override public void addCorsMappings(CorsRegistry registry) { ArrayList allowedOriginPatterns = new ArrayList<>(); diff --git a/likelion-security/src/main/java/likelion/univ/security/FilterExceptionProcessor.java b/likelion-security/src/main/java/likelion/univ/security/FilterExceptionProcessor.java index a6710eaa..ccba8dee 100644 --- a/likelion-security/src/main/java/likelion/univ/security/FilterExceptionProcessor.java +++ b/likelion-security/src/main/java/likelion/univ/security/FilterExceptionProcessor.java @@ -1,22 +1,21 @@ package likelion.univ.security; import com.fasterxml.jackson.databind.ObjectMapper; -import likelion.univ.annotation.Processor; -import likelion.univ.exception.base.BaseException; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; - -import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.time.LocalDateTime; import java.util.HashMap; import java.util.Map; +import javax.servlet.http.HttpServletResponse; +import likelion.univ.annotation.Processor; +import likelion.univ.exception.base.BaseException; +import lombok.RequiredArgsConstructor; @Processor @RequiredArgsConstructor public class FilterExceptionProcessor { private final ObjectMapper objectMapper; + public void excute(HttpServletResponse response, BaseException e) throws IOException { Map errorResponse = new HashMap<>(); errorResponse.put("timestamp", LocalDateTime.now()); @@ -30,4 +29,4 @@ public void excute(HttpServletResponse response, BaseException e) throws IOExcep response.setContentType("application/json"); response.getWriter().write(objectMapper.writeValueAsString(errorResponse)); } -} \ No newline at end of file +} diff --git a/likelion-security/src/main/java/likelion/univ/security/SecurityUtils.java b/likelion-security/src/main/java/likelion/univ/security/SecurityUtils.java index 08281aa8..d0fe0ab8 100644 --- a/likelion-security/src/main/java/likelion/univ/security/SecurityUtils.java +++ b/likelion-security/src/main/java/likelion/univ/security/SecurityUtils.java @@ -1,22 +1,21 @@ package likelion.univ.security; -import likelion.univ.exception.NotAuthentiatedException; +import likelion.univ.exception.NotAuthenticatedException; import lombok.extern.slf4j.Slf4j; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; -import javax.servlet.http.HttpServletRequest; - @Slf4j public class SecurityUtils { - private SecurityUtils(){}; + public static Long getCurrentUserId() { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - if (authentication != null && authentication.isAuthenticated() && authentication.getPrincipal() instanceof Long) { + if (authentication != null && authentication.isAuthenticated() + && authentication.getPrincipal() instanceof Long) { return (Long) authentication.getPrincipal(); } else { - throw new NotAuthentiatedException(); + throw new NotAuthenticatedException(); } } } diff --git a/likelion-security/src/main/java/likelion/univ/security/filter/CustomAccessDeniedHandler.java b/likelion-security/src/main/java/likelion/univ/security/filter/CustomAccessDeniedHandler.java index 6e623a81..6dd01259 100644 --- a/likelion-security/src/main/java/likelion/univ/security/filter/CustomAccessDeniedHandler.java +++ b/likelion-security/src/main/java/likelion/univ/security/filter/CustomAccessDeniedHandler.java @@ -1,18 +1,16 @@ package likelion.univ.security.filter; +import java.io.IOException; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import likelion.univ.exception.AccessDeniedRequestException; import likelion.univ.security.FilterExceptionProcessor; import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.web.access.AccessDeniedHandler; import org.springframework.stereotype.Component; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; - @Component @RequiredArgsConstructor public class CustomAccessDeniedHandler implements AccessDeniedHandler { @@ -23,8 +21,9 @@ public class CustomAccessDeniedHandler implements AccessDeniedHandler { public void handle( HttpServletRequest request, HttpServletResponse response, - AccessDeniedException accessDeniedException) throws IOException, ServletException { + AccessDeniedException accessDeniedException + ) throws IOException, ServletException { /* 예외처리를 커스터마이징 하는 용도 */ filterExceptionProcessor.excute(response, new AccessDeniedRequestException()); } -} \ No newline at end of file +} diff --git a/likelion-security/src/main/java/likelion/univ/security/filter/FilterProcessor.java b/likelion-security/src/main/java/likelion/univ/security/filter/FilterProcessor.java index 526f7435..54ac2972 100644 --- a/likelion-security/src/main/java/likelion/univ/security/filter/FilterProcessor.java +++ b/likelion-security/src/main/java/likelion/univ/security/filter/FilterProcessor.java @@ -2,7 +2,6 @@ import likelion.univ.annotation.Processor; import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; import org.springframework.security.config.annotation.SecurityConfigurerAdapter; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.web.DefaultSecurityFilterChain; @@ -10,7 +9,7 @@ @Processor @RequiredArgsConstructor -public class FilterProcessor extends SecurityConfigurerAdapter{ +public class FilterProcessor extends SecurityConfigurerAdapter { private final JwtAuthenticationFilter jwtAuthenticationFilter; private final CustomAccessDeniedHandler customAccessDeniedHandler; @@ -20,6 +19,4 @@ public HttpSecurity common(HttpSecurity builder) throws Exception { builder.exceptionHandling().accessDeniedHandler(customAccessDeniedHandler); return builder; } - - -} \ No newline at end of file +} diff --git a/likelion-security/src/main/java/likelion/univ/security/filter/JwtAuthenticationFilter.java b/likelion-security/src/main/java/likelion/univ/security/filter/JwtAuthenticationFilter.java index a5091962..29289b89 100644 --- a/likelion-security/src/main/java/likelion/univ/security/filter/JwtAuthenticationFilter.java +++ b/likelion-security/src/main/java/likelion/univ/security/filter/JwtAuthenticationFilter.java @@ -1,5 +1,14 @@ package likelion.univ.security.filter; +import static likelion.univ.constant.StaticValue.ACCESS_TOKEN; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import likelion.univ.exception.base.BaseException; import likelion.univ.jwt.JwtProvider; import likelion.univ.jwt.dto.DecodedJwtToken; @@ -14,16 +23,6 @@ import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import static likelion.univ.constant.StaticValue.ACCESS_TOKEN; - @Component @RequiredArgsConstructor @Slf4j @@ -31,6 +30,7 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter { private final JwtProvider jwtProvider; private final FilterExceptionProcessor filterExceptionProcessor; + @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { @@ -41,12 +41,13 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse SecurityContextHolder.getContext().setAuthentication(authentication); //SecurityContextHolder에 담기 } chain.doFilter(request, response); - }catch (BaseException e){ + } catch (BaseException e) { filterExceptionProcessor.excute(response, e); } } + private Authentication getAuthentication(String token) { - DecodedJwtToken decodedJwtToken = jwtProvider.decodeToken(token,ACCESS_TOKEN); + DecodedJwtToken decodedJwtToken = jwtProvider.decodeToken(token, ACCESS_TOKEN); Long userId = decodedJwtToken.getUserId(); String role = decodedJwtToken.getRole(); @@ -55,11 +56,12 @@ private Authentication getAuthentication(String token) { return new UsernamePasswordAuthenticationToken(userId, null, authorities); } + private String resolveToken(HttpServletRequest request) { String bearerToken = request.getHeader("Authorization"); if (bearerToken != null && bearerToken.startsWith("Bearer ")) { return bearerToken.substring(7); - } else if (bearerToken != null){ + } else if (bearerToken != null) { return bearerToken; } return null; diff --git a/likelion-security/src/main/resources/application-security-test.yml b/likelion-security/src/main/resources/application-security-test.yml new file mode 100644 index 00000000..934666f7 --- /dev/null +++ b/likelion-security/src/main/resources/application-security-test.yml @@ -0,0 +1,4 @@ +jwt: + secret-key: "testSecrettestSecrettestSecrettestSecrettestSecrettestSecrettestSecret" + access-token-exp: 100000 + refresh-token-exp: 100000 diff --git a/likelion-socket/src/main/java/likelion/univ/MutsaApplication.java b/likelion-socket/src/main/java/likelion/univ/MutsaApplication.java index 9ba2ebe5..54296b76 100644 --- a/likelion-socket/src/main/java/likelion/univ/MutsaApplication.java +++ b/likelion-socket/src/main/java/likelion/univ/MutsaApplication.java @@ -6,8 +6,8 @@ @SpringBootApplication public class MutsaApplication { - public static void main(String[] args) { - SpringApplication.run(MutsaApplication.class, args); - } + public static void main(String[] args) { + SpringApplication.run(MutsaApplication.class, args); + } }