Skip to content

Commit

Permalink
feat: 폴더관련 CRUD 추가 및 이에 따른 콜렉트하기, 콜렉션조회 수정
Browse files Browse the repository at this point in the history
  • Loading branch information
pparkjs committed Sep 18, 2024
1 parent 56a278b commit 2ef43a2
Show file tree
Hide file tree
Showing 21 changed files with 352 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,16 @@ public class Collect {
@JoinColumn(name = "list_id")
private ListEntity list;

@ManyToOne(fetch = LAZY)
@JoinColumn(name = "folder_id")
private Folder folder;

@Column(name = "user_id", nullable = false)
private Long userId;

public Collect(ListEntity list, Long userId) {
public Collect(ListEntity list, Long userId, Folder folder) {
this.list = list;
this.userId = userId;
this.folder = folder;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.listywave.collection.application.domain;

import com.listywave.common.BaseEntity;
import com.listywave.common.exception.CustomException;
import jakarta.persistence.Column;
import jakarta.persistence.Embedded;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

import static com.listywave.common.exception.ErrorCode.INVALID_ACCESS;
import static lombok.AccessLevel.PROTECTED;

@Entity
@Getter
@AllArgsConstructor
@Table(name = "folder")
@NoArgsConstructor(access = PROTECTED)
public class Folder extends BaseEntity {

@Column(name = "user_id", nullable = false)
private Long userId;

@Embedded
private FolderName name;

public static Folder create(Long loginUserId, FolderName folderName) {
return new Folder(loginUserId, folderName);
}

public void update(FolderName folderName, Long userId) {
validateOwner(userId);
this.name = folderName;
}
public String getFolderName(){
return this.name.getValue();
}

public void validateOwner(Long userId) {
if (!this.userId.equals(userId)) {
throw new CustomException(INVALID_ACCESS);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.listywave.collection.application.domain;

import com.listywave.common.exception.CustomException;
import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;
import lombok.*;

import static com.listywave.common.exception.ErrorCode.LENGTH_EXCEEDED_EXCEPTION;

@Getter
@Builder
@Embeddable
@EqualsAndHashCode
@NoArgsConstructor(access = AccessLevel.PROTECTED, force = true)
public class FolderName {

private static final int LENGTH_LIMIT = 30;

@Column(name = "name", nullable = false, length = LENGTH_LIMIT)
private final String value;

public FolderName(String value) {
validate(value);
this.value = value;
}

private void validate(String value) {
if (value.length() > LENGTH_LIMIT) {
throw new CustomException(LENGTH_EXCEEDED_EXCEPTION, "폴더 이름은 " + LENGTH_LIMIT + "자를 넘을 수 없습니다.");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ public record ListsResponse(
Long ownerId,
String ownerNickname,
String ownerProfileImageUrl,
String representativeImageUrl,
LocalDateTime updatedDate,
List<ListItemsResponse> listItems
) {
Expand All @@ -58,7 +57,6 @@ public static ListsResponse of(ListEntity list) {
.ownerId(list.getUser().getId())
.ownerNickname(list.getUser().getNickname())
.ownerProfileImageUrl(list.getUser().getProfileImageUrl())
.representativeImageUrl(list.getRepresentImageUrl())
.updatedDate(list.getUpdatedDate())
.listItems(toList(list.getTop3Items().getValues()))
.build();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.listywave.collection.application.dto;

public record FolderCreateResponse(Long folderId) {

public static FolderCreateResponse of(Long id) {
return new FolderCreateResponse(id);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.listywave.collection.application.dto;

import java.util.List;

public record FolderListResponse(
List<FolderResponse> folders
) {

public static FolderListResponse of(List<FolderResponse> list){
return new FolderListResponse(list);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.listywave.collection.application.dto;

public record FolderResponse(
Long folderId,
String folderName,
Long listCount
) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

import com.listywave.alarm.application.domain.AlarmEvent;
import com.listywave.collection.application.domain.Collect;
import com.listywave.collection.application.domain.Folder;
import com.listywave.collection.application.dto.CollectionResponse;
import com.listywave.collection.repository.CollectionRepository;
import com.listywave.collection.repository.FolderRepository;
import com.listywave.list.application.domain.category.CategoryType;
import com.listywave.list.application.domain.list.ListEntity;
import com.listywave.list.application.dto.response.CategoryTypeResponse;
Expand All @@ -26,24 +28,27 @@ public class CollectionService {

private final UserRepository userRepository;
private final ListRepository listRepository;
private final FolderRepository folderRepository;
private final CollectionRepository collectionRepository;
private final ApplicationEventPublisher applicationEventPublisher;

public void collectOrCancel(Long listId, Long loginUserId) {
public void collectOrCancel(Long listId, Long folderId, Long loginUserId) {
User loginUser = userRepository.getById(loginUserId);
ListEntity list = listRepository.getById(listId);
Folder folder = folderRepository.getById(folderId);

folder.validateOwner(loginUserId);
list.validateNotOwner(loginUser);

if (collectionRepository.existsByListAndUserId(list, loginUser.getId())) {
cancelCollect(list, loginUser.getId());
} else {
addCollect(list, loginUser);
addCollect(list, loginUser, folder);
}
}

private void addCollect(ListEntity list, User user) {
Collect collection = new Collect(list, user.getId());
private void addCollect(ListEntity list, User user, Folder folder) {
Collect collection = new Collect(list, user.getId(), folder);
collectionRepository.save(collection);
list.increaseCollectCount();

Expand All @@ -55,9 +60,10 @@ private void cancelCollect(ListEntity list, Long userId) {
list.decreaseCollectCount();
}

public CollectionResponse getCollection(Long loginUserId, Long cursorId, Pageable pageable, CategoryType category) {
public CollectionResponse getCollection(Long loginUserId, Long cursorId, Pageable pageable, Long folderId) {
User user = userRepository.getById(loginUserId);
Slice<Collect> result = collectionRepository.getAllCollectionList(cursorId, pageable, user.getId(), category);
folderRepository.getById(folderId);
Slice<Collect> result = collectionRepository.getAllCollectionList(cursorId, pageable, user.getId(), folderId);
List<Collect> collectionList = result.getContent();

cursorId = null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package com.listywave.collection.application.service;

import com.listywave.collection.application.domain.Collect;
import com.listywave.collection.application.domain.Folder;
import com.listywave.collection.application.domain.FolderName;
import com.listywave.collection.application.dto.FolderCreateResponse;
import com.listywave.collection.application.dto.FolderListResponse;
import com.listywave.collection.repository.CollectionRepository;
import com.listywave.collection.repository.FolderRepository;
import com.listywave.common.exception.CustomException;
import com.listywave.user.application.domain.User;
import com.listywave.user.application.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

import static com.listywave.common.exception.ErrorCode.DUPLICATE_FOLDER_NAME_EXCEPTION;

@Service
@Transactional
@RequiredArgsConstructor
public class FolderService {

private final FolderRepository folderRepository;
private final CollectionRepository collectionRepository;
private final UserService userService;

public FolderCreateResponse createFolder(Long loginUserId, String folderName) {
User user = userService.getById(loginUserId);
if(folderRepository.existsByNameValueAndUserId(folderName, user.getId())){
throw new CustomException(DUPLICATE_FOLDER_NAME_EXCEPTION);
}
Folder newFolder = Folder.create(user.getId(), new FolderName(folderName));
Folder folder = folderRepository.save(newFolder);
return FolderCreateResponse.of(folder.getId());
}

public void updateFolder(Long loginUserId, Long folderId, String folderName) {
User user = userService.getById(loginUserId);
if(folderRepository.existsByNameValueAndUserId(folderName, user.getId())){
throw new CustomException(DUPLICATE_FOLDER_NAME_EXCEPTION);
}
Folder folder = folderRepository.getById(folderId);
folder.update(new FolderName(folderName), user.getId());
}

public void deleteFolder(Long loginUserId, Long folderId) {
User user = userService.getById(loginUserId);
Folder folder = folderRepository.getById(folderId);
folder.validateOwner(user.getId());
cancelCollectsByFolder(folder);
folderRepository.deleteById(folderId);
}

private void cancelCollectsByFolder(Folder folder) {
List<Collect> collects = collectionRepository.findAllByFolder(folder);
collects.forEach(collect -> collect.getList().decreaseCollectCount());
collectionRepository.deleteAllByFolder(folder);
}

public FolderListResponse getFolders(Long loginUserId) {
User user = userService.getById(loginUserId);
return FolderListResponse.of(folderRepository.findByFolders(user.getId()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,24 @@ public class CollectionController {

private final CollectionService collectionService;

@PostMapping("/lists/{listId}/collect")
@PostMapping("/lists/{listId}/collect/{folderId}")
ResponseEntity<Void> collectOrCancel(
@PathVariable("listId") Long listId,
@PathVariable("folderId") Long folderId,
@Auth Long loginUserId
) {
collectionService.collectOrCancel(listId, loginUserId);
collectionService.collectOrCancel(listId, folderId, loginUserId);
return ResponseEntity.noContent().build();
}

@GetMapping("/lists/collect")
ResponseEntity<CollectionResponse> getCollection(
@Auth Long loginUserId,
@RequestParam(name = "category", defaultValue = "entire") CategoryType category,
@RequestParam(name = "folderId", required = true) Long folderId,
@RequestParam(name = "cursorId", required = false) Long cursorId,
@PageableDefault(size = 10) Pageable pageable
) {
CollectionResponse collection = collectionService.getCollection(loginUserId, cursorId, pageable, category);
CollectionResponse collection = collectionService.getCollection(loginUserId, cursorId, pageable, folderId);
return ResponseEntity.ok(collection);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.listywave.collection.presentation.controller;

import com.listywave.collection.application.dto.FolderCreateResponse;
import com.listywave.collection.application.dto.FolderListResponse;
import com.listywave.collection.application.service.FolderService;
import com.listywave.collection.presentation.dto.FolderCreateRequest;
import com.listywave.collection.presentation.dto.FolderUpdateRequest;
import com.listywave.common.auth.Auth;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import static org.springframework.http.HttpStatus.CREATED;

@RestController
@RequiredArgsConstructor
public class FolderController {

private final FolderService folderService;

@PostMapping("/collect/folder")
ResponseEntity<FolderCreateResponse> create(
@Auth Long loginUserId,
@RequestBody FolderCreateRequest request
) {
FolderCreateResponse response = folderService.createFolder(loginUserId, request.folderName());
return ResponseEntity.status(CREATED).body(response);
}

@PutMapping("/collect/folder/{folderId}")
ResponseEntity<Void> update(
@Auth Long loginUserId,
@PathVariable("folderId") Long folderId,
@RequestBody FolderUpdateRequest request
) {
folderService.updateFolder(loginUserId, folderId, request.folderName());
return ResponseEntity.noContent().build();
}

@DeleteMapping("/collect/folder/{folderId}")
ResponseEntity<Void> delete(
@Auth Long loginUserId,
@PathVariable("folderId") Long folderId
) {
folderService.deleteFolder(loginUserId, folderId);
return ResponseEntity.noContent().build();
}

@GetMapping("/collect/folder")
ResponseEntity<FolderListResponse> getFolders(
@Auth Long loginUserId
) {
FolderListResponse response = folderService.getFolders(loginUserId);
return ResponseEntity.ok(response);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.listywave.collection.presentation.dto;

public record FolderCreateRequest(
String folderName
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.listywave.collection.presentation.dto;

public record FolderUpdateRequest(
String folderName
) {
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package com.listywave.collection.repository;

import com.listywave.collection.application.domain.Collect;
import com.listywave.collection.application.domain.Folder;
import com.listywave.collection.repository.custom.CustomCollectionRepository;
import com.listywave.list.application.domain.list.ListEntity;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.List;

public interface CollectionRepository extends JpaRepository<Collect, Long>, CustomCollectionRepository {

Expand All @@ -20,4 +21,10 @@ public interface CollectionRepository extends JpaRepository<Collect, Long>, Cust
@Modifying
@Query("delete from Collect c where c.list in :lists")
void deleteAllByListIn(@Param("lists") List<ListEntity> lists);

@Modifying
@Query("delete from Collect c where c.folder =:folder")
void deleteAllByFolder(@Param("folder") Folder folder);

List<Collect> findAllByFolder(Folder folder);
}
Loading

0 comments on commit 2ef43a2

Please sign in to comment.