diff --git a/src/main/java/in/koreatech/koin/domain/timetableV2/dto/TimetableFrameCreateRequest.java b/src/main/java/in/koreatech/koin/domain/timetableV2/dto/TimetableFrameCreateRequest.java index cb23713c1..f52ed5046 100644 --- a/src/main/java/in/koreatech/koin/domain/timetableV2/dto/TimetableFrameCreateRequest.java +++ b/src/main/java/in/koreatech/koin/domain/timetableV2/dto/TimetableFrameCreateRequest.java @@ -1,17 +1,25 @@ package in.koreatech.koin.domain.timetableV2.dto; +import static com.fasterxml.jackson.databind.PropertyNamingStrategies.*; +import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.NOT_REQUIRED; import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; +import com.fasterxml.jackson.databind.annotation.JsonNaming; + import in.koreatech.koin.domain.timetable.model.Semester; import in.koreatech.koin.domain.timetableV2.model.TimetableFrame; import in.koreatech.koin.domain.user.model.User; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; +@JsonNaming(SnakeCaseStrategy.class) public record TimetableFrameCreateRequest( @Schema(description = "학기 정보", example = "20192", requiredMode = REQUIRED) @NotBlank(message = "학기 정보를 입력해주세요") - String semester + String semester, + + @Schema(description = "시간표 이름", example = "시간표1", requiredMode = NOT_REQUIRED) + String timetableName ) { public TimetableFrame toTimetablesFrame(User user, Semester semester, String name, boolean isMain) { return TimetableFrame.builder() diff --git a/src/main/java/in/koreatech/koin/domain/timetableV2/dto/TimetableFrameUpdateRequest.java b/src/main/java/in/koreatech/koin/domain/timetableV2/dto/TimetableFrameUpdateRequest.java index 12ece7a7f..1ef01920d 100644 --- a/src/main/java/in/koreatech/koin/domain/timetableV2/dto/TimetableFrameUpdateRequest.java +++ b/src/main/java/in/koreatech/koin/domain/timetableV2/dto/TimetableFrameUpdateRequest.java @@ -15,7 +15,7 @@ public record TimetableFrameUpdateRequest( @Schema(description = "시간표 이름", example = "시간표1", requiredMode = REQUIRED) @Size(max = 255, message = "시간표 이름의 최대 길이는 255자입니다.") @NotBlank(message = "시간표 이름을 입력해주세요.") - String name, + String timetableName, @Schema(description = "메인 시간표 여부", example = "false", requiredMode = REQUIRED) @NotNull(message = "시간표 메인 여부를 입력해주세요.") diff --git a/src/main/java/in/koreatech/koin/domain/timetableV2/dto/TimetableFrameUpdateResponse.java b/src/main/java/in/koreatech/koin/domain/timetableV2/dto/TimetableFrameUpdateResponse.java index 17245cad4..6a13cd730 100644 --- a/src/main/java/in/koreatech/koin/domain/timetableV2/dto/TimetableFrameUpdateResponse.java +++ b/src/main/java/in/koreatech/koin/domain/timetableV2/dto/TimetableFrameUpdateResponse.java @@ -14,7 +14,7 @@ public record TimetableFrameUpdateResponse( Integer id, @Schema(description = "시간표 이름", example = "시간표1", requiredMode = REQUIRED) - String name, + String timetableName, @Schema(description = "메인 시간표 여부", example = "false", requiredMode = REQUIRED) Boolean isMain diff --git a/src/main/java/in/koreatech/koin/domain/timetableV2/dto/TimetableLectureResponse.java b/src/main/java/in/koreatech/koin/domain/timetableV2/dto/TimetableLectureResponse.java index 29b2c3a9a..763fcac3a 100644 --- a/src/main/java/in/koreatech/koin/domain/timetableV2/dto/TimetableLectureResponse.java +++ b/src/main/java/in/koreatech/koin/domain/timetableV2/dto/TimetableLectureResponse.java @@ -33,6 +33,9 @@ public record InnerTimetableLectureResponse( @Schema(description = "시간표 id", example = "1", requiredMode = REQUIRED) Integer id, + @Schema(description = "강의 id", example = "1", requiredMode = NOT_REQUIRED) + Integer lectureId, + @Schema(description = "수강 정원", example = "38", requiredMode = NOT_REQUIRED) String regularNumber, @@ -81,6 +84,7 @@ public static List from(List ti null, null, null, + null, parseIntegerClassTimesFromString(timetableLecture.getClassTime()), timetableLecture.getClassPlace(), timetableLecture.getMemo(), @@ -94,6 +98,7 @@ public static List from(List ti } else { response = new InnerTimetableLectureResponse( timetableLecture.getId(), + timetableLecture.getLecture().getId(), timetableLecture.getLecture().getRegularNumber(), timetableLecture.getLecture().getCode(), timetableLecture.getLecture().getDesignScore(), diff --git a/src/main/java/in/koreatech/koin/domain/timetableV2/service/TimetableServiceV2.java b/src/main/java/in/koreatech/koin/domain/timetableV2/service/TimetableServiceV2.java index 5deb41316..9752c9570 100644 --- a/src/main/java/in/koreatech/koin/domain/timetableV2/service/TimetableServiceV2.java +++ b/src/main/java/in/koreatech/koin/domain/timetableV2/service/TimetableServiceV2.java @@ -47,8 +47,8 @@ public TimetableFrameResponse createTimetablesFrame(Integer userId, TimetableFra User user = userRepository.getById(userId); int currentFrameCount = timetableFrameRepositoryV2.countByUserIdAndSemesterId(userId, semester.getId()); boolean isMain = (currentFrameCount == 0); - - TimetableFrame timetableFrame = request.toTimetablesFrame(user, semester, "시간표" + (currentFrameCount+1), isMain); + String name = (request.timetableName() != null) ? request.timetableName() : "시간표" + (currentFrameCount + 1); + TimetableFrame timetableFrame = request.toTimetablesFrame(user, semester, name, isMain); TimetableFrame savedTimetableFrame = timetableFrameRepositoryV2.save(timetableFrame); return TimetableFrameResponse.from(savedTimetableFrame); } @@ -66,7 +66,7 @@ public TimetableFrameUpdateResponse updateTimetableFrame(Integer timetableFrameI throw new KoinIllegalArgumentException("메인 시간표는 필수입니다."); } } - timeTableFrame.updateTimetableFrame(semester, timetableFrameUpdateRequest.name(), isMain); + timeTableFrame.updateTimetableFrame(semester, timetableFrameUpdateRequest.timetableName(), isMain); return TimetableFrameUpdateResponse.from(timeTableFrame); } diff --git a/src/test/java/in/koreatech/koin/acceptance/TimetableV2ApiTest.java b/src/test/java/in/koreatech/koin/acceptance/TimetableV2ApiTest.java index f1ab28b8a..c10fed6f6 100644 --- a/src/test/java/in/koreatech/koin/acceptance/TimetableV2ApiTest.java +++ b/src/test/java/in/koreatech/koin/acceptance/TimetableV2ApiTest.java @@ -78,6 +78,34 @@ void setup() { """)); } + @Test + void 특정_시간표_frame을_이름을_지어_생성한다() throws Exception { + User user = userFixture.준호_학생().getUser(); + String token = userFixture.getToken(user); + Semester semester = semesterFixture.semester("20192"); + + mockMvc.perform( + post("/v2/timetables/frame") + .header("Authorization", "Bearer " + token) + .content(String.format(""" + { + "semester": "%s", + "timetable_name": "%s" + } + """, semester.getSemester(), "이름지어본시간표" + )) + .contentType(MediaType.APPLICATION_JSON) + ) + .andExpect(status().isOk()) + .andExpect(content().json(""" + { + "id": 1, + "timetable_name": "이름지어본시간표", + "is_main": true + } + """)); + } + @Test void 특정_시간표_frame을_수정한다() throws Exception { User user = userFixture.준호_학생().getUser(); @@ -91,7 +119,7 @@ void setup() { .header("Authorization", "Bearer " + token) .content(String.format(""" { - "name": "새로운 이름", + "timetable_name": "새로운 이름", "is_main": true } """ @@ -102,7 +130,7 @@ void setup() { .andExpect(content().json(""" { "id": 1, - "name": "새로운 이름", + "timetable_name": "새로운 이름", "is_main": true } """)); @@ -244,6 +272,7 @@ void setup() { "timetable": [ { "id": 1, + "lecture_id" : null, "regular_number": null, "code": null, "design_score": null, @@ -259,6 +288,7 @@ void setup() { }, { "id": 2, + "lecture_id" : null, "regular_number": null, "code": null, "design_score": null, @@ -324,6 +354,7 @@ void setup() { "timetable": [ { "id": 1, + "lecture_id" : null, "regular_number": null, "code": null, "design_score": null, @@ -339,6 +370,7 @@ void setup() { }, { "id": 2, + "lecture_id" : null, "regular_number": null, "code": null, "design_score": null, @@ -383,6 +415,7 @@ void setup() { "timetable": [ { "id" : 1, + "lecture_id" : 1, "regular_number": "25", "code": "ARB244", "design_score": "0", @@ -398,6 +431,7 @@ void setup() { }, { "id": 2, + "lecture_id": 2, "regular_number": "22", "code": "BSM590", "design_score": "0",