Skip to content

[BE] SISC1-225 [FEAT] session user 구현#148

Merged
Kosw6 merged 7 commits intomainfrom
SISC1-225-BE-SessionUser-구현
Nov 27, 2025

Hidden character warning

The head ref may contain hidden characters: "SISC1-225-BE-SessionUser-\uad6c\ud604"
Merged

[BE] SISC1-225 [FEAT] session user 구현#148
Kosw6 merged 7 commits intomainfrom
SISC1-225-BE-SessionUser-구현

Conversation

@ochanhyeok
Copy link
Contributor

@ochanhyeok ochanhyeok commented Nov 27, 2025

Summary by CodeRabbit

  • New Features

    • 관리자가 라운드별로 사용자의 출석 상태를 수정할 수 있는 관리자 전용 API 추가(사유 포함).
    • 세션에 사용자를 추가·제거·조회하는 관리자 전용 API 추가.
    • 사용자가 세션에 추가될 때 과거 라운드에 대한 출석 레코드를 자동 생성하는 흐름 추가.
    • 출석 세션 위치 정보에 반경(radiusMeters) 필드 추가.
  • Chores

    • 불필요한 임포트 정리.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Nov 27, 2025

Walkthrough

세션 사용자 관리(추가/제거/조회)와 라운드별 참석 상태 업데이트 기능을 추가하고, 여러 DTO·엔티티·저장소·서비스·컨트롤러를 도입했으며 일부 불필요한 임포트를 제거했습니다. (요약 50단어 이내)

Changes

Cohort / File(s) 변경 요약
컨트롤러 정리
backend/src/main/java/org/sejongisc/backend/attendance/controller/AttendanceController.java
사용하지 않는 임포트 제거
라운드 참석 상태 엔드포인트
backend/src/main/java/org/sejongisc/backend/attendance/controller/AttendanceRoundController.java
관리자 권한(PRESIDENT/VICE_PRESIDENT) 요구 PUT /api/attendance/rounds/{roundId}/attendances/{userId} 추가; DTO 임포트 와일드카드로 통합; 요청/응답 로그 추가
세션 사용자 관리 엔드포인트
backend/src/main/java/org/sejongisc/backend/attendance/controller/AttendanceSessionController.java
SessionUserService 주입; POST/DELETE/GET /{sessionId}/users (관리자 권한) 추가 및 로그/응답 상태 적용
응답 DTO 확장
backend/src/main/java/org/sejongisc/backend/attendance/dto/AttendanceSessionResponse.java
LocationInfo 내부에 radiusMeters 필드 추가
요청 DTO 추가
backend/src/main/java/org/sejongisc/backend/attendance/dto/AttendanceStatusUpdateRequest.java, .../SessionUserRequest.java
참석 상태 업데이트용(status,reason) 및 세션 사용자 추가용(userId) DTO 추가 (검증 포함)
응답 DTO 추가
backend/src/main/java/org/sejongisc/backend/attendance/dto/RoundAttendanceResponse.java, .../SessionUserResponse.java
라운드별 참석·세션 사용자 응답 DTO 추가
새 엔티티
backend/src/main/java/org/sejongisc/backend/attendance/entity/SessionUser.java
세션-사용자 링크 JPA 엔티티 추가(유니크 제약·인덱스 포함)
저장소 확장
backend/src/main/java/org/sejongisc/backend/attendance/repository/AttendanceRepository.java, .../AttendanceRoundRepository.java
findAllBySessionAndUserId(...), findBySession_SessionIdAndRoundDateBefore(...) 메서드 추가
새 저장소 인터페이스
backend/src/main/java/org/sejongisc/backend/attendance/repository/SessionUserRepository.java
SessionUser 관리용 JpaRepository 추가 및 조회/확인/삭제 등 쿼리 메서드 추가
서비스 변경 — Attendance
backend/src/main/java/org/sejongisc/backend/attendance/service/AttendanceService.java
updateAttendanceStatusByRound(roundId,userId,status,reason) 추가: 검증·생성·업데이트 로직 및 로깅
새 서비스 — SessionUser
backend/src/main/java/org/sejongisc/backend/attendance/service/SessionUserService.java
세션 사용자 추가/제거/조회, 중복/존재 검증, 과거 라운드에 대한 ABSENT 자동 생성 및 관련 Attendance 삭제 로직 추가
서비스 정리
backend/src/main/java/org/sejongisc/backend/attendance/service/AttendanceSessionService.java
불필요한 임포트 제거 및 경미한 포맷 정리

