Skip to content

[BE] SISC1-224 [FIX] 출석 라운드 관련 수정 - #145

Merged
Kosw6 merged 5 commits into
mainfrom
SISC1-224-BE-출석-라운드-관련-수정
Nov 26, 2025

Hidden character warning

The head ref may contain hidden characters: "SISC1-224-BE-\ucd9c\uc11d-\ub77c\uc6b4\ub4dc-\uad00\ub828-\uc218\uc815"
Merged

Kosw6 merged 5 commits into
mainfrom
SISC1-224-BE-출석-라운드-관련-수정

Conversation

@ochanhyeok

@ochanhyeok ochanhyeok commented Nov 26, 2025 •

Copy link
Copy Markdown
Member

Summary by CodeRabbit

릴리스 노트

  • Breaking Changes

    • 체크인 API 엔드포인트 제거
    • 출석 응답의 필드명 변경 (roundId → id, roundDate → date)
    • 세션 시작 시간 형식 변경 (날짜시간 → 시간만 표기)
    • 출석 허용 시간 단위 변경 (초 → 분)
  • 개선 사항

    • 지각 판정 로직 개선 (라운드 기반 시간 임계값 추가)
    • 세션 상태 계산 방식 단순화

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

@coderabbitai

coderabbitai Bot commented Nov 26, 2025 •

Copy link
Copy Markdown

Walkthrough

세션 기반 출석 확인 API 엔드포인트와 관련 서비스 메서드가 제거되었습니다. 동시에 시간 필드 표현이 변경되었습니다: startsAt (LocalDateTime) → defaultStartTime (LocalTime), windowSeconds (초) → allowedMinutes (분). DTO 필드도 이름이 변경되었습니다: roundId/roundDate → id/date.

Changes

내용 / 파일(들) 요약
API 엔드포인트 및 서비스 제거
backend/src/main/java/org/sejongisc/backend/attendance/controller/AttendanceController.java, backend/src/main/java/org/sejongisc/backend/attendance/service/AttendanceService.java
POST /sessions/{sessionId}/check-in 엔드포인트와 AttendanceService.checkIn() 메서드 제거. 세션 기반 출석 확인 흐름 제거.
DTO 필드명 변경
backend/src/main/java/org/sejongisc/backend/attendance/dto/AttendanceRoundResponse.java, backend/src/test/java/org/sejongisc/backend/attendance/controller/AttendanceRoundControllerTest.java
필드 이름 변경: roundId → id, roundDate → date. 테스트 코드도 함께 업데이트됨.
세션 요청 필드 타입 및 이름 변경
backend/src/main/java/org/sejongisc/backend/attendance/dto/AttendanceSessionRequest.java
startsAt (LocalDateTime) → defaultStartTime (LocalTime). windowSeconds (초 단위) → allowedMinutes (분 단위). 유효성 검사 제약 및 Swagger 스키마 업데이트.
엔티티 필드 변경 및 로직 재구성
backend/src/main/java/org/sejongisc/backend/attendance/entity/AttendanceSession.java, backend/src/main/java/org/sejongisc/backend/attendance/entity/Attendance.java
startsAt/windowSeconds → defaultStartTime/allowedMinutes. 새로운 메서드: getEndTime(), isCheckInAvailableForRound(LocalTime). 제거된 메서드: getEndsAt(), isCheckInAvailable(), getRemainingSeconds(). 상태 계산 로직 단순화. 지연 감지 로직 업데이트.
저장소 및 서비스 메서드 변경
backend/src/main/java/org/sejongisc/backend/attendance/repository/AttendanceSessionRepository.java, backend/src/main/java/org/sejongisc/backend/attendance/service/AttendanceSessionService.java
findAllByOrderByStartsAtDesc() 메서드 제거. 서비스에서 시간 기반 정렬 및 활성 세션 필터링 로직 제거. convertToResponse()에서 새 필드 사용.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Controller as AttendanceController
    participant Service as AttendanceSessionService
    participant Repo as Repository
    
    Note over Client,Controller: POST /sessions/{sessionId}/check-in<br/>(REMOVED)
    
    rect rgb(200, 100, 100)
    Client-XController: POST /check-in (deprecated)
    Note over Controller: Endpoint removed<br/>No longer available
    Controller--XClient: 404 Not Found
    end
    
    Note over Service: Round-based check-in<br/>(Active flow)
    Client->>Service: checkInByRound(roundId, request, userId)
    Service->>Service: Validate attendance round
    Service->>Repo: Query & Update
    Repo-->>Service: Attendance record
    Service-->>Client: AttendanceResponse
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 분

특별히 주의가 필요한 부분:

  • AttendanceSession 엔티티의 주요 구조 변경: 시간 표현 방식 전환 (LocalDateTime → LocalTime), 데이터베이스 컬럼명 변경, 메서드 추가/제거
  • Attendance 엔티티의 지연 감지 로직 재구현: null 처리, 라운드 기반 및 세션 기반 임계값 검사
  • API 엔드포인트 제거의 영향 범위: 컨트롤러, 서비스, 잠재적 클라이언트 코드
  • AttendanceSessionService 전반적 리팩토링: 여러 메서드에서 시간 필드 마이그레이션
  • 데이터베이스 마이그레이션 고려: 새로운 컬럼 추가, 기존 데이터 변환 로직 검증

Possibly related PRs

Suggested reviewers

  • discipline24

Poem

🐰 시간은 흘러흘러, 새로운 형태로
분 단위의 춤, 로컬타임의 노래 🎵
세션은 가고, 라운드만 남아
더 간결하고 명확한 흐름이 되네
토끼의 축복과 함께! 🌙✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 70.59% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive PR 제목이 출석 라운드 관련 수정을 언급하지만, 실제 변경사항에는 체크인 API 제거, DTO 필드명 변경, 세션 필드 변경 등 광범위한 수정이 포함되어 있습니다. 제목을 더 구체적으로 수정하여 주요 변경사항을 명확히 반영하도록 권장합니다. 예: '[BE] SISC1-224 [FIX] 출석 세션 필드 구조 변경 및 라운드 기반 체크인 통합'
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ 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-224-BE-출석-라운드-관련-수정

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.

@Kosw6
Kosw6 merged commit ab6d453 into main Nov 26, 2025
1 check was pending
@Kosw6
Kosw6 deleted the SISC1-224-BE-출석-라운드-관련-수정 branch November 26, 2025 05:01

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
backend/src/main/java/org/sejongisc/backend/attendance/service/AttendanceSessionService.java (1)

82-94: 주석과 구현의 불일치

주석에는 "생성 순으로 정렬"이라고 되어 있지만, findAll()은 정렬 순서를 보장하지 않습니다. 정렬이 필요하다면 명시적인 정렬을 추가하거나, 정렬이 불필요하다면 주석을 수정해주세요.

정렬이 필요한 경우:

     @Transactional(readOnly = true)
     public List<AttendanceSessionResponse> getAllSessions() {
-        List<AttendanceSession> sessions = attendanceSessionRepository.findAll();
+        List<AttendanceSession> sessions = attendanceSessionRepository.findAll(Sort.by(Sort.Direction.DESC, "createdAt"));

정렬이 불필요한 경우 주석을 수정:

-     * - 생성 순으로 정렬
+     * - 정렬 순서 보장 없음
🧹 Nitpick comments (3)
backend/src/main/java/org/sejongisc/backend/attendance/entity/AttendanceSession.java (1)

61-62: defaultStartTime null 체크 누락

allowedMinutes에 대해 null 처리가 되어 있지만, defaultStartTime이 null인 경우 NPE가 발생할 수 있습니다. 컬럼에 nullable = false가 설정되어 있지만 빌더 패턴이나 직렬화 과정에서 null이 설정될 수 있습니다.

 public LocalTime getEndTime() {
+    if (defaultStartTime == null) {
+        return null;
+    }
     return defaultStartTime.plusMinutes(allowedMinutes != null ? allowedMinutes : 30);
 }
backend/src/main/java/org/sejongisc/backend/attendance/service/AttendanceSessionService.java (2)

16-16: 사용되지 않는 import 가능성

startsAt (LocalDateTime)이 defaultStartTime (LocalTime)으로 변경되면서 LocalDateTime import가 더 이상 사용되지 않는 것으로 보입니다.

-import java.time.LocalDateTime;

96-108: getAllSessions와 중복된 구현

getPublicSessions가 getAllSessions와 완전히 동일한 구현입니다. 의도적인 것인지 확인이 필요합니다:

  • 공개 세션만 필터링하는 로직이 필요한 것이 아닌지?
  • 중복이 의도적이라면 한 메서드가 다른 메서드를 호출하도록 리팩터링 고려

또한 Line 99의 주석도 getAllSessions와 동일한 정렬 불일치 문제가 있습니다.

     @Transactional(readOnly = true)
     public List<AttendanceSessionResponse> getPublicSessions() {
-        List<AttendanceSession> sessions = attendanceSessionRepository.findAll();
-
-        return sessions.stream()
-                .map(this::convertToResponse)
-                .collect(Collectors.toList());
+        return getAllSessions();
     }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4ed85e8 and c8c9bfb.

📒 Files selected for processing (9)
  • backend/src/main/java/org/sejongisc/backend/attendance/controller/AttendanceController.java (0 hunks)
  • backend/src/main/java/org/sejongisc/backend/attendance/dto/AttendanceRoundResponse.java (3 hunks)
  • backend/src/main/java/org/sejongisc/backend/attendance/dto/AttendanceSessionRequest.java (3 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/repository/AttendanceSessionRepository.java (0 hunks)
  • backend/src/main/java/org/sejongisc/backend/attendance/service/AttendanceService.java (0 hunks)
  • backend/src/main/java/org/sejongisc/backend/attendance/service/AttendanceSessionService.java (9 hunks)
  • backend/src/test/java/org/sejongisc/backend/attendance/controller/AttendanceRoundControllerTest.java (8 hunks)
💤 Files with no reviewable changes (3)
  • backend/src/main/java/org/sejongisc/backend/attendance/service/AttendanceService.java
  • backend/src/main/java/org/sejongisc/backend/attendance/controller/AttendanceController.java
  • backend/src/main/java/org/sejongisc/backend/attendance/repository/AttendanceSessionRepository.java
🧰 Additional context used
🧬 Code graph analysis (2)
backend/src/test/java/org/sejongisc/backend/attendance/controller/AttendanceRoundControllerTest.java (1)
frontend/src/contexts/AttendanceContext.jsx (1)
  • value (202-229)
backend/src/main/java/org/sejongisc/backend/attendance/service/AttendanceSessionService.java (2)
frontend/src/contexts/AttendanceContext.jsx (1)
  • sessions (52-52)
frontend/src/components/attendancemanage/SessionModifyModal.jsx (1)
  • defaultAvailableMinutes (29-31)
🔇 Additional comments (16)
backend/src/main/java/org/sejongisc/backend/attendance/entity/Attendance.java (1)

71-92: 지각 판단 로직 개선 - LGTM with minor concern

라운드 기반 및 세션 기반 출석에 대해 각각 적절한 기준 시간을 사용하고 있으며, null 처리도 잘 되어 있습니다.

다만 AttendanceSession.isCheckInAvailableForRound()와 마찬가지로 자정을 넘는 경우 LocalTime 비교가 의도대로 동작하지 않을 수 있습니다. 예를 들어 23:55에 시작한 라운드에서 00:02에 체크인하면 00:02.isAfter(00:00) (23:55 + 5분)이 true가 되어 지각으로 처리되지만, 실제로는 시작 후 7분이므로 지각이 맞습니다. 그러나 시작 시간이 00:02이고 체크인이 23:58인 경우 잘못된 결과가 나올 수 있습니다.

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

65-77: fromEntity 매핑 변경 - LGTM

엔티티에서 DTO로의 변환 로직이 새로운 필드명에 맞게 올바르게 업데이트되었습니다.


29-38: Unable to verify frontend compatibility - repository access required

I was unable to access the repository to verify whether the frontend code actually references the old field names (roundId, roundDate). The repository appears to be private or inaccessible.

To complete this verification, you would need to:

  1. Manually search the frontend codebase for usage of roundId and roundDate fields
  2. Check AttendanceContext.jsx and related components that consume the AttendanceRoundResponse API
  3. Confirm whether these field names are hardcoded in API response handling or if they use dynamic property access that would adapt to the new field names

Without this information, I cannot definitively confirm whether this breaking change requires frontend updates.

backend/src/test/java/org/sejongisc/backend/attendance/controller/AttendanceRoundControllerTest.java (5)

78-98: 테스트 코드 업데이트 - LGTM

AttendanceRoundResponse DTO의 필드명 변경(roundId → id, roundDate → date)에 맞게 테스트 빌더와 JSON 경로 검증이 올바르게 업데이트되었습니다.


127-142: 조회 테스트 업데이트 - LGTM

새로운 필드명으로 응답 객체 생성 및 검증이 일관되게 수정되었습니다.


153-177: 목록 조회 테스트 - LGTM

여러 라운드를 조회하는 테스트에서 각 응답 객체의 필드명이 올바르게 업데이트되었습니다.


194-212: 수정 테스트 업데이트 - LGTM

라운드 수정 성공 테스트가 새로운 필드명을 올바르게 사용하고 있습니다.


321-336: 날짜별 조회 테스트 - LGTM

특정 날짜의 라운드 조회 테스트가 새로운 필드명을 사용하여 올바르게 업데이트되었습니다.

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

29-36: 시간 표현 변경 - Breaking API 변경

startsAt (LocalDateTime) → defaultStartTime (LocalTime)로 변경되었습니다. API 클라이언트에서 요청 형식을 변경해야 합니다. 스키마 설명과 예시가 올바르게 업데이트되었습니다.


38-47: 유효성 검사 범위 변경 - LGTM

windowSeconds → allowedMinutes로 변경되고, 유효 범위가 5분 ~ 240분(4시간)으로 설정되었습니다. 검증 어노테이션과 메시지가 적절히 업데이트되었습니다.

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

30-34: Database migration scripts verification inconclusive

The repository could not be accessed to verify whether database migration scripts have been prepared for the field changes (startsAt → defaultStartTime, windowSeconds → allowedMinutes) and column renames (default_start_time, allowed_minutes).

Please manually verify that the following are in place:

  • Migration scripts (SQL or XML) exist in your migration tool's directory (typically db/migration/, sql/, or similar)
  • If using Flyway, verify versioned SQL files (e.g., V*.sql) exist
  • If using Liquibase, verify changelog XML/YAML files exist
  • The migration covers table schema changes and data type conversions

75-77: Unable to verify calculateCurrentStatus() method behavior due to repository access limitations

The verification process encountered persistent repository access failures, preventing examination of:

  • All call sites of calculateCurrentStatus()
  • The SessionStatus enum definition
  • Evidence of whether state calculation was migrated to a round level
  • The impact on dependent code

The original review comment warrants manual investigation to confirm whether this unconditional return of SessionStatus.OPEN is intentional or represents incomplete refactoring.

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

37-68: LGTM!

로깅과 세션 빌더가 새로운 필드명(defaultStartTime, allowedMinutes)으로 올바르게 업데이트되었습니다.


110-123: LGTM!

라운드 기반 로직으로의 변경이 올바르게 구현되었습니다. OPEN 상태의 세션만 필터링하는 방식이 명확합니다.


125-160: LGTM!

세션 수정 로직이 새로운 필드명(defaultStartTime, allowedMinutes)으로 올바르게 업데이트되었습니다.


273-297: LGTM!

convertToResponse 메서드가 새로운 필드를 올바르게 매핑하고 있습니다. 엔티티의 allowedMinutes가 응답 DTO의 defaultAvailableMinutes로 매핑되는 것이 프론트엔드 컨텍스트(SessionModifyModal.jsx)와 일치합니다.

Comment on lines +68 to +69
public boolean isCheckInAvailableForRound(java.time.LocalTime currentTime) {
return !currentTime.isBefore(defaultStartTime) && currentTime.isBefore(getEndTime());

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

자정을 넘는 세션 시간 처리 문제

LocalTime 비교는 자정을 넘는 경우를 올바르게 처리하지 못합니다. 예를 들어 세션이 23:00에 시작하고 60분간 진행되면 종료 시간이 00:00이 되는데, 23:30의 currentTime은 isBefore(00:00)에서 false를 반환하여 체크인이 불가능하게 됩니다.

자정을 넘는 세션이 예상되는 경우 다음과 같이 수정을 고려해 주세요:

 public boolean isCheckInAvailableForRound(java.time.LocalTime currentTime) {
-    return !currentTime.isBefore(defaultStartTime) && currentTime.isBefore(getEndTime());
+    LocalTime endTime = getEndTime();
+    if (endTime.isBefore(defaultStartTime)) {
+        // 자정을 넘는 경우
+        return !currentTime.isBefore(defaultStartTime) || currentTime.isBefore(endTime);
+    }
+    return !currentTime.isBefore(defaultStartTime) && currentTime.isBefore(endTime);
 }
🤖 Prompt for AI Agents
In
backend/src/main/java/org/sejongisc/backend/attendance/entity/AttendanceSession.java
around lines 68-69, the current LocalTime comparison fails for sessions that
span midnight; change the logic to detect when getEndTime() is before or equal
to defaultStartTime (meaning the interval wraps past midnight) and in that case
allow check-in when currentTime is >= defaultStartTime OR currentTime is <
getEndTime(); otherwise use the normal non-wrapping check (currentTime >=
defaultStartTime AND currentTime < getEndTime()). Ensure you use LocalTime
comparisons (isBefore/isAfter/equals) consistently to include equality at start
time.

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