Skip to content

Commit cd5ddd9

Browse files
authored
Merge pull request #44 from AI-Tutor-2024/feat/folder-note-struct
[FEAT] 폴더-노트 구조 정보 조회 기능 구현
2 parents 70d67f1 + 973ae83 commit cd5ddd9

File tree

4 files changed

+157
-4
lines changed

4 files changed

+157
-4
lines changed

src/main/java/com/example/ai_tutor/domain/folder/application/FolderService.java

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
package com.example.ai_tutor.domain.folder.application;
22
import com.example.ai_tutor.domain.folder.domain.Folder;
33
import com.example.ai_tutor.domain.folder.domain.repository.FolderRepository;
4+
import com.example.ai_tutor.domain.folder.dto.response.*;
45
import com.example.ai_tutor.domain.folder.dto.request.FolderCreateReq;
5-
import com.example.ai_tutor.domain.folder.dto.response.FolderListRes;
6-
import com.example.ai_tutor.domain.folder.dto.response.FolderNameListRes;
7-
import com.example.ai_tutor.domain.folder.dto.response.FolderResponse;
86
import com.example.ai_tutor.domain.note.dto.response.FolderInfoRes;
97
import com.example.ai_tutor.domain.professor.domain.Professor;
108
import com.example.ai_tutor.domain.professor.domain.repository.ProfessorRepository;
@@ -20,6 +18,7 @@
2018

2119
import java.util.List;
2220
import java.util.Objects;
21+
import java.util.stream.Collectors;
2322

2423
@Service
2524
@RequiredArgsConstructor
@@ -156,10 +155,57 @@ public ResponseEntity<?> deleteFolder(UserPrincipal userPrincipal, Long folderId
156155
.build();
157156

158157
return ResponseEntity.ok(apiResponse);
158+
159+
}
160+
161+
162+
public FolderAndNoteListRes getFolderAndNoteList(UserPrincipal userPrincipal) {
163+
validateUser(userPrincipal);
164+
Professor professor = validateProfessor(userPrincipal);
165+
166+
List<Folder> folders = professor.getFolders();
167+
List<FolderAndNoteDetailRes> folderNoteDetailList = mapToFolderAndNoteDetailResList(folders);
168+
169+
return FolderAndNoteListRes.builder()
170+
.folderCount(folderNoteDetailList.size())
171+
.folderNoteDetailList(folderNoteDetailList)
172+
.build();
159173
}
160174