Sequence Diagram(s)

sequenceDiagram
    participant Admin as Admin (Controller)
    participant RoundCtrl as AttendanceRoundController
    participant SessionCtrl as AttendanceSessionController
    participant AttService as AttendanceService
    participant SUService as SessionUserService
    participant Repo as Repositories
    participant DB as Database

    rect rgb(220,240,255)
    Note over Admin,DB: 시나리오 A — 세션에 사용자 추가
    Admin->>SessionCtrl: POST /{sessionId}/users (userId)
    SessionCtrl->>SUService: addUserToSession(sessionId, userId)
    SUService->>Repo: validate session, user
    Repo-->>SUService: session,user
    SUService->>Repo: existsBySessionIdAndUserId?
    Repo-->>SUService: false
    SUService->>Repo: save SessionUser
    Repo->>DB: INSERT session_user
    SUService->>Repo: find rounds before today
    Repo-->>SUService: list of past rounds
    SUService->>Repo: for each round create ABSENT Attendance if missing
    Repo->>DB: INSERT attendance (status=ABSENT)*
    SUService-->>SessionCtrl: SessionUserResponse
    SessionCtrl-->>Admin: 201 CREATED + body
    end

    rect rgb(220,255,220)
    Note over Admin,DB: 시나리오 B — 라운드 참석 상태 업데이트
    Admin->>RoundCtrl: PUT /rounds/{r}/attendances/{u} (status, reason)
    RoundCtrl->>AttService: updateAttendanceStatusByRound(r, u, status, reason)
    AttService->>Repo: validate round, user, status
    Repo-->>AttService: entities & valid
    AttService->>Repo: find existing Attendance
    Repo-->>AttService: attendance? (optional)
    AttService->>Repo: save updated/created Attendance
    Repo->>DB: INSERT/UPDATE attendance
    AttService-->>RoundCtrl: AttendanceResponse
    RoundCtrl-->>Admin: 200 OK + body
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45분

  • 추가로 주의할 파일/영역:
    • SessionUserService.addUserToSession(): 과거 라운드에 대한 대량 생성 성능·트랜잭션 영향
    • AttendanceService.updateAttendanceStatusByRound(): 생성 vs 업데이트 분기 및 상태 유효성 검증
    • SessionUserRepository의 JPQL 쿼리 문법·인덱스 활용
    • SessionUser 엔티티 매핑(지연 로딩, cascade, toString 순환 참조 방지)

Possibly related PRs

Suggested reviewers

  • discipline24

Poem

🥕 토끼가 깡충깡충 뛰며 말하네,
새로 온 사용자 한 명, 세션에 착지!
지나간 라운드엔 부재 기록 남기고,
관리자는 상태를 톡! 바꾸면 끝.
토끼가 당근으로 축하 파티를 열겠네 🐇✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 제목이 변경 사항의 주요 목표를 명확하게 반영하고 있습니다. 'session user 구현'은 새로운 SessionUser 엔티티, 서비스, 저장소 및 관련 DTO/컨트롤러 추가라는 핵심 변경 사항을 정확히 설명합니다.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch SISC1-225-BE-SessionUser-구현

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (10)
backend/src/main/java/org/sejongisc/backend/attendance/dto/AttendanceSessionResponse.java (1)

67-69: 반경 값에 대한 유효성 검증 추가를 고려하세요.

radiusMeters 필드에 유효성 검증 어노테이션이 없습니다. 이 DTO가 요청에도 사용되거나 향후 사용될 가능성이 있다면, 다음 사항을 고려하세요:

  • 음수 값 방지
  • 합리적인 최대값 설정 (예: 1000미터 이하)
  • null 허용 여부 명확화

예시:

