Skip to content

Conversation

@Sewoni
Copy link
Contributor

@Sewoni Sewoni commented Dec 1, 2025

Pull Request

📋 Jira Issue

📝 변경 사항 요약

주요 변경사항

  • 근로자 본인 근태 조회 API가 attendances 테이블을 조회하도록 수정
  • 대시보드 금일 출근/지각 인원이 attendances 테이블을 조회하도록 수정
  • 모든 API 엔드포인트에 /v1 prefix 통일

🎯 변경 목적

문제: 얼굴인식 출퇴근 시스템은 attendances 테이블에 저장하지만, 근로자 본인 근태 조회 및 대시보드는 attendance_records 테이블을 조회하여 데이터가 표시되지 않는 버그가 있었음

해결: 모든 근태 조회 로직이 실제 데이터가 저장되는 attendances 테이블을 조회하도록 수정

🔍 변경 내역 상세

버그 수정 (Bug Fixes)

  • EmployeeMyService: attendance_recordsattendances 테이블 조회로 변경
  • DashboardService: attendance_recordsattendances 테이블 조회로 변경
  • 금일 지각 인원을 Attendance.isLate 필드 기반으로 실제 계산

리팩토링 (Refactoring)

  • EmployeeController: /sites/{siteId}/employees/v1/sites/{siteId}/employees
  • DocumentController: /documents/v1/documents
  • AttendanceRepository: findBySiteIdAndSearchDate() 메서드 추가

🧪 테스트 방법

단위 테스트

  • 기존 테스트 통과 확인 (GitHub Actions)
  • 로컬 테스트: 312 tests completed, 2 failed (PdfService 폰트 테스트 - 기존 이슈, 변경과 무관)

수동 테스트

  1. 근로자 계정으로 로그인
  2. GET /v1/employees/me/attendance 호출 → 얼굴인식 출퇴근 기록 표시 확인
  3. GET /v1/employees/me/home 호출 → 금일 근태 정보 표시 확인
  4. 관리자 계정으로 GET /v1/sites/{siteId}/dashboard 호출 → 금일 출근/지각 인원 표시 확인

API 테스트 예시

# 근로자 본인 근태 조회
curl -X GET http://localhost:8080/api/v1/employees/me/attendance \
  -H "Authorization: Bearer {token}"

# 대시보드 조회
curl -X GET http://localhost:8080/api/v1/sites/1/dashboard \
  -H "Authorization: Bearer {token}"

⚠️ Breaking Changes

  • Breaking Changes 있음

Breaking Changes 설명:

  • EmployeeController 엔드포인트 변경: /sites/{siteId}/employees/v1/sites/{siteId}/employees
  • DocumentController 엔드포인트 변경: /documents/v1/documents
  • 프론트엔드에서 해당 API 호출 시 경로 수정 필요

🔗 의존성 변경

  • 의존성 변경 없음

🗄️ 데이터베이스 변경

  • DB 변경 없음

✅ 체크리스트

코드 품질

  • 코드 스타일 가이드 준수
  • Lombok 어노테이션 적절히 사용
  • 불필요한 주석 제거
  • 하드코딩된 값 제거
  • 로그 레벨 적절히 설정

테스트

  • 모든 테스트 통과 (GitHub Actions)
  • 빌드 성공 (./gradlew clean build)

보안

  • SQL Injection 취약점 검토
  • 인증/인가 로직 검토

성능

  • N+1 쿼리 문제 검토 (Site 정보 일괄 조회)
  • 불필요한 DB 쿼리 최적화

문서

  • API 문서 업데이트 (Swagger 주석)
  • Jira Story 상태 업데이트

Git

  • Conventional Commits 규칙 준수
  • Jira 키 포함 (Refs: BU-231)

📌 리뷰어에게

  • attendance_records 테이블은 현재 어디서도 사용되지 않음 (추후 삭제 또는 용도 재정의 필요)
  • 엔드포인트 변경으로 프론트엔드 수정 필요

Summary by CodeRabbit

릴리스 노트

  • API 변경사항

    • Document API 경로: /documents/v1/documents
    • Employee API 경로: /sites/{siteId}/employees/v1/sites/{siteId}/employees
  • 개선사항

    • 근태 데이터 조회 성능 최적화
    • 대시보드 데이터 처리 방식 개선
  • 문서 정리

    • 배포 가이드 및 기여 가이드 제거

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

