From e9965158e86a273dc7abb1313a72cb2733374175 Mon Sep 17 00:00:00 2001 From: seongjae6751 Date: Mon, 2 Dec 2024 23:22:11 +0900 Subject: [PATCH 1/4] =?UTF-8?q?feat:=20=EC=8B=9C=EA=B0=84=ED=91=9C=20?= =?UTF-8?q?=ED=94=84=EB=A0=88=EC=9E=84=20=ED=95=9C=EB=B2=88=EC=97=90=20?= =?UTF-8?q?=EB=8B=A4=20=EC=A1=B0=ED=9A=8C=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/TimetableApiV2.java | 2 +- .../controller/TimetableControllerV2.java | 6 +++--- .../TimetableFrameRepositoryV2.java | 2 ++ .../service/TimetableFrameService.java | 21 ++++++++++++++++++- 4 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/main/java/in/koreatech/koin/domain/timetableV2/controller/TimetableApiV2.java b/src/main/java/in/koreatech/koin/domain/timetableV2/controller/TimetableApiV2.java index 4f52486ba..a69669a87 100644 --- a/src/main/java/in/koreatech/koin/domain/timetableV2/controller/TimetableApiV2.java +++ b/src/main/java/in/koreatech/koin/domain/timetableV2/controller/TimetableApiV2.java @@ -77,7 +77,7 @@ ResponseEntity updateTimetableFrame( @Operation(summary = "시간표 프레임 조회") @SecurityRequirement(name = "Jwt Authentication") @GetMapping("/v2/timetables/frame") - ResponseEntity> getTimetablesFrame( + ResponseEntity getTimetablesFrame( @RequestParam(name = "semester") String semester, @Auth(permit = {STUDENT}) Integer userId ); diff --git a/src/main/java/in/koreatech/koin/domain/timetableV2/controller/TimetableControllerV2.java b/src/main/java/in/koreatech/koin/domain/timetableV2/controller/TimetableControllerV2.java index 6ae345064..987d9a040 100644 --- a/src/main/java/in/koreatech/koin/domain/timetableV2/controller/TimetableControllerV2.java +++ b/src/main/java/in/koreatech/koin/domain/timetableV2/controller/TimetableControllerV2.java @@ -54,11 +54,11 @@ public ResponseEntity updateTimetableFrame( } @GetMapping("/v2/timetables/frames") - public ResponseEntity> getTimetablesFrame( - @RequestParam(name = "semester") String semester, + public ResponseEntity getTimetablesFrame( + @RequestParam(name = "semester", required = false) String semester, @Auth(permit = {STUDENT}) Integer userId ) { - List response = frameServiceV2.getTimetablesFrame(userId, semester); + Object response = frameServiceV2.getTimetablesFrame(userId, semester); return ResponseEntity.ok(response); } diff --git a/src/main/java/in/koreatech/koin/domain/timetableV2/repository/TimetableFrameRepositoryV2.java b/src/main/java/in/koreatech/koin/domain/timetableV2/repository/TimetableFrameRepositoryV2.java index b696e4313..456e4c05b 100644 --- a/src/main/java/in/koreatech/koin/domain/timetableV2/repository/TimetableFrameRepositoryV2.java +++ b/src/main/java/in/koreatech/koin/domain/timetableV2/repository/TimetableFrameRepositoryV2.java @@ -82,4 +82,6 @@ SELECT COUNT(t) FROM TimetableFrame t void deleteAllByUser(User user); void deleteAllByUserAndSemester(User user, Semester semester); + + List findAllByUserId(Integer userId); } diff --git a/src/main/java/in/koreatech/koin/domain/timetableV2/service/TimetableFrameService.java b/src/main/java/in/koreatech/koin/domain/timetableV2/service/TimetableFrameService.java index 028adb70e..8b604d5a6 100644 --- a/src/main/java/in/koreatech/koin/domain/timetableV2/service/TimetableFrameService.java +++ b/src/main/java/in/koreatech/koin/domain/timetableV2/service/TimetableFrameService.java @@ -4,7 +4,9 @@ import static in.koreatech.koin.domain.timetableV2.validation.TimetableFrameValidate.validateUserAuthorization; import java.util.List; +import java.util.Map; import java.util.Objects; +import java.util.stream.Collectors; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -57,13 +59,30 @@ public TimetableFrameUpdateResponse updateTimetableFrame( return timetableFrameUpdater.updateTimetableFrame(frame, userId, request.timetableName(), request.isMain()); } - public List getTimetablesFrame(Integer userId, String semesterRequest) { + public Object getTimetablesFrame(Integer userId, String semesterRequest) { + if (semesterRequest == null) { + return getAllTimetablesFrame(userId); + } + Semester semester = semesterRepositoryV2.getBySemester(semesterRequest); return timetableFrameRepositoryV2.findAllByUserIdAndSemesterId(userId, semester.getId()).stream() .map(TimetableFrameResponse::from) .toList(); } + @Transactional(readOnly = true) + public Map>> getAllTimetablesFrame(Integer userId) { + List timetableFrames = timetableFrameRepositoryV2.findAllByUserId(userId); + + Map> groupedBySemester = timetableFrames.stream() + .collect(Collectors.groupingBy( + frame -> frame.getSemester().getSemester(), + Collectors.mapping(TimetableFrameResponse::from, Collectors.toList()) + )); + + return Map.of("semesters", groupedBySemester); + } + @Transactional public void deleteAllTimetablesFrame(Integer userId, String semester) { User user = userRepository.getById(userId); From 2d10096cc41acf3c142471472617ae0454c9c9ba Mon Sep 17 00:00:00 2001 From: seongjae6751 Date: Mon, 2 Dec 2024 23:25:31 +0900 Subject: [PATCH 2/4] =?UTF-8?q?test:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../acceptance/TimetableFrameApiTest.java | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/src/test/java/in/koreatech/koin/acceptance/TimetableFrameApiTest.java b/src/test/java/in/koreatech/koin/acceptance/TimetableFrameApiTest.java index bae5f276f..769d1d7ba 100644 --- a/src/test/java/in/koreatech/koin/acceptance/TimetableFrameApiTest.java +++ b/src/test/java/in/koreatech/koin/acceptance/TimetableFrameApiTest.java @@ -234,4 +234,59 @@ void setup() { assertThat(timetableFrameRepositoryV2.findById(frame2.getId())).isNotPresent(); assertThat(timetableFrameRepositoryV2.findById(frame3.getId())).isNotPresent(); } + + @Test + void 모든_학기의_시간표_프레임을_조회한다() throws Exception { + Semester semester1 = semesterFixture.semester("20241"); + Semester semester2 = semesterFixture.semester("20242"); + + timetableV2Fixture.시간표1(user, semester1); + timetableV2Fixture.시간표2(user, semester1); + + timetableV2Fixture.시간표1(user, semester2); + timetableV2Fixture.시간표2(user, semester2); + timetableV2Fixture.시간표3(user, semester2); + + mockMvc.perform( + get("/v2/timetables/frames") + .header("Authorization", "Bearer " + token) + .contentType(MediaType.APPLICATION_JSON) + ) + .andExpect(status().isOk()) + .andExpect(content().json(""" + { + "semesters": { + "20241": [ + { + "id": 1, + "timetable_name": "시간표1", + "is_main": true + }, + { + "id": 2, + "timetable_name": "시간표2", + "is_main": false + } + ], + "20242": [ + { + "id": 3, + "timetable_name": "시간표1", + "is_main": true + }, + { + "id": 4, + "timetable_name": "시간표2", + "is_main": false + }, + { + "id": 5, + "timetable_name": "시간표3", + "is_main": false + } + ] + } + } + """)); + } } From 315c8a929797bf0c73299a00a1843cad7df55ffb Mon Sep 17 00:00:00 2001 From: seongjae6751 Date: Tue, 3 Dec 2024 14:30:28 +0900 Subject: [PATCH 3/4] =?UTF-8?q?chore:=20=EB=A6=AC=EB=B7=B0=EB=B0=98?= =?UTF-8?q?=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../koin/domain/timetableV2/controller/TimetableApiV2.java | 4 ++-- .../domain/timetableV2/service/TimetableFrameService.java | 3 --- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/main/java/in/koreatech/koin/domain/timetableV2/controller/TimetableApiV2.java b/src/main/java/in/koreatech/koin/domain/timetableV2/controller/TimetableApiV2.java index a69669a87..8be8c7a84 100644 --- a/src/main/java/in/koreatech/koin/domain/timetableV2/controller/TimetableApiV2.java +++ b/src/main/java/in/koreatech/koin/domain/timetableV2/controller/TimetableApiV2.java @@ -76,9 +76,9 @@ ResponseEntity updateTimetableFrame( ) @Operation(summary = "시간표 프레임 조회") @SecurityRequirement(name = "Jwt Authentication") - @GetMapping("/v2/timetables/frame") + @GetMapping("/v2/timetables/frames") ResponseEntity getTimetablesFrame( - @RequestParam(name = "semester") String semester, + @RequestParam(name = "semester", required = false) String semester, @Auth(permit = {STUDENT}) Integer userId ); diff --git a/src/main/java/in/koreatech/koin/domain/timetableV2/service/TimetableFrameService.java b/src/main/java/in/koreatech/koin/domain/timetableV2/service/TimetableFrameService.java index 8b604d5a6..ea0bd3c8e 100644 --- a/src/main/java/in/koreatech/koin/domain/timetableV2/service/TimetableFrameService.java +++ b/src/main/java/in/koreatech/koin/domain/timetableV2/service/TimetableFrameService.java @@ -5,7 +5,6 @@ import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.stream.Collectors; import org.springframework.stereotype.Service; @@ -23,7 +22,6 @@ import in.koreatech.koin.domain.timetableV2.factory.TimetableFrameUpdater; import in.koreatech.koin.domain.user.model.User; import in.koreatech.koin.domain.user.repository.UserRepository; -import in.koreatech.koin.global.auth.exception.AuthorizationException; import in.koreatech.koin.global.concurrent.ConcurrencyGuard; import lombok.RequiredArgsConstructor; @@ -70,7 +68,6 @@ public Object getTimetablesFrame(Integer userId, String semesterRequest) { .toList(); } - @Transactional(readOnly = true) public Map>> getAllTimetablesFrame(Integer userId) { List timetableFrames = timetableFrameRepositoryV2.findAllByUserId(userId); From 164bda7f3bcd267770c396f0f558879a644401c2 Mon Sep 17 00:00:00 2001 From: seongjae6751 Date: Wed, 4 Dec 2024 13:38:48 +0900 Subject: [PATCH 4/4] =?UTF-8?q?chore:=20dto=EB=A1=9C=20=EB=B3=80=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/response/TimetableFramesResponse.java | 42 +++++++++++++++++++ .../service/TimetableFrameService.java | 12 ++---- 2 files changed, 45 insertions(+), 9 deletions(-) create mode 100644 src/main/java/in/koreatech/koin/domain/timetableV2/dto/response/TimetableFramesResponse.java diff --git a/src/main/java/in/koreatech/koin/domain/timetableV2/dto/response/TimetableFramesResponse.java b/src/main/java/in/koreatech/koin/domain/timetableV2/dto/response/TimetableFramesResponse.java new file mode 100644 index 000000000..4e382e971 --- /dev/null +++ b/src/main/java/in/koreatech/koin/domain/timetableV2/dto/response/TimetableFramesResponse.java @@ -0,0 +1,42 @@ +package in.koreatech.koin.domain.timetableV2.dto.response; + +import static com.fasterxml.jackson.databind.PropertyNamingStrategies.*; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import com.fasterxml.jackson.databind.annotation.JsonNaming; + +import in.koreatech.koin.domain.timetableV2.model.TimetableFrame; +import io.swagger.v3.oas.annotations.media.Schema; + +@JsonNaming(SnakeCaseStrategy.class) +public record TimetableFramesResponse( + @Schema(description = "학기별 시간표 프레임", example = """ + { + "20241": [ + { + "id": 1, + "timetable_name": "시간표1", + "is_main": true + }, + { + "id": 2, + "timetable_name": "시간표2", + "is_main": false + } + ] + } + """, requiredMode = Schema.RequiredMode.REQUIRED) + Map> semesters +) { + public static TimetableFramesResponse from(List timetableFrames) { + Map> groupedBySemester = timetableFrames.stream() + .collect(Collectors.groupingBy( + frame -> frame.getSemester().getSemester(), + Collectors.mapping(TimetableFrameResponse::from, Collectors.toList()) + )); + return new TimetableFramesResponse(groupedBySemester); + } +} diff --git a/src/main/java/in/koreatech/koin/domain/timetableV2/service/TimetableFrameService.java b/src/main/java/in/koreatech/koin/domain/timetableV2/service/TimetableFrameService.java index ea0bd3c8e..060c05ab9 100644 --- a/src/main/java/in/koreatech/koin/domain/timetableV2/service/TimetableFrameService.java +++ b/src/main/java/in/koreatech/koin/domain/timetableV2/service/TimetableFrameService.java @@ -15,6 +15,7 @@ import in.koreatech.koin.domain.timetableV2.dto.request.TimetableFrameUpdateRequest; import in.koreatech.koin.domain.timetableV2.dto.response.TimetableFrameResponse; import in.koreatech.koin.domain.timetableV2.dto.response.TimetableFrameUpdateResponse; +import in.koreatech.koin.domain.timetableV2.dto.response.TimetableFramesResponse; import in.koreatech.koin.domain.timetableV2.model.TimetableFrame; import in.koreatech.koin.domain.timetableV2.repository.SemesterRepositoryV2; import in.koreatech.koin.domain.timetableV2.repository.TimetableFrameRepositoryV2; @@ -68,16 +69,9 @@ public Object getTimetablesFrame(Integer userId, String semesterRequest) { .toList(); } - public Map>> getAllTimetablesFrame(Integer userId) { + public TimetableFramesResponse getAllTimetablesFrame(Integer userId) { List timetableFrames = timetableFrameRepositoryV2.findAllByUserId(userId); - - Map> groupedBySemester = timetableFrames.stream() - .collect(Collectors.groupingBy( - frame -> frame.getSemester().getSemester(), - Collectors.mapping(TimetableFrameResponse::from, Collectors.toList()) - )); - - return Map.of("semesters", groupedBySemester); + return TimetableFramesResponse.from(timetableFrames); } @Transactional