/SimpleHR project
SimpleHR project

교대(변형)근로 관리 스펙

conceptedited by Cairni · 방금 · AIv12

개요

교대(변형)근로 관리는 Simple HR 프로젝트에서 교대근무 및 변형근무 부서를 조회·운영하는 기능이다. 근무 정책과 밀접하게 연동되며, 근태 관리의 실제 근무 패턴 기록에 영향을 준다. 2025-06-23 기준 최종 수정 현황이 반영되었다. fix-task-0623 (26년 06월 23일 수정사항) 2025-06-24 수정사항 추가 반영. fix-task-0624 (26년 06월 24일 수정사항) 2025-06-25 수정사항 추가 반영. fix-task-0625 (26년 06월 25일 수정사항) 2026-07-13 수정사항 추가 반영. fix-task-0713 (26년 07월 13일 수정사항) 2026-07-14 수정사항 추가 반영. fix-task-0714 (26년 07월 14일 수정사항) 2026-07-15 수정사항 추가 반영. fix-task-0715 수정사항


2025-06-23 수정 현황

사용자 교대일정 (/user/shift-schedule) — Mock→실 API 연동

항목상태상세
캘린더(월/주간)❌ 미구현generateMonthShifts() mock → shiftScheduleApi / calendarApi.listAutoLayers() 실 연동 필요
다가오는 교대 사이드바❌ 미구현하드코딩된 목 데이터 → 실 데이터에서 오늘 이후 N건 추출 로직 필요
교대변경 이력❌ 미구현Mock 테이블 → 사용자용 ShiftSwapRequest 조회 API 필요 (백엔드 미구현)
교대변경 요청 모달❌ 미구현UI만 존재 → 사용자용 ShiftSwapRequest 생성 API 필요 (백엔드 미구현)
교대 희망 신청❌ 미구현UI만 존재 → 백엔드 모델+API 전체 신규 필요
모바일 연장근로 메뉴 접근 경로❌ 확인 필요모바일 네비게이션에서 연장근로 메뉴 접근 경로 확인 필요

fix-task-0623 (26년 06월 23일 수정사항) fix-task-0624 (26년 06월 24일 수정사항) fix-task-0625 (26년 06월 25일 수정사항)

교대(변형)근로관리 페이지 (/admin/shift)

항목상태상세
우측 상단 날짜 필터 동작 불가✅ 완료교대 근로 관리 필터 작동 복구 fix-task-0612.md
휴가 승인·취소 시 스케줄 복원❌ 미지원휴가 승인 시 기존 ShiftSchedule 행 삭제 후 VACATION 삽입 → 취소 시 원래 스케줄 복원되지 않음. 직원 휴가 신청 시 해당 날짜를 휴가로 표시하고 스케줄 배정은 차단 필요 fix-task-0612.md
변형 근로 동적 수정 확인✅ 완료변형근무 슬롯 선택 팝업 레이아웃 수정 fix-task-0612.md
페이징 처리 통일✅ 완료전체 모듈에 일관된 페이징 방식 적용 fix-task-0623 (26년 06월 23일 수정사항)

2025-06-24 추가 수정 현황

근무일 변경 기준시간 및 근로정책 적용 시점

항목상태상세
shift_day_boundary (근무일 변경 기준시간)❌ 미구현DB 저장되지만 근태/급여 로직 미반영. 야간 교대근무 시 근무일 판정 기준으로, 미구현 시 휴일근로/야간시간 집계 오류 가능
근로정책 수정 시점 지정✅ 완료변경 시점 이후에만 새 정책 적용, 이전 근태 기록 보존. 삭제 시에도 과거 기록 보존. fix-task-0714 (26년 07월 14일 수정사항)

fix-task-0624 (26년 06월 24일 수정사항)

퇴근 미체크 자동 처리 스케줄러

항목상태상세
퇴근 미체크 자동 처리 배치✅ 완료매일 KST 00:15 실행. 최근 7일 이내 check_out_time IS NULL 레코드를 unchecked_checkout_policy 설정에 따라 자동 처리
AUTO_END_TIME✅ 완료scheduled_end 시간으로 퇴근 자동 기록 + 근무시간/상태 재계산
LEAVE_BLANK✅ 완료스킵(빈 값 유지)
advisory lock 중복 방지✅ 완료lock(820620)으로 multi-worker 중복 실행 방지. 급여 영향 없음(급여는 OvertimeRequest 기반)
HNT 수동 보정 대상✅ 완료6/17~6/24 19건은 스케줄러 자동 처리 대상. 2~3월 4건(scheduled_end NULL)만 관리자 UI에서 수동 처리 필요

fix-task-0624 (26년 06월 24일 수정사항)


휴가와의 연동 흐름


2025-06-25 추가 수정 현황

사용자 교대일정 (/user/shift-schedule) — 연동 상태 업데이트

아래 항목은 2025-06-25 기준으로도 미구현 상태가 유지된다. fix-task-0625 (26년 06월 25일 수정사항)