- EmployeeMyService: attendance_records 대신 attendances 테이블 조회
- DashboardService: 금일 출근/지각 인원을 attendances 테이블에서 조회
- AttendanceRepository: findBySiteIdAndSearchDate 메서드 추가

기존에 attendance_records 테이블을 조회하던 로직이 실제 데이터가
저장되는 attendances 테이블을 조회하도록 변경

Refs: BU-231
- EmployeeController: /sites/{siteId}/employees → /v1/sites/{siteId}/employees
- DocumentController: /documents → /v1/documents

Refs: BU-231
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 1, 2025

개요

이 PR은 데이터 계층의 Attendance 엔티티로의 전환을 중심으로 진행되는 대규모 리팩토링이며, API 컨트롤러에 v1 버전 접두사를 추가하고, 테스트 데이터 파일 및 관련 스크립트를 제거합니다.

변경 사항

코호트 / 파일 변경 요약
저장소 계층 확장
src/main/java/com/concrete/buildup/domain/attendance/repository/AttendanceRepository.java
사이트 ID와 검색 날짜로 출석 기록을 조회하는 새 쿼리 메서드 findBySiteIdAndSearchDate(Long siteId, LocalDate searchDate) 추가
API 버전 관리
src/main/java/com/concrete/buildup/domain/document/controller/DocumentController.java
src/main/java/com/concrete/buildup/domain/employee/controller/EmployeeController.java
DocumentController 기본 경로를 /documents에서 /v1/documents로 변경
EmployeeController 기본 경로를 /sites/{siteId}/employees에서 /v1/sites/{siteId}/employees로 변경
서비스 계층 엔티티 마이그레이션
src/main/java/com/concrete/buildup/domain/employee/service/EmployeeMyService.java
AttendanceRecord를 Attendance로 교체, 6개월 데이터 범위를 LocalDate 기반으로 업데이트, 다중 단계 그룹화 로직을 단순 스트림 변환으로 제거, 배치 Site 조회로 N+1 방지 유지, 오늘 출석 조회 로직 리팩토링
대시보드 서비스 데이터 접근 리팩토링
src/main/java/com/concrete/buildup/domain/site/service/DashboardService.java
AttendanceRecord에서 Attendance로 마이그레이션, findBySiteIdAndSearchDate 쿼리 활용, 직원별 고유 ID 계산으로 단순화, 이전 N+1 쿼리 로직 제거
유틸리티 및 설정 파일 삭제
BCryptHashGenerator.java
CONTRIBUTING.md
DEPLOYMENT-GUIDE.md
테스트 암호 해시 생성 프로그램 삭제
기여 가이드 문서 삭제
배포 가이드 문서 삭제
테스트 데이터 파일 삭제
dashboard-test-data.sql
ec2-additional-test-data.sql
ec2-korean-test-data.sql
ec2-test-data-english.sql
ec2-test-data.sql
사이트별 대시보드 테스트 데이터 세트 제거
EC2 시나리오 테스트 데이터 스크립트 제거
한글 테스트 데이터 인구 스크립트 제거
영문 EC2 테스트 데이터 스크립트 제거
EC2 프론트엔드 테스트 데이터 초기화 스크립트 제거
스키마 및 마이그레이션 파일 삭제
local-schema.sql
local-tables-summary.txt
migrations/cleanup-work-reports-schema-20250127.sql
migrations/sync-schema-20250126.sql
로컬 데이터베이스 전체 스키마 DDL 제거
로컬 데이터베이스 테이블 구조 문서 제거
work_reports 테이블 컬럼 정리 마이그레이션 제거
로컬/EC2 스키마 동기화 마이그레이션 스크립트 제거
API 테스트 스크립트 삭제
test-api.sh
test-api-cookies.sh
test-api-simple.sh
기본 API 엔드포인트 테스트 스크립트 제거
쿠키 기반 인증 API 테스트 스크립트 제거
간단한 API 엔드포인트 테스트 스크립트 제거

예상 코드 리뷰 난이도

🎯 3 (중간) | ⏱️ ~25분

  • 주의가 필요한 영역:
    • EmployeeMyService.java: AttendanceRecord에서 Attendance로의 복잡한 데이터 변환 로직 검증 필요 (메서드 getMyAttendanceList, getTodayAttendance 내 stream 처리 및 siteName/status 도출 로직)
    • DashboardService.java: 집계 로직 단순화로 인한 정확성 검증 필요 (todayAttendance 개수 계산, todayLateCount 변경 로직)
    • AttendanceRepository 신규 메서드와 기존 사용처 호환성 확인 필요

관련 PR

🐰 Attendance의 춤을 추네요,
레코드는 작별, 새 엔티티 환영!
v1의 길로 API 버전업,
테스트 파일들 안녕히~ 잘 가요 👋
리팩토링의 봄, 우리 함께 걸어요!

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목이 주요 변경사항인 attendances 테이블 조회 및 v1 엔드포인트 통일을 명확하게 요약하고 있습니다.
Description check ✅ Passed PR 설명이 템플릿의 모든 주요 섹션(Jira 이슈, 변경사항 요약, 변경 목적, 변경 내역, 테스트 방법, Breaking Changes, 체크리스트)을 완벽하게 작성했습니다.
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 feature/BU-231

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 826b0f4 and 4fa1d0f.

⛔ Files ignored due to path filters (2)
  • docker-test-output.log is excluded by !**/*.log
  • test-output.log is excluded by !**/*.log
📒 Files selected for processing (15)
  • BCryptHashGenerator.java (0 hunks)
  • CONTRIBUTING.md (0 hunks)
  • DEPLOYMENT-GUIDE.md (0 hunks)
  • dashboard-test-data.sql (0 hunks)
  • ec2-additional-test-data.sql (0 hunks)
  • ec2-korean-test-data.sql (0 hunks)
  • ec2-test-data-english.sql (0 hunks)
  • ec2-test-data.sql (0 hunks)
  • local-schema.sql (0 hunks)
  • local-tables-summary.txt (0 hunks)
  • migrations/cleanup-work-reports-schema-20250127.sql (0 hunks)
  • migrations/sync-schema-20250126.sql (0 hunks)
  • test-api-cookies.sh (0 hunks)
  • test-api-simple.sh (0 hunks)
  • test-api.sh (0 hunks)
💤 Files with no reviewable changes (15)
  • CONTRIBUTING.md
  • migrations/cleanup-work-reports-schema-20250127.sql
  • test-api-simple.sh
  • local-tables-summary.txt
  • ec2-korean-test-data.sql
  • test-api-cookies.sh
  • test-api.sh
  • ec2-test-data-english.sql
  • ec2-test-data.sql
  • local-schema.sql
  • DEPLOYMENT-GUIDE.md
  • dashboard-test-data.sql
  • ec2-additional-test-data.sql
  • migrations/sync-schema-20250126.sql
  • BCryptHashGenerator.java

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.

@Sewoni Sewoni self-assigned this Dec 1, 2025
@Sewoni Sewoni linked an issue Dec 1, 2025 that may be closed by this pull request
1 task
@Sewoni Sewoni changed the title fix: 근태 조회 API attendances 테이블 조회 및 v1 엔드포인트 통일 fix/BU-231: 근태 조회 API attendances 테이블 조회 및 v1 엔드포인트 통일 Dec 1, 2025
Copy link
Contributor

@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: 1

Caution

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

⚠️ Outside diff range comments (1)
src/main/java/com/concrete/buildup/domain/site/service/DashboardService.java (1)

203-221: Remove unused method isContractActiveOnDate

The method at lines 203-221 is not called anywhere in the codebase. It appears to be leftover from the previous AttendanceRecord-based implementation and can be safely deleted.

🧹 Nitpick comments (1)
DEMO-SCENARIO.md (1)

67-79: Markdown 린터 경고 - 테이블 앞뒤 빈 줄 누락

정적 분석 도구에서 테이블 앞뒤에 빈 줄이 필요하다고 경고합니다 (MD058). 시연 문서이므로 선택적으로 수정하셔도 됩니다.

예시 수정:

 #### 기업 관리자
+
 | 항목 | 값 |
 |------|-----|
 | 아이디 | buildup_corp |
 | 비밀번호 | Test1234! |
 | 이름 | 김건설 |
+
 #### 현장 관리자
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 778a888 and 826b0f4.

📒 Files selected for processing (6)
  • DEMO-SCENARIO.md (1 hunks)
  • src/main/java/com/concrete/buildup/domain/attendance/repository/AttendanceRepository.java (1 hunks)
  • src/main/java/com/concrete/buildup/domain/document/controller/DocumentController.java (1 hunks)
  • src/main/java/com/concrete/buildup/domain/employee/controller/EmployeeController.java (1 hunks)
  • src/main/java/com/concrete/buildup/domain/employee/service/EmployeeMyService.java (6 hunks)
  • src/main/java/com/concrete/buildup/domain/site/service/DashboardService.java (4 hunks)