@Schema(description = "출석 인정 반경 (미터)", example = "100")
@Positive(message = "반경은 양수여야 합니다")
@Max(value = 1000, message = "반경은 1000미터를 초과할 수 없습니다")
private Integer radiusMeters;

또한, Integer 타입 사용으로 null 값이 허용됩니다. 이것이 의도된 동작(선택적 필드)인지 확인하고, 필수 필드라면 @NotNull 어노테이션 추가를 검토하세요.

backend/src/main/java/org/sejongisc/backend/attendance/dto/RoundAttendanceResponse.java (2)

17-20: 응답 DTO의 불변성을 고려해보세요.

현재 @Data 어노테이션은 setter를 포함하고 있습니다. 응답 DTO는 일반적으로 불변 객체로 만드는 것이 thread-safety와 명확성 측면에서 더 좋습니다.

다음 diff를 적용하여 불변 DTO로 변경할 수 있습니다:

-@Data
+@Value
 @Builder
-@NoArgsConstructor
-@AllArgsConstructor

참고: @Value는 모든 필드를 final로 만들고 setter를 생성하지 않으며, @Builder와 함께 사용할 때 @AllArgsConstructor가 자동으로 포함됩니다. Jackson 역직렬화가 필요한 경우 생성자 기반 역직렬화를 사용합니다.


23-30: 필드 정의가 적절합니다.

  • UUID 타입의 userId는 보안과 고유성 측면에서 좋습니다.
  • AttendanceStatus enum 사용으로 타입 안전성을 확보했습니다.
  • 응답 DTO이므로 validation 어노테이션이 없는 것이 올바릅니다.

선택적 제안: @JsonProperty 어노테이션의 값이 필드명과 동일한 경우, Jackson의 기본 설정에서는 중복입니다. 명시성을 위해 유지하는 것도 좋지만, 제거해도 동작에는 영향이 없습니다.

backend/src/main/java/org/sejongisc/backend/attendance/dto/AttendanceStatusUpdateRequest.java (1)

20-21: status 필드에 enum 타입 사용 고려

현재 String 타입으로 선언되어 있어 유효하지 않은 값이 서비스 레이어까지 전달됩니다. AttendanceStatus enum을 직접 사용하면 역직렬화 시점에 유효성 검증이 가능합니다.

+import org.sejongisc.backend.attendance.entity.AttendanceStatus;
+
 @Data
 @Builder
 @NoArgsConstructor
 @AllArgsConstructor
 public class AttendanceStatusUpdateRequest {

-    @NotBlank(message = "출석 상태는 필수입니다 (PRESENT, LATE, ABSENT, EXCUSED)")
-    private String status;
+    @NotNull(message = "출석 상태는 필수입니다 (PRESENT, LATE, ABSENT, EXCUSED)")
+    private AttendanceStatus status;

     private String reason;
 }
backend/src/main/java/org/sejongisc/backend/attendance/repository/AttendanceRoundRepository.java (1)

57-59: 메서드 이름과 엔티티 필드명 불일치

메서드 이름에서 Session_SessionId를 사용하고 있으나, 엔티티에서는 attendanceSession.attendanceSessionId를 사용합니다. @Query가 명시되어 있어 동작에는 문제가 없지만, 일관성을 위해 네이밍을 맞추는 것이 좋습니다.

