Skip to content

Commit bc0e9f2

Browse files
authored
강의 일기장 작성 대상 강의 api 추가 (#489)
1 parent e0c6acd commit bc0e9f2

File tree

8 files changed

+80
-26
lines changed

8 files changed

+80
-26
lines changed

api/src/main/kotlin/controller/DiaryController.kt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
package com.wafflestudio.snutt.controller
22

33
import com.wafflestudio.snutt.common.dto.OkResponse
4+
import com.wafflestudio.snutt.common.enums.Semester
5+
import com.wafflestudio.snutt.common.exception.DiaryTargetLectureNotFoundException
46
import com.wafflestudio.snutt.config.CurrentUser
57
import com.wafflestudio.snutt.diary.dto.DiaryDailyClassTypeDto
68
import com.wafflestudio.snutt.diary.dto.DiaryQuestionnaireDto
79
import com.wafflestudio.snutt.diary.dto.DiarySubmissionSummaryDto
810
import com.wafflestudio.snutt.diary.dto.DiarySubmissionsOfYearSemesterDto
11+
import com.wafflestudio.snutt.diary.dto.DiaryTargetLectureDto
912
import com.wafflestudio.snutt.diary.dto.request.DiaryQuestionnaireRequestDto
1013
import com.wafflestudio.snutt.diary.dto.request.DiarySubmissionRequestDto
1114
import com.wafflestudio.snutt.diary.service.DiaryService
@@ -18,6 +21,7 @@ import org.springframework.web.bind.annotation.PathVariable
1821
import org.springframework.web.bind.annotation.PostMapping
1922
import org.springframework.web.bind.annotation.RequestBody
2023
import org.springframework.web.bind.annotation.RequestMapping
24+
import org.springframework.web.bind.annotation.RequestParam
2125
import org.springframework.web.bind.annotation.RestController
2226

2327
@RestController
@@ -38,6 +42,17 @@ class DiaryController(
3842
diaryService.generateQuestionnaire(user.id!!, body.lectureId, body.dailyClassTypes),
3943
)
4044

45+
@GetMapping("/target")
46+
suspend fun getRandomTargetLecture(
47+
@CurrentUser user: User,
48+
@RequestParam year: Int,
49+
@RequestParam semester: Semester,
50+
): DiaryTargetLectureDto {
51+
val targetLecture =
52+
diaryService.getDiaryTargetLecture(user.id!!, year, semester, listOf()) ?: throw DiaryTargetLectureNotFoundException
53+
return DiaryTargetLectureDto(targetLecture)
54+
}
55+
4156
@GetMapping("/my")
4257
suspend fun getMySubmissions(
4358
@CurrentUser user: User,

core/src/main/kotlin/common/exception/ErrorType.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ enum class ErrorType(
8989
DIARY_QUESTION_NOT_FOUND(HttpStatus.NOT_FOUND, 40411, "강의 일기장 질문이 유효하지 않습니다", "강의 일기장 질문이 유효하지 않습니다"),
9090
DIARY_DAILY_CLASS_TYPE_NOT_FOUND(HttpStatus.NOT_FOUND, 40412, "강의 일기장 오늘 한 일이 유효하지 않습니다", "강의 일기장 오늘 한 일이 유효하지 않습니다"),
9191
DIARY_SUBMISSION_NOT_FOUND(HttpStatus.NOT_FOUND, 40412, "강의 일기장 기록이 유효하지 않습니다", "강의 일기장 기록이 유효하지 않습니다"),
92+
DIARY_TARGET_LECTURE_NOT_FOUND(HttpStatus.NOT_FOUND, 40413, "강의 일기장을 작성할 강의가 없습니다", "강의 일기장을 작성할 강의가 없습니다"),
9293
DUPLICATE_VACANCY_NOTIFICATION(HttpStatus.CONFLICT, 40900, "빈자리 알림 중복", "이미 빈자리 알림을 받고 있는 강좌입니다"),
9394
DUPLICATE_EMAIL(HttpStatus.CONFLICT, 40901, "이미 사용 중인 이메일입니다", "이미 사용 중인 이메일입니다", "회원가입 실패"),
9495
DUPLICATE_FRIEND(HttpStatus.CONFLICT, 40902, "이미 친구 관계이거나 친구 요청을 보냈습니다", "이미 친구 관계이거나 친구 요청을 보냈습니다"),

core/src/main/kotlin/common/exception/SnuttException.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ object DiaryDailyClassTypeNotFoundException : SnuttException(ErrorType.DIARY_DAI
139139

140140
object DiarySubmissionNotFoundException : SnuttException(ErrorType.DIARY_SUBMISSION_NOT_FOUND)
141141

142+
object DiaryTargetLectureNotFoundException : SnuttException(ErrorType.DIARY_TARGET_LECTURE_NOT_FOUND)
143+
142144
object UserNotFoundByNicknameException : SnuttException(ErrorType.USER_NOT_FOUND_BY_NICKNAME)
143145

144146
object ThemeNotFoundException : SnuttException(ErrorType.THEME_NOT_FOUND)
Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
package com.wafflestudio.snutt.diary.data
22

3+
import com.wafflestudio.snutt.timetables.data.TimetableLecture
4+
35
data class DiaryQuestionnaire(
4-
val lectureTitle: String,
6+
val courseTitle: String,
57
val questions: List<DiaryQuestion>,
6-
val nextLectureId: String?,
7-
val nextLectureTitle: String?,
8+
val nextLecture: TimetableLecture?,
89
)

core/src/main/kotlin/diary/dto/DiaryQuestionnaireDto.kt

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,17 @@ package com.wafflestudio.snutt.diary.dto
33
import com.wafflestudio.snutt.diary.data.DiaryQuestionnaire
44

55
data class DiaryQuestionnaireDto(
6-
val lectureTitle: String,
6+
val courseTitle: String,
77
val questions: List<DiaryQuestionDto>,
8-
val nextLectureId: String?,
9-
val nextLectureTitle: String?,
8+
val nextLecture: DiaryTargetLectureDto?,
109
)
1110

1211
fun DiaryQuestionnaireDto(diaryQuestionnaire: DiaryQuestionnaire) =
1312
DiaryQuestionnaireDto(
14-
lectureTitle = diaryQuestionnaire.lectureTitle,
13+
courseTitle = diaryQuestionnaire.courseTitle,
1514
questions =
1615
diaryQuestionnaire.questions.map {
1716
DiaryQuestionDto(it)
1817
},
19-
nextLectureId = diaryQuestionnaire.nextLectureId,
20-
nextLectureTitle = diaryQuestionnaire.nextLectureTitle,
18+
nextLecture = diaryQuestionnaire.nextLecture?.let { DiaryTargetLectureDto(it) },
2119
)

core/src/main/kotlin/diary/dto/DiarySubmissionSummaryDto.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ data class DiarySubmissionSummaryDto(
77
val id: String,
88
val lectureId: String,
99
val date: LocalDateTime,
10-
val lectureTitle: String,
10+
val courseTitle: String,
1111
val shortQuestionReplies: List<DiaryShortQuestionReply>,
1212
val comment: String,
1313
)
@@ -25,7 +25,7 @@ fun DiarySubmissionSummaryDto(
2525
id = submission.id!!,
2626
lectureId = submission.lectureId,
2727
date = submission.createdAt,
28-
lectureTitle = submission.courseTitle,
28+
courseTitle = submission.courseTitle,
2929
shortQuestionReplies = shortQuestionReplies,
3030
comment = submission.comment,
3131
)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.wafflestudio.snutt.diary.dto
2+
3+
import com.wafflestudio.snutt.timetables.data.TimetableLecture
4+
5+
data class DiaryTargetLectureDto(
6+
val lectureId: String,
7+
val courseTitle: String,
8+
)
9+
10+
fun DiaryTargetLectureDto(timetableLecture: TimetableLecture): DiaryTargetLectureDto =
11+
DiaryTargetLectureDto(
12+
lectureId = timetableLecture.lectureId!!,
13+
courseTitle = timetableLecture.courseTitle,
14+
)

core/src/main/kotlin/diary/service/DiaryService.kt

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.wafflestudio.snutt.diary.service
22

3+
import com.wafflestudio.snutt.common.enums.Semester
34
import com.wafflestudio.snutt.common.exception.DiaryDailyClassTypeNotFoundException
45
import com.wafflestudio.snutt.common.exception.DiaryQuestionNotFoundException
56
import com.wafflestudio.snutt.common.exception.DiarySubmissionNotFoundException
@@ -16,6 +17,7 @@ import com.wafflestudio.snutt.diary.repository.DiaryDailyClassTypeRepository
1617
import com.wafflestudio.snutt.diary.repository.DiaryQuestionRepository
1718
import com.wafflestudio.snutt.diary.repository.DiarySubmissionRepository
1819
import com.wafflestudio.snutt.lectures.service.LectureService
20+
import com.wafflestudio.snutt.timetables.data.TimetableLecture
1921
import com.wafflestudio.snutt.timetables.repository.TimetableRepository
2022
import kotlinx.coroutines.flow.toList
2123
import org.springframework.stereotype.Service
@@ -28,6 +30,13 @@ interface DiaryService {
2830
dailyClassTypeNames: List<String>,
2931
): DiaryQuestionnaire
3032

33+
suspend fun getDiaryTargetLecture(
34+
userId: String,
35+
year: Int,
36+
semester: Semester,
37+
idsToExclude: List<String>,
38+
): TimetableLecture?
39+
3140
suspend fun getActiveDailyClassTypes(): List<DiaryDailyClassType>
3241

3342
suspend fun getAllDailyClassTypes(): List<DiaryDailyClassType>
@@ -72,33 +81,47 @@ class DiaryServiceImpl(
7281
): DiaryQuestionnaire {
7382
val dailyClassTypeIds = diaryDailyClassTypeRepository.findAllByNameIn(dailyClassTypeNames).map { it.id!! }
7483
val availableQuestions = diaryQuestionRepository.findByTargetDailyClassTypeIdsInAndActiveTrue(dailyClassTypeIds)
84+
val questions =
85+
availableQuestions
86+
.shuffled()
87+
.take(3)
88+
7589
val lecture = lectureService.getByIdOrNull(lectureId) ?: throw LectureNotFoundException
90+
val nextLecture = getDiaryTargetLecture(userId, lecture.year, lecture.semester, listOf(lecture.id!!))
91+
92+
return DiaryQuestionnaire(
93+
courseTitle = lecture.courseTitle,
94+
questions = questions,
95+
nextLecture = nextLecture,
96+
)
97+
}
7698

99+
override suspend fun getDiaryTargetLecture(
100+
userId: String,
101+
year: Int,
102+
semester: Semester,
103+
idsToExclude: List<String>,
104+
): TimetableLecture? {
77105
val userTimetable =
78-
timetableRepository.findByUserIdAndYearAndSemesterAndIsPrimaryTrue(userId, lecture.year, lecture.semester)
106+
timetableRepository.findByUserIdAndYearAndSemesterAndIsPrimaryTrue(userId, year, semester)
79107
?: throw TimetableNotFoundException
80-
81108
val recentlySubmittedIds =
82109
diarySubmissionRepository
83110
.findAllByUserIdAndCreatedAtIsAfter(
84111
userId,
85112
LocalDateTime.now().minusDays(1),
86113
).map { it.lectureId }
87114
val nextLectureCandidates =
88-
userTimetable.lectures.filterNot { it.lectureId == lectureId || recentlySubmittedIds.contains(it.lectureId) }
89-
val nextLecture = nextLectureCandidates.randomOrNull()
90-
91-
val questions =
92-
availableQuestions
93-
.shuffled()
94-
.take(3)
115+
userTimetable.lectures
116+
.filterNot { it.lectureId == null }
117+
.filterNot { it.lectureId in idsToExclude }
118+
.let { candidates ->
119+
candidates
120+
.filterNot { recentlySubmittedIds.contains(it.lectureId) }
121+
.ifEmpty { candidates }
122+
}
95123

96-
return DiaryQuestionnaire(
97-
lectureTitle = lecture.courseTitle,
98-
questions = questions,
99-
nextLectureId = nextLecture?.lectureId,
100-
nextLectureTitle = nextLecture?.courseTitle,
101-
)
124+
return nextLectureCandidates.randomOrNull()
102125
}
103126

104127
override suspend fun getActiveDailyClassTypes(): List<DiaryDailyClassType> = diaryDailyClassTypeRepository.findAllByActiveTrue()

0 commit comments

Comments
 (0)