-
Notifications
You must be signed in to change notification settings - Fork 0
[TEST] AI PR Review Test #135
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
base: develop
Are you sure you want to change the base?
Changes from all commits
455e732
cee9ccb
53e2fb5
4459482
d9d571e
11aa896
d375ae8
4156718
cc08270
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -23,7 +23,8 @@ public class RedisConfig { | |||||||||||||||
|
|
||||||||||||||||
| @Bean | ||||||||||||||||
| public RedisConnectionFactory redisConnectionFactory() { | ||||||||||||||||
| RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration(redisHost, redisPort); | ||||||||||||||||
| // RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration(redisHost, redisPort); | ||||||||||||||||
| RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration("localhost", 6379); | ||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Redis 연결 정보가 "localhost:6379"로 하드코딩되어 있습니다. 기존에
Suggested change
|
||||||||||||||||
| configuration.setPassword(redisPassword); | ||||||||||||||||
|
Comment on lines
+26
to
28
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Redis 호스트/포트를 하드코딩하면 환경설정이 무력화됩니다 현재 테스트 yml은 6378 포트를 가리키는데, 코드가 6379를 강제하면서 프로파일별 설정을 모두 무시합니다. 구성 분리 원칙에 어긋나고 테스트/운영에서 장애로 이어질 수 있습니다. 프로퍼티 주입을 다시 사용해 주세요. 적용 diff: -// RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration(redisHost, redisPort);
- RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration("localhost", 6379);
+ RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration(redisHost, redisPort);추가로 비밀번호가 비어있는 환경에서는 설정을 생략하는 것이 안전합니다. - configuration.setPassword(redisPassword);
+ if (redisPassword != null && !redisPassword.isBlank()) {
+ configuration.setPassword(redisPassword);
+ }📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||
|
|
||||||||||||||||
| return new LettuceConnectionFactory(configuration); | ||||||||||||||||
|
|
||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| package gdsc.binaryho.imhere.core.attendance.application; | ||
|
|
||
| import lombok.Getter; | ||
| import lombok.RequiredArgsConstructor; | ||
|
|
||
| @Getter | ||
| @RequiredArgsConstructor | ||
| public class AttendanceFailedEvent { | ||
|
|
||
| private final long lectureId; | ||
| private final long studentId; | ||
| private final Throwable exception; | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,15 +1,21 @@ | ||||||||||
| package gdsc.binaryho.imhere.core.attendance.application; | ||||||||||
|
|
||||||||||
| import static gdsc.binaryho.imhere.core.attendance.domain.AttendanceHistory.createAcceptedAttendanceHistory; | ||||||||||
| import static gdsc.binaryho.imhere.core.attendance.domain.AttendanceHistory.createAwaitAttendanceHistory; | ||||||||||
| import static gdsc.binaryho.imhere.core.attendance.domain.AttendanceHistory.createFailedAttendanceHistory; | ||||||||||
|
|
||||||||||
| import gdsc.binaryho.imhere.core.attendance.application.port.AttendanceHistoryCacheRepository; | ||||||||||
| import gdsc.binaryho.imhere.core.attendance.domain.AttendanceHistory; | ||||||||||
| import lombok.RequiredArgsConstructor; | ||||||||||
| import lombok.extern.log4j.Log4j2; | ||||||||||
| 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; | ||||||||||
|
|
||||||||||
| @Log4j2 | ||||||||||
| @Service | ||||||||||
| @RequiredArgsConstructor | ||||||||||
| public class AttendanceHistoryCacheService { | ||||||||||
|
|
@@ -19,13 +25,41 @@ public class AttendanceHistoryCacheService { | |||||||||
| @Async | ||||||||||
| @Transactional(propagation = Propagation.REQUIRES_NEW) | ||||||||||
| @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) | ||||||||||
| public void cache(StudentAttendedEvent event) { | ||||||||||
| public void cacheAttendanceHistory(AttendanceRequestedEvent event) { | ||||||||||
| long lectureId = event.getLectureId(); | ||||||||||
| long studentId = event.getStudentId(); | ||||||||||
| String timestamp = event.getTimestamp().toString(); | ||||||||||
|
|
||||||||||
| AttendanceHistory attendanceHistory = AttendanceHistory.of( | ||||||||||
| lectureId, studentId, timestamp); | ||||||||||
| AttendanceHistory attendanceHistory = createAwaitAttendanceHistory(lectureId, studentId); | ||||||||||
| attendanceHistoryCacheRepository.cache(attendanceHistory); | ||||||||||
| } | ||||||||||
|
|
||||||||||
| @Async | ||||||||||
| @Transactional(propagation = Propagation.REQUIRES_NEW) | ||||||||||
| @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) | ||||||||||
| public void saveAttendance(AttendanceSaveSucceedEvent event) { | ||||||||||
| long lectureId = event.getLectureId(); | ||||||||||
| long studentId = event.getStudentId(); | ||||||||||
|
|
||||||||||
| AttendanceHistory attendanceHistory = createAcceptedAttendanceHistory(lectureId, studentId); | ||||||||||
| attendanceHistoryCacheRepository.cache(attendanceHistory); | ||||||||||
| } | ||||||||||
|
|
||||||||||
| @Async | ||||||||||
| @Transactional(propagation = Propagation.REQUIRES_NEW) | ||||||||||
| @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) | ||||||||||
| public void saveAttendance(AttendanceFailedEvent event) { | ||||||||||
| long lectureId = event.getLectureId(); | ||||||||||
| long studentId = event.getStudentId(); | ||||||||||
|
|
||||||||||
| AttendanceHistory attendanceHistory = createFailedAttendanceHistory(lectureId, studentId); | ||||||||||
| attendanceHistoryCacheRepository.cache(attendanceHistory); | ||||||||||
| logAttendanceFailed(studentId, lectureId, event.getException()); | ||||||||||
| } | ||||||||||
|
|
||||||||||
| private void logAttendanceFailed(Long studentId, Long lectureId, RuntimeException exception) { | ||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
| String exceptionName = exception.getClass().getName(); | ||||||||||
| String exceptionMessage = exception.getMessage(); | ||||||||||
| log.info("[출석 실패] 학생 id {}, 수업 id : {}, 예외 이름 : {}, 예외 메시지 : {}", | ||||||||||
| studentId, lectureId, exceptionName, exceptionMessage); | ||||||||||
| } | ||||||||||
| } | ||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| package gdsc.binaryho.imhere.core.attendance.application; | ||
|
|
||
| import lombok.Getter; | ||
| import lombok.RequiredArgsConstructor; | ||
|
|
||
| @Getter | ||
| @RequiredArgsConstructor | ||
| public class AttendanceRequestedEvent { | ||
|
|
||
| private final long lectureId; | ||
| private final long studentId; | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,53 @@ | ||||||||||||||||
| package gdsc.binaryho.imhere.core.attendance.application; | ||||||||||||||||
|
|
||||||||||||||||
| import org.springframework.data.redis.core.RedisTemplate; | ||||||||||||||||
|
|
||||||||||||||||
| public enum AttendanceSaveRequestStatus { | ||||||||||||||||
|
|
||||||||||||||||
| /* | ||||||||||||||||
| * 또한, 설문을 통해 유저들이 요청한 “출석 성공 조회”기능을 위해, 출석 요청, 성공, 예외 발생시 이벤트를 발행해 캐싱한다. | ||||||||||||||||
| * 출석 성공은 다른 상태를 덮어 쓰고, 다른 상태는 출석 성공을 덮어 쓸 수 없다. | ||||||||||||||||
| * */ | ||||||||||||||||
|
|
||||||||||||||||
| PROCESSING { | ||||||||||||||||
| @Override | ||||||||||||||||
| public void cache( | ||||||||||||||||
| RedisTemplate<String, String> redisTemplate, String key, String value) { | ||||||||||||||||
| String savedValue = redisTemplate.opsForValue().getAndDelete(key); | ||||||||||||||||
| if (SUCCESS.name().equals(savedValue)) | ||||||||||||||||
| redisTemplate.opsForValue().set(key, value); | ||||||||||||||||
| } | ||||||||||||||||
| }, | ||||||||||||||||
|
|
||||||||||||||||
| SUCCESS { | ||||||||||||||||
| @Override | ||||||||||||||||
| public void cache( | ||||||||||||||||
| RedisTemplate<String, String> redisTemplate, String key, String value) { | ||||||||||||||||
| String savedValue = redisTemplate.opsForValue().getAndDelete(key); | ||||||||||||||||
| redisTemplate.opsForValue().set(key, savedValue, value); | ||||||||||||||||
| } | ||||||||||||||||
| }, | ||||||||||||||||
|
Comment on lines
+22
to
+29
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. SUCCESS 캐싱 로직이 잘못되었습니다 Line 27에서 의도에 따라 다음 중 하나로 수정하세요: @Override
public void cache(
RedisTemplate<String, String> redisTemplate, String key, String value) {
- String savedValue = redisTemplate.opsForValue().getAndDelete(key);
- redisTemplate.opsForValue().set(key, savedValue, value);
+ // 옵션 1: 기존 값과 관계없이 새 값으로 덮어쓰기
+ redisTemplate.opsForValue().set(key, value);
+
+ // 옵션 2: 기존 값이 SUCCESS가 아닐 때만 덮어쓰기
+ // String savedValue = redisTemplate.opsForValue().get(key);
+ // if (!SUCCESS.name().equals(savedValue)) {
+ // redisTemplate.opsForValue().set(key, value);
+ // }
}🤖 Prompt for AI Agents |
||||||||||||||||
|
|
||||||||||||||||
| FAILED { | ||||||||||||||||
| @Override | ||||||||||||||||
| public void cache( | ||||||||||||||||
| RedisTemplate<String, String> redisTemplate, String key, String value) { | ||||||||||||||||
| redisTemplate.opsForSet().add(key, value); | ||||||||||||||||
| } | ||||||||||||||||
| }, | ||||||||||||||||
|
|
||||||||||||||||
| NO_REQUEST { | ||||||||||||||||
| @Override | ||||||||||||||||
| public void cache( | ||||||||||||||||
| RedisTemplate<String, String> redisTemplate, String key, String value) { | ||||||||||||||||
| redisTemplate.opsForSet().add(key, value); | ||||||||||||||||
| } | ||||||||||||||||
| }; | ||||||||||||||||
|
|
||||||||||||||||
| public abstract void cache( | ||||||||||||||||
| RedisTemplate<String, String> redisTemplate, String key, String value); | ||||||||||||||||
|
|
||||||||||||||||
| public boolean canCache(String originalValue) { | ||||||||||||||||
| this.name() | ||||||||||||||||
| } | ||||||||||||||||
|
Comment on lines
+50
to
+52
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 컴파일 에러: 불완전한 메서드
public boolean canCache(String originalValue) {
- this.name()
+ // SUCCESS 상태는 다른 상태로 덮어쓸 수 없음
+ return !SUCCESS.name().equals(originalValue);
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||
| } | ||||||||||||||||
|
Comment on lines
+12
to
+53
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 enum 클래스에 몇 가지 심각한 문제가 있어 컴파일 및 실행이 불가능합니다.
전체적인 로직을 재검토하고 수정해야 합니다.
Comment on lines
+5
to
+53
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
이러한 문제들은 출석 상태 관리 로직의 오작동을 유발하므로 반드시 수정되어야 합니다. |
||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,32 @@ | ||||||||||||||
| 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.lecture.domain.Lecture; | ||||||||||||||
| import gdsc.binaryho.imhere.core.member.Member; | ||||||||||||||
| import lombok.RequiredArgsConstructor; | ||||||||||||||
| import lombok.extern.log4j.Log4j2; | ||||||||||||||
| import org.springframework.stereotype.Service; | ||||||||||||||
| import org.springframework.transaction.annotation.Transactional; | ||||||||||||||
|
|
||||||||||||||
| @Log4j2 | ||||||||||||||
| @Service | ||||||||||||||
| @RequiredArgsConstructor | ||||||||||||||
| public class AttendanceSaveService { | ||||||||||||||
|
|
||||||||||||||
| private final AttendanceRepository attendanceRepository; | ||||||||||||||
|
|
||||||||||||||
| @Transactional | ||||||||||||||
| public void save(Attendance attendance) { | ||||||||||||||
| attendanceRepository.save(attendance); | ||||||||||||||
| logAttendanceHistory(attendance); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| private void logAttendanceHistory(Attendance attendance) { | ||||||||||||||
| Member student = attendance.getStudent(); | ||||||||||||||
| Lecture lecture = attendance.getLecture(); | ||||||||||||||
| log.info("[출석 완료] {}({}) , 학생 : {} ({})", | ||||||||||||||
| lecture::getLectureName, lecture::getId, | ||||||||||||||
| student::getUnivId, student::getName); | ||||||||||||||
|
Comment on lines
+28
to
+30
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| package gdsc.binaryho.imhere.core.attendance.application; | ||
|
|
||
| import lombok.Getter; | ||
| import lombok.RequiredArgsConstructor; | ||
|
|
||
| @Getter | ||
| @RequiredArgsConstructor | ||
| public class AttendanceSaveSucceedEvent { | ||
|
|
||
| private final long lectureId; | ||
| private final long studentId; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Redis 연결 정보가 하드코딩되어 있습니다. 이전처럼
@Value어노테이션을 사용하여application.yml파일에서 설정을 읽어오도록 수정해야 합니다. 이렇게 하면 다른 환경(개발, 운영 등)에서 유연하게 설정을 변경할 수 있습니다.