Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

[REFACTOR] UserService 구현 포함, 전체 코드 리팩토링 #180

Merged
merged 21 commits into from
Oct 10, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
9ca26e1
:recycle: docker compose 테스트 DB 설정 제거
kimminkyeu Oct 8, 2024
8902f53
Merge remote-tracking branch 'refs/remotes/origin/backend' into back/…
kimminkyeu Oct 8, 2024
05b2def
Merge remote-tracking branch 'refs/remotes/origin/backend' into back/…
kimminkyeu Oct 9, 2024
92bc750
Merge remote-tracking branch 'refs/remotes/origin/backend' into back/…
kimminkyeu Oct 9, 2024
75b21c8
:sparkles: feat: UserService 기능 구현
kimminkyeu Oct 9, 2024
c49e271
:recycle: refactor: Tag Feature 리팩토링 (의존성 제거)
kimminkyeu Oct 9, 2024
25e1735
:recycle: refactor: Pick 도메인 리팩토링
kimminkyeu Oct 9, 2024
a15c914
:recycle: refactor: Structure 도메인 리팩토링
kimminkyeu Oct 9, 2024
58a413c
:recycle: refactor: Link 도메인 리팩토링
kimminkyeu Oct 9, 2024
0db8e24
:recycle: refactor: Folder 도메인 리팩토링
kimminkyeu Oct 9, 2024
3432868
:recycle: refactor: FolderStructure 도메인 리펙토링
kimminkyeu Oct 9, 2024
8da4f56
:recycle: refactor: FolderStructure 도메인 리펙토링 (기존 코드 삭제)
kimminkyeu Oct 9, 2024
d949c16
:recycle: refactor: OAuth 도메인 리펙토링
kimminkyeu Oct 9, 2024
e034c49
:recycle: refactor: User 이름 랜덤 생성기 추가
kimminkyeu Oct 9, 2024
2b55700
:recycle: refactor: Folder 예외 추가
kimminkyeu Oct 9, 2024
946949b
:recycle: refactor: Parser 테스트 주석 처리 (provider 의존성 필요)
kimminkyeu Oct 9, 2024
0566ca7
:recycle: refactor: 주석 오류 수정
kimminkyeu Oct 9, 2024
7909ba1
:recycle: refactor: 테스트 코드 준비
kimminkyeu Oct 9, 2024
cc07097
:recycle: refactor: 코드 리뷰 피드백 반영
kimminkyeu Oct 10, 2024
4319206
Merge remote-tracking branch 'refs/remotes/origin/backend' into back/…
kimminkyeu Oct 10, 2024
9d6d458
:recycle: refactor: 코드 리뷰 피드백 반영
kimminkyeu Oct 10, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package kernel360.techpick.core.model.folder;