항목상태상세
캘린더(월/주간) 연동❌ 미구현실 API 연동 미완료
다가오는 교대 사이드바 연동❌ 미구현실 데이터 추출 로직 미완료
교대변경 이력 API❌ 미구현백엔드 API 미구현
교대변경 요청 모달 API❌ 미구현백엔드 API 미구현
교대 희망 신청❌ 미구현백엔드 모델+API 전체 신규 필요
모바일 연장근로 메뉴 접근 경로❌ 확인 필요모바일 네비게이션에서 연장근로 메뉴 접근 경로 확인 필요

근로정책 급여 연동 — 2025-06-25 완료/미완료 항목

항목상태상세
근무제 연동(LINKED) 정산방식 급여 반영✅ 완료
저녁시간 연장근로 제외(exclude_dinner_from_overtime)✅ 완료
연장근로 입력 단위 제한(overtime_input_unit)✅ 완료
연장근로 최소시간 제한(overtime_min_input)✅ 완료
점심시간 휴게시간 차감(use_lunch_as_break)✅ 완료
선택근무 퇴근 허용시간(checkout_allow_from/to)✅ 완료
선택/탄력근무 출근 허용시간(flex_start_from/to)✅ 완료출퇴근 허용시간 검증 및 에러 메시지 형식 통일 포함
법정근로 내 연장 구분(legal_overtime_split)✅ 완료
모바일 연장근로 메뉴 접근 경로❌ 확인 필요
대체휴일/대체근무(substitution_enabled)❌ 미구현
근무일 변경 기준시간(shift_day_boundary)❌ 미구현DB 저장되지만 근태/급여 로직 미반영
출장 일정 사용(business_trip_enabled)❌ 미구현
탄력근로 시작 날짜(flexible_start_date)❌ 미구현

fix-task-0625 (26년 06월 25일 수정사항)

연장근로 시간대 겹침 방지 (신규)


2026-07-13 미구현 이슈 현황

수동 배정 시 최소 연속 휴식 시간 검증 미구현

근무 정책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.pyassign_shift_roster() + 프론트 셀 배정(bulkCreate) 시 전일 퇴근~당일 출근 간격 검증 추가

fix-task-0713 (26년 07월 13일 수정사항) fix-task-0715 수정사항

교대근로 순환 패턴(cycle_pattern) 기반 자동 배정 미구현

cycle_pattern(예: ["D","D","D","OFF","N","N","OFF"])과 rotation_cycle_days 저장·로드는 정상이지만, 교대근무(SHIFT) 모드에서 패턴 기반 자동 순환 배정 로직이 없다.

  • 현재 자동배정(auto_assign_variant_shifts)은 변형근무(VARIANT) 모드 전용. SHIFT 모드는 관리자가 수동으로 셀 배정해야 함
  • 프론트에서 패턴 기반 법정한도 체크(주간시간 검증)는 구현됨. 백엔드 저장 시 패턴 유효성 재검증은 없음

fix-task-0713 (26년 07월 13일 수정사항) fix-task-0715 수정사항

직원 상세 드로어에서 예약된 근로정책 변경 표시 미구현

교대근무 법정 기준 초과 시 저장 차단 → 경고 후 저장 허용으로 변경 (2026-07-14 완료)

기존에는 교대근무 패턴이 주 52시간을 초과하면 저장 버튼이 비활성화되어 정책 등록 자체가 불가능했다. 삼성서울병원 전화예약실 등 실제 교대근무 고객사가 테스트 중 등록 불가 문제를 겪었다. fix-task-0714 (26년 07월 14일 수정사항)

  • 수정 완료 — 법정 기준 초과 시에도 저장 버튼이 활성화됨
  • 저장 클릭 시 "법정 기준을 초과합니다. 저장하시겠습니까?" 확인 팝업 표시
  • 확인 누르면 정상 저장; 화면에 "법정 기준 초과 — 초과분은 대체 휴가로 해결할 수 있습니다" 안내 표시

직원 개별로 근로정책 변경 시 "날짜 지정"으로 미래 적용일을 선택하면 EmployeeWorkPolicyeffective_from=미래날짜로 저장되지만, 드로어에서는 현재 적용 중인 정책명만 표시된다.

  • 예: "2026-08-01 부터 '야간정책' 변경 예정" 같은 안내 표시 필요
  • 수정 대상: 백엔드 EmployeeDetail 스키마에 pending_work_policy_name, pending_work_policy_effective_from 추가 + _employee_to_detail()에서 미래 EWP 조회 + 프론트 드로어 읽기 모드에 표시

fix-task-0713 (26년 07월 13일 수정사항)

같은 날 연장근로 신청 시

근로정책 수정 시 적용 시점 이전 데이터 소급 적용 문제 (2026-07-14 완료)

근로정책 수정 시 과거 데이터까지 소급 적용되던 문제가 수정되었다. fix-task-0714 (26년 07월 14일 수정사항)

  • 수정 완료 — 근로정책 변경 시 변경 시점 이후에만 새 정책이 적용되고, 이전 근태 기록은 변경 전 정책이 그대로 유지됨
  • 근로정책 삭제 시에도 과거 출퇴근·급여 기록에 저장된 정책 정보는 삭제되지 않고 보존됨
  • 적용 시점 모달: 사용 중인 정책은 내일 이후만 선택 가능하며, 미래 날짜 선택 시 예약 변경으로 저장되고 변경 이력 조회/취소 가능
  • 값 변경 없이 저장 시 "변경된 항목이 없습니다" 토스트만 표시