175+
private List<FolderAndNoteDetailRes> mapToFolderAndNoteDetailResList(List<Folder> folders) {
176+
return folders.stream()
177+
.map(folder -> {
178+
List<FolderAndNoteDetailRes.NotesInFolderRes> notes = folder.getNotes().stream()
179+
.map(note -> FolderAndNoteDetailRes.NotesInFolderRes.from(
180+
note.getNoteId(),
181+
note.getTitle()
182+
))
183+
.collect(Collectors.toList());
184+
185+
return FolderAndNoteDetailRes.from(
186+
folder.getFolderId(),
187+
folder.getFolderName(),
188+
notes
189+
);
190+
})
191+
.collect(Collectors.toList());
192+
}
193+
194+
161195
private User getUser(UserPrincipal userPrincipal){
162196
return userRepository.findById(userPrincipal.getId()).orElseThrow(()
163197
-> new IllegalArgumentException("사용자를 찾을 수 없습니다."));
164198
}
199+
200+
private User validateUser(UserPrincipal userPrincipal) {
201+
return userRepository.findById(userPrincipal.getId())
202+
.orElseThrow(() -> new IllegalArgumentException("사용자를 찾을 수 없습니다."));
203+
}
204+
205+
private Professor validateProfessor(UserPrincipal userPrincipal) {
206+
return professorRepository.findByUser(userRepository.findById(userPrincipal.getId())
207+
.orElseThrow(() -> new IllegalArgumentException("사용자를 찾을 수 없습니다.")))
208+
.orElseThrow(() -> new IllegalArgumentException("교수를 찾을 수 없습니다."));
209+
}
210+
165211
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package com.example.ai_tutor.domain.folder.dto.response;
2+
3+
import io.swagger.v3.oas.annotations.media.Schema;
4+
import lombok.AllArgsConstructor;
5+
import lombok.Builder;
6+
import lombok.Getter;
7+
import lombok.NoArgsConstructor;
8+
9+
import java.util.List;
10+
@Getter
11+
@Builder
12+
@AllArgsConstructor
13+
@NoArgsConstructor
14+
public class FolderAndNoteDetailRes {
15+
16+
@Schema(example = "1", description = "폴더의 id입니다.")
17+
private Long folderId;
18+
19+
@Schema(example = "빅데이터기술특론", description = "폴더의 이름입니다.")
20+
private String folderName;
21+
22+
23+
@Schema(example = "2", description = "해당 폴더에 포함된 노트 개수입니다.")
24+
private int noteCount;
25+
26+
@Schema(description = "노트 목록입니다.")
27+
private List<NotesInFolderRes> notesInFolderRes;
28+
29+
public static FolderAndNoteDetailRes from(Long folderId, String folderName, List<NotesInFolderRes> notesInFolderRes) {
30+
return FolderAndNoteDetailRes.builder()
31+
.folderId(folderId)
32+
.folderName(folderName)
33+
.noteCount(notesInFolderRes != null ? notesInFolderRes.size() : 0)
34+
.notesInFolderRes(notesInFolderRes)
35+
.build();
36+
}
37+
38+
@Getter
39+
@Builder
40+
@AllArgsConstructor
41+
@NoArgsConstructor
42+
public static class NotesInFolderRes {
43+
44+
@Schema(example = "1", description = "노트의 id입니다.")
45+
private Long noteId;
46+
47+
@Schema(example = "빅데이터기술특론 노트", description = "노트의 이름입니다.")
48+
private String noteName;
49+
50+
public static NotesInFolderRes from(Long noteId, String noteName) {
51+
return NotesInFolderRes.builder()
52+
.noteId(noteId)
53+
.noteName(noteName)
54+
.build();
55+
}
56+
}
57+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.example.ai_tutor.domain.folder.dto.response;
2+
3+
import io.swagger.v3.oas.annotations.media.Schema;
4+
import lombok.AllArgsConstructor;
5+
import lombok.Builder;
6+
import lombok.Getter;
7+
import lombok.NoArgsConstructor;
8+
9+
import java.util.List;
10+
11+
@Getter
12+
@Builder
13+
@AllArgsConstructor
14+
@NoArgsConstructor
15+
public class FolderAndNoteListRes {
16+
@Schema(type = "Long", example = "3", description = "폴더의 개수입니다.")
17+
private int folderCount;
18+
19+
@Schema(type = "List", description = "폴더 목록입니다.")
20+
private List<FolderAndNoteDetailRes> folderNoteDetailList;
21+
22+
}
23+
24+

src/main/java/com/example/ai_tutor/domain/folder/presentation/FolderController.java

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
package com.example.ai_tutor.domain.folder.presentation;
22

33
import com.example.ai_tutor.domain.folder.application.FolderService;
4+
import com.example.ai_tutor.domain.folder.dto.response.FolderAndNoteListRes;
45
import com.example.ai_tutor.domain.folder.dto.request.FolderCreateReq;
56
import com.example.ai_tutor.domain.folder.dto.response.FolderListRes;
67
import com.example.ai_tutor.domain.folder.dto.response.FolderNameListRes;
78
import com.example.ai_tutor.domain.note.dto.response.FolderInfoRes;
8-
import com.example.ai_tutor.global.config.security.token.CurrentUser;
99
import com.example.ai_tutor.global.config.security.token.UserPrincipal;
1010
import com.example.ai_tutor.global.payload.ErrorResponse;
1111
import com.example.ai_tutor.global.payload.Message;
@@ -19,6 +19,7 @@
1919
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
2020
import lombok.RequiredArgsConstructor;
2121
import org.springframework.http.ResponseEntity;
22+
import org.springframework.security.access.prepost.PreAuthorize;
2223
import org.springframework.security.core.annotation.AuthenticationPrincipal;
2324
import org.springframework.web.bind.annotation.*;
2425
import io.swagger.v3.oas.annotations.tags.Tag;
@@ -111,4 +112,29 @@ public ResponseEntity<?> deleteFolder(
111112
return folderService.deleteFolder(userPrincipal, folderId);
112113
}
113114

115+
// 폴더-노트 구조 조회
116+
@PreAuthorize("isAuthenticated()")
117+
@Operation(summary = "폴더-노트 구조 조회 API",
118+
security = { @SecurityRequirement(name = "BearerAuth") },
119+
description = "폴더와 그 안에 있는 노트들의 구조를 조회하는 API입니다.")
120+
@ApiResponses(value = {
121+
@ApiResponse(responseCode = "200", description = "폴더-노트 구조 조회 성공", content = { @Content(mediaType = "application/json", schema = @Schema(implementation = FolderAndNoteListRes.class) ) } ),
122+
@ApiResponse(responseCode = "400", description = "폴더-노트 구조 조회 실패", content = { @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponse.class) ) } ),
123+
})
124+
@GetMapping("/notes")
125+
public ResponseEntity<com.example.ai_tutor.global.payload.ApiResponse> getFolderAndNoteList(
126+
@Parameter(description = "Access Token을 입력해주세요.", required = true) @AuthenticationPrincipal UserPrincipal userPrincipal
127+
) {
128+
FolderAndNoteListRes result = folderService.getFolderAndNoteList(userPrincipal);
129+
130+
com.example.ai_tutor.global.payload.ApiResponse<Object> apiResponse = com.example.ai_tutor.global.payload.ApiResponse.builder()
131+
.check(true)
132+
.information(result)
133+
.build();
134+
135+
return ResponseEntity.ok(apiResponse);
136+
137+
}
138+
139+
114140
}

0 commit comments

Comments
 (0)