-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* refactor : AttendanceService의 public method들을 최상단으로 이동 (#117) * refactor : Attendance의 Member 이름을 student로 변경 (#117) * refactor : AttendanceResponse를 용도에 맞게 AttendancesResponse로 이름 변경 (#117) * feat : 학생의 출석 기록 확인 기능 구현 (#117) * refactor : 강사의 출석 정보 조회 응답에 강의 정보 제거 (#117) * refactor : 출석시 로깅 메서드 분리 (#117) * refactor : 유저 권한 확인 메서드가 검증할 권한을 입력 받도록 변경 (#117) * refactor : 강사용 출석 기록 확인 API에 강사 권한 검증 추가 (#117) * refactor : 학생의 최근 출석 정보를 가져오는 기능 구현 (#117) * chore : OpenLecture의 정적 팩터리 메서드 이름 변경 (#117) * refactor : key를 스스로 만드는 것을 강제하는 추상 클래스 CacheEntity 구현 (#117) * feat : 출석 기록을 저장하는 AttendanceHistory 구현 (#117) * feat :AttendanceHistory를 캐싱하는 AttendanceHistoryCacheRepository 구현 (#117) * feat :StudentAttendedEvent와 AttendanceHistory를 캐싱하는 Listener 구현 (#117) * refactor : RedisKeyPrefixes의 이름을 RedisKeyConstants로 변경 (#117) * feat : 학생 출석시 StudentAttendedEvent를 발행하는 기능 구현 (#117) * feat : Look Aside로 최근 출석 내역을 가져오는 getStudentRecentAttendance 구현 (#117) * refactor : AttendanceService를 학생, 강사를 기준으로 분리 (#117) * feat : 테스트를 위한 FakeAttendanceHistoryCacheRepository 구현 (#117) * refactor : 강사용 출석 정보 API에서 요청자가 강사인지 검증하는 메서드 추가 (#117) * test : 코드 변경에 맞춰 테스트 코드 변경 (#117) * chore : Attendance 객체 패키지 변경 (#117) * refactor : AttendanceController Endpoint Restful하게 변경 (#117) * refactor : 학생 출석 조회 API 구현 (#117) * test : 학생 출석 조회 API Controller Slice Test 구현 (#117) * chore : Response 객체 패키지 변경 (#117) * refactor : AttendanceHistory 객체 캐싱 시간 설정 (#117)
- Loading branch information
Showing
29 changed files
with
678 additions
and
235 deletions.
There are no files selected for viewing
3 changes: 2 additions & 1 deletion
3
...imhere/config/redis/RedisKeyPrefixes.java → ...mhere/config/redis/RedisKeyConstants.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,10 @@ | ||
package gdsc.binaryho.imhere.config.redis; | ||
|
||
public class RedisKeyPrefixes { | ||
public class RedisKeyConstants { | ||
|
||
public static final String ATTENDANCE_NUMBER_KEY_PREFIX = "$lecture_id$"; | ||
public static final String VERIFICATION_CODE_KEY_PREFIX = "$email$"; | ||
public static final String OPEN_LECTURE_KEY_PREFIX = "$open_lecture$"; | ||
public static final String LECTURE_STUDENT_KEY_PREFIX = "$lecture_student$"; | ||
public static final String ATTENDANCE_HISTORY_KEY_FORMAT = "$attendance_history$lecture_id:%d$student_id:%d$"; | ||
} |
31 changes: 31 additions & 0 deletions
31
.../java/gdsc/binaryho/imhere/core/attendance/application/AttendanceHistoryCacheService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package gdsc.binaryho.imhere.core.attendance.application; | ||
|
||
import gdsc.binaryho.imhere.core.attendance.application.port.AttendanceHistoryCacheRepository; | ||
import gdsc.binaryho.imhere.core.attendance.domain.AttendanceHistory; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.scheduling.annotation.Async; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Propagation; | ||
import org.springframework.transaction.annotation.Transactional; | ||
import org.springframework.transaction.event.TransactionPhase; | ||
import org.springframework.transaction.event.TransactionalEventListener; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
public class AttendanceHistoryCacheService { | ||
|
||
private final AttendanceHistoryCacheRepository attendanceHistoryCacheRepository; | ||
|
||
@Async | ||
@Transactional(propagation = Propagation.REQUIRES_NEW) | ||
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) | ||
public void cache(StudentAttendedEvent event) { | ||
long lectureId = event.getLectureId(); | ||
long studentId = event.getStudentId(); | ||
String timestamp = event.getTimestamp().toString(); | ||
|
||
AttendanceHistory attendanceHistory = AttendanceHistory.of( | ||
lectureId, studentId, timestamp); | ||
attendanceHistoryCacheRepository.cache(attendanceHistory); | ||
} | ||
} |
75 changes: 75 additions & 0 deletions
75
...main/java/gdsc/binaryho/imhere/core/attendance/application/LecturerAttendanceService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package gdsc.binaryho.imhere.core.attendance.application; | ||
|
||
|
||
import gdsc.binaryho.imhere.core.attendance.domain.Attendance; | ||
import gdsc.binaryho.imhere.core.attendance.infrastructure.AttendanceRepository; | ||
import gdsc.binaryho.imhere.core.attendance.model.response.LecturerAttendanceResponse; | ||
import gdsc.binaryho.imhere.core.lecture.domain.Lecture; | ||
import gdsc.binaryho.imhere.core.lecture.exception.LectureNotFoundException; | ||
import gdsc.binaryho.imhere.core.lecture.infrastructure.LectureRepository; | ||
import gdsc.binaryho.imhere.core.member.Role; | ||
import gdsc.binaryho.imhere.security.util.AuthenticationHelper; | ||
import gdsc.binaryho.imhere.util.SeoulDateTimeHolder; | ||
import java.time.LocalDateTime; | ||
import java.util.List; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.log4j.Log4j2; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
@Log4j2 | ||
@Service | ||
@RequiredArgsConstructor | ||
public class LecturerAttendanceService { | ||
|
||
private final AttendanceRepository attendanceRepository; | ||
private final LectureRepository lectureRepository; | ||
|
||
private final SeoulDateTimeHolder seoulDateTimeHolder; | ||
private final AuthenticationHelper authenticationHelper; | ||
|
||
@Transactional(readOnly = true) | ||
public LecturerAttendanceResponse getLecturerAttendances(Long lectureId) { | ||
authenticationHelper.verifyMemberHasRole(Role.LECTURER); | ||
|
||
List<Attendance> attendances = attendanceRepository.findAllByLectureId(lectureId); | ||
validateLectureOwnerRequested(lectureId, attendances); | ||
return new LecturerAttendanceResponse(attendances); | ||
} | ||
|
||
@Transactional(readOnly = true) | ||
public LecturerAttendanceResponse getLecturerDayAttendances(Long lectureId, Long milliseconds) { | ||
authenticationHelper.verifyMemberHasRole(Role.LECTURER); | ||
|
||
LocalDateTime timestamp = getTodaySeoulDateTime(milliseconds); | ||
List<Attendance> attendances = attendanceRepository | ||
.findByLectureIdAndTimestampBetween(lectureId, timestamp, timestamp.plusDays(1)); | ||
validateLectureOwnerRequested(lectureId, attendances); | ||
return new LecturerAttendanceResponse(attendances); | ||
} | ||
|
||
private LocalDateTime getTodaySeoulDateTime(Long milliseconds) { | ||
return seoulDateTimeHolder.from(milliseconds) | ||
.withHour(0).withMinute(0).withSecond(0); | ||
} | ||
|
||
private void validateLectureOwnerRequested(Long lectureId, List<Attendance> attendances) { | ||
attendances.stream() | ||
.findAny() | ||
.ifPresentOrElse( | ||
attendance -> authenticationHelper.verifyRequestMemberLogInMember(getLecturerId(attendance)), | ||
() -> authenticationHelper.verifyRequestMemberLogInMember(getLecturerId(lectureId)) | ||
); | ||
} | ||
|
||
private long getLecturerId(Attendance attendance) { | ||
Lecture lecture = attendance.getLecture(); | ||
return lecture.getMember().getId(); | ||
} | ||
|
||
private long getLecturerId(Long id) { | ||
Lecture lecture = lectureRepository.findById(id) | ||
.orElseThrow(() -> LectureNotFoundException.EXCEPTION); | ||
return lecture.getMember().getId(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
14 changes: 14 additions & 0 deletions
14
src/main/java/gdsc/binaryho/imhere/core/attendance/application/StudentAttendedEvent.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package gdsc.binaryho.imhere.core.attendance.application; | ||
|
||
import java.time.LocalDateTime; | ||
import lombok.Getter; | ||
import lombok.RequiredArgsConstructor; | ||
|
||
@Getter | ||
@RequiredArgsConstructor | ||
public class StudentAttendedEvent { | ||
|
||
private final long lectureId; | ||
private final long studentId; | ||
private final LocalDateTime timestamp; | ||
} |
11 changes: 11 additions & 0 deletions
11
...sc/binaryho/imhere/core/attendance/application/port/AttendanceHistoryCacheRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package gdsc.binaryho.imhere.core.attendance.application.port; | ||
|
||
import gdsc.binaryho.imhere.core.attendance.domain.AttendanceHistory; | ||
import java.util.List; | ||
|
||
public interface AttendanceHistoryCacheRepository { | ||
|
||
List<AttendanceHistory> findAllByLectureIdAndStudentId(long lectureId, long studentId); | ||
|
||
void cache(AttendanceHistory attendanceHistory); | ||
} |
Oops, something went wrong.