근무 정책 스펙 참조

work_days OFF 요일 출근 차단 미구현 (2026-07-14 신규 이슈, 2026-07-15 수정 완료)


2026-07-15 수정사항 현황

work_days OFF 요일 출근 차단 수정 완료 (2026-07-15)

근태 관리_resolve_scheduled_for_day()work_days OFF 체크가 추가되고, get_user_dashboard()에 주휴일 판정이 추가되어 출근 버튼 비활성화가 구현되었다. OT_HOLIDAY 승인 시 출근 허용 흐름은 동일하다. (커밋: 0e9ac95) fix-task-0715 수정사항

근로정책 적용시점 반영 및 이력 덮어쓰기 수정 완료 (2026-07-15)

근무 정책의 적용시점 저장 및 이력 관리가 전면 개선되었다. fix-task-0715 수정사항

수정 항목내용
이력 덮어쓰기 방지항상 신규 EWP INSERT, 기존 EWP는 effective_to 설정으로 종료
날짜 기반 활성 판정is_primary 플립 대신 effective_from/to 날짜 범위 + ORDER BY effective_from DESC로 활성 정책 결정
미래 예약 처리적용일 도래 시 Read 쿼리가 자연 전환; 스케줄러(close_superseded_ewps)가 이전 EWP의 effective_to 자동 채움
적용시점 표시EmployeeDetail 응답에 work_policy_effective_from, scheduled_work_policy_name, scheduled_work_policy_date 추가, 드로어에 표시
이력 모달GET /employees/{id}/work-policy-history API + 프론트 변경이력 모달 (적용중/예약중/취소 배지)
  • 배포 체크리스트: docs/fix_tasks/0715/report/deploy-checklist.md

미구현 항목 (2026-07-15 기준)

근태 관리에서 _resolve_scheduled_for_day()ShiftScheduleHoliday만 확인하고, work_days의 OFF 요일은 체크하지 않는다. fix-task-0714 (26년 07월 14일 수정사항)

  • 예: 토요일을 OFF로 설정해도 Holiday로 등록하지 않으면 출근이 차단되지 않음
  • 조회 시(get_my_attendance)에는 합성 ATT_HOLIDAY 레코드로 "휴무" 표시는 되지만, check_in() 시점에 is_off 판정에 work_days가 반영되지 않아 실제 출근 차단 안 됨
  • 수정 대상: backend/app/services/attendance_service.py_resolve_scheduled_for_day() 함수에 work_days OFF 요일 → is_off=True 반환 추가
  • 수정 후 기존 check_in() 흐름(is_off=True → OT_HOLIDAY 승인 확인 → 없으면 차단, 있으면 허용)을 그대로 타므로 연장근로(휴일근무) 승인 시 비근무 요일에도 출근 가능
2026-07-15 수정 완료. _resolve_scheduled_for_day()work_days OFF 체크 추가 및 get_user_dashboard()에 주휴일 판정 추가. fix-task-0715 수정사항

시간대가 겹치는 경우를 방지하는 OT_TIME_OVERLAP 검증이 추가되었다. fix-task-0625 (26년 06월 25일 수정사항)

  • 백엔드+프론트엔드 동시 적용
  • PC 위자드, 대시보드 빠른 신청, 모바일 3곳에서 날짜/시간 입력 시 겹침 실시간 검증
  • 겹침 감지 시 빨간 글씨 안내 + 신청 버튼 차단
  • 통합 테스트(test_checkin_allow_time.py, test_overtime_time_overlap.py) 추가

현재 상태: 휴가 취소 시 원래 스케줄이 복원되지 않는 상태. 직원 휴가 신청 시점에 해당 날짜 스케줄 배정을 차단하는 로직 필요. fix-task-0612.md


핵심 구현: 교대 부서 조회

policy_service.pylist_shift_departments, _lookup_policy_for_department 두 함수에서 교대/변형근무 부서를 찾는 경로가 2개 존재한다. 시드 데이터로 인해 별도의 경로를 구현한 결과이다.

1차 — DepartmentWorkPolicy 경로

  • 관리자가 부서별 근로정책 UI에서 교대/변형 정책을 부서에 직접 할당한 경우 동작
  • DepartmentWorkPolicy 테이블 JOIN으로 조회
  • 직원에게 shift_team_name이 없어도 부서가 목록에 노출됨

2차 — Employee fallback 경로

  • 시드 데이터 등 직원에게 직접 shift_team_name + work_policy_id가 배정된 경우 동작
  • Employee.shift_team_name IS NOT NULL 조건으로 부서 역추적
  • DepartmentWorkPolicy 레코드가 없는 기존 데이터에서 동작

관련 페이지

Made with CairniExplore public wikis →