[BE] SISC1-223 [FIX] 출석 세션 시간 변수 수정#140
Conversation
워크스루(Walkthrough)출석 관리 시스템의 필드명 및 데이터 구조를 일관성 있게 정규화한 변경사항입니다. 변경 사항(Changes)
예상 코드 리뷰 난이도🎯 3 (중간) | ⏱️ ~25분 추가 검토 대상:
관련 PR
제안된 검토자
시
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
backend/src/test/java/org/sejongisc/backend/attendance/controller/AttendanceRoundControllerTest.java (1)
268-311: 실패 시나리오 테스트에서 서비스 mock 응답 누락
checkInByRound_fail_upcoming과checkInByRound_fail_closed테스트에서attendanceService.checkInByRound()에 대한 mock 응답이 설정되지 않았습니다. 테스트 의도가 명확하지 않으며, 실패 응답을 검증하려면 적절한 mock 설정이 필요합니다.실패 시나리오를 정확히 테스트하려면 mock 응답을 추가하는 것이 좋습니다:
AttendanceCheckInResponse failResponse = AttendanceCheckInResponse.builder() .roundId(roundId) .success(false) .failureReason("출석 시간이 아닙니다") .build(); when(attendanceService.checkInByRound(any(), any())).thenReturn(failResponse);backend/src/main/java/org/sejongisc/backend/attendance/service/AttendanceSessionService.java (1)
26-27:attendanceRepository필드 제거 필요검증 결과,
attendanceRepository는 선언되기만 할 뿐 파일 내 어디에서도 사용되지 않습니다. 라인 26에서 제거하세요.
🧹 Nitpick comments (5)
backend/src/main/java/org/sejongisc/backend/attendance/service/AttendanceService.java (2)
146-150: 시간 조회 중복 및 잠재적 경계 조건 문제
LocalTime.now()와LocalDate.now()가 Line 147-148에서 조회되고, Line 231에서 다시LocalTime.now()를 조회합니다. 자정 경계에서 실행될 경우 날짜와 시간이 불일치할 수 있습니다.메서드 시작 시
LocalDateTime.now()를 한 번만 조회하여 사용하는 것을 권장합니다:+ LocalDateTime checkDateTime = LocalDateTime.now(); + java.time.LocalTime checkTime = checkDateTime.toLocalTime(); + java.time.LocalDate checkDate = checkDateTime.toLocalDate(); - java.time.LocalTime checkTime = java.time.LocalTime.now(); - java.time.LocalDate checkDate = java.time.LocalDate.now();
243-249:checkedAt타임스탬프 일관성 개선 권장Line 245에서
java.time.LocalDateTime.now()를 다시 호출합니다. Line 147-148에서 이미 조회한 시간 값을 재사용하면 로그와 저장된 값 간의 일관성을 유지할 수 있습니다.- .checkedAt(java.time.LocalDateTime.now()) + .checkedAt(LocalDateTime.of(checkDate, checkTime))backend/src/main/java/org/sejongisc/backend/attendance/service/AttendanceSessionService.java (2)
83-106:getAllSessions와getPublicSessions메서드가 동일합니다.두 메서드의 구현이 완전히 동일합니다. 의도적인 것이라면 하나의 private 메서드로 추출하여 재사용하거나,
getPublicSessions에서 필터링 조건이 필요한지 확인해 주세요.public List<AttendanceSessionResponse> getPublicSessions() { - List<AttendanceSession> sessions = attendanceSessionRepository.findAll(); - - return sessions.stream() - .sorted((a, b) -> b.getCreatedDate().compareTo(a.getCreatedDate())) - .map(this::convertToResponse) - .collect(Collectors.toList()); + return getAllSessions(); // 또는 공개 세션 필터링 로직 추가 }
113-122:findAll()사용 시 성능 고려세 개의 조회 메서드가 모두
findAll()을 사용하고 메모리에서 정렬/필터링합니다. 데이터가 증가하면 성능 이슈가 발생할 수 있습니다.Repository에 정렬/필터링이 포함된 쿼리 메서드를 추가하는 것을 고려해 주세요:
// AttendanceSessionRepository List<AttendanceSession> findByStatusOrderByCreatedDateDesc(SessionStatus status); List<AttendanceSession> findAllByOrderByCreatedDateDesc();backend/src/main/java/org/sejongisc/backend/attendance/entity/AttendanceSession.java (1)
28-35: 세션 기본 시간·기본 인정 시간 필드 추가 방향 타당
defaultStartTime·defaultAvailableMinutes로 세션의 기본 라운드 설정을 분리한 구조가 도메인 상 자연스럽습니다.
다만 비즈니스 상 항상 기본 인정 시간이 있어야 한다면defaultAvailableMinutes에도nullable = false제약을 두는 것을 고려해볼 수 있습니다.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (12)
backend/src/main/java/org/sejongisc/backend/attendance/controller/AttendanceRoundController.java(1 hunks)backend/src/main/java/org/sejongisc/backend/attendance/controller/AttendanceSessionController.java(2 hunks)backend/src/main/java/org/sejongisc/backend/attendance/dto/AttendanceRoundRequest.java(2 hunks)backend/src/main/java/org/sejongisc/backend/attendance/dto/AttendanceRoundResponse.java(2 hunks)backend/src/main/java/org/sejongisc/backend/attendance/dto/AttendanceSessionRequest.java(2 hunks)backend/src/main/java/org/sejongisc/backend/attendance/entity/Attendance.java(1 hunks)backend/src/main/java/org/sejongisc/backend/attendance/entity/AttendanceSession.java(3 hunks)backend/src/main/java/org/sejongisc/backend/attendance/service/AttendanceRoundService.java(2 hunks)backend/src/main/java/org/sejongisc/backend/attendance/service/AttendanceService.java(2 hunks)backend/src/main/java/org/sejongisc/backend/attendance/service/AttendanceSessionService.java(7 hunks)backend/src/test/java/org/sejongisc/backend/attendance/controller/AttendanceRoundControllerTest.java(8 hunks)backend/src/test/java/org/sejongisc/backend/attendance/service/AttendanceRoundServiceTest.java(8 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
backend/src/main/java/org/sejongisc/backend/attendance/service/AttendanceSessionService.java (2)
frontend/src/components/attendancemanage/SessionModifyModal.jsx (1)
defaultAvailableMinutes(29-31)frontend/src/contexts/AttendanceContext.jsx (1)
sessions(52-52)
backend/src/main/java/org/sejongisc/backend/attendance/entity/AttendanceSession.java (1)
frontend/src/components/attendancemanage/SessionModifyModal.jsx (1)
defaultAvailableMinutes(29-31)
🔇 Additional comments (27)
backend/src/main/java/org/sejongisc/backend/attendance/dto/AttendanceRoundResponse.java (2)
38-38: API 필드명 변경 확인 필요
roundDate에서date로 필드명이 변경되었습니다. 이는 JSON 응답의 필드명도 변경되어 API 소비자에게 영향을 줄 수 있는 breaking change입니다.프론트엔드 및 다른 API 클라이언트에서 이 변경 사항이 반영되었는지 확인이 필요합니다.
70-76: LGTM!엔티티에서 DTO로의 매핑이 올바르게 구현되었습니다.
round.getRoundDate()를date필드로 매핑하는 것이 적절합니다.backend/src/main/java/org/sejongisc/backend/attendance/controller/AttendanceRoundController.java (1)
58-60: LGTM!로그 메시지가 DTO 필드명 변경(
date,availableMinutes)에 맞게 올바르게 업데이트되었습니다.backend/src/main/java/org/sejongisc/backend/attendance/controller/AttendanceSessionController.java (2)
37-43: LGTM!API 문서가 새로운 필드 명칭(
기본 시작 시간,출석 인정 시간)에 맞게 올바르게 업데이트되었습니다. DTO 변경 사항과 일관성을 유지하고 있습니다.
135-142: LGTM!세션 수정 엔드포인트의 설명이 새로운 필드 용어와 일치하도록 업데이트되었습니다.
backend/src/main/java/org/sejongisc/backend/attendance/dto/AttendanceRoundRequest.java (2)
36-42:date필드에@NotNull검증 누락 확인 필요
startTime과availableMinutes필드에는@NotNull검증이 있지만,date필드에는 없습니다. 이것이 의도된 동작인지 확인이 필요합니다.만약 날짜가 필수값이라면 다음과 같이 추가해야 합니다:
+ @NotNull(message = "라운드 날짜는 필수입니다") @Schema( description = "라운드 진행 날짜 (YYYY-MM-DD 형식)", example = "2025-11-06", type = "string", format = "date" ) private LocalDate date;
53-63: LGTM!
availableMinutes필드의 검증 어노테이션(@NotNull,@Min,@Max)이 적절하게 설정되어 있습니다. 1분에서 120분 범위 제한이 합리적입니다.backend/src/main/java/org/sejongisc/backend/attendance/entity/Attendance.java (2)
71-86:isLate()로직 검증 필요현재 로직에서는
checkedAt.isAfter(roundStartTime)으로 지각 여부를 판단하고 있습니다. 이는 라운드 시작 시간 직후에 체크인해도 지각으로 처리됩니다.일반적인 출석 시스템에서는:
- 시작 시간 이후 일정 시간(예: 10분) 내 체크인 → 정시 출석
- 그 이후 체크인 → 지각
현재 비즈니스 요구사항이 "시작 시간 정각 이후는 모두 지각"인지 확인이 필요합니다. 만약 일정 유예 시간이 필요하다면 다음과 같이 수정할 수 있습니다:
// 예: 시작 시간 + 5분 이후 체크인 시 지각 처리 LocalDateTime lateThreshold = roundStartTime.plusMinutes(5); return checkedAt.isAfter(lateThreshold);
85-86: 라운드 없는 경우 지각 판단 불가 처리 확인라운드가 없는 세션의 경우
false를 반환하여 지각이 아닌 것으로 처리됩니다. 이 동작이 의도된 것인지, 아니면 세션 레벨의 시작 시간을 기준으로 판단해야 하는지 확인이 필요합니다.backend/src/main/java/org/sejongisc/backend/attendance/service/AttendanceService.java (1)
78-98: 라운드 기반 체크인 로직이 적절하게 구현되었습니다.활성 라운드를 찾는 스트림 필터 로직과 지각 판별 로직이 명확합니다.
roundStart.plusMinutes(5)를 사용한 지각 기준 시간 계산도 적절합니다.backend/src/main/java/org/sejongisc/backend/attendance/service/AttendanceRoundService.java (2)
37-61: DTO에서 엔티티로의 필드 매핑이 올바르게 구현되었습니다.요청 DTO의
date/availableMinutes필드를 엔티티의roundDate/allowedMinutes필드로 적절하게 매핑하고 있습니다. 로깅도 명확합니다.
110-123: 메서드 시그니처 검증 완료 - 문제 없음
updateRoundInfo메서드의 파라미터 순서와 타입이 모두 정확하게 일치합니다. 서비스에서 전달하는getDate(),getStartTime(),getAvailableMinutes()는 엔티티의updateRoundInfo(LocalDate newDate, LocalTime newStartTime, Integer newAllowedMinutes)메서드와 정확히 매칭되며, 업데이트되는 필드(roundDate,startTime,allowedMinutes)도 올바릅니다.backend/src/main/java/org/sejongisc/backend/attendance/dto/AttendanceSessionRequest.java (1)
30-50: 필드 리네이밍 및 타입 변경이 적절합니다.
startsAt(LocalDateTime) →defaultStartTime(LocalTime) 및windowSeconds→defaultAvailableMinutes변경이 "기본값" 개념에 더 적합합니다.@Future제약 조건 제거도 시간 템플릿 특성에 맞습니다.backend/src/test/java/org/sejongisc/backend/attendance/controller/AttendanceRoundControllerTest.java (1)
64-99: 테스트 케이스가 새로운 필드명으로 올바르게 업데이트되었습니다.요청/응답 빌더와 JSON path 검증이
date와availableMinutes로 일관되게 수정되었습니다.backend/src/main/java/org/sejongisc/backend/attendance/service/AttendanceSessionService.java (2)
35-64: 세션 생성 로직이 새로운 필드명으로 올바르게 업데이트되었습니다.
defaultStartTime과defaultAvailableMinutes필드가 적절하게 사용되고 있습니다.
287-295: 응답 변환 로직이 올바르게 업데이트되었습니다.
defaultStartTime과defaultAvailableMinutes필드가 응답 DTO에 정확하게 매핑되고 있습니다.backend/src/test/java/org/sejongisc/backend/attendance/service/AttendanceRoundServiceTest.java (8)
52-56: 라운드 생성 요청 필드명 변경 정합성 OK
AttendanceRoundRequest에date,availableMinutes를 사용하는 것으로 잘 맞춰져 있고, 엔티티/서비스 변경과도 일관성 있어 보입니다.
81-86: 생성 응답 검증에서getDate·getAvailableMinutes사용 적절응답 DTO의 필드 이름(
date,availableMinutes)에 맞게 어서션이 수정되어 기대값과 매핑이 명확합니다.
97-101: 세션 미존재 실패 케이스도 새 필드명으로 잘 반영예외 시나리오에서도 요청 DTO에
date,availableMinutes를 사용하도록 정리되어 있어 API 일관성이 유지됩니다.
133-137: 단건 조회 응답의getDate검증 적절기존
roundDate대신getDate()로 검증하도록 바뀐 부분이 DTO 변경과 정확히 일치합니다.
186-190: 세션별 라운드 리스트의 날짜 필드 검증도 새 규약에 맞음
responses.get(i).getDate()로 각 라운드 날짜를 확인하는 방식이 새 응답 스펙을 잘 따라가고 있습니다.
201-205: 수정 요청에서date·availableMinutes사용 적합라운드 수정 테스트도 요청 DTO 변경에 맞게 필드명을 교체해, 서비스 레이어와 규약이 일치합니다.
228-232: 수정 응답 어서션이 새 필드명과 잘 매칭됨수정 후 응답에서
getDate(),getAvailableMinutes()를 검증하는 부분이 의도한 도메인 모델을 잘 표현하고 있습니다.
287-290: 날짜 기준 조회 응답의getDate사용 적절특정 날짜 조회에서도
response.getDate()로 비교하는 것이 자연스럽고, 전체 API 변경 방향과도 일관됩니다.backend/src/main/java/org/sejongisc/backend/attendance/entity/AttendanceSession.java (3)
3-9: 세션 시간 표현을 위한JsonFormat·LocalTime도입 적절기본 시작 시간을
LocalTime으로 두고"HH:mm:ss"포맷을 명시한 것은 프론트와의 직렬화/역직렬화 명세를 명확히 해줘서 좋습니다.
60-67: 세션 상태 조회를getCurrentStatus로 노출한 점 합리적Javadoc으로 상태 의미를 명시하고, 실제 구현은 내부
status필드를 그대로 반환해 단순·명료합니다. 기존 호출처들이getCurrentStatus()를 사용한다면, 변경 부담 없이 읽기 좋은 형태입니다. (AI 요약 기준 이전 시간 기반 계산 로직을 걷어낸 것으로 보입니다.)
70-73: 체크인 가능 여부를 상태 기반으로 단순화한 점 좋음
SessionStatus.OPEN.equals(this.status)로만 체크인 가능 여부를 판단해, 시간 계산에 따른 복잡도를 없애고 상태 전환 로직으로 책임을 분리한 것이 명확합니다.status가 null이어도 NPE 없이 안전하게 false를 반환하는 점도 괜찮습니다.
Summary by CodeRabbit
릴리스 노트
문서
리팩토링
테스트
✏️ Tip: You can customize this high-level summary in your review settings.