🧰 Additional context used
🪛 markdownlint-cli2 (0.18.1)
DEMO-SCENARIO.md

67-67: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)


74-74: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)


101-101: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


123-123: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


144-144: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


165-165: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


181-181: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


195-195: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


215-215: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


228-228: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


240-240: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


269-269: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


284-284: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


296-296: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


309-309: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


324-324: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


339-339: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


362-362: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


382-382: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


393-393: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


405-405: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


412-412: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


424-424: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


443-443: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


456-456: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


469-469: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


481-481: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


499-499: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


513-513: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


527-527: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


547-547: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


562-562: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


574-574: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


594-594: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


604-604: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


620-620: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


642-642: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


665-665: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


679-679: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


691-691: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


709-709: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


719-719: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)


731-731: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


740-740: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)


752-752: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


767-767: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)


772-772: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


787-787: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


822-822: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


833-833: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


850-850: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


857-857: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


869-869: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


892-892: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


920-920: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


996-996: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


1006-1006: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


1016-1016: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


1026-1026: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


1033-1033: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


1042-1042: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


1048-1048: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


1057-1057: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


1069-1069: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build-and-test
🔇 Additional comments (7)
src/main/java/com/concrete/buildup/domain/attendance/repository/AttendanceRepository.java (1)

95-102: LGTM!

Spring Data JPA 명명 규칙을 따르는 새로운 쿼리 메서드입니다. DashboardService에서 현장별 일일 출석 조회에 적절하게 활용됩니다. 기존 repository 패턴과 일관성 있게 구현되었습니다.

src/main/java/com/concrete/buildup/domain/document/controller/DocumentController.java (1)

27-27: LGTM - API 버전 프리픽스 통일

/documents/v1/documents로 엔드포인트가 변경되었습니다. PR 목표에 따른 API 버전 통일 작업으로, EmployeeController/v1/sites/{siteId}/employees 변경과 일관성을 유지합니다.

프론트엔드에서 해당 엔드포인트 경로 업데이트가 필요합니다. 문서 관련 API 호출 경로가 모두 수정되었는지 확인해 주세요.

src/main/java/com/concrete/buildup/domain/employee/controller/EmployeeController.java (1)

33-33: LGTM - API 버전 프리픽스 통일

/sites/{siteId}/employees/v1/sites/{siteId}/employees로 엔드포인트가 변경되었습니다. DocumentController와 동일하게 v1 프리픽스가 적용되어 API 버전 관리가 통일되었습니다.

src/main/java/com/concrete/buildup/domain/site/service/DashboardService.java (1)

177-199: LGTM - AttendanceRecord에서 Attendance로의 마이그레이션

출근/지각 인원 계산 로직이 개선되었습니다:

  • findBySiteIdAndSearchDate를 사용한 효율적인 조회
  • distinct()를 통한 중복 제거로 동일 근로자 중복 카운팅 방지
  • Boolean.TRUE.equals()로 null-safe한 지각 여부 체크

기존 N+1 문제가 있던 로직 대비 더 깔끔하고 효율적인 구현입니다.

src/main/java/com/concrete/buildup/domain/employee/service/EmployeeMyService.java (3)

92-127: LGTM - 출퇴근 내역 조회 로직 개선

AttendanceRecord에서 Attendance 엔티티로의 마이그레이션이 잘 구현되었습니다:

  • LocalDate 기반 조회로 타임스탬프 범위 조회 대비 단순화
  • Site 정보 일괄 조회로 N+1 문제 방지 유지
  • 스트림 기반 변환으로 가독성 향상

147-160: LGTM - 근태 상태 결정 로직

Attendance 엔티티의 checkOutTimesearchDate를 기반으로 상태를 결정하는 로직이 명확합니다. 퇴근 완료/근무중/미퇴근 상태 구분이 적절합니다.


289-312: LGTM - 금일 근태 조회 로직

Attendance 테이블 기반으로 금일 근태를 조회하는 로직이 잘 구현되었습니다. 첫 번째 출근 기록을 반환하는 것은 홈 화면 표시 목적에 적합합니다.

- 테스트 데이터 SQL 파일 삭제
- 테스트 스크립트 및 로그 파일 삭제
- 임시 문서 파일 삭제
@Sewoni Sewoni merged commit e69ca95 into develop Dec 1, 2025
4 checks passed
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.

[BU-231] [BE] 근로자용 api hotfix

2 participants