Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโ€™ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor/#119/refactor responsibility driven design(swm 361) #128

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
c30e960
[SWM-361] Refactor : refactor package structure
D-w-nJ Oct 16, 2023
58f8e12
[SWM-361] Refactor : course enroll logic
D-w-nJ Oct 17, 2023
81779d6
[SWM-361] Refactor : refactor GET /lectures, lecture keyword search api
D-w-nJ Oct 17, 2023
ad7c944
[SWM-261] Refactor : refactor GET /course/{courseId}
D-w-nJ Oct 17, 2023
724b69f
[SWM-361] Refactor : refactor PUT /lectures/{courseVideoId}/time api
D-w-nJ Oct 20, 2023
8948921
hide api key
D-w-nJ Oct 20, 2023
bca8886
[SWM-261] Refactor : refactor GET /material/{courseVideoId} api
D-w-nJ Oct 20, 2023
4a0a8ad
[SWM-361] Refactor : material apis
D-w-nJ Oct 22, 2023
d3312ac
Refactor : material saver
D-w-nJ Oct 23, 2023
cfe518b
Fix : refresh token without access token
D-w-nJ Oct 23, 2023
bdc1fa9
[SWM-361] Refactor : refactor youtube api method name
D-w-nJ Oct 24, 2023
7440322
[SWM-361] Refactor : youtube service to mapper
D-w-nJ Oct 24, 2023
5cc1b18
[SWM-361] Refactor : remove EnrollCondition class
D-w-nJ Oct 25, 2023
5181d29
[SWM-361] fix : modify package name (lecture -> search)
Son-GyeongSik Oct 25, 2023
13190fb
[SWM-361] fix : relocation vo files (common -> each package)
Son-GyeongSik Oct 25, 2023
ca66c5a
[SWM-384] refactor : recommendation refactoring
Son-GyeongSik Oct 25, 2023
e0af386
[SWM-384] Refactor : 2 section recommendations refactor
Son-GyeongSik Oct 25, 2023
e59facc
[SWM-382] Refactor : my course room refactor
Son-GyeongSik Oct 25, 2023
53faf03
[SWM-380] Fix : fix course view duration bug
Son-GyeongSik Oct 25, 2023
958b579
Feat : add course not found case
D-w-nJ Oct 28, 2023
4d4f6bc
conflict resolved
D-w-nJ Oct 28, 2023
50c7ef3
Merge branch 'main' into refactor/#119/refactor-responsibility-drivenโ€ฆ
D-w-nJ Oct 28, 2023
432a25d
[SWM-383] Refactor : Dashboard refactor
Son-GyeongSik Oct 28, 2023
753587a
Fix : change expires_at field to access_expires_at in login response
D-w-nJ Oct 28, 2023
b17d96e
Merge branch 'refactor/#119/refactor-responsibility-driven-design(swmโ€ฆ
D-w-nJ Oct 28, 2023
f78f487
Fix : update videoEntity with youtube remaining summary id
D-w-nJ Oct 28, 2023
4936d70
Fix : handle error in grading multiple choice quiz
D-w-nJ Oct 28, 2023
e96d371
save course progress according to video count
D-w-nJ Oct 30, 2023
659d0fc
feat : course video progress to 100 in case fully watched
D-w-nJ Oct 30, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.m9d.sroom.gpt;
package com.m9d.sroom.ai;