-    List<AttendanceRound> findBySession_SessionIdAndRoundDateBefore(
+    List<AttendanceRound> findByAttendanceSession_AttendanceSessionIdAndRoundDateBefore(
             @Param("sessionId") UUID sessionId,
             @Param("date") LocalDate date);
backend/src/main/java/org/sejongisc/backend/attendance/repository/SessionUserRepository.java (1)

4-4: 사용되지 않는 import입니다.

User 클래스는 이 인터페이스에서 사용되지 않습니다.

-import org.sejongisc.backend.user.entity.User;
backend/src/main/java/org/sejongisc/backend/attendance/service/SessionUserService.java (3)

44-59: 예외 처리 패턴 일관성을 검토해 주세요.

IllegalArgumentException 대신 프로젝트의 CustomExceptionErrorCode 패턴을 사용하는 것이 일관성 있을 수 있습니다. CustomUserDetailsService에서 CustomException(ErrorCode.USER_NOT_FOUND)를 사용하는 것을 참고하세요.

-        AttendanceSession session = attendanceSessionRepository.findById(sessionId)
-                .orElseThrow(() -> new IllegalArgumentException("세션을 찾을 수 없습니다: " + sessionId));
+        AttendanceSession session = attendanceSessionRepository.findById(sessionId)
+                .orElseThrow(() -> new CustomException(ErrorCode.SESSION_NOT_FOUND));

-        User user = userRepository.findById(userId)
-                .orElseThrow(() -> new IllegalArgumentException("사용자를 찾을 수 없습니다: " + userId));
+        User user = userRepository.findById(userId)
+                .orElseThrow(() -> new CustomException(ErrorCode.USER_NOT_FOUND));

72-103: 과거 라운드 자동 결석 처리 로직이 잘 구현되었습니다.

중복 체크 후 결석 기록을 생성하는 방식이 적절합니다. 다만, Line 102의 로그 메시지가 실제 생성된 레코드 수가 아닌 전체 과거 라운드 수를 출력합니다. 정확한 로깅을 원하시면 카운터를 추가하는 것을 고려해 주세요.


154-169: 세션 참여자 조회 메서드가 잘 구현되었습니다.

@Transactional(readOnly = true) 사용이 적절합니다. 세션 존재 여부만 확인하는 용도라면 existsById를 사용하여 불필요한 엔티티 로딩을 줄일 수 있습니다.

-        AttendanceSession session = attendanceSessionRepository.findById(sessionId)
-                .orElseThrow(() -> new IllegalArgumentException("세션을 찾을 수 없습니다: " + sessionId));
+        if (!attendanceSessionRepository.existsById(sessionId)) {
+            throw new IllegalArgumentException("세션을 찾을 수 없습니다: " + sessionId);
+        }
backend/src/main/java/org/sejongisc/backend/attendance/controller/AttendanceRoundController.java (1)

10-10: DTO 와일드카드 import 대신 명시적 import 사용을 고려해 주세요

현재 org.sejongisc.backend.attendance.dto.* 와일드카드 import는 사용 DTO 파악이 어렵고, 향후 클래스 이름 충돌 가능성을 키울 수 있습니다. 이 파일에서 사용하는 DTO가 많지 않으므로 명시적으로 나열하는 편이 유지보수에 더 유리해 보입니다.

예시:

-import org.sejongisc.backend.attendance.dto.*;
+import org.sejongisc.backend.attendance.dto.AttendanceRoundRequest;
+import org.sejongisc.backend.attendance.dto.AttendanceRoundResponse;
+import org.sejongisc.backend.attendance.dto.AttendanceCheckInRequest;
+import org.sejongisc.backend.attendance.dto.AttendanceCheckInResponse;
+import org.sejongisc.backend.attendance.dto.AttendanceResponse;
+import org.sejongisc.backend.attendance.dto.AttendanceStatusUpdateRequest;
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b80c836 and b6655bd.

📒 Files selected for processing (15)
  • backend/src/main/java/org/sejongisc/backend/attendance/controller/AttendanceController.java (0 hunks)
  • backend/src/main/java/org/sejongisc/backend/attendance/controller/AttendanceRoundController.java (2 hunks)
  • backend/src/main/java/org/sejongisc/backend/attendance/controller/AttendanceSessionController.java (3 hunks)
  • backend/src/main/java/org/sejongisc/backend/attendance/dto/AttendanceSessionResponse.java (1 hunks)
  • backend/src/main/java/org/sejongisc/backend/attendance/dto/AttendanceStatusUpdateRequest.java (1 hunks)
  • backend/src/main/java/org/sejongisc/backend/attendance/dto/RoundAttendanceResponse.java (1 hunks)
  • backend/src/main/java/org/sejongisc/backend/attendance/dto/SessionUserRequest.java (1 hunks)
  • backend/src/main/java/org/sejongisc/backend/attendance/dto/SessionUserResponse.java (1 hunks)
  • backend/src/main/java/org/sejongisc/backend/attendance/entity/SessionUser.java (1 hunks)
  • backend/src/main/java/org/sejongisc/backend/attendance/repository/AttendanceRepository.java (1 hunks)
  • backend/src/main/java/org/sejongisc/backend/attendance/repository/AttendanceRoundRepository.java (1 hunks)
  • backend/src/main/java/org/sejongisc/backend/attendance/repository/SessionUserRepository.java (1 hunks)
  • backend/src/main/java/org/sejongisc/backend/attendance/service/AttendanceService.java (1 hunks)
  • backend/src/main/java/org/sejongisc/backend/attendance/service/AttendanceSessionService.java (0 hunks)
  • backend/src/main/java/org/sejongisc/backend/attendance/service/SessionUserService.java (1 hunks)
💤 Files with no reviewable changes (2)
  • backend/src/main/java/org/sejongisc/backend/attendance/controller/AttendanceController.java
  • backend/src/main/java/org/sejongisc/backend/attendance/service/AttendanceSessionService.java
🧰 Additional context used
🧬 Code graph analysis (4)
backend/src/main/java/org/sejongisc/backend/attendance/dto/AttendanceStatusUpdateRequest.java (3)
backend/src/main/java/org/sejongisc/backend/attendance/dto/RoundAttendanceResponse.java (1)
  • Data (17-31)
backend/src/main/java/org/sejongisc/backend/attendance/dto/SessionUserRequest.java (1)
  • Data (11-19)
frontend/src/utils/axios.js (1)
  • message (43-46)
backend/src/main/java/org/sejongisc/backend/attendance/dto/SessionUserRequest.java (2)
backend/src/main/java/org/sejongisc/backend/attendance/dto/AttendanceStatusUpdateRequest.java (1)
  • Data (14-24)
backend/src/main/java/org/sejongisc/backend/attendance/dto/SessionUserResponse.java (1)
  • Data (11-26)
backend/src/main/java/org/sejongisc/backend/attendance/service/SessionUserService.java (1)
backend/src/main/java/org/sejongisc/backend/common/auth/springsecurity/CustomUserDetailsService.java (1)
  • RequiredArgsConstructor (16-38)
backend/src/main/java/org/sejongisc/backend/attendance/dto/RoundAttendanceResponse.java (1)
backend/src/main/java/org/sejongisc/backend/attendance/dto/AttendanceStatusUpdateRequest.java (1)
  • Data (14-24)
🔇 Additional comments (13)
backend/src/main/java/org/sejongisc/backend/attendance/dto/RoundAttendanceResponse.java (1)

12-16: 문서화가 잘 되어 있습니다!

엔드포인트와 응답 형식을 명확하게 설명하는 JavaDoc이 작성되어 있어 좋습니다.

backend/src/main/java/org/sejongisc/backend/attendance/service/AttendanceService.java (1)

296-348: LGTM!

라운드 기반 출석 상태 수정 로직이 잘 구현되어 있습니다. 라운드와 사용자 검증, 상태 값 파싱, 기존 기록 유무에 따른 생성/업데이트 분기 처리가 적절합니다. 로깅도 충분히 상세합니다.

backend/src/main/java/org/sejongisc/backend/attendance/repository/AttendanceRepository.java (1)

63-65: LGTM!

세션 내 특정 사용자의 모든 출석 기록(라운드 관계없이)을 조회하는 메서드가 적절하게 추가되었습니다. 기존 findByAttendanceSessionAndUser_UserId (단일 Optional 반환)와 용도가 명확히 구분됩니다.

backend/src/main/java/org/sejongisc/backend/attendance/dto/SessionUserRequest.java (1)

11-19: LGTM!

프로젝트의 다른 DTO들과 일관된 패턴으로 구현되었습니다. @NotNull 검증과 Lombok 어노테이션 사용이 적절합니다.

backend/src/main/java/org/sejongisc/backend/attendance/dto/SessionUserResponse.java (1)

11-26: LGTM!

DTO 구조가 적절하며, Lombok 어노테이션 사용과 필드 구성이 SessionUser 엔티티와 잘 매핑됩니다.

backend/src/main/java/org/sejongisc/backend/attendance/entity/SessionUser.java (2)

21-37: 엔티티 설계가 잘 되어 있습니다.

유니크 제약 조건과 인덱스 설정이 적절하며, LAZY 페치 전략을 사용한 점이 좋습니다. userName 캐싱 방식도 의도가 명확하게 문서화되어 있습니다.


55-67: 순환 참조 방지를 위한 toString 오버라이드가 적절합니다.

null 체크가 포함되어 있어 안전합니다. 다만, LAZY 로딩된 엔티티의 ID 접근 시 트랜잭션 외부에서 호출되면 LazyInitializationException이 발생할 수 있으니 주의가 필요합니다.

backend/src/main/java/org/sejongisc/backend/attendance/controller/AttendanceSessionController.java (2)

298-317: GET /{sessionId}/users 엔드포인트에 권한 검증이 누락되었습니다.

다른 관리자 전용 엔드포인트들과 달리 이 엔드포인트에는 @PreAuthorize 어노테이션이 없습니다. 세션 참여자 정보가 민감할 수 있으므로 의도된 것인지 확인이 필요합니다.

의도적으로 공개 API로 설계한 것이라면 주석이나 API 설명에 이를 명시해 주세요. 그렇지 않다면 다음과 같이 수정하세요:

 @GetMapping("/{sessionId}/users")
+@PreAuthorize("hasRole('PRESIDENT') or hasRole('VICE_PRESIDENT')")
 public ResponseEntity<List<SessionUserResponse>> getSessionUsers(@PathVariable UUID sessionId) {

248-296: 사용자 추가/제거 엔드포인트가 잘 구현되었습니다.

  • HTTP 상태 코드(201 CREATED, 204 No Content)가 RESTful 규약에 맞게 적용되었습니다.
  • 권한 검증과 로깅이 기존 패턴과 일관되게 구현되었습니다.
backend/src/main/java/org/sejongisc/backend/attendance/repository/SessionUserRepository.java (1)

17-45: JPQL 쿼리가 잘 정의되어 있습니다.

정렬 순서, 파라미터 바인딩, 존재 여부 확인 쿼리 등이 적절하게 구현되었습니다.

backend/src/main/java/org/sejongisc/backend/attendance/service/SessionUserService.java (2)

116-149: 사용자 제거 로직이 적절합니다.

SessionUser와 관련된 Attendance 레코드를 함께 삭제하는 로직이 잘 구현되었습니다. 다만, SessionUserRepository.deleteBySessionIdAndUserId@Modifying 어노테이션이 필요합니다 (해당 파일의 리뷰 코멘트 참조).


179-190: DTO 변환 메서드가 간결하게 구현되었습니다.

트랜잭션 컨텍스트 내에서 호출되므로 LAZY 로딩된 엔티티 접근에 문제가 없습니다.

backend/src/main/java/org/sejongisc/backend/attendance/controller/AttendanceRoundController.java (1)

252-275: 출석 상태 수정 엔드포인트 구현이 컨벤션과 잘 맞습니다

  • URL, HTTP 메서드, @PreAuthorize 권한 설정이 기존 컨트롤러 패턴과 일관적이고,
  • 요청 DTO(AttendanceStatusUpdateRequest) + 응답 DTO(AttendanceResponse) 조합도 명확하며,
  • 상태/사유를 모두 로깅하고 서비스 레이어로 위임하는 구조가 적절해 보입니다.

컨트롤러 레벨에서 별도 예외 처리를 하지 않고 서비스/글로벌 예외 핸들러에 위임하는 구조라면, 현재 구현 그대로 사용해도 무방해 보입니다.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
backend/src/main/java/org/sejongisc/backend/attendance/service/SessionUserService.java (1)

141-145: 삭제된 엔티티 순회 로깅 확인

deleteAll() 호출 후 삭제된 엔티티들을 순회하며 로깅하고 있습니다. 메모리상의 객체는 여전히 유효하므로 동작에는 문제가 없으나, 로그 순서상 삭제 완료 메시지(Line 140) 이후에 개별 항목을 로깅하는 것이 의미적으로 혼란스러울 수 있습니다.

-        if (!attendancesToDelete.isEmpty()) {
-            log.info("🗑️ Attendance 레코드 삭제 시작: 삭제 대상 수={}", attendancesToDelete.size());
-
-            attendanceRepository.deleteAll(attendancesToDelete);
-
-            log.info("✅ Attendance 레코드 삭제 완료: 삭제된 레코드 수={}", attendancesToDelete.size());
-            for (Attendance a : attendancesToDelete) {
-                log.info("  - 삭제됨: roundId={}, status={}",
-                        a.getAttendanceRound() != null ? a.getAttendanceRound().getRoundId() : "null",
-                        a.getAttendanceStatus());
-            }
-        }
+        if (!attendancesToDelete.isEmpty()) {
+            log.info("🗑️ Attendance 레코드 삭제 시작: 삭제 대상 수={}", attendancesToDelete.size());
+            for (Attendance a : attendancesToDelete) {
+                log.info("  - 삭제 대상: roundId={}, status={}",
+                        a.getAttendanceRound() != null ? a.getAttendanceRound().getRoundId() : "null",
+                        a.getAttendanceStatus());
+            }
+
+            attendanceRepository.deleteAll(attendancesToDelete);
+            log.info("✅ Attendance 레코드 삭제 완료: 삭제된 레코드 수={}", attendancesToDelete.size());
+        }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b6655bd and 4f9cd38.

📒 Files selected for processing (3)
  • backend/src/main/java/org/sejongisc/backend/attendance/repository/SessionUserRepository.java (1 hunks)
  • backend/src/main/java/org/sejongisc/backend/attendance/service/AttendanceService.java (1 hunks)
  • backend/src/main/java/org/sejongisc/backend/attendance/service/SessionUserService.java (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
backend/src/main/java/org/sejongisc/backend/attendance/service/SessionUserService.java (1)
backend/src/main/java/org/sejongisc/backend/attendance/service/AttendanceService.java (1)
  • Service (21-380)
🔇 Additional comments (6)
backend/src/main/java/org/sejongisc/backend/attendance/service/AttendanceService.java (1)

291-349: LGTM! checkedAt 누락 문제가 해결되었습니다.

이전 리뷰에서 지적된 checkedAt 필드 누락 문제가 Line 331에서 java.time.LocalDateTime.now()로 설정되어 해결되었습니다. 라운드 기반 출석 상태 수정 로직이 올바르게 구현되어 있습니다.

backend/src/main/java/org/sejongisc/backend/attendance/repository/SessionUserRepository.java (1)

1-61: LGTM! @Modifying 어노테이션이 올바르게 추가되었습니다.

이전 리뷰에서 지적된 DELETE 쿼리의 @Modifying 어노테이션 누락 문제가 Line 51, 58에서 해결되었습니다. 레포지토리 인터페이스가 올바르게 구현되어 있습니다.

backend/src/main/java/org/sejongisc/backend/attendance/service/SessionUserService.java (4)

44-110: 세션 사용자 추가 로직이 잘 구현되었습니다.

사용자 추가 시 과거 라운드에 대한 자동 결석 처리 로직(Line 72-104)이 적절하게 구현되어 있습니다. 중복 참여 검증, 유효성 검사, 그리고 포괄적인 로깅이 포함되어 있어 관리 및 디버깅에 용이합니다.


156-178: 조회 메서드들이 올바르게 구현되었습니다.

getSessionUsersisUserInSession 메서드가 @Transactional(readOnly = true)로 적절하게 설정되어 있어 읽기 성능 최적화가 잘 되어 있습니다.


133-133: Method findAllBySessionAndUserId exists and is correctly defined.

The method is properly defined at line 65 in AttendanceRepository.java with the correct signature and @Query annotation. The call at line 133 in SessionUserService.java matches the method signature exactly (both parameters align with their types: AttendanceSession session and UUID userId). No runtime error will occur.


73-76: Review comment is incorrect - no issue found

The method findBySession_SessionIdAndRoundDateBefore exists and is correctly implemented in AttendanceRoundRepository (lines 54-61). It uses a @Query annotation with explicit JPQL that properly references r.attendanceSession.attendanceSessionId, which correctly maps to the AttendanceRound entity's field name attendanceSession. The method call in SessionUserService.java (line 73) is valid and requires no changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants