근태 관리 스펙
개요
근태 관리 스펙은 Simple HR 프로젝트의 출퇴근 기록, 휴일근로 처리, 퇴근 미체크 자동화 등 근태 관련 핵심 기능을 정의합니다. 근무 정책 스펙 및 급여관리 스펙과 긴밀하게 연동됩니다.
출퇴근 기록
PC 출퇴근
- PC에서 출퇴근 등록 시 "지역이 아니라고 나옴" 버그가 보고됨 — 미수정 상태 fix-task-0624-26년-06월-24일-수정사항
- PC에서 출퇴근 체크가 되지 않는 문제가 추가로 보고됨 — 확인 필요 fix-task-0702-26년-07월-02일-수정사항
GPS 출퇴근
- GPS 기반 출퇴근 상세 스펙은 GPS 출퇴근 스펙 참조
GPS 출근 위치 저장 (미구현) fix-task-0703-26년-07월-03일-수정사항
- 출장 자주 가는 직원을 위해 GPS로 출근 가능하되, 출근하기 누르면 위치가 저장되도록 구현 필요 — 미구현
출퇴근 요청 승인 UI 개선 (0703)
fix-task-0703-26년-07월-03일-수정사항 에서 완료된 출퇴근 요청 승인 관련 개선 사항:
- 출퇴근 요청 승인 시 해당 직원의 근로정책 시작/종료 시간을 기본값으로 표시
- 결재라인 동그라미 UI로 변경 (사용자 결재 모달과 동일 디자인)
canAct순서 기반 로직: 본인 차례가 아니면 버튼 숨기고 "OOO님 결재 대기중" 표시- 레거시 데이터(결재선 없는 건)에서 결재자를 결재라인에 표시
approver_name필드명 통일- 반려사유를 상세 드로어 상단으로 이동, 배경/테두리 제거
- 사용자 결재 모달 enum 한글 매핑 추가 (
request_type,leave_type등) - 사용자 결재 모달
requested_time로컬 시간 변환
퇴근 미체크 자동 처리 스케줄러
퇴근을 체크하지 않은 레코드를 자동으로 처리하는 배치 스케줄러가 구현되었습니다. fix-task-0624-26년-06월-24일-수정사항
| 항목 | 내용 |
|---|---|
| 실행 주기 | 매일 KST 00:15 |
| 대상 범위 | 최근 7일 이내 퇴근 미체크 레코드 |
정책: AUTO_END_TIME | scheduled_end 시간으로 퇴근 자동 기록 + 근무시간/상태 재계산 |
정책: LEAVE_BLANK | 스킵 (빈 값 유지) |
| 중복 방지 | advisory lock (820620) 적용 |
| 급여 영향 | 없음 — 급여는 OvertimeRequest 기반이며 AttendanceRecord.overtime_hours 직접 읽지 않음 |
배포 후 수동 보정 현황
| 대상 | 건수 | 처리 방식 |
|---|---|---|
| HNT 6/17~6/24 퇴근 미체크 | 19건 | |
2~3월 (scheduled_end NULL) | 4건 | 필요 시 관리자 UI에서 수동 처리 |
form_id=NULL 레거시 계약 (HNT) | 0건 | 확인 완료 |
휴일근로 처리
휴일 관리 스펙에서 지정된 휴일에 근로 시 아래와 같이 처리됩니다. fix-task-0624-26년-06월-24일-수정사항
휴일근로 할증 자동 분리 (근기법 §56②)
- 일자별
OT_HOLIDAY8시간 이내: 1.5배 할증 - 8시간 초과분: 2.0배 할증 자동 분리
- 프로덕션 소급 대상: 0건 확인 완료
휴일 캘린더 부서 스코프 필터
- 버그 수정:
DEPARTMENT스코프 휴일이 전 직원에게 노출되던 문제 해결 - 해당 부서 직원에게만 휴일 표시되도록 필터링 적용
휴일 직원 화면 반영
휴일 지정 시 휴일근로 신청 후 출근 처리 (0714)
fix-task-0714 (26년 07월 14일 수정사항)
- 관리자가 휴일을 등록하면 해당일 직원들의 근태가 자동으로 "휴일"로 표시됨.
- 직원이 휴일근로 신청 후 승인받으면 출근 가능. 승인 없이는 출근 불가.
- 휴일에 승인을 받고 출근하면, 승인된 근무시간(출근·퇴근 시각)이 근태 기록에 정상 반영됨. 출퇴근 방법(버튼/GPS)에 관계없이 동일하게 적용.
- 출퇴근관리 화면에서 해당 직원의 정책명과 근무시간도 정상 표시.
신규 휴일 지정 시:
- 1.직원 화면 일정관리에 휴일 표시
- 2.직원 화면 근무관리에 휴일 표시
- 3.휴일 근로 시 → 근로신청 및 휴일근로로 인식 → 급여 반영
휴일/휴일근무 상태 표시 수정 fix-task-0702-26년-07월-02일-수정사항: 휴일 지정 시 직원 근태 현황에 "휴일"로 표시. 휴일근로 신청 후 출근하면 "휴일" 대신 "휴일근무"로 표시되어 근무 여부를 구분할 수 있도록 수정 완료. (기존 문제: 출근 클릭 시 출근 시간은 찍히나 상태가 "근무중"이 아닌 "휴일"로 표시되던 오류)
출퇴근관리 통계 누락 수정 (0714) fix-task-0714 (26년 07월 14일 수정사항)
- 출퇴근관리 화면 상단 통계(출근/지각/결근/휴가 수)에서 휴일에 출근한 직원과 외근 직원이 집계에서 빠지던 문제 수정. 이제 휴일 출근자는 "출근"으로, 미출근자는 "미출근"으로, 외근자는 "출근"으로 정상 집계.
- 오늘 및 미래 날짜에서 아직 출근하지 않은 직원이 "미출근(결근)"으로 표시되던 것을 "출근 전"으로 구분하여 표시. 출근 시간이 아직 되지 않은 직원도 결근으로 잘못 세지 않음.
- 회사 전체 휴일뿐 아니라 특정 부서에만 지정한 휴일도 동일하게 처리 — 해당 부서 직원에게만 적용.
근무 정책 이력 관리
근무 정책 스펙 연동 항목. fix-task-0624-26년-06월-24일-수정사항
- 요구사항: 근로 정책 수정 시 수정 시점을 입력하여, 해당 시점 이후부터만 변경 정책이 적용되어야 함
- 확인 완료: 이미 정상 구현되어 있음. 근로정책 수정 시 즉시 반영이 아니라 "언제부터 적용할지" 날짜를 선택할 수 있으며(최소 내일부터), 지정한 날짜가 되면 자동으로 새 정책이 적용됨. 이전 기록은 당시 정책 기준으로 보존됨. fix-task-0702-26년-07월-02일-수정사항
- 0714 재확인 완료 — 근로정책 변경 시 변경 시점 이후만 새 정책이 적용되고, 이전 근태 기록은 변경 전 정책이 그대로 유지됨. 근로정책 삭제 시에도 과거 출퇴근·급여 기록에 저장된 정책 정보는 사라지지 않고 보존됨. 적용시점 모달은 정책 값을 실제로 변경해야 뜨도록 변경됨 — 값 변경 없이 저장 시 "변경된 항목이 없습니다" 토스트만 표시. fix-task-0714 (26년 07월 14일 수정사항)
미구현 항목 (근무 정책 ↔ 근태 연동)
근로 정책 work_days OFF 요일 출근 차단 미구현 fix-task-0714 (26년 07월 14일 수정사항)
_resolve_scheduled_for_day()에서ShiftSchedule과Holiday만 확인하고,work_days의 OFF 요일은 체크하지 않음.- 예: 토요일을 OFF로 설정해도 Holiday로 등록하지 않으면 출근이 차단되지 않음.
- 조회 시(
get_my_attendance)에는 합성ATT_HOLIDAY레코드로 "휴무" 표시는 되지만,check_in()시점에is_off판정에work_days가 반영되지 않아 실제 출근 차단 안 됨. - 수정 대상:
backend/app/services/attendance_service.py—_resolve_scheduled_for_day()함수에work_daysOFF 요일 →is_off=True반환 추가. - 기존
check_in()흐름(is_off=True→OT_HOLIDAY승인 확인 → 없으면 차단, 있으면 허용)을 그대로 타므로, 연장근로(휴일근무) 승인 시 비근무 요일에도 출근 가능.
직원 상세 드로어 예약 근로정책 변경 표시 미구현 fix-task-0714 (26년 07월 14일 수정사항)
- 직원 개별로 근로정책 변경 시 "날짜 지정"으로 미래 적용일을 선택하면
EmployeeWorkPolicy에effective_from=미래날짜로 저장되지만, 드로어에서는 현재 적용 중인 정책명만 표시됨. - 예약 변경이 있을 때 "2026-08-01 부터 '야간정책' 변경 예정" 같은 표시 필요.
- 수정 대상: 백엔드
EmployeeDetail스키마에pending_work_policy_name,pending_work_policy_effective_from추가 +_employee_to_detail()에서 미래 EWP 조회 + 프론트 드로어 읽기 모드에 표시.
아래 항목들은 근무 정책 ↔ 급여 연동 현황 및 이슈 및 근로정책-급여-연동-현황분석.md에서 상세 추적 중입니다.
근로 정책 수정 폼 하드코딩 버그 (미완료) fix-task-0703-26년-07월-03일-수정사항
formNightSurcharge/formHolidaySurcharge가useState("50")으로 하드코딩, setter 없음 → 수정 시 항상 50을 전송 (DB 기본값 1.5와 단위 불일치)shift_day_boundary가null일 때"06:00"폴백 → 변경 없는데도 값이 달라져 불필요한scheduled_change생성- night/holiday surcharge rate 단위 통일 필요 (1.5 배수 vs 50 퍼센트)
상세 내용은 급여 계산 하드코딩 이슈 목록 및 개선 방향 참조
교대/변형근로 수동 배정 최소 연속 휴식 시간 검증 미구현 fix-task-0714 (26년 07월 14일 수정사항)
교대(변형)근로 관리 스펙 연동.
- 정책에
min_consecutive_rest_hours값 저장·로드는 정상. 변형근무 자동배정(auto_assign_variant_shifts)에서는rest_hours검증이 구현됨. - 수동 셀 클릭 배정(
assign_shift_roster,bulkCreate) 시에는 전일 퇴근~당일 출근 간격 검증이 없음. - 예: 야간(18:00~06:00) 다음날 바로 주간(06:00~18:00) 수동 배정 시 휴식 0시간이지만 경고/차단 없음.
- 수정 대상:
backend/app/services/policy_service.py—assign_shift_roster()+ 프론트 셀 배정(bulkCreate) 시 전일 퇴근~당일 출근 간격 검증 추가.
교대근로 순환 패턴(cycle_pattern) 기반 자동 배정 미구현 fix-task-0714 (26년 07월 14일 수정사항)
cycle_pattern(예:["D","D","D","OFF","N","N","OFF"])과rotation_cycle_days저장·로드는 정상이지만, 교대근무(SHIFT) 모드에서 패턴 기반 자동 순환 배정 로직이 없음.- 현재 자동배정(
auto_assign_variant_shifts)은 변형근무(VARIANT) 모드 전용. SHIFT 모드는 관리자가 수동으로 셀 배정해야 함. - 프론트에서 패턴 기반 법정한도 체크(주간시간 검증)는 구현됨. 백엔드 저장 시 패턴 유효성 재검증은 없음.
{"title":"근무 정책 연동 미구현 항목","columns":[{"name":"미구현","color":"red","items":[{"text":"근무일 변경 기준시간(shift_day_boundary): DB 저장되나 근태/급여 로직 미반영. 야간 교대 시 휴일근로/야간시간 집계 오류 가능","ref":"[[fix-task-0624-26년-06월-24일-수정사항]]"},{"text":"점심시간 휴게시간 차감(use_lunch_as_break): UI만 존재, DB 필드 없어 저장 안 됨. 근로시간 계산에 영향","ref":"[[fix-task-0624-26년-06월-24일-수정사항]]"},{"text":"선택근무 퇴근 허용시간(checkout_allow_from/to): UI만 존재, DB 필드 없어 저장 안 됨","ref":"[[fix-task-0624-26년-06월-24일-수정사항]]"},{"text":"탄력근로 시작 날짜(flexible_start_date): UI만 존재, DB 필드 없어 저장 안 됨. 탄력근무 주기 기준점","ref":"[[fix-task-0624-26년-06월-24일-수정사항]]"}]},{"name":"UI만 구현 (백엔드 미구현)","color":"orange","items":[{"text":"저녁시간 연장근로 제외(exclude_dinner_from_overtime): UI 토글만 존재, DB 필드·백엔드 로직 미구현. 구현 전까지 UI 숨김/비활성화 검토","ref":"[[fix-task-0624-26년-06월-24일-수정사항]]"},{"text":"대체휴일/대체근무(substitution_enabled): UI 토글만 존재, DB·백엔드 미구현. 구현 전까지 UI 숨김/비활성화 검토","ref":"[[fix-task-0624-26년-06월-24일-수정사항]]"},{"text":"출장 일정 사용(business_trip_enabled): DB·UI 있으나 자동 출퇴근 기록 채우는 로직 미구현","ref":"[[fix-task-0624-26년-06월-24일-수정사항]]"},{"text":"법정근로 내 연장 구분(legal_overtime_split): DB·UI 있으나 근태/급여 로직 미구현. 법내 연장(할증 없음) vs 법외 연장(1.5배) 구분","ref":"[[fix-task-0624-26년-06월-24일-수정사항]]"},{"text":"연장근로 입력 단위 제한(overtime_input_unit): DB·UI 있으나 신청 API에서 단위 검증 미구현","ref":"[[fix-task-0624-26년-06월-24일-수정사항]]"},{"text":"연장근로 최소시간 제한(overtime_min_input): DB·UI 있으나 신청 API에서 최소시간 검증 미구현","ref":"[[fix-task-0624-26년-06월-24일-수정사항]]"}]},{"name":"완료","color":"green","items":[{"text":"휴일근로 8시간 초과 자동 분리 (근기법 §56②): OT_HOLIDAY 1.5배/2.0배 자동 분리 및 급여 반영 완료","ref":"[[fix-task-0624-26년-06월-24일-수정사항]]"},{"text":"DEPARTMENT 스코프 휴일 부서별 필터 적용: 전 직원 노출 버그 수정","ref":"[[fix-task-0624-26년-06월-24일-수정사항]]"},{"text":"퇴근 미체크 자동 처리 배치 구현 (KST 00:15, advisory lock 적용)","ref":"[[fix-task-0624-26년-06월-24일-수정사항]]"}]}]}
{"title":"근무 정책 연동 미구현 항목","columns":[{"name":"미구현","color":"red","items":[{"text":"근무일 변경 기준시간(shift_day_boundary): DB 저장되나 근태/급여 로직 미반영. 야간 교대 시 휴일근로/야간시간 집계 오류 가능","ref":"[[fix-task-0624-26년-06월-24일-수정사항]]"},{"text":"점심시간 휴게시간 차감(use_lunch_as_break): UI만 존재, DB 필드 없어 저장 안 됨. 근로시간 계산에 영향","ref":"[[fix-task-0624-26년-06월-24일-수정사항]]"},{"text":"선택근무 퇴근 허용시간(checkout_allow_from/to): UI만 존재, DB 필드 없어 저장 안 됨","ref":"[[fix-task-0624-26년-06월-24일-수정사항]]"},{"text":"탄력근로 시작 날짜(flexible_start_date): UI만 존재, DB 필드 없어 저장 안 됨. 탄력근무 주기 기준점","ref":"[[fix-task-0624-26년-06월-24일-수정사항]]"}]},{"name":"UI만 구현 (백엔드 미구현)","color":"orange","items":[{"text":"저녁시간 연장근로 제외(exclude_dinner_from_overtime): UI 토글만 존재, DB 필드·백엔드 로직 미구현. 구현 전까지 UI 숨김/비활성화 검토","ref":"[[fix-task-0624-26년-06월-24일-수정사항]]"},{"text":"대체휴일/대체근무(substitution_enabled): UI 토글만 존재, DB·백엔드 미구현. 구현 전까지 UI 숨김/비활성화 검토","ref":"[[fix-task-0624-26년-06월-24일-수정사항]]"},{"text":"출장 일정 사용(business_trip_enabled): DB·UI 있으나 자동 출퇴근 기록 채우는 로직 미구현","ref":"[[fix-task-0624-26년-06월-24일-수정사항]]"},{"text":"법정근로 내 연장 구분(legal_overtime_split): DB·UI 있으나 근태/급여 로직 미구현. 법내 연장(할증 없음) vs 법외 연장(1.5배) 구분","ref":"[[fix-task-0624-26년-06월-24일-수정사항]]"},{"text":"연장근로 입력 단위 제한(overtime_input_unit): DB·UI 있으나 신청 API에서 단위 검증 미구현","ref":"[[fix-task-0624-26년-06월-24일-수정사항]]"},{"text":"연장근로 최소시간 제한(overtime_min_input): DB·UI 있으나 신청 API에서 최소시간 검증 미구현","ref":"[[fix-task-0624-26년-06월-24일-수정사항]]"}]},{"name":"완료","color":"green","items":[{"text":"휴일근로 8시간 초과 자동 분리 (근기법 §56②): OT_HOLIDAY 1.5배/2.0배 자동 분리 및 급여 반영 완료","ref":"[[fix-task-0624-26년-06월-24일-수정사항]]"},{"text":"DEPARTMENT 스코프 휴일 부서별 필터 적용: 전 직원 노출 버그 수정","ref":"[[fix-task-0624-26년-06월-24일-수정사항]]"},{"text":"퇴근 미체크 자동 처리 배치 구현 (KST 00:15, advisory lock 적용)","ref":"[[fix-task-0624-26년-06월-24일-수정사항]]"},{"text":"휴일/휴일근무 상태 구분 표시 수정: 휴일근로 신청 후 출근 시 '휴일근무'로 표시","ref":"[[fix-task-0702-26년-07월-02일-수정사항]]"},{"text":"근로정책 수정 시 적용 시점 선택 기능 정상 동작 확인 완료","ref":"[[fix-task-0702-26년-07월-02일-수정사항]]"}]}]}사용자 교대일정 화면 (/user/shift-schedule) — Mock→실 API 미연동
교대(변형)근로 관리 스펙 연동. 아래 항목은 현재 mock 데이터로 동작 중입니다. fix-task-0624-26년-06월-24일-수정사항
| 기능 | 현재 상태 | 필요 작업 |
|---|---|---|
| 캘린더(월/주간) | generateMonthShifts() mock | shiftScheduleApi / calendarApi.listAutoLayers() 연동 필요 |
| 다가오는 교대 사이드바 | 하드코딩 | 실 데이터에서 오늘 이후 N건 추출 로직 필요 |
| 교대변경 이력 | mock 테이블 | 사용자용 ShiftSwapRequest 조회 API 필요 (백엔드 미구현) |
| 교대변경 요청 모달 | UI만 존재 | 사용자용 ShiftSwapRequest 생성 API 필요 (백엔드 미구현) |
| 교대 희망 신청 | UI만 존재 | 백엔드 모델+API 전체 신규 필요 |
관련 스펙 및 문서
- 근무 정책 스펙 — 근태 계산 기준 정책 정의
- 급여관리 스펙 — 근태 데이터 기반 급여 산정
- 근무 정책 ↔ 급여 연동 현황 및 이슈 — 미구현 항목 상세 추적
- 휴일 관리 스펙 — 휴일 지정 및 휴일근로 처리 기준
- GPS 출퇴근 스펙 — GPS 기반 출퇴근 상세
- 교대(변형)근로 관리 스펙 — 교대근무 관련 상세
- 휴가 관리 스펙 — 휴가 및 연차 처리
- 결재 관리 스펙 — 근로신청 결재 연동
- 액션 아이템 — 미구현 항목 전체 추적
- 사직서 처리 워크플로 스펙 — 사직서 기안 → 자동 Resignation 생성 → 퇴직 처리 연동
- 모바일 앱 스펙 — 모바일 첨부파일 구현 등 모바일 근태 관련 기능
E2E 테스트 시나리오 (관리자 근태 관리)
전체 테스트 시나리오는 E2E 테스트 시나리오 - Part 1 관리자 (대시보드, 근태, 직원관리) 참조. 테스트 환경: 업체명 디비안츠, 최고관리자 허빈(deviantce@deviantce.com), 직원 김소민(somin@deviantce.com). E2E 테스트 시나리오 - Part 1 관리자 (대시보드, 근태, 직원관리)
출퇴근 관리 (/admin/attendance) 시나리오
| # | 시나리오 | 기대 결과 |
|---|---|---|
| 1 | 김소민이 출근 체크를 한 뒤 허빈이 출퇴근 관리에 진입한다 | 출근 시 상태 "근무중" + 출근 시간 기록, 퇴근 시 상태 "퇴근" + 퇴근 시간 기록 |
| 2 | 김소민이 출근 체크를 하지 않은 상태에서 허빈이 출퇴근 관리에 진입한다 | 김소민의 상태가 "미출근"으로 표시된다 |
| 3 | 김소민이 정책 출근 시간 이후에 출근 체크를 한다 | 김소민의 상태가 "지각"으로 표시되고, 지각 컬럼에 지각 시간(분)이 표시된다 |
상세 드로어: 기본정보(성명/사번/소속/직위/근로정책/전화번호)와 근무정보 표시 E2E 테스트 시나리오 - Part 1 관리자 (대시보드, 근태, 직원관리)
정책시간 자동인정: 미출근 상태에서 정책 시간으로 자동 기록 E2E 테스트 시나리오 - Part 1 관리자 (대시보드, 근태, 직원관리)
관리자 수정: 출근시각/퇴근시각/휴게/상태/사유 수정, 수정이력 저장 E2E 테스트 시나리오 - Part 1 관리자 (대시보드, 근태, 직원관리)
연장근로 관리 시나리오
- 관리자 직접 등록: 소속/근로유형/대상자/근로일/근로시간/사유 입력 E2E 테스트 시나리오 - Part 1 관리자 (대시보드, 근태, 직원관리)
- 신청 내역 조회: 이름/상태/소속/유형/근로일/근로시간/연장/금주누적/잔여/수당예상/승인자/신청사유 표시 E2E 테스트 시나리오 - Part 1 관리자 (대시보드, 근태, 직원관리)
휴가 관리 시나리오
휴가 관리 스펙 연동. 관리자 화면에서 지원하는 주요 시나리오: E2E 테스트 시나리오 - Part 1 관리자 (대시보드, 근태, 직원관리)
- 직원 상세: 기본정보 + 연차 현황(총 부여/사용/잔여)
- 연차 조정, 신청 승인/반려, 변동 이력
- 부서별 일괄 지급
- 연차촉진 (→ 연차촉진 스펙 참조)
교대근로/변형근로 시나리오
교대(변형)근로 관리 스펙 연동. E2E 테스트 시나리오 - Part 1 관리자 (대시보드, 근태, 직원관리)
- 교대근로 스케줄 구성 및 슬롯 배정
- 변형근로 자동 배정 및 세트 설정
교대근무 법정시간 초과 저장 허용 (0714): 기존에는 교대근무 패턴이 주 52시간을 초과하면 저장 버튼이 비활성화되어 정책 등록 자체가 불가능했음. 이제 법정 기준 초과 시에도 저장 버튼이 활성화되며, 저장 시 "법정 기준을 초과합니다. 저장하시겠습니까?" 확인 팝업이 뜸. 확인 시 정상 저장. 화면에 "법정 기준 초과 — 초과분은 대체 휴가로 해결할 수 있습니다" 안내 표시. fix-task-0714 (26년 07월 14일 수정사항)
근태결재 및 근태분석 시나리오
결재 관리 스펙 연동. E2E 테스트 시나리오 - Part 1 관리자 (대시보드, 근태, 직원관리)
- 결재 목록 조회, 승인/반려, 상세 내용 조회
- 근태분석: 종합/부서분석/개인성과/지각분석/준법리포트