HBEA410_휴가신청
(Hereby) 직원 앱 > 결재 허브([[HBEA400_결재 허브]]) > 휴가신청
| 앱 | 직원 앱 (Hereby Works, 포트 4002) |
| 대상 사용자 | 조건3 [EMPLOYEE] (self scope 인증 세션) |
| 프로토타입 | TBU |
| 관련 정책 | [[POL_결재워크플로우]] · [[POL_연차부여]] |
| Status | review |
| Owner | 카나 |
개요
휴가신청은 결재 허브([[HBEA400_결재 허브]]) 첫 서브탭으로, 상단 연차현황 카드 + 신청 내역 리스트 + FAB(+) 휴가 신청 폼으로 구성된다. 신청은 leave_requests 레코드를 self scope로 생성(status=pending)하며, 승인/반려/취소는 관리자 결재([[HBAD251_연차 현황·결재]])가 처리한다 — 직원 측에는 상세 진입·취소 경로가 없다. 휴가 유형은 Admin 휴가 유형([[HBAD261_유형 설정 (연장근무·외근·휴가)]])을 소비하며, 커스텀 유형 문자열도 관측된다(census 실데이터 "ㅅㄷㄴㅅ"). 공통 서브탭 골격(상태 필터 칩·FAB·신청→결재 흐름)은 [[HBEA400_결재 허브]]을 참조한다(중복 정의 금지).
문서 히스토리
| 날짜 | 작성자 | 팀 | 변경 내용 |
|---|---|---|---|
| 2026-07-06 | 카나 | PM | 최초 작성 |
| 2026-07-10 | 카나 | PM | 라이브 기능 검토 반영 |
| 2026-07-13 | 카나 | PM | 버튼 행동 명세 보강 |
| 2026-07-21 | 카나 | PM | GC700 깊이 재작성 |
| 2026-07-21 | 카나 | PM | 셀 스타일 확정판 적용 (콸 승인) |
| 2026-07-21 | 카나 | PM | TC 크로스체크 확정분 반영 (🟡) |
| 2026-07-23 | 카나 | PM | 코드 변경 반영(2577546·425fac8·3b25572·318f7e1) |
| 2026-07-24 | 카나 | PM | 코드 변경 반영(04b1b82·7e16a37) |
| 2026-09-26 | 카나 | PM | 개발측 직접 보강(9/18 ㄴ31 사유 프리셋 원천 = 유형별 reasonPresets) 미러·컨플 부본에 역수용 — 정본(docs/spec) 우선 |
| 2026-10-07 | 카나 | PM | PR #1035 반영(bf34a923·c575f11a): 칸 아래 오류+자동 스크롤(50)·도움 시트(51)·초안 저장 14일(52) · PR #1053 반영(90b7cf44, MED-901): 시간 단위 휴가 선택기 격자(53) — 커밋 근거, 라이브 실사 이월(TBU) |
| 2026-10-09 | 카나 | PM | PR #1122(결재선) 반영 + 라이브 실사(웹): 결재자(받는 사람) 줄(60)·결재자 지정 풀레이어(61)·「신청하기」 하단 고정+필수 칸 게이트+submitHint(40 보강, cf5521c5·f6143234) |
| 2026-10-10 | 카나 | PM | (10/9 머지분) PR #1127(MED-959) 반영: 승인된 휴가 「취소 신청」 — 범위(전체/오늘부터 남은 날)·사유·철회·연차 복원(ㄴ33 신설), 내역 행 상세 진입·「신청 취소」 10/10 실측 정정(ㄴ31) · 주간 스윕 재실증: 결재자 줄(60) 오류 폴백 "보내면 서버가 결재자를 정해요." 실측·지정 풀레이어(61) 재확인(▲▼ 순서 버튼 존재, 다건 이동 동작은 TBU) |
| 2026-10-13 | 카나 | PM | (10/10~12 머지분) PR #1137(MED-957·958) 반차·신청 단위·서버 차감 미리보기(54) · #1198 시간 단위 다일 기간(ㄴ21 — 10/13 라이브 실측) · #1192·#1196(MED-984) 비근무일 경고·판정 교정(55) · #1143(MED-968) 초과 사용 정책 · #1191(MED-983) 신청 중 미리 빼기(56, 10 보강) |
| 2026-10-14 | 카나 | PM | (10/13 머지분, 72b404f — 프로덕션 배포) 54 비고 보강: 차감 미리보기 날짜를 UTC 달력일(calendarDateInput)로 전송 — 종전 로컬 자정 전송이 서버 UTC 절단으로 하루 앞 날짜 판정(월요일 신청이 「쉬는 날」 0일, 토요일 1일 차감, MED-984 3차 QA). 제출 경로는 원래 정상 — 미리보기만 교정, 두 경로 변환 단일화 - 카나/PM |
| 2026-10-17 | 카나 | PM | 주간 정합 스윕 라이브 실측 — ① 휴가 신청 폼 상단 「남은 연차 11일」 노출 확인(10 연차현황·#1191 연동, 홈 버튼 「휴가 신청 남은 연차 11일」·신청 탭 「연차현황 11일 남음 (올해 11일 중 0일 사용)」 동시 확인) ② 유형 select 실측(예비군/반차/차감없음/테스트 등 org 커스텀 사유) · 「반차」 선택 시 시간 단위 입력 그룹 노출 — OQ 반차 항목 갱신(시간제 사유로 동작, isHalfDay UI 미실측 유지) ③ 사유 칩(개인 사정/병원 진료/가족 행사/건강 회복/여행)+결재자(받는 사람) 「소원영 급여담당 매니저 · 기본 · 보내면 이 분이 확인해요.」+「변경」 실측 ④ 폼 하단 고정 문구 「쉬는 날을 골라 주세요.」·「신청하기」 미입력 시 disabled 실측. #1192 비근무일 경고·61 ▲▼는 조작 수단·데이터 제약으로 이월 |
Data I/O
Server → Client
| 변수 | DB 엔티티.컬럼 | 값 없을 때 | 비고 |
|---|---|---|---|
| $ | leave_grants.grantedDays − 승인 사용일수 | 0/빈값 표기 | census "11 일 남음 / 올해 11일 중 0일 사용" |
| $ | leave_requests[] (self) | Empty "휴가 신청 내역이 없어요" | 본인 신청만 |
| $ | auth.getCurrentUser().leaveReasons (org 커스텀 휴가 사유) | 빈 select | 원천 = 조직 설정 organization.updateSettings({leaveReasons}) (HBAD 조직 설정). picker는 사유 id를 소비 (TC 확정: leave-request-custom-reason.test.ts). 모델 변경: 유형은 절대 시간이 아니라 차감 배수(종일 1 / 반차 0.5 / 반반차 0.25 / 차감 없음 0) + 시간 단위(hourly) 유형 2원 체계 (구 {hours, deductionDays} 서술 대체, 코드 반영: 318f7e1 leaveReasonSchema) |
| $ | leave_requests.status 집계 | 카운트 0은 라벨만 | census "전체 3 / 대기중 2 / 취소 1" |
Client → Server
| 액션 | 전달 값 | tRPC procedure | 권한 토큰 |
|---|---|---|---|
| 휴가 신청 ("신청하기") | leaveType·startDate·endDate·reason (·isHalfDay·halfDayPeriod). 시간 단위 유형 시: startTime·requestedMinutes(30분 단위) 추가 | leaveRequest.request (TC 라이브 확인) — leaveType은 enum 고정이 아니라 org 커스텀 휴가 사유 id를 수용. 커스텀 사유가 설정된 조직에서는 기본 LeaveType enum(ANNUAL 등) 전달 시 "Invalid leave type" throw(legacy enum 거부) (TC 확정: leave-request-custom-reason.test.ts). 서버 가드: 신청 기간 전체가 법정유급휴일(공휴일)이면 거절, 기간에 낀 공휴일은 차감 자동 제외 (코드 반영: 425fac8) / 당일 신청 시 이미 지난 시작 시간 차단 (코드 반영: 3b25572) / 유형별 허용 팀 아니면 본인 소속 팀 신청 차단 (코드 반영: 7e16a37) / 시간 단위 유형 선택 시 유형 defaultMinutes를 사용 시간에 프리필 (코드 반영: 04b1b82) (코드 반영: 2577546 LeaveRequest.requestedMinutes·startTime migration 1855) | self |
| 상태 필터 | statusKey | 리스트 필터 ([[HBEA400_결재 허브]]) | self |
외부 통합 (cross-app)
| 외부 시스템 | 데이터 | 동기/비동기 | 비고 |
|---|---|---|---|
| 관리자 결재 [[HBAD251_연차 현황·결재]] | 대기중 → 승인/반려/취소 상태 write-back | 비동기 | 직원 측 취소 경로 없음 |
| Admin 휴가 유형 [[HBAD261_유형 설정 (연장근무·외근·휴가)]] | leaveType 원천 | 동기 | select 옵션 |
| 연차 부여 기준 [[HBAD262_연차 부여 기준]] | grantedDays 부여 기준 | 동기 | 잔여 산정 |
화면 플로우 (Mermaid 의무)
휴가신청 사양표
| 번호 | 항목/기능명 | 타입 | 사양 및 기능 설명 | 연관/영향 범위 | 비고 |
|---|---|---|---|---|---|
| 00 | 화면 진입 조건 | - | 조건1 [직원 인증] · 결재 허브 "휴가신청" 서브탭 선택 시 노출 | 인증 세션 (self) | |
| 01 | 초기 상태 | Output | 연차현황 카드 + 상태 필터 칩 + 신청 내역 리스트. CASE01 [내역 있음] → 행 목록 / CASE02 [0건] → Empty 문구 | $ | |
| 10 | 연차현황 카드 | Card | 상단 카드. "11 일 남음" 강조 + "올해 11일 중 0일 사용" 보조. CASE01 [부여·사용 있음] → 잔여 계산값 표기. (10/12 머지, #1191, MED-983) 표시 잔여 = 사용 가능 일수(available = 원장 잔여 − 신청 중 차감 예정) — 신청 중(PENDING) 건이 있으면 "승인을 기다리는 N일을 미리 뺐어요. 반려되면 그만큼 돌아와요." 한 줄 추가(신청 폼 「남은 연차」·홈 한 줄도 동일 기준). 원장에는 쓰지 않음(반려·취소·철회 시 자연 복구) | leave_grants (grantedDays) · 사용일수 집계 · leaveRequest PENDING 차감 예정 | census 실데이터 · #1191 커밋 근거 — 문구 실사 TBU(실사 계정 신청 중 0건) |
| 20 | 상태 필터 칩 | Filter | • 신청 내역을 상태로 거르는 칩. "전체 3" / "대기중 2" / "승인" / "반려" / "취소 1"(카운트 0은 라벨만). 공통 사양 [[HBEA400_결재 허브]] • 클릭 → 목록 필터 | leave_requests.status | census 실 카운트 |
| 30 | 신청 내역 리스트 | List | 본인 휴가 신청 행 목록. 필터 칩에 종속 | leave_requests[] | TBU: ${leave_requests} 부재 → 리스트 비우고 Empty / 로드 실패 UI 미검증(무반응이면 버그 후보) |
| ㄴ31 | 내역 행 | Row | • 1행 = {유형} / {날짜} / {상태 배지}. ⚠ 10/10 실사 정정: 행 클릭 시 상세(2depth)가 열림 — 「진행 상황」(신청함→검토 중→결과)·신청 내용(신청일·사유)·하단 「신청 취소」(검토 중 건) 실측. 종전 "비인터랙티브" 기술은 2탭 재편(#1035) 이전 기준 • 검토 중 건 「신청 취소」 → 확인창 경유 취소([[HBEA400_결재 허브]] 05) | leave_requests (leaveType·startDate·reason·status) | census: "ㅅㄷㄴㅅ 7월 14일 가족 행사dd 대기" 등 · 10/10 상세 실측(반차 검토 중 건) |
| ㄴ33 | 승인된 휴가 — 취소 신청 (MED-959) | Feature | • (10/9 머지, #1127) 승인된 휴가 상세 하단: 종전 안내 "취소하려면 팀장에게 문의해 주세요." 대신 「취소 신청」 버튼 — 결재를 받아 취소 - 범위: 휴가 시작 전이면 전체, 이미 시작했으면 오늘부터 남은 날만(버튼 위에 "휴가 전체가 취소돼요" 또는 "10월 9일부터 남은 3일만 취소할 수 있어요"처럼 범위 표시 — 가이드 원문). 이미 끝난 휴가는 취소 불가 - 사유를 적어 보내면 목록 카드에 「취소 신청 중」 배지([[HBEA400_결재 허브]] 07). 휴가 상태는 결재 끝까지 「승인」 유지 - 결재 전 **「취소 신청 철회」**로 거둘 수 있음. 거절되면 상세에 거절 사유 표시 - 승인되면 휴가 취소(또는 종료일 단축)·차감 연차 복원·알림 수신. 처리는 결재선 밖 — 휴가 승인 권한 보유자 누구나([[HBTM210]]·[[HBAD251]]·직원 앱 결재할 문서) | leave_requests.cancelRequestedAt·cancelRequestReason·originalEndDate · 마이그레이션 1966 | 신설 (#1127) · 커밋+가이드 fragment 근거 — 승인된 휴가 데이터 없어 실사 TBU |
| ㄴ32 | 상태 배지 | Badge | "대기" / 승인 / 반려 / 취소. CASE01 [대기] · CASE04 [취소] 관측 | leave_requests_status_enum | TBU: enum 매핑 |
| ㄴ30-E | Empty | Text | 신청 0건 → "휴가 신청 내역이 없어요" (원문 카피) | ||
| 40 | 신청 작성 FAB | Button (+) | • 휴가 신청 폼을 여는 우하단 "+"(접근성 이름 "새 신청"). 조건3 [EMPLOYEE] self scope • 클릭 → "휴가 신청" 폼 모달 오픈 | 휴가 신청 폼 | 공통 FAB([[HBEA400_결재 허브]]) |
서브 화면 / 모달 사양표
휴가 신청 폼 (모달) 사양표
| 번호 | 항목/기능명 | 타입 | 사양 및 기능 설명 | 연관/영향 범위 | 비고 |
|---|---|---|---|---|---|
| 00 | 진입 조건 | - | 휴가신청 서브탭 FAB(+) "새 신청" 클릭 시 모달 오픈. 제목 "휴가 신청" | 40 FAB | |
| 01 | 초기 상태 | - | 유형 미선택 / 날짜 미입력 / 사유 빈 textarea. "신청하기" 노출 | ||
| 10 | 유형 | Select | • 휴가 유형(사유)을 고르는 드롭다운. org 커스텀 휴가 사유를 소비 — 옵션 원천 = auth.getCurrentUser().leaveReasons, 제출 시 사유 id 전달• 클릭 → 유형 드롭다운 오픈 - 규칙: 커스텀 사유 설정 조직에서는 기본 LeaveType enum(ANNUAL 등) 전달 시 "Invalid leave type" throw (legacy enum 거부) - 규칙: 유형별 팀 제한 — 본인 소속 팀이 유형의 허용 팀이 아니면 신청 불가(서버 검증, 코드 반영: 7e16a37) - CASE01 [시간 단위(hourly) 유형 선택]: 시간 단위 연차 입력 UI(ㄴ21) 노출 + 유형의 defaultMinutes가 사용 시간에 프리필(30분 단위 조정 가능, 코드 반영: 04b1b82) | auth.getCurrentUser().leaveReasons ← organization.updateSettings({leaveReasons}) (HBAD 조직 설정) | 커스텀 사유 id 소비 (TC 확정: leave-request-custom-reason.test.ts) · 유형 = 차감 배수/시간 단위 2원 체계(코드 반영: 318f7e1) · 팀 제한(7e16a37)·프리필(04b1b82) |
| 20 | 시작일·종료일 | DatePicker | • 휴가 적용 기간을 지정하는 "시작일" / "종료일" 2필드 • 입력 → 기간 설정 - 규칙: 신청 기간 전체가 법정유급휴일(공휴일)이면 접수 거절, 기간에 낀 공휴일은 차감 자동 제외 (서버 가드) - (10/10 머지, #1137, MED-957) 신청 단위(leaveReasonUnit)로 입력이 갈림: 종일·차감 없음 = 시작일~종료일(시간대 select 제거 — 2026-07 개편 때 들어간 날짜별 시간대 입력 폐지) / 반차 = 날짜 하나 + 「오전 반차」·「오후 반차」(0.5일, isHalfDay·halfDayPeriod 전송) / 시간 단위 = 기간 + 하루 사용 시간(ㄴ21) | leave_requests.startDate / endDate | 코드 반영: 425fac8 · 반차 UI는 차감 0.5 유형 등록 병원만 — 실사 조직 미등록이라 TBU(#1137) |
| ㄴ21 | 시간 단위 연차 입력 | Group | • 시간 단위(hourly) 유형 선택 시에만 노출되는 입력 그룹. (10/12 머지, #1198) 하루 단위 강제 폐지 — 종료일을 보여 시작일~종료일 기간 신청 가능(1건). 기간이 여러 날이면 라벨이 **「하루 사용 시간 *」**로 바뀌고 안내 "하루 2시간 = 0.29일씩 차감 · 기간의 근무일마다 선택한 시간만큼 연차가 차감돼요."(10/13 실측) — requestedMinutes는 하루당 값, 근무일마다 같은 시간 차감 - 시작 시간: 선택 입력(「시작 시간 (선택)」, 첫 옵션 「적지 않음」 — 10/13 실측, #1137) — 값이 있을 때만 자정 넘김·같은 날 시간대 겹침 검사, 같은 날 합계 상한은 항상 검사 - 사용 시간: 신청 시간 단위 격자(53) 입력 → leave_requests.requestedMinutes. 유형 선택 시 유형의 defaultMinutes가 프리필(코드 반영: 04b1b82) • 규칙: 다일 신청은 날마다 같은 날 시간 단위 신청의 시간대 겹침·하루 합계 상한 검사(오류 문구 앞에 날짜 — "2026-10-15 같은 날 신청 합계가 …") / 같은 날 일 단위 휴가와 병존 불가(기간 전체 기준) — 서버 가드 | leave_requests.startTime / requestedMinutes (migration 1855) | 코드 반영: 2577546 · 다일 기간·요약 "10월 21일 ~ 10월 23일 · 매일 2시간" 10/13 라이브 실측(#1198) · 관리자·팀장 차감 라벨 "3일 × 2시간" 형식은 [[HBAD251_연차 현황·결재]] 참조 |
| 30 | 사유 | Textarea | • 휴가 사유 자유 입력. "사유 (선택)", placeholder "휴가 사유" • 입력 → leave_requests.reason 채움 | leave_requests.reason | |
| ㄴ31 | 사유 프리셋 | Button group | • 클릭 → textarea에 해당 문구 삽입(자유편집 병행) • 원천(2026-09-18 변경): 선택한 유형의 leaveReasons[].reasonPresets(admin 유형 설정 [[HBAD261_유형 설정 (연장근무·외근·휴가)]] ㄴ31a에서 관리) — 3상: undefined(미관리)=기본 5종 "개인 사정"/"병원 진료"/"가족 행사"/"건강 회복"/"여행"(DEFAULT_LEAVE_REASON_PRESETS, 구 하드코딩과 동일) / []=칩 미노출 / [...]=관리 리스트 그대로. 판정 함수 leaveReasonPresetOptions(formatters.ts, TC: formatters.test.ts) | leave_requests.reason · leaveReasonSchema.reasonPresets | census 원문 프리셋 → 유형별 관리 전환(2026-09-18) |
| 40 | 신청하기 | Button | • 폼을 제출해 휴가 신청을 생성하는 버튼 • 클릭 → 즉시 제출(컨펌 없음), 성공: leave_requests(status=pending) 생성 + 내역 최상단 "대기" 행 추가 + 상태 칩 카운트 증가 + 모달 닫힘 → 관리자 결재([[HBAD251_연차 현황·결재]]) 인입 - 서버 가드: 기간 전체 공휴일 거절(425fac8) / 당일 지난 시작 시간 차단(3b25572) / 유형별 허용 팀 제한 — 본인 소속 팀 미허용 시 신청 차단(7e16a37) | leaveRequest.request({leaveType, startDate, endDate, reason}) (시간 단위 유형 시 startTime·requestedMinutes 추가) — leaveType = org 커스텀 사유 id (enum 아님). 커스텀 사유 설정 조직에서 legacy enum(ANNUAL 등) 전달 시 "Invalid leave type" throw (TC 확정: 01:1.3 leave / leave-request-custom-reason.test.ts) | 코드 반영: 2577546·425fac8·3b25572·7e16a37(팀 제한)·04b1b82(프리필) · (10/8, #1122, cf5521c5·f6143234) 버튼이 내용 맨 아래로 이동, 필수 칸이 다 차야 활성(checkRequestForm 한 벌, 신청서 6종 공통) — 꺼진 버튼 위에 빠진 칸 한 줄(submitHint, 라이브 원문 "쉬는 날을 골라 주세요." 2026-10-09 실측). TBU: 제출 실패 UI(무반응이면 버그 후보) |
| 50 | 칸 아래 오류 + 자동 스크롤 (제출 가드 개편) | Rule | • (10/7, #1035, bf34a923·c575f11a) 신청 버튼을 끄지 않고(보내는 중·올리는 중에만 비활성), 필수 칸이 비면 누를 때 그 칸 아래에 이유를 표시하고 그 칸으로 자동 스크롤. 같은 칸·같은 오류 반복 시 도움말·문의 안내 표시(닫기 가능) • 공용 로직 utils/field-guidance(칸 오류·반복 안내·스크롤) + utils/request-form-errors(검사 규칙) — 휴가·연장·외근 + 전 신청서 공통(서류 제출·인센티브·주말 당직·보고서·정정 요청·근무 형태 변경) | utils/field-guidance | 신설 (#1035) · 오류 문구 원문 TBU(실사 대기) |
| 51 | 도움 시트 | Sheet | • (10/7, #1035, bf34a923) 제목 줄 「도움」으로 신청서별 문답 시트 — 없는 내용은 불편·기능 신고로 연결. 도움 시트 없는 신청서는 반복 안내에서 「문의하기」만 표시. 문답 x-for key = 질문(값 기준) | — | 신설 (#1035) · 문답 내용 TBU(실사 대기) |
| 52 | 초안 저장 (나가기 가드) | Dialog | • (10/7, #1035, bf34a923) 써 넣은 것이 있는 신청서를 닫으면 저장/지우기/계속 작성을 물음. 저장한 초안은 이 기기에 사용자별 14일 보관(첨부 제외), 다시 열면 채워지고 홈 「지금 할 일」에 「이어서 작성」으로 표시([[HBEA200_근무 탭 (홈)]] 25) | utils/request-draft | 신설 (#1035) · 다이얼로그 원문 TBU(실사 대기) |
| 53 | 시간 단위 휴가 선택기 격자 | Select | • (10/7, #1053, 90b7cf44, MED-901) 시간 단위 휴가의 사용 시간·시작/종료 시각 선택지가 조직 설정 「신청 시간 단위」(15/30/60분, 기본 30분) 격자만 표시 — 기존 신청 값이 격자 밖이면 선택지에 끼워 보임 | organization.getRequestTimeStep · [[HBAD270_설정 (조직 설정·내 정보)]] ㄴ42 | 신설 (#1053) |
| 54 | 차감 미리보기 (서버 계산) | Rule | • (10/10 머지, #1137, MED-958) 신청 전 차감 일수를 서버가 셈 — 새 조회 leaveRequest.estimateDeduction이 승인 때 원장 계산(computeDeductionForRequest)과 같은 함수로 유형 배수·본인 소정근로시간·비근무일/공휴일 제외·듀티 근무를 반영. 입력 변경 시 잠깐 뒤 1회 조회, 응답이 현 입력과 맞을 때만 표시(응답 없으면 달력일 추정 「최대 N일」 폴백)• 표시(10/13 실측): 요약에 기간·「매일 N시간」·"연차 0.8571일 차감 · 남은 연차 11일 → 10.14일" / 쉬는 날이 끼면 "쉬는 날·공휴일 M일은 차감에서 빠져요"(커밋 근거) • (10/13, 72b404f) 미리보기 날짜 전송을 제출 경로와 같은 UTC 달력일(calendarDateInput)로 단일화 — 로컬 자정 전송이 서버 UTC 절단으로 하루 앞 요일·공휴일을 판정하던 결함(월요일 「쉬는 날」 0일 처리) 수정 | leaveRequest.estimateDeduction | 신설 (#1137) · 다일 시간 단위 10/13 실측(#1198) · UTC 교정(72b404f, 프로드) |
| 55 | 비근무일 신청 경고 | Notice | • (10/12 머지, #1192·#1196, MED-984) 고른 날이 전부 비근무일(근무형태 적용 요일 밖·공휴일)이라 차감 0이면 「0일 차감」 대신 경고 — "선택한 날은 근무일이 아니라 연차가 차감되지 않아요. 근무형태 「…」 기준으로 쉬는 날이에요."(미리보기 응답 nonWorkingDay·근무형태 이름). 신청 자체는 막지 않음(예비군·공가 등). 접수 결과 금액 줄도 「근무일이 아니라 연차 차감 없음」 • 판정 교정(#1196): applicableDays에 적힌 요일만 근무일(빠진 요일=쉬는 날, 없으면 월~금 가정) / 듀티는 확정·게시 근무표의 근무 배정일만 차감(OFF·휴가 칸 제외) — 근무표 없는 3교대는 신청일 그대로(duty_workdays) | leaveRequest.estimateDeduction (nonWorkingDay·workPatternName) | 신설 (#1192) · 실사 계정 3교대·근무표 없음이라 경고 미노출 정상 확인(10/13) — 경고 문구 실측 TBU |
| 56 | 잔여 초과(과사용)·신청 중 예약 | Rule | • (10/10·10/12 머지, #1143·#1191) 신청 한도·초과 판정은 사용 가능 일수(available = 원장 잔여 − 신청 중 차감 예정) 기준. 잔여보다 많으면 연차 정책 overuseMode([[HBAD262_연차 부여 기준]] 연차 정책)에 따라: 경고만(allow — 접수·승인됨, 잔여 마이너스 가능) / 결재자 확인(approver_confirm — 접수되고 승인 때 결재자가 「초과 승인」) / 차단(block — 접수 거절, "잔여 15일 중 신청 중 2일을 빼면 13일"형 문구)• 수정·재승인 중인 신청 자신은 예약에서 제외(이중 계산 방지) | resolveLeaveOveruseMode · available | 신설 (#1143·#1191) — 커밋 근거, 경고 UI 실사 TBU |
| 60 | 결재자(받는 사람) 줄 | Group | • (10/8, #1122) 폼 하단, 「신청하기」 위에 「결재자(받는 사람)」 줄 — 적용 중인 결재선의 결재자(이름·팀·역할)와 출처 태그(라이브: 「기본」), 안내 "보내면 이 분이 확인해요."(원문, 1단계 단수형) + 「변경」 버튼 • 결재자 결정 순서: 직원이 고른 결재선 → 팀 → 상위 팀 → 병원 기본 → 자동(팀장 → 인사 관리자) ([[POL_결재선]]) • 「변경」 클릭 → 결재자 지정 풀레이어(61). CASE01 [병원 공통 설정 직접 지정 OFF 또는 역할 제한]: 변경 불가·후보 제한(서버 검증) | ApprovalLine · approval_steps | 신설 (#1122, cf5521c5) · 라이브 실사 2026-10-09(「소원영 급여담당 매니저 · 기본」 실측) · 10/10 재실증 — 결재선 조회 일시 실패 시 줄에 오류 문구("실행 중 오류가 발생했습니다. 잠시 후 다시 시도해 주세요. …") + 폴백 안내 "보내면 서버가 결재자를 정해요." 표시(재진입 시 정상, 실측). 보내기 전 확인 시트의 결재자 줄도 결재 순서와 같은 모양 |
| 61 | 결재자 지정 풀레이어 | Layer | • (10/8, #1122) 제목 「결재자 지정」 — 상단 「결재 순서 · {n}/5명」 줄(위아래 이동·빼기) + 검색 + 후보 체크박스 목록(이름·소속·역할, 읽는 중에도 열림) + 「내 결재선으로 저장 — 다음 신청부터 이 결재자들이 자동으로 들어가요.」(원문) 체크 + 「{n}명 적용」 버튼 • 바텀시트 아님 — 신청서와 같은 풀레이어(2f3f6019). 검색 중 결재 순서 한 줄 접힘·키보드 동안 저장 바 숨김(모바일, cf5521c5) • 신청서 6종 공통 한 벌(approver-select.html) — 나의 결재선 편집([[HBEA400_결재 허브]] 06)과 동일 화면 | 공통 approver-select | 신설 (#1122) · 라이브 실사 2026-10-09 |
연동·플로우
- 신청 흐름: STEP1 [신청] FAB("새 신청") → 휴가 신청 폼 "신청하기"(
leaveRequest.request) → leave_requests(status=pending) 생성 → 내역 최상단 "대기" 행 추가·상태 칩 카운트 증가 → STEP2 [결재] 관리자 결재([[HBAD251_연차 현황·결재]]) 승인/반려/취소 → 상태 배지·필터 카운트 갱신. 직원 측 내역 행은 비인터랙티브(상세·취소 없음). - 연차 산정: 부여(leave_grants.grantedDays) − 승인 사용일수 = 잔여. 부여 기준은 Admin 연차 부여 기준([[HBAD262_연차 부여 기준]]) 소관. 모델 변경: 잔여 계산이 불변 원장(LeaveLedgerEntry, append-only) 기반으로 전환됨 (코드 반영: 318f7e1 — 상세 [[HBAD262_연차 부여 기준]]).
- 부수 변경 (코드 반영: 2577546 본문): 외근 신청 사유가 선택 입력으로 전환, 연장·외근·문서 모달 문구 정비 — 해당 모달은 [[HBEA420]] 소관(본 문서 외).
권한 / 상태 요약
| 시나리오 | 트리거 | 결과 | 비고 |
|---|---|---|---|
| CASE01 [폼 제출 성공] | "신청하기" | 대기 행 추가 + 칩 카운트 증가 | self scope |
| CASE02 [승인] | 관리자 결재 | 상태 배지 "승인", 연차 차감 | [[HBAD251_연차 현황·결재]] |
| CASE03 [반려] | 관리자 결재 (사유 필수) | 상태 배지 "반려" | 반려 사유 placeholder "반려사유를 입력해 주세요." |
| CASE04 [취소] | 관리자/TM 경로 | 상태 배지 "취소" | 직원 self-cancel 없음 |
| 조건3 [EMPLOYEE] | 내역 행 클릭 | 무반응 (비인터랙티브) | 상세·취소 경로 없음 |
Open Question
유형 커스텀 문자열("ㅅㄷㄴㅅ")이 Admin 유형 미선택 시 자유입력인지, 테스트 데이터 잔재인지. TBU.→ 해소: leaveType은 org 설정 커스텀 휴가 사유(organization.updateSettings({leaveReasons:[{id, name, hours, deductionDays}]}))의 id를 수용하며, picker는auth.getCurrentUser().leaveReasons를 소비. "ㅅㄷㄴㅅ" 등은 org 커스텀 사유 name (TC 확정: leave-request-custom-reason.test.ts).반차(isHalfDay/halfDayPeriod) 폼 노출 여부 및 잔여 차감 단위(0.5일). TBU.→ 해소(10/10, #1137): 신청 단위 「반차」 유형(차감 0.5)이 등록된 병원에서 날짜 하나 + 오전/오후 선택으로 노출, isHalfDay·halfDayPeriod 전송·0.5일 차감(유형 배수 우선, 구식 조직은 isHalfDay로 0.5). 목록·상세에 「· 오전」「· 오후」.실사 조직은 유형 미등록이라 화면 실측 TBU.→ (2026-10-17 주간 스윕) 실사 조직에 명칭 「반차」 유형이 등록됐으나 시간 단위(hourly) 커스텀 사유로 동작 — 선택 시 오전/오후가 아니라 ㄴ21 시간 단위 입력 그룹(「사용 시간 *」 30분~7시간 30분 단위 + 「시작 시간 (선택)」 적지 않음/00:00~23:30) 노출, 환산 안내 「4시간 = 0.57일 차감 · 선택한 시간만큼만 연차가 차감돼요」(소정 7h 기준 4/7) 실측. isHalfDay 오전/오후 UI는 여전히 미실측(이월) — 이 조직 「반차」는 명칭만 반차인 시간제 사유. 스샷 live-1017-ea-leave-form.png- 필수값 미입력·제출 실패 시 폼 동작(차단/토스트/무반응). 라이브 미검증. TBU.