import com.m9d.sroom.gpt.service.GPTService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
Expand All @@ -9,12 +8,12 @@
@Component
@Slf4j
@RequiredArgsConstructor
public class GPTScheduler {
public class AiScheduler {

private final GPTService gptService;
private final AiService aiService;

@Scheduled(cron = "0/5 * * * * *")
public void requestToGptRepeat() {
gptService.saveResultFromFastApi();
aiService.saveResultFromFastApi();
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package com.m9d.sroom.gpt.service;
package com.m9d.sroom.ai;

import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.m9d.sroom.gpt.vo.MaterialResultsVo;
import com.m9d.sroom.gpt.vo.MaterialVo;
import com.m9d.sroom.material.service.MaterialService;
import com.m9d.sroom.ai.vo.MaterialResultsVo;
import com.m9d.sroom.ai.vo.MaterialVo;
import com.m9d.sroom.material.MaterialSaver;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
Expand All @@ -19,7 +19,7 @@
@Service
@Slf4j
@RequiredArgsConstructor
public class GPTService {
public class AiService {

@Value("${ai.request-url}")
private String gptRequestUrl;
Expand All @@ -29,7 +29,7 @@ public class GPTService {

private final WebClient webClient;

private final MaterialService materialService;
private final MaterialSaver materialSaver;

private final Gson gson;

Expand Down Expand Up @@ -91,7 +91,7 @@ private MaterialVo getMaterialVo(String resultStr) throws NullPointerException {

public void saveResultEach(MaterialResultsVo materialVo) {
try {
materialService.saveMaterials(materialVo);
materialSaver.saveMaterials(materialVo);
} catch (Exception e) {
log.error("failed to save summary, quizzes from GPT. error message = {}", e.getMessage(), e);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.m9d.sroom.gpt.exception;
package com.m9d.sroom.ai.exception;

import com.m9d.sroom.global.error.NotMatchException;
import com.m9d.sroom.common.error.NotMatchException;

public class QuizTypeNotMatchException extends NotMatchException {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.m9d.sroom.gpt.exception;
package com.m9d.sroom.ai.exception;

public class ResultFromGptNotMatchException extends RuntimeException{
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.m9d.sroom.gpt.model;
package com.m9d.sroom.ai.model;

public enum MaterialVaildStatus {

Expand Down
44 changes: 44 additions & 0 deletions src/main/java/com/m9d/sroom/ai/vo/MaterialResultsVo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.m9d.sroom.ai.vo;

import com.m9d.sroom.quiz.vo.Quiz;
import com.m9d.sroom.summary.Summary;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;

import java.sql.Timestamp;
import java.util.List;
import java.util.stream.Collectors;

@Setter
@RequiredArgsConstructor
@Getter
public class MaterialResultsVo {

private String video_id;

private int is_valid;

private String summary;

private List<QuizVo> quizzes;

public String getVideoId() {
return video_id;
}

public int getIsValid() {
return is_valid;
}

public Summary getSummary(){
return new Summary(summary, new Timestamp(System.currentTimeMillis()), false);
}

public List<Quiz> getQuizList(){
return quizzes.stream()
.map(QuizVo::toQuiz)
.collect(Collectors.toList());
}

}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.m9d.sroom.gpt.vo;
package com.m9d.sroom.ai.vo;

import lombok.Data;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.m9d.sroom.gpt.vo;
package com.m9d.sroom.ai.vo;

import com.fasterxml.jackson.databind.JsonNode;
import com.m9d.sroom.quiz.vo.Quiz;
import com.m9d.sroom.quiz.QuizType;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
Expand Down Expand Up @@ -31,4 +32,8 @@ public String getQuizQuestion() {
public List<String> getOptions() {
return quiz_select_options;
}

public Quiz toQuiz() {
return Quiz.toInheritor(QuizType.fromValue(quiz_type), quiz_question, quiz_select_options, answer);
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.m9d.sroom.global;
package com.m9d.sroom.common;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
Expand Down
144 changes: 144 additions & 0 deletions src/main/java/com/m9d/sroom/common/LearningActivityUpdater.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
package com.m9d.sroom.common;

import com.m9d.sroom.common.entity.*;
import com.m9d.sroom.common.repository.course.CourseRepository;
import com.m9d.sroom.common.repository.coursedailylog.CourseDailyLogRepository;
import com.m9d.sroom.common.repository.coursevideo.CourseVideoRepository;
import com.m9d.sroom.common.repository.member.MemberRepository;
import com.m9d.sroom.common.repository.video.VideoRepository;
import com.m9d.sroom.course.CourseServiceHelper;
import com.m9d.sroom.course.vo.CourseVideo;
import com.m9d.sroom.search.dto.VideoCompletionStatus;
import org.springframework.stereotype.Service;

import java.sql.Date;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

import static com.m9d.sroom.search.constant.SearchConstant.LAST_VIEW_TIME_ADJUSTMENT_IN_SECONDS;

@Service
public class LearningActivityUpdater {
private final CourseRepository courseRepository;
private final CourseDailyLogRepository courseDailyLogRepository;
private final MemberRepository memberRepository;
private final CourseVideoRepository courseVideoRepository;
private final CourseServiceHelper courseServiceHelper;
private final VideoRepository videoRepository;

public LearningActivityUpdater(CourseRepository courseRepository, CourseDailyLogRepository courseDailyLogRepository,
MemberRepository memberRepository, CourseVideoRepository courseVideoRepository,
CourseServiceHelper courseServiceHelper, VideoRepository videoRepository) {
this.courseRepository = courseRepository;
this.courseDailyLogRepository = courseDailyLogRepository;
this.memberRepository = memberRepository;
this.courseVideoRepository = courseVideoRepository;
this.courseServiceHelper = courseServiceHelper;
this.videoRepository = videoRepository;
}

public void updateCourseDailyLog(Long memberId, Long courseId, VideoCompletionStatus status) {
Optional<CourseDailyLogEntity> dailyLogOptional = courseDailyLogRepository.findByCourseIdAndDate(courseId,
Date.valueOf(LocalDate.now()));
int learningTimeToAdd = Math.max(status.getTimeGap(), 0);
int lectureCountToAdd = status.isCompletedNow() ? 1 : 0;

if (dailyLogOptional.isEmpty()) {
CourseDailyLogEntity initialDailyLog = CourseDailyLogEntity.builder()
.memberId(memberId)
.courseId(courseId)
.dailyLogDate(Date.valueOf(LocalDate.now()))
.learningTime(learningTimeToAdd)
.quizCount(0)
.lectureCount(lectureCountToAdd)
.build();
courseDailyLogRepository.save(initialDailyLog);
} else {
CourseDailyLogEntity dailyLog = dailyLogOptional.get();
dailyLog.setLearningTime(dailyLog.getLearningTime() + learningTimeToAdd);
dailyLog.setLectureCount(dailyLog.getLectureCount() + lectureCountToAdd);
courseDailyLogRepository.updateById(dailyLog.getCourseDailyLogId(), dailyLog);
}
}

public void updateMemberLeaningTime(Long memberId, VideoCompletionStatus status) {
MemberEntity member = memberRepository.getById(memberId);
member.setTotalLearningTime(Math.max(status.getTimeGap(), 0) + member.getTotalLearningTime());
memberRepository.updateById(memberId, member);
}

public void updateCourseProgress(Long memberId, CourseEntity courseEntity) {
List<CourseVideo> courseVideoList = courseServiceHelper.getCourseVideoList(courseEntity.getCourseId());

if (courseVideoList.size() == 1) {
VideoEntity videoEntity = videoRepository.getById(courseVideoList.get(0).getVideoId());
courseEntity.setProgress(courseVideoList.get(0).getProgress(videoEntity.getDuration()));
} else if (courseVideoList.size() > 1) {
courseEntity.setProgress(courseEntity.toCourse(courseVideoList).getCompletionRatio());
} else {
courseEntity.setProgress(0);
}
courseRepository.updateById(courseEntity.getCourseId(), courseEntity);

if (courseEntity.getProgress() == 100) {
MemberEntity member = memberRepository.getById(memberId);
member.setCompletionRate(memberRepository.countCompletedCourseById(memberId) * 100
/ memberRepository.countCourseById(memberId));
memberRepository.updateById(memberId, member);
}
}

public void updateCourseVideoStatus(CourseVideoEntity courseVideoEntity, int viewDuration, boolean completed) {
courseVideoEntity.setMaxDuration(Math.max(viewDuration, courseVideoEntity.getMaxDuration()));
courseVideoEntity.setStartTime(viewDuration);
courseVideoEntity.setComplete(completed);
courseVideoEntity.setLastViewTime(new Timestamp(System.currentTimeMillis()));
courseVideoRepository.updateById(courseVideoEntity.getCourseVideoId(), courseVideoEntity);
}

public void updateCourseLastViewTime(CourseEntity courseEntity) {
courseEntity.setLastViewTime(new Timestamp(System.currentTimeMillis()));
courseRepository.updateById(courseEntity.getCourseId(), courseEntity);
}

public void updateLastViewVideoToNext(Long courseId, int videoIndex) {
Optional<CourseVideoEntity> courseVideoOptional = courseVideoRepository
.findByCourseIdAndPrevIndex(courseId, videoIndex);

if (courseVideoOptional.isPresent()) {
CourseVideoEntity courseVideo = courseVideoOptional.get();
courseVideo.setLastViewTime(
Timestamp.valueOf(LocalDateTime.now().plusSeconds(LAST_VIEW_TIME_ADJUSTMENT_IN_SECONDS)));
courseVideoRepository.updateById(courseVideo.getCourseVideoId(), courseVideo);
}
}

public void updateDailyLogQuizCount(Long memberId, Long courseId, int submittedQuizCount) {
Optional<CourseDailyLogEntity> courseDailyLogOptional = courseDailyLogRepository
.findByCourseIdAndDate(courseId, Date.valueOf(LocalDate.now()));
if (courseDailyLogOptional.isEmpty()) {
courseDailyLogRepository.save(CourseDailyLogEntity.builder()
.memberId(memberId)
.courseId(courseId)
.dailyLogDate(Date.valueOf(LocalDate.now()))
.learningTime(0)
.quizCount(submittedQuizCount)
.lectureCount(0)
.build());
} else {
CourseDailyLogEntity dailyLog = courseDailyLogOptional.get();
dailyLog.setQuizCount(dailyLog.getQuizCount() + submittedQuizCount);
courseDailyLogRepository.updateById(dailyLog.getCourseDailyLogId(), dailyLog);
}
}

public void updateMemberQuizCount(Long memberId, int submittedQuizCount, int submittedCorrectQuizCount) {
MemberEntity memberEntity = memberRepository.getById(memberId);
memberEntity.setTotalSolvedCount(submittedQuizCount + memberEntity.getTotalSolvedCount());
memberEntity.setTotalCorrectCount(submittedCorrectQuizCount + memberEntity.getTotalCorrectCount());
memberRepository.updateById(memberEntity.getMemberId(), memberEntity);
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.m9d.sroom.global.mapper;
package com.m9d.sroom.common.entity;

import lombok.Builder;
import lombok.Getter;
Expand All @@ -10,7 +10,7 @@
@Getter
@Setter
@Builder
public class CourseDailyLog {
public class CourseDailyLogEntity {

private Long courseDailyLogId;

Expand All @@ -26,8 +26,8 @@ public class CourseDailyLog {

private int lectureCount;

public static RowMapper<CourseDailyLog> getRowMapper() {
return ((rs, rowNum) -> CourseDailyLog.builder()
public static RowMapper<CourseDailyLogEntity> getRowMapper() {
return ((rs, rowNum) -> CourseDailyLogEntity.builder()
.courseDailyLogId(rs.getLong("course_daily_log_id"))
.memberId(rs.getLong("member_id"))
.courseId(rs.getLong("course_id"))
Expand Down
Loading
Loading