import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.type.SqlTypes;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
Expand All @@ -11,6 +14,8 @@
import jakarta.persistence.Table;
import kernel360.techpick.core.model.common.TimeTracking;
import kernel360.techpick.core.model.user.User;
import kernel360.techpick.feature.structure.service.Structure;
import kernel360.techpick.feature.structure.service.node.server.ServerNode;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
Expand All @@ -23,26 +28,28 @@ public class StructureJson extends TimeTracking {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;

@JdbcTypeCode(SqlTypes.JSON)
@Column(columnDefinition = "longblob", nullable = false)
private String structure;
private Structure<ServerNode> structure;
kimminkyeu marked this conversation as resolved.
Show resolved Hide resolved

@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;

private StructureJson(String structure, User user) {
private StructureJson(Structure<ServerNode> structure, User user) {
this.structure = structure;
this.user = user;
}

public void updateStructure(String structure) {
public void updateStructure(Structure<ServerNode> structure) {
this.structure = structure;
}

// TODO: 엔티티 사용자가 정적 팩토리 메소드로 필요한 함수를 구현 하세요
public static StructureJson create(String structure, User user) {
public static StructureJson create(Structure<ServerNode> structure, User user) {
return new StructureJson(structure, user);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public interface StructureApi {
description = "구조 json을 정상적으로 조회했습니다."
)
)
public ResponseEntity<String> getStructureByUserId(Authentication auth);
ResponseEntity<String> getStructure();

@Operation(
summary = "폴더 이동",
Expand All @@ -43,7 +43,7 @@ public interface StructureApi {
description = "접근할 수 없는 폴더입니다."
)
})
public ResponseEntity<Void> moveFolder(Authentication auth, Long folderId, StructureMoveRequest request);
ResponseEntity<Void> moveFolder(StructureMoveRequest request);

@Operation(
summary = "휴지통에 있는 폴더 삭제",
Expand All @@ -63,7 +63,7 @@ public interface StructureApi {
description = "접근할 수 없는 폴더입니다."
)
})
public ResponseEntity<Void> deleteFolder(Authentication auth, Long folderId, StructureDeleteRequest request);
ResponseEntity<Void> deleteFolder(StructureDeleteRequest request);

@Operation(
summary = "픽 이동",
Expand All @@ -83,7 +83,7 @@ public interface StructureApi {
description = "접근할 수 없는 폴더입니다."
)
})
public ResponseEntity<Void> movePick(Authentication auth, Long pickId, StructureMoveRequest request);
ResponseEntity<Void> movePick(StructureMoveRequest request);

@Operation(
summary = "휴지통에 있는 픽 삭제",
Expand All @@ -103,5 +103,5 @@ public interface StructureApi {
description = "접근할 수 없는 폴더입니다."
)
})
public ResponseEntity<Void> deletePick(Authentication auth, Long pickId, StructureDeleteRequest request);
ResponseEntity<Void> deletePick(StructureDeleteRequest request);
}
Original file line number Diff line number Diff line change
@@ -1,73 +1,76 @@
package kernel360.techpick.feature.structure.controller;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
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.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import kernel360.techpick.feature.structure.service.Structure;
import kernel360.techpick.feature.structure.service.StructureService;
import kernel360.techpick.feature.structure.service.dto.StructureDeleteRequest;
import kernel360.techpick.feature.structure.service.dto.StructureMoveRequest;
import kernel360.techpick.feature.structure.service.node.client.ClientNode;
import kernel360.techpick.feature.user.service.UserService;
import lombok.RequiredArgsConstructor;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/structures")
public class StructureController implements StructureApi {

private final UserService userService;
private final StructureService structureService;

@Override
@GetMapping
public ResponseEntity<String> getStructureByUserId(Authentication auth) {
public ResponseEntity<String> getStructure() {
Structure<ClientNode> structure
= structureService.getClientStructure(userService.getCurrentUser());

return ResponseEntity.ok(structureService.getStructureByUserId((Long)auth.getPrincipal()));
return ResponseEntity.ok(structure.serialize());
}

@Override
@PutMapping("/folders/{folderId}")
public ResponseEntity<Void> moveFolder(Authentication auth, @PathVariable Long folderId,
@RequestBody StructureMoveRequest request) {

request.updateUserIdAndTargetId(auth, folderId);
structureService.moveFolder(request);
@PutMapping("/folders")
public ResponseEntity<Void> moveFolder(
@RequestBody StructureMoveRequest request
) {
structureService.moveFolder(userService.getCurrentUser(), request);

return ResponseEntity.noContent().build();
}

@Override
@DeleteMapping("/folders/{folderId}")
public ResponseEntity<Void> deleteFolder(Authentication auth, @PathVariable Long folderId,
@RequestBody StructureDeleteRequest request) {

request.updateUserIdAndTargetId(auth, folderId);
structureService.deleteFolder(request);
@DeleteMapping("/folders")
public ResponseEntity<Void> deleteFolder(
@RequestBody StructureDeleteRequest request
) {
structureService.deleteFolder(userService.getCurrentUser(), request);

return ResponseEntity.noContent().build();
}

@Override
@PutMapping("/picks/{pickId}")
public ResponseEntity<Void> movePick(Authentication auth, @PathVariable Long pickId,
@RequestBody StructureMoveRequest request) {
@PutMapping("/picks")
public ResponseEntity<Void> movePick(
@RequestBody StructureMoveRequest request
) {
structureService.movePick(userService.getCurrentUser(), request);

request.updateUserIdAndTargetId(auth, pickId);
structureService.movePick(request);
return ResponseEntity.noContent().build();
}

@Override
@DeleteMapping("/picks/{pickId}")
public ResponseEntity<Void> deletePick(Authentication auth, @PathVariable Long pickId,
@RequestBody StructureDeleteRequest request) {
@DeleteMapping("/picks")
public ResponseEntity<Void> deletePick(
@RequestBody StructureDeleteRequest request
) {
structureService.deletePick(userService.getCurrentUser(), request);

request.updateUserIdAndTargetId(auth, pickId);
structureService.deletePick(request);
return ResponseEntity.noContent().build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package kernel360.techpick.feature.structure.model;

import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

import kernel360.techpick.core.model.folder.Folder;
import kernel360.techpick.core.model.pick.Pick;
import kernel360.techpick.core.model.user.User;
import kernel360.techpick.feature.folder.service.FolderStructureService;
import kernel360.techpick.feature.pick.service.PickStructureService;

public class StructureDataProxy {

Comment on lines +14 to +15
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p4: 이 클래스가 어디에 어떻게 쓰이는 것인지 모르겠음... 설명 부탁!!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

대면 확인함

private final Map<Long, Pick> pickMap;
private final Map<Long, Folder> folderMap;

private StructureDataProxy(Map<Long, Pick> pickMap, Map<Long, Folder> folderMap) {
this.pickMap = pickMap;
this.folderMap = folderMap;
}

private StructureDataProxy(List<Pick> pickList, List<Folder> folderList) {
this.pickMap = pickList.stream().collect(Collectors.toMap(Pick::getId, Function.identity()));
this.folderMap = folderList.stream().collect(Collectors.toMap(Folder::getId, Function.identity()));
}

public static StructureDataProxy fromStructureService(
User user,
PickStructureService pickStructureService,
FolderStructureService folderStructureService
) {
return new StructureDataProxy(
pickStructureService.getPickListByUser(user),
folderStructureService.getFolderListByUserAndParentFolderIsNotNull(user)
);
}

public Pick findPickById(Long pickId) {
return this.pickMap.get(pickId);
}

public Folder findFolderById(Long folderId) {
return this.folderMap.get(folderId);
}

public boolean containsPick(Long pickId) {
return this.pickMap.containsKey(pickId);
}

public boolean containsFolder(Long folderId) {
return this.folderMap.containsKey(folderId);
}

public int pickListSize() {
return this.pickMap.size();
}

public int folderListSize() {
return this.folderMap.size();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import org.springframework.stereotype.Component;

import kernel360.techpick.core.model.folder.StructureJson;
import kernel360.techpick.core.model.user.User;
import kernel360.techpick.feature.structure.exception.ApiStructureException;
import kernel360.techpick.feature.structure.repository.StructureJsonRepository;
import kernel360.techpick.feature.structure.service.Structure;
Expand All @@ -15,18 +16,15 @@ public class StructureJsonProvider {

private final StructureJsonRepository structureJsonRepository;

public StructureJson save(StructureJson structureJson) {
return structureJsonRepository.save(structureJson);
}

public StructureJson findByUserId(Long userId) {
return structureJsonRepository.findByUserId(userId)
public StructureJson findStructure(User user) {
return structureJsonRepository
.findByUserId(user.getId())
.orElseThrow(ApiStructureException::USER_STRUCTURE_JSON_NOT_FOUND);
}

public void updateStructureJsonByUserIdAndStructure(Long userId, Structure<ServerNode> structure) {
StructureJson structureJson = this.findByUserId(userId);
structureJson.updateStructure(structure.serialize());
this.save(structureJson);
public StructureJson updateStructureByUser(User user, Structure<ServerNode> structure) {
StructureJson structureJson = this.findStructure(user);
structureJson.updateStructure(structure);
return structureJsonRepository.save(structureJson);
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
package kernel360.techpick.feature.structure.model;

import org.springframework.stereotype.Component;

import kernel360.techpick.core.model.folder.StructureJson;
import kernel360.techpick.core.model.user.User;
import kernel360.techpick.feature.folder.service.dto.FolderDeleteDto;
import kernel360.techpick.feature.folder.service.dto.FolderMoveDto;
import kernel360.techpick.feature.pick.service.dto.PickDeleteDto;
Expand All @@ -13,55 +9,38 @@
import kernel360.techpick.feature.structure.service.dto.StructureMoveRequest;
import kernel360.techpick.feature.structure.service.node.client.ClientNode;
import kernel360.techpick.feature.structure.service.node.server.ServerNode;
import kernel360.techpick.feature.user.UserRepository;
import lombok.RequiredArgsConstructor;

@Component
@RequiredArgsConstructor
public class StructureMapper {

/**
* toClientNode 변환 과정에서 name이 설정됩니다.
*/
private final NameProvider nameProvider;
private final UserRepository userRepository;

public Structure<ClientNode> toClientStructure(Structure<ServerNode> serverStructure) {
public static Structure<ClientNode> toClientStructure(
Structure<ServerNode> serverStructure,
StructureDataProxy structureDataProxy
) {
return new Structure<>(

serverStructure.getRootFolder()
.stream()
.map(node -> node.toClientNode(nameProvider))
.map(node -> node.toClientNode(structureDataProxy))
.toList(),

serverStructure.getRecycleBinFolder()
.stream()
.map(node -> node.toClientNode(nameProvider))
.map(node -> node.toClientNode(structureDataProxy))
.toList()
);
}

public FolderMoveDto toFolderMoveDto(StructureMoveRequest request) {
return new FolderMoveDto(request.getUserId(), request.getTargetId(), request.getParentFolderId());
public static FolderMoveDto toFolderMoveDto(StructureMoveRequest request) {
return new FolderMoveDto(request.targetId(), request.parentFolderId());
}

public FolderDeleteDto toFolderDeleteDto(StructureDeleteRequest request) {
return new FolderDeleteDto(request.getUserId(), request.getTargetId());
public static FolderDeleteDto toFolderDeleteDto(StructureDeleteRequest request) {
return new FolderDeleteDto(request.targetId());
}

public PickMoveDto toPickMoveDto(StructureMoveRequest request) {
return new PickMoveDto(request.getTargetId(), request.getUserId(), request.getParentFolderId());
public static PickMoveDto toPickMoveDto(StructureMoveRequest request) {
return new PickMoveDto(request.targetId(), request.parentFolderId());
}

public PickDeleteDto toPickDeleteDto(StructureDeleteRequest request) {
return new PickDeleteDto(request.getTargetId(), request.getUserId());
}

public StructureJson toStructureJson(Long userId, Structure<ServerNode> structure) {

String json = structure.serialize();
User user = userRepository.findById(userId).get();

return StructureJson.create(json, user);
public static PickDeleteDto toPickDeleteDto(StructureDeleteRequest request) {
return new PickDeleteDto(request.targetId());
}
}
Loading