diff --git a/api/src/main/kotlin/handler/TimetableLectureHandler.kt b/api/src/main/kotlin/handler/TimetableLectureHandler.kt index 07e8296e..851297c4 100644 --- a/api/src/main/kotlin/handler/TimetableLectureHandler.kt +++ b/api/src/main/kotlin/handler/TimetableLectureHandler.kt @@ -10,6 +10,7 @@ import org.springframework.stereotype.Component import org.springframework.web.reactive.function.server.ServerRequest import org.springframework.web.reactive.function.server.ServerResponse import org.springframework.web.reactive.function.server.awaitBody +import org.springframework.web.reactive.function.server.awaitBodyOrNull @Component class TimetableLectureHandler( @@ -36,7 +37,7 @@ class TimetableLectureHandler( val userId = req.userId val timetableId = req.pathVariable("timetableId") val lectureId = req.pathVariable("lectureId") - val isForced = req.awaitBody().isForced + val isForced = req.awaitBodyOrNull()?.isForced ?: false timetableLectureService.addLecture( userId = userId, @@ -88,6 +89,6 @@ class TimetableLectureHandler( data class ForcedReq( @JsonProperty("is_forced") - val isForced: Boolean + val isForced: Boolean? ) } diff --git a/core/src/main/kotlin/timetables/data/TimetableLecture.kt b/core/src/main/kotlin/timetables/data/TimetableLecture.kt index a0850af5..5c59d6f6 100644 --- a/core/src/main/kotlin/timetables/data/TimetableLecture.kt +++ b/core/src/main/kotlin/timetables/data/TimetableLecture.kt @@ -5,6 +5,7 @@ import com.fasterxml.jackson.databind.PropertyNamingStrategies import com.fasterxml.jackson.databind.annotation.JsonNaming import com.wafflestudio.snu4t.lectures.data.ClassPlaceAndTime import com.wafflestudio.snu4t.lectures.data.Lecture +import org.bson.types.ObjectId import org.springframework.data.annotation.Id import org.springframework.data.mongodb.core.index.Indexed import org.springframework.data.mongodb.core.mapping.Field @@ -14,7 +15,7 @@ import org.springframework.data.mongodb.core.mapping.FieldType data class TimetableLecture( @Id @JsonProperty("_id") - var id: String? = null, + var id: String = ObjectId.get().toHexString(), @Field("academic_year") @JsonProperty("academic_year") var academicYear: String?, @@ -45,7 +46,6 @@ data class TimetableLecture( ) fun TimetableLecture(lecture: Lecture, colorIndex: Int) = TimetableLecture( - id = null, lectureId = lecture.id, academicYear = lecture.academicYear, category = lecture.category, diff --git a/core/src/main/kotlin/timetables/dto/request/TimetableLectureModifyLegacyRequestDto.kt b/core/src/main/kotlin/timetables/dto/request/TimetableLectureModifyLegacyRequestDto.kt index 28eba211..cabfc593 100644 --- a/core/src/main/kotlin/timetables/dto/request/TimetableLectureModifyLegacyRequestDto.kt +++ b/core/src/main/kotlin/timetables/dto/request/TimetableLectureModifyLegacyRequestDto.kt @@ -4,10 +4,12 @@ import com.fasterxml.jackson.annotation.JsonProperty import com.wafflestudio.snu4t.timetables.data.ColorSet data class TimetableLectureModifyLegacyRequestDto( - @JsonProperty("_id") - val id: String, @JsonProperty("course_title") - val courseTitle: String, + val courseTitle: String?, + @JsonProperty("academic_year") + val academicYear: String?, + val category: String?, + val classification: String?, val instructor: String?, val credit: Long?, @JsonProperty("class_time_json") @@ -15,5 +17,6 @@ data class TimetableLectureModifyLegacyRequestDto( val remark: String?, val color: ColorSet?, val colorIndex: Int?, + @JsonProperty("is_forced") val isForced: Boolean = false, ) diff --git a/core/src/main/kotlin/timetables/repository/TimetableCustomRepository.kt b/core/src/main/kotlin/timetables/repository/TimetableCustomRepository.kt index 64541aad..01f7c040 100644 --- a/core/src/main/kotlin/timetables/repository/TimetableCustomRepository.kt +++ b/core/src/main/kotlin/timetables/repository/TimetableCustomRepository.kt @@ -10,7 +10,9 @@ import com.wafflestudio.snu4t.timetables.data.TimetableLecture import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.reactive.asFlow import kotlinx.coroutines.reactor.awaitSingleOrNull +import org.bson.types.ObjectId import org.springframework.data.mapping.toDotPath +import org.springframework.data.mongodb.core.FindAndModifyOptions import org.springframework.data.mongodb.core.ReactiveMongoTemplate import org.springframework.data.mongodb.core.find import org.springframework.data.mongodb.core.findModifyAndAwait @@ -29,16 +31,11 @@ interface TimetableCustomRepository { lectureNumber: String ): Flow - suspend fun pushLecture(timeTableId: String, lecture: TimetableLecture): Timetable - suspend fun pullLecture(timeTableId: String, lectureId: String): Timetable - suspend fun pullLectures(timeTableId: String, lectureIds: List): Timetable + suspend fun pushLecture(timeTableId: String, timetableLecture: TimetableLecture): Timetable + suspend fun pullLecture(timeTableId: String, timetableLectureId: String): Timetable + suspend fun pullLectures(timeTableId: String, timetableLectureIds: List): Timetable suspend fun updateLecture(timeTableId: String, timetableLecture: TimetableLecture): Timetable - suspend fun findLatestChildTimetable( - userId: String, - year: Int, - semester: Semester, - title: String - ): Timetable? + suspend fun findLatestChildTimetable(userId: String, year: Int, semester: Semester, title: String): Timetable? } class TimetableCustomRepositoryImpl( @@ -72,35 +69,32 @@ class TimetableCustomRepositoryImpl( ).asFlow() } - override suspend fun pushLecture(timeTableId: String, lecture: TimetableLecture): Timetable = + override suspend fun pushLecture(timeTableId: String, timetableLecture: TimetableLecture): Timetable = reactiveMongoTemplate.update().matching(Timetable::id isEqualTo timeTableId).apply( - Update().push(Timetable::lectures.toDotPath(), lecture).currentDate(Timetable::updatedAt.toDotPath()), - ).findModifyAndAwait() - - override suspend fun pullLecture(timeTableId: String, lectureId: String): Timetable = + Update().push(Timetable::lectures.toDotPath(), timetableLecture) + .currentDate(Timetable::updatedAt.toDotPath()), + ).withOptions(FindAndModifyOptions.options().returnNew(true)).findModifyAndAwait() + override suspend fun pullLecture(timeTableId: String, timetableLectureId: String): Timetable = reactiveMongoTemplate.update().matching(Timetable::id isEqualTo timeTableId).apply( Update().pull( Timetable::lectures.toDotPath(), - Query.query(TimetableLecture::lectureId isEqualTo lectureId) + Query.query(TimetableLecture::id isEqualTo timetableLectureId) ).currentDate(Timetable::updatedAt.toDotPath()), - ).findModifyAndAwait() + ).withOptions(FindAndModifyOptions.options().returnNew(true)).findModifyAndAwait() - override suspend fun pullLectures(timeTableId: String, lectureIds: List): Timetable = + override suspend fun pullLectures(timeTableId: String, timetableLectureIds: List): Timetable = reactiveMongoTemplate.update().matching(Timetable::id isEqualTo timeTableId).apply( Update().pull( Timetable::lectures.toDotPath(), - Query.query(TimetableLecture::lectureId.inValues(lectureIds)) + Query.query(TimetableLecture::id.inValues(timetableLectureIds.map { ObjectId(it) })) ).currentDate(Timetable::updatedAt.toDotPath()), - ).findModifyAndAwait() + ).withOptions(FindAndModifyOptions.options().returnNew(true)).findModifyAndAwait() - override suspend fun updateLecture( - timeTableId: String, - timetableLecture: TimetableLecture - ): Timetable = - reactiveMongoTemplate.update() - .matching(Timetable::id.isEqualTo(timeTableId).and("lecture_list._id").isEqualTo(timetableLecture.id)).apply( - Update().apply { set("""lecture_list.$""", timetableLecture) } - ).findModifyAndAwait() + override suspend fun updateLecture(timeTableId: String, timetableLecture: TimetableLecture): Timetable = + reactiveMongoTemplate.update().matching( + Timetable::id.isEqualTo(timeTableId).and("lecture_list._id").isEqualTo(ObjectId(timetableLecture.id)) + ).apply(Update().apply { set("""lecture_list.$""", timetableLecture) }) + .withOptions(FindAndModifyOptions.options().returnNew(true)).findModifyAndAwait() override suspend fun findLatestChildTimetable( userId: String, diff --git a/core/src/main/kotlin/timetables/service/TimetableLectureService.kt b/core/src/main/kotlin/timetables/service/TimetableLectureService.kt index f55dcedf..badb4009 100644 --- a/core/src/main/kotlin/timetables/service/TimetableLectureService.kt +++ b/core/src/main/kotlin/timetables/service/TimetableLectureService.kt @@ -91,7 +91,10 @@ class TimetableLectureServiceImpl( val timetable = timetableRepository.findByUserIdAndId(userId, timetableId) ?: throw TimetableNotFoundException val timetableLecture = timetable.lectures.find { it.id == timetableLectureId } ?: throw LectureNotFoundException timetableLecture.apply { - courseTitle = modifyTimetableLectureRequestDto.courseTitle + courseTitle = modifyTimetableLectureRequestDto.courseTitle ?: courseTitle + academicYear = modifyTimetableLectureRequestDto.academicYear ?: academicYear + category = modifyTimetableLectureRequestDto.category ?: category + classification = modifyTimetableLectureRequestDto.classification ?: classification instructor = modifyTimetableLectureRequestDto.instructor ?: instructor credit = modifyTimetableLectureRequestDto.credit ?: credit remark = modifyTimetableLectureRequestDto.remark ?: remark @@ -125,7 +128,7 @@ class TimetableLectureServiceImpl( } overlappingLectures.isNotEmpty() && isForced -> { - timetableRepository.pullLectures(timetable.id!!, overlappingLectures.map { it.id!! }) + timetableRepository.pullLectures(timetable.id!!, overlappingLectures.map { it.id }) } } return timetableRepository.pushLecture(timetable.id!!, timetableLecture) diff --git a/core/src/main/resources/application-common.yml b/core/src/main/resources/application-common.yml index 6b0602d1..55868c55 100644 --- a/core/src/main/resources/application-common.yml +++ b/core/src/main/resources/application-common.yml @@ -11,7 +11,7 @@ spring: database: logging: level: - org.springframework.data.mongodb.core.MongoTemplate: DEBUG + org.springframework.data.mongodb.core.ReactiveMongoTemplate: DEBUG google: firebase: