Skip to content

[feat] 지금 출석을 받는 중인지 조회 API - #261

Merged
kimseongchan0914 merged 7 commits into
developfrom
feat/attendance-active
Oct 27, 2026
Merged

kimseongchan0914 merged 7 commits into
developfrom
feat/attendance-active

Conversation

@kimseongchan0914

@kimseongchan0914 kimseongchan0914 commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

✨ 작업 내용

학생이 지금 출석을 받는 중인지 조회하는 API를 추가했습니다(CheckUp-Client#357).

API 설명
GET /api/v1/attendance/active 로그인한 학생 기준 { "dormitory": bool, "studyRoom": bool }
  • 용도별로 출석을 받는 세션이 하나라도 있으면 true입니다.
    • QR: 그 용도의 lease가 남은 QR 세션. QR은 층을 가리지 않습니다.
    • 얼굴: 그 용도로 학생 본인 층을 맡은 활성 얼굴 인식 세션(유휴 시간 안에 활동). 층이 없는 예전 세션은 모든 층으로 셉니다(기존 onSessionFloor와 같음). 호실이 없는 학생은 얼굴 세션을 세지 않습니다.
  • 세션 id·관리자·토큰은 주지 않고 여부만 줍니다.
  • 학생 정보가 없는 계정은 /attendance/me와 같이 403 MISSING_STUDENT_INFO입니다.

🔍 리뷰 시 참고사항

  • QR 용도별 인덱스: QR 세션은 관리자별 집합만 있어 용도별로 찾을 수 없었습니다. Redis 정렬 집합 qr:purpose:{purpose}(점수 = lease 만료 epoch ms)를 추가했습니다.
    • save에서 추가, delete에서 제거합니다.
    • heartbeat(saveIfPresent)는 기존 Lua 안에서 세션 키가 있을 때만 갱신하므로, close 뒤 늦은 heartbeat가 인덱스에 되살리지 않습니다.
    • heartbeat 때 lease가 이미 지난 항목(점수 < now)만 정리합니다. 조회는 ZCOUNT (now, +inf)라 정리 전 항목도 세지 않습니다. 키 TTL은 세션과 같은 lease-ttl입니다.
    • 배포 시점에 열려 있던 QR 세션은 다음 heartbeat(최대 약 20초)부터 인덱스에 잡힙니다.
  • 얼굴: FaceRecognitionSessionRepository.existsActiveOnFloor(active·purpose·lastActivityAt > cutoff·floor) 한 쿼리입니다. migration은 없습니다.
  • AttendanceActiveService를 따로 둔 이유: FaceRecognitionService가 AttendanceService를 쓰므로, AttendanceService에 넣으면 순환 의존이 생깁니다.
  • polling 부담: 요청당 학생 조회 1번(PostgreSQL), Redis ZCOUNT 2번, 얼굴 세션 존재 쿼리 최대 2번입니다. 학생 약 200명이 30초마다 부르면 초당 약 7건이라 부담은 작다고 봅니다.
  • 하네스 포인터(dd79ac3)는 하네스 main에 머지된 커밋입니다([docs] 학생 출석 접수 여부 API 계약 추가 Start-Up-harness#38, contracts/README.md에 이 API 추가).

검증: 관련 테스트(QrSessionRepositoryTest, QrSessionServiceTest, FaceSessionStoreTest, FaceRecognitionServiceTest, AttendanceActiveServiceTest, AttendanceControllerTest) 72개 통과. 로컬 ./gradlew clean build는 666개 중 이번 변경과 무관한 FaceTemplateRepositoryTest 1개가 로컬 개발 DB에 남은 템플릿 데이터 때문에 실패했습니다. 실제 웹 연동은 확인하지 않았습니다.


✅ 체크리스트

  • 문서(README, .env.example 등) 변경이 필요한 경우 작성 또는 수정했나요?
  • 작업한 코드가 정상적으로 동작하는 것을 직접 확인했나요?
  • 필요한 경우 테스트 코드를 작성하거나 수정했나요?
  • Merge 대상 브랜치를 올바르게 설정했나요?
  • PR에 관련 없는 작업이 포함되지 않았나요?
  • 적절한 라벨과 리뷰어를 설정했나요?

📎 관련 이슈(선택)

🤖 Generated with Claude Code

@kimseongchan0914
kimseongchan0914 merged commit e466150 into develop Oct 27, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature 새로운 기능 추가

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants