Skip to content

HBAD201_직원 추가·수정 모달 ​

(Hereby) 관리자 패널 > App Shell > 인사 관리 > 직원 관리 > 직원 추가·수정 모달

메타앱: 관리자 패널 (App Shell)대상 사용자: 조건1 [직원 관리 권한 보유 역할]프로토타입: TBU관련 정책: [[POL_급여정본경계]] · [[POL_권한(RBAC)]]Status: reviewOwner: 카나

개요 ​

직원 추가·수정은 단일 모달 + 4단계 스텝(① 기본정보 / ② 인사정보 / ③ 자격증/면허 등록 / ④ 근로계약)이다. 1회 저장으로 4개 생성물이 동시 생성된다: ① Employee ② 소속(팀·역할 n:m) ③ 근로계약·급여 seed ④ 자격증 요건. 하단 버튼은 "취소" / "미리보기" / "등록"(저장 중 "등록 중..." disabled). 기본 상태는 비활성이다 (activation gate — 안내 "비활성 상태로 등록돼요. 사용하기 위해서는 재직으로 변경해 주세요."). 전화번호 입력 시 SMS 임시비밀번호 안내가 발송된다. 자격증/면허 요구를 선택하면 자격증 화면에 "파일 미제출" 상태로 등록된다. 급여 seed는 계약·호봉·수당·근무시간을 급여 원천으로 넘긴다 (POL_급여정본경계 — 정본 변환은 HR 시트 commit에서).

문서 히스토리 ​

  • 2026-07-06 최초 작성 - 카나/콸
  • 2026-07-10 라이브 기능 검토 반영 - 카나/콸
  • 2026-07-13 버튼 행동 명세 보강 - 카나/콸
  • 2026-07-17 코드 변경 반영(de57b65·0125f00) - 카나/콸
  • 2026-07-21 GC700 깊이 재작성 (라이브 재검증 7/20 — 4단계 전 필드·안내 원문·이탈 가드·등록 중 상태) - 카나/콸
  • 2026-07-21 가독성 패스 (GUIDE §7) - 카나/PM
  • 2026-07-21 셀 스타일 확정판 적용 (콸 승인) - 카나/PM
  • 2026-07-24 코드 변경 반영(c1b2158) - 카나/콸
  • 2026-09-16 병동 이중 배정 수정(팀 이동 시 한 줄로 합침·teamIds auto→move) 반영(#711 리뷰 후속, 1fce4e2) - 카나/콸
  • 2026-09-16 급여 제외 플래그(비급여 계정 대장 제외) 반영(#722, b8a8c77) - 카나/콸
  • 2026-09-18 직무 필드 마스터 연동 전환(직무 마스터 목록 선택 + 기본 근무 자동 채움 「직무 기본 → 팀 대표」 순서, 허용 근무형태 우선 노출, 직군 기본값) 반영(7f63a4b, #791) — 커밋 근거, 라이브 실사 이월(TBU) - 카나/PM
  • 2026-09-21 소속 피커 활성 전용화+검색 줄(공용 패널 동일 규칙, 65daef2 #809)·직무 기본 근무 안내 문구 플레이스홀더 치환 수정(d216f26 #802)·근무 배정 출처(shiftAssignedVia) 기록 반영(c4eb0f9 #804) — 커밋 근거, 라이브 실사 이월(TBU) - 카나/PM
  • 2026-09-23 직무 기본 근무와의 차이 표시(「≠ 직무 기본」·「기본」) + 기본 근무 재적용 규칙(33948ca, #851, MED-693)·직원 등록/수정 패널 「근로형태」(workPatternName) 항목 신설(73c0cb4, #823) 반영 — 커밋 근거, 라이브 실사 이월(TBU) - 카나/PM
  • 2026-09-25 낮 스윕 라이브 실사 — 직원 정보 수정 = 5탭 모달(기본정보/인사정보/자격증·면허/근로계약/계정·보안) 실측. 인사정보 탭 구성: 입사일 · 출근 기록 방식(조직 기본값/앱/지문 단말기(Secom)/관리자 수동 입력) · 소속(팀·역할) · 병동 배정 · 직무 · 근로형태(ㄴ50-4 원문 채록·TBU 해소) · 상태 · 근무 그룹(+「근무 유형 전체 보기」 링크) · 급여 지급 대상 토글 · 시스템 관리자 토글. 소속 피커 검색 줄(ㄴ30-1) 실측. info 안내 원문 "근무 형태는 근태 현황의 근무 설정에서 추가/수정 가능해요." - 카나/PM
  • 2026-10-01 「고정 수당」 탭 신설(반복 고정 수당 정의 — 목록·상태 배지·종료일 저장·금액 정정·추가)(dea7be96, #969)·계정·보안 「직접 설정」 임시 비밀번호 형식 허용(01d3cc5b, #948)·퇴직 취소(재직 복귀) 흐름(기본정보 안내·상태 드롭다운 항목·사유 필수·정산 완료 거절)(25e9ddfa, #959)·신규 입사자 시트 자동 추가 미리보기/완료 안내(6ea0ac58, #908) 반영 — 커밋 근거 + 라이브 실측 2026-10-01(#959 퇴직 취소 안내·상태 드롭다운·사유 입력, #969 고정 수당 탭 구성·원문, #880 사번 도움말) / #948·#908 라이브 실사 이월(TBU) - 카나/PM
  • 2026-10-02 ④ 근로계약 「수습 종료 후」 블록 신설 — 수습 종료 다음 날 시행 계약 변경 예약(50~ㄴ52, 미리보기 한 줄)(fa1b1d8a, #965, MED-823)·#995 비밀번호 최소 길이 병원 설정 연동 — repo 직접 수정 역수용 — 커밋 근거 + 라이브 실사 확인(10/2: 섹션명·안내·필드 3개 원문) / 유효성 안내·미리보기 줄·예약 생성은 라이브 실사 이월(TBU) - 카나/PM
  • 2026-10-07 PR #1059(3e90dfbd, MED-925·924·923) 반영: 주 소속 지정 출처 MANUAL 전환+당일 근태 재판정(ㄴ50-2)·부 그룹 줄 ×·effectiveShift 표시(ㄴ50-5) · PR #1050(515ac04b, MED-926) 반영: 역할 변경 = 폼 변경, 저장 시 team.updateMember(ㄴ50-6) · PR #1067(0a071d0b, MED-937) 반영: 「등록된 직무가 없어요」 템플릿 미닫힘으로 근로형태·근무 배정 영역 소실되던 결함 수정(ㄴ50-7) — 커밋 근거, 라이브 실사 이월(TBU) - 카나/PM
  • 2026-10-08 (10/7 머지분) PR #1084(bee9679·3d441c2, MED-951 계열) 반영: 수습 종료 후 계약 예약 = 같은 직원·같은 시행일 계약 변경 예약 중복 차단(Data I/O·50·CASE07) + 예약 목록 열람 = 급여 조회(전체) 권한 · PR #1088(876ec23, MED-953) 반영: 소속 팀 트리 순서 = 팀 관리 저장 순서(compareTeamOrder, ㄴ30-1) · OQ 「예약된 변경」 채번 제안(HBAD275) — 커밋 근거, 라이브 실사 이월(TBU) - 카나/PM
  • 2026-10-13 (10/11 머지분) PR #1154(MED-969) 반영: 직원 수정 패널 근무 배정 아래 「허용 근무 유형」 체크 목록(50 보강) — 커밋 근거, 실사 TBU - 카나/PM
  • 2026-10-14 (10/13 머지분, #1227 d35e4e3) 계정·보안 탭에 「패스키·기기 키로만 로그인」 해제 추가(20 신설) — 직원이 켠 패스키 전용 로그인을 관리자가 끄는 복구 동선(기기 분실 대비). 관리자는 해제만 가능, 켜는 것은 키 보유 직원 본인만(employees.passkeyOnlyLogin · security.setPasskeyOnly) — 커밋 근거, 10/14 실사는 패널 DOM 중첩으로 탭 내부 미도달(탭 존재는 실측, TBU) - 카나/PM

Data I/O ​

Client → Server

액션

메타직원 추가 (1회, 4 생성물)
메타ㄴ ① employees
메타ㄴ ② team_members
메타ㄴ ③ employment_contracts
메타ㄴ ④ employee_certifications
메타미리보기

Server side 효과

효과엔티티.컬럼값 없을 때비고
SMS 임시비밀번호 발송login_otp_codes 계열 (추정) + mustChangePassword=true전화번호 미입력 시 미발송안내 "전화번호를 입력해야, 임시 비밀번호를 SMS로 발송을 할 수 있어요."
기본 상태 비활성employees.status = 비활성-activation gate
출근 기록 방식employees.attendanceMethod조직 기본값 사용앱/Secom/수동 4옵션
신규 입사자 시트 자동 추가sdk.employee.previewNewEmployeeSheets(hireDate)(저장 전 대상 시트) · employee.create 응답 sheetAutoAdd {enabled, added:[{id,name}]}조직 설정 꺼짐 시 enabled:false(안내 미노출) · 자동 추가 실패 시 null(등록은 유지)조직 토글 [[HBAD270_설정 (조직 설정·내 정보)]] ㄴ33 · 코드 반영: 6ea0ac58, #908
퇴직 취소sdk.employee.cancelTermination({id, reason}) — 퇴사 기록 메모에 사유 남기고 무효화 · employees.status=재직 · 활성 소속 팀 단톡방 복귀 (한 트랜잭션)정산 끝난 퇴사 기록이면 아무것도 바꾸지 않고 거절권한 employee:update · 팀장 지정·세션은 복구 안 함 · 코드 반영: 25e9ddfa, #959
수습 종료 후 계약 예약employee.create 입력 probation { endDate, baseSalary?, hourlyRate? } → 같은 트랜잭션에서 scheduled_actions(kind contract_change, 시행일 = 종료일 + 1일, 소유자 = 등록자, 요구 권한 employee:update, 출처 probation/직원 id, 메모 "수습 종료({endDate}) 후 조건")블록 비우면 예약 안 함 · 종료일 < 입사일이면 서버 거부 "수습 종료일은 입사일 이후여야 해요."시행일 잡이 소유자 권한으로 계약 기간 분할(#960) · 코드 반영: fa1b1d8a, #965 · (10/8, #1084) 수습 예약도 공용 createScheduledAction 경유 → 같은 직원·같은 시행일 계약 변경 예약이 이미 있으면 거부(CONFLICT, 동시 생성도 하나만) — 원문 "같은 시행일({date})의 계약 변경 예약이 이미 있어요. 「예약된 변경」에서 기존 예약을 확인하고, 바꾸려면 기존 예약을 취소한 뒤 다시 만들어 주세요." · 예약 목록·요약·상세 열람 = 급여 조회(조직 전체) 권한 필요 (bee9679·3d441c2)
반복 고정 수당 정의recurring_allowance_definitions(코드·이름·월 금액·시작일·종료일·메모, append-only chainId·version) · sdk.recurringAllowance.list/create/correct0건 시 "정의된 고정 수당이 없어요."권한 employee:read/employee:update · 급여대장 열 원천 recurring_allowance · 코드 반영: dea7be96, #969

① 기본정보 사양표 ​

번호항목/기능명타입사양 및 기능 설명연관/영향 범위비고
00노출 조건-• 목록에서 이 모달을 여는 두 진입 경로
 - CASE01 [직원 추가]: "직원 추가" 클릭 → "직원 추가" 모달
 - CASE02 [편집]: 목록 행 "편집" 클릭 → "직원 정보 수정" 모달
[[HBAD200_직원 관리]]
01초기 상태-• STEP1 [기본정보] 섹션 노출employees
05퇴직자 안내Notice• 퇴직 처리된 직원(status=TERMINATED)의 수정 모달 기본정보 탭 상단 경고 안내(원문): "퇴직 처리된 직원이에요. 실수라면 「퇴직 취소」로 재직으로 되돌릴 수 있어요."
• "퇴직 취소하러 가기" 클릭 → 인사정보 탭 전환 + 상태(40)에 "퇴직 취소(재직 복귀)" 선택된 상태
 - CASE01 [퇴직자 아님]: 미노출
employees.status · ② 40 상태 ㄴ40-1신설 (코드 반영: 25e9ddfa, #959) · 라이브 실측 2026-10-01(안내·버튼·탭 전환 원문 일치, 스샷 live-1001-hbad201-cancel-termination.png)
10성 * / 이름 * / 사번 *Input• 성·이름·사번 입력. 사번에 "자동 생성" 체크박스
• 입력 시: 각 값 반영
 - CASE01 [자동 생성 체크]: 사번 자동 채움
• 사번 도움말(원문): "사번은 입력한 대로 저장돼요. 로그인·검색·중복 확인은 대소문자를 가리지 않아요."
employees.employeeNumber사번 자동 생성 · 대소문자 규칙(8ced12cd, #880) · 라이브 실측 2026-10-01(도움말 원문)
11이메일 / 생년월일Input• 이메일 / 생년월일 입력 ("음력" 체크박스)employees
12주민등록번호Input• 마스킹 입력(password)
 - CASE01 [생년월일 선입력 게이트]: 생년월일 입력 후 활성
employees마스킹 · 선입력 게이트
13전화번호Input• 국가코드 선택(+82 / +1 / +81 / +86 / +44) + 번호 입력. 안내 "전화번호를 입력해야, 임시 비밀번호를 SMS로 발송을 할 수 있어요."
 - CASE01 [값 없음]: 미입력 시 SMS 미발송
SMS 임시비밀번호
14주소Search• 주소 검색(도로명·지번) + 상세주소 입력
• 입력 시: 선택 주소 반영
employees

② 인사정보 사양표 ​

번호항목/기능명타입사양 및 기능 설명연관/영향 범위비고
00섹션Section• 헤더 "인사정보" — "필수 인사정보" + "기타 인사정보" 그룹
• 연차 자격 판정이 그룹 근무형태까지 확장(mergeGroupShiftsToWorkPattern) — 그룹 배정 시 그룹 근무형태가 자격 산정에 병합 (코드 반영: c1b2158)
employees · team_members · 연차 자격 판정자격 판정 그룹 확장(c1b2158)
10입사일 *Date• "입사일 *" 날짜 입력 ("오늘" 단축 버튼). 필수
• 입력 시: 선택 날짜 반영
employees.joinedAt필수
20출근 기록 방식Dropdown• 근태 원천 방식 선택 (안내 "조직 기본값 또는 개별 설정"). 옵션 4종: "조직 기본값 사용" / "앱 (Web/Mobile)" / "지문 단말기 (Secom)" / "관리자 수동 입력"
• 선택 시: 해당 방식 반영
 - CASE01 [미선택]: 조직 기본값 사용
employees.attendanceMethod근태 원천
30소속 (팀 · 역할)Button• "소속 (팀 · 역할)" + "소속 추가" 버튼. 팀·역할 멀티 배정. 모달(large)에서는 "+ 소속 추가" 라벨 버튼 유지 (7/16 변경 유지)
• 클릭 시: 소속(팀·역할) 배정 행 추가
• 병동 이중 배정 방지(코드 반영: 1fce4e2): 수정 모달에서 팀을 병동이 연결된 다른 팀으로 옮길 때, 서버 병동 배정과 저장 전 줄이 같은 병동이면 한 줄로 합쳐 저장 버튼이 꺼지던 문제 수정(claimSameWardRows/mergeServerWardRows). 팀 이동 시 이전 병동 배정을 새 병동으로 옮겨(teamIds 처리 auto→move) 같은 병동이 두 줄로 남지 않게 함. 병동 배정 줄(병동·교대형태·수간호사 한 줄)이 같은 병동으로 두 줄이면 저장 버튼 비활성
team_members · 간호 프로필 · [[HBAD210_팀 관리]] 구성원별 팀 관리 팝업n:m · 이중 배정 수정(#711 리뷰 후속, 1fce4e2) · 회귀 테스트 5건(ward-assignment-rows.test.ts)
ㄴ30-1소속 피커 활성 전용 + 검색Picker• 공용 직원 수정 패널(EditEmployeePanel)·추가 패널이 관리자 직원 관리와 같은 피커 규칙을 사용
 - 팀 트리 피커: 비활성 팀을 하위까지 숨김 / 역할 피커: 비활성 역할 제외
 - 예외: 지금 배정된 값은 비활성이어도 유지(선택 표시 보존)
 - 메뉴 상단 고정 검색 줄(.ds-menu__search), 팀 검색 중에는 계층·접기 무시하고 평면 표시
[[HBAD200_직원 관리]] · teams.isActive · roles.isActive · [[HBAD210_팀 관리]] ㄴ12-1신설 (코드 반영: 65daef2, #809) · (10/8, #1088, MED-953) 팀 트리 형제 순서 = 팀 관리에서 끌어 저장한 순서(core compareTeamOrder — sortOrder 먼저, 없으면 이름순) — 직원 추가·수정 패널 공통, TBU(실사 대기) · 라이브 실사(2026-09-25): 인사정보 탭 「소속 추가」 피커 오픈 시 상단 고정 검색 줄(.ds-menu__search, placeholder 팀 검색) + 팀 트리 노출 실측
40상태Radio• "재직" / "비활성" 선택. 안내 "비활성 상태로 등록돼요. 사용하기 위해서는 재직으로 변경해 주세요."
• 선택 시: 해당 상태 반영
 - CASE01 [비활성(기본)]: activation gate
employees.statusactivation gate
ㄴ40-1퇴직 취소(재직 복귀)Dropdown• 퇴직자에게만 상태 드롭다운에 "퇴직 취소(재직 복귀)" 항목 노출(실측 옵션: 재직 / 비활성 / 휴직 / 퇴직 / 퇴직 취소(재직 복귀)). "재직"을 직접 골라도 같은 흐름
• 선택 시: 안내 박스 + "취소 사유" 입력(필수, 최대 500자, placeholder "예: 퇴직 처리를 잘못 눌렀어요") 노출
 - 안내(원문): "퇴직 취소하면 퇴사 기록이 무효 처리되고(정산 이력은 보존) 상태가 재직으로 돌아오며, 팀 단톡방에도 다시 들어가요. 팀장 지정은 자동으로 되살아나지 않으니 팀 관리에서 다시 지정하고, 직원은 앱에 다시 로그인해야 해요."
sdk.employee.cancelTermination() · resignation · 팀 단톡방 · [[HBAD200_직원 관리]]신설 (코드 반영: 25e9ddfa, #959, MED-834) · 라이브 실측 2026-10-01(옵션·안내·사유 placeholder 원문 일치, 아래 "휴직/퇴직 이력" 목록 노출) · 저장 동작(ㄴ40-2)은 미실행
ㄴ40-2퇴직 취소 저장Action• 저장 클릭 → 즉시 실행(cancelTermination), 성공: 모달 닫힘 + 토스트 "{name} 님의 퇴직을 취소했어요. 상태가 재직으로 돌아왔어요."
 - CASE01 [사유 없음]: 경고 "퇴직 취소 사유를 입력해 주세요." (저장 안 됨)
 - CASE02 [정산 끝난 퇴사 기록]: 거절 "퇴직 정산이 끝난 기록이라 취소할 수 없어요. 정산을 먼저 되돌려 주세요."
 - CASE03 [기타 실패]: "퇴직 취소 실패: {오류}"
employee:update코드 반영: 25e9ddfa, #959
45급여 제외Toggle• 직원을 급여 대장(대상)에서 빼는 급여 제외 플래그(직원 관리 employees-content 화면에도 표시). 켜면 이 직원의 계정이 비급여 계정으로 처리돼 급여 대장 집계에서 제외됨
• 선택 시: 플래그 반영
employees(급여 제외 플래그) · 급여 대장(HBHR)신규 (코드 반영: #722, b8a8c77)
47직무Dropdown• 직무를 직무 마스터 목록에서 선택하는 드롭다운(9/18 — 자유 텍스트에서 마스터 연동 선택으로 전환). placeholder "직무를 선택하세요"
• 선택 시: 그 직무의 기본 근무(그룹 › 형태)가 근무 배정(50)에 자동 선택되고 안내 노출 — 원문 "직무 「{name}」의 기본 근무가 선택됐어요. 다르면 바꿔 주세요." (기본값일 뿐 제한 아님 — 팀 대표 근무보다 먼저 적용, 등록할 때 변경 가능). 직무에 허용 근무형태가 있으면 근무형태 목록에서 그 형태들이 먼저 노출. 직군을 따로 고르지 않으면 직무의 직군이 기본값
 - -E [직무 마스터 0건]: "등록된 직무가 없어요. 설정 › 근무 설정 › 직무에서 먼저 등록해 주세요."
employees.jobDutyId (FK job_duties) · [[HBAD260_근무 설정 (근무 그룹·유형)]] 직무 사양표 · 50 근무 배정신설 (코드 반영: 7f63a4b, #791) · 자동 근무 채움 순서 = 직무 기본 근무 → 팀 대표 근무 · 라이브 실사(2026-09-25): 인사정보 탭 「직무」 드롭다운 + placeholder "직무를 선택하세요" 실측(직무 0건 조직이라 선택 동작·안내 문구는 미실증)
ㄴ47-1직무 기본 근무 안내 문구Fix• 직무를 고르면 기본 근무를 채운 뒤 안내를 띄우는데, 패널 _t 래퍼가 치환 값을 스토어로 넘기지 않아 플레이스홀더가 그대로 보이던 문제 수정
 - 오류 표기(수정 전): "직무 「{name}」의 기본 근무가 선택됐어요."
 - 수정 후: 직무명이 치환되어 표시
job_duties.defaultShiftId · i18n t(key, vars)수정 (코드 반영: d216f26, #802) · TBU: 라이브 실사 이월
50근무 배정 (근무 그룹 → 근무형태)Dropdown• 근무 배정을 '근무 그룹 → 근무형태' 2단계로 개편 (코드 반영: c1b2158)
 - STEP1 [근무 그룹]: 근무 그룹 선택 — employees.shiftGroupId(FK shift_groups, nullable). 근무형태 없이 그룹만 배정 가능
 - STEP2 [근무형태]: 근무형태 필드는 그룹 선택 시에만 노출(폭 50%). 근무 유형 목록 연동 선택 (예: "미지정" / "일반근무" / "3교대 주간" / "3교대 오후" / "3교대 야간" / "스케줄 근무" 등 — junk 데이터 관찰)
• 선택 시: 그룹·근무형태 반영. 안내 문구 "추가/수정 가능"으로 갱신. 직무(47) 선택 시 그 직무의 기본 근무가 자동 선택됨(직무 기본 → 팀 대표 순서, 변경 가능)
employees.shiftGroupId (FK shift_groups, nullable) · employment_contracts · 47 직무 · employees.allowedShiftIds2단계 개편 (코드 반영: c1b2158) · junk 데이터 존재 · 직무 기본 근무 자동 채움(7f63a4b, #791) · (10/11 머지, #1154, MED-969) 근무 배정 아래 「허용 근무 유형」 체크 목록(「그룹 · 근무」 라벨) — 이 직원이 배정 그룹 밖에서도 앱 「근무 시간 설정」에서 스스로 고를 수 있는 근무(employees.allowedShiftIds, 마이그레이션 1971). 팀 단위 목록([[HBAD210_팀 관리]] ㄴ50-1)과 합집합, 급여 근로형태 불변 — 커밋 근거, 실사 TBU
ㄴ50-2근무 배정 출처 기록Field• 근무 배정이 어떤 경로로 정해졌는지를 함께 저장(shiftAssignedVia)
 - 값: 직접 선택 / 직무 기본 / 팀 대표 / 일괄 배정 / 엑셀 / 시트 / 직원 앱 자기 선택
• 주 소속 지정 시 출처 = 직접 선택(MANUAL)로 전환(10/7, #1059, MED-925) — 종전엔 새 주 소속 줄의 출처(직무 기본·팀 대표)가 그대로 복사돼 다음 기본 근무 재적용이 방금 고른 근무를 되돌렸음. 주 소속 변경 뒤 당일 근태를 다시 판정(attendance-shift-recompute.service — 마감·퇴근·수동 수정·휴가/휴일/결근·off_day는 건너뜀)
• 저장된 출처는 직원 정보 수정·직원 목록·근태 현황·직원 앱 근태 홈에 표시
employees.shiftAssignedVia · team_members.shiftAssignedVia (마이그레이션 1917)신설 (코드 반영: c4eb0f9, #804) · TBU: 라이브 실사 이월
ㄴ50-3직무 기본 근무와의 차이 표시Label• 직원 수정 패널이 근무 배정과 그 직원 직무의 기본 근무가 같은지를 표시 — 「≠ 직무 기본」(다름) / 「기본」(기본에서 온 값). 직원 목록([[HBAD200_직원 관리]] ㄴ46-3)과 같은 표기
• 직무·근로형태만 바꿔 저장하면 기본 근무 재적용 규칙(decideDefaultShiftReapply)으로 근무가 직무 기본 근무에 맞춰짐
 - 맞추는 대상: 비었음 · 그룹만 배정 · 비활성 값 · 기본에서 온 값
 - CASE01 [직접 고른 값]: 바꾸지 않고 유지
 - 배경: 직무는 있는데 근무형태가 비었거나 직무와 무관한 옛 값이 남아 「미지정」으로 보이던 결함(MED-693)
job_duties.defaultShiftId · [[HBAD200_직원 관리]] · [[HBAD260_근무 설정 (근무 그룹·유형)]] 40-5 기본 근무 재적용신설 (코드 반영: 33948ca, #851, MED-693) · TBU: 라이브 실사 이월
ㄴ50-4근로형태 (workPatternName)Field• 직원 등록/수정 패널에 「근로형태」 항목 추가 — 설정 › 「근로형태」 탭(근로형태 마스터)에 등록된 값을 직원에게 지정
• 대량 업로드 템플릿에도 같은 「근로형태」 열이 추가됨([[HBAD200_직원 관리]] ㄴ33)
 - 근로형태 마스터 화면 = 신규 탭 · 전용 사양서 미작성(신규 화면 후보)
 - 필드 실측(2026-09-25 실사): 인사정보 탭, 「직무」 바로 아래 배치. 라벨 "근로형태" + placeholder "근로형태를 선택하세요 (선택)" — 선택 항목(필수 아님). 도움말 원문 "근로형태를 지정하면 월 근로시간·연장·야간·포괄시간·통상시급이 근로형태 기준으로 채워져요. 직접 고친 값은 수동으로 남아요."
employees.workPatternId · [[HBAD260_근무 설정 (근무 그룹·유형)]] 탭 목록 ㄴ02-1신설 (코드 반영: 73c0cb4, #823) · 라이브 실사 확인(2026-09-25 — 필드 위치·선택 항목·도움말 원문 채록, TBU 해소)
ㄴ50-5부 그룹 제거 (줄 ×) · effectiveShiftField• (10/7, #1059, MED-924·923) 수정 화면에서 부 근무 그룹 줄에 ×(제거) — 주 소속 줄은 안내로 거절
• 직원 상세에 effectiveShift(판정에 쓰는 근무·출처)를 돌려주고 개인 설정에 한 줄로 표시 — 직원 앱 근무 화면에는 판정 순서(스케줄 → 직원 근무 → 근로형태/직무 기본값)를 표시
employee.clearSecondaryShiftGroups · [[HBAD200_직원 관리]] ㄴ26신설 (3e90dfbd, #1059) · 표시 원문 TBU(실사 대기)
ㄴ50-6역할 변경 = 폼 변경 (저장 시 반영)Rule• (10/7, #1050, MED-926) 소속 역할 선택을 다른 입력과 같은 폼 변경으로만 잡음 — 저장 때 persistBasicEdits의 역할 루프가 team.updateMember로 보냄(종전: 고르면 바로 서버 저장 + 기준선 재설정으로 저장 버튼이 안 켜지고, onSaved 미호출로 닫은 뒤 직원 목록·팀 명단에 옛 역할이 남던 버그)team.updateMember · 30 소속신설 (515ac04b, #1050)
ㄴ50-7「등록된 직무가 없어요」 템플릿 렌더 수정Rule• (10/7, #1067, MED-937) 직무가 1개 이상 등록된 조직에서 직원 추가 › 인사정보의 「근로형태」·「근무 배정」 영역이 통째로 렌더되지 않아 등록 버튼이 영구 비활성이던 결함 수정 — 「등록된 직무가 없어요」 x-if의 닫는 태그가 근무 배정 블록 아래에 있던 것을 경고 한 줄 뒤에서 닫음50 근무 배정 · ㄴ50-4 근로형태신설 (0a071d0b, #1067)
ㄴ51근무 유형 전체 보기 (참고 팝업)Button• 위저드에서 그룹별 등록 근무 유형을 열람하는 "근무 유형 전체 보기" 참고 팝업
• 클릭 시: 그룹별 등록 유형 목록 팝업 오픈(참고용)
shift_groups · 근무 유형신규 (코드 반영: c1b2158)

③ 자격증/면허 등록 사양표 ​

번호항목/기능명타입사양 및 기능 설명연관/영향 범위비고
00섹션Section• 헤더 "자격증/면허 등록" — "자격 유형 선택"employee_certifications신설 섹션 · 생성물 ④
10안내 문구Info• 자격증 등록 안내 (원문 카피): "직원이 제출해야 할 자격증/면허를 선택해 주세요." / "선택한 항목은 자격증/면허 화면에 '파일 미제출' 상태로 등록돼요." / "입사 후 '문서 결재' > '자격증/면허' 탭에서 자격 정보를 등록할 수 있어요."원문 카피
20자격 유형 선택Checkbox• 자격 15종 + 커스텀 체크 선택: "테스트" / "ㅁㄴㅇㄹㅁㄴㅇㄹㅁㄴ"(커스텀/junk) / "간호사" / "간호조무사" / "물리치료사" / "작업치료사" / "언어치료사" / "방사선사" / "임상병리사" / "약사" / "영양사" / "사회복지사" / "의사" / "치과의사" / "응급구조사" / "요양보호사"
 - CASE01 [선택]: 해당 자격 "파일 미제출" 등록
employee_certifications15종+커스텀
30자격증 요청 안함Option• "자격증 제출을 요청하지 않아요." 옵션
 - CASE01 [선택]: 자격증 요건 미생성
employee_certifications

④ 근로계약 사양표 ​

번호항목/기능명타입사양 및 기능 설명연관/영향 범위비고
00섹션Section• 헤더 "근로계약" — "계약 정보" / "급여 기준" / "근무 시간"employment_contracts (급여 원천)POL_급여정본경계
10계약유형Dropdown• 계약 유형 선택: "정규직" / "임시직" / "계약직" / "인턴" / "파트타임" (5종)
• 선택 시: 해당 유형 반영
employment_contracts
20급여형태Dropdown• 급여 형태 선택: "월급" / "시급" / "일급" / "연봉" (4종)
• 선택 시: 해당 형태 반영
employment_contracts
30급여 기준Input• 급여 원천 6필드 입력: "기본급 (원)" / "호봉 (원)" / "근속수당 (원)" / "식대 (원)" / "교통비 (원)" / "직책수당 (원)"employment_contracts (급여 원천)
40근무 시간Input• 근무 시간 2필드 입력: "주당 기본근무시간" / "주당 최대근무시간"standardWeeklyHours / maxWeeklyHours52h 한도
50수습 종료 후Section• (직원 추가) 근로계약 하단 선택 블록 — 수습 종료 다음 날부터 적용될 새 계약을 예약
• 안내(원문): "종료일 다음 날부터 적용되는 새 계약을 예약해요. 수습 기간의 시트는 위 계약 값으로, 그 뒤는 여기 값으로 계산돼요. 비우면 예약하지 않아요."
scheduled_actions(contract_change) · [[HBHR210_계약급여내역 시트]] 예약 목록신설 (코드 반영: fa1b1d8a, #965, MED-823) · 라이브 실사 확인(10/2 — 섹션명·안내 원문) · 대량 업로드는 범위 밖(계약 열 없음)
ㄴ51수습 종료일 / 수습 후 기본급 / 수습 후 통상시급Input• "수습 종료일"(날짜, 입사일 이전 선택 불가) / "수습 후 기본급" / "수습 후 통상시급"(숫자) — 금액 2칸은 종료일 입력 전 비활성
• 입력 시: 종료일이 있으면 「예약한다」로 간주, 금액 중 하나 이상 필수
 - CASE01 [종료일 < 입사일 또는 금액 둘 다 없음]: 블록 아래 오류(원문) "수습 종료일은 입사일 이후여야 하고, 수습 후 기본급이나 통상시급 중 하나는 입력해야 해요." + 근로계약 카테고리 빨간 점 + "등록" 비활성
 - CASE02 [종료일 비움]: 예약 안 함(통과)
createEmployee.probation · 90 등록라이브 실사 확인(10/2 — 필드 3개 라벨) · TBU: 오류 노출·등록 비활성 라이브 미실증
ㄴ52미리보기 수습 줄Text• "미리보기" 검토 화면 근로계약 영역에 라벨 "수습 종료 후" + 값(원문 형식) "{date} 까지 수습 · 다음 날부터 {values}" — {values} 예 "기본급 3,000,000원 · 수습 후 통상시급 14,000원"
 - CASE01 [블록 비움]: 줄 미노출
90 미리보기TBU: 라이브 실사 이월

⑤ 고정 수당 사양표 (직원 정보 수정 — 반복 고정 수당 정의) ​

번호항목/기능명타입사양 및 기능 설명연관/영향 범위비고
00고정 수당 탭Tab• 직원 수정 패널 카테고리 "고정 수당"(근로계약과 계정·보안 사이). 매달 반복되는 고정 수당을 「이 직원에게 이 기간 동안」 정의로 관리
• 안내(원문): "매달 반복되는 고정 수당(자격 수당·직책 수당 등)을 기간으로 정의해요. 시트는 그 달에 유효한 정의를 읽으므로 종료일이 지나면 다음 달부터 자동으로 빠지고, 지난달 시트 값은 그대로예요."
recurring_allowance_definitions · [[HBHR200_급여대장 시트]] 열 원천 recurring_allowance신설 (코드 반영: dea7be96, #969, MED-824) · 수정 모달 탭 5→6 · 라이브 실측 2026-10-01(탭 순서 기본정보/인사정보/자격증/면허/근로계약/고정 수당/계정·보안, 안내·섹션·필드·placeholder 원문 일치, 월 금액 기본 0, 스샷 live-1001-hbad201-fixed-allowance.png) · 목록 행·종료일 저장·금액 정정은 정의 0건이라 미실증
10정의된 고정 수당 목록List• 제목 "정의된 고정 수당". 행 = 상태 배지 · 수당 이름 · 코드 · 월 금액(원) / 시작일 ~ 종료일(없으면 "무기한") · 메모
 - 상태 배지: "적용 중"(초록) / "예정"(파랑) / "종료"(회색) — 종료된 정의도 포함 표시
sdk.recurringAllowance.list({employeeId, includeEnded:true})로딩 중 스피너
10-EEmptyText• "정의된 고정 수당이 없어요."
ㄴ11종료일 저장Button• 행별 "종료일" 날짜 입력(시작일 이후만) + "종료일 저장"
• 클릭 → 즉시 실행(correct validUntil), 성공: 목록 재조회. 종료일 다음 달부터 시트에서 빠지고 지난달 시트는 그대로. 비우고 저장하면 무기한
 - CASE01 [값 변화 없음·저장 중]: 버튼 비활성
sdk.recurringAllowance.correct()실패: "고정 수당 저장 실패: {오류}"
ㄴ12금액 정정Button• 행별 "월 금액" 입력 + "금액 정정"
• 클릭 → 컨펌 "금액을 정정할까요? 이 정의가 걸친 아직 확정하지 않은 달에 모두 반영돼요. 특정 날부터 바꾸려면 종료일을 넣고 새로 추가해 주세요." → 실행(같은 정의 v+1)
 - CASE01 [금액 변화 없음·저장 중]: 버튼 비활성
sdk.recurringAllowance.correct() · 미커밋 달 시트 값실패: "고정 수당 저장 실패: {오류}"
20고정 수당 추가Form• 제목 "고정 수당 추가". 입력: "수당 이름"(최대 100자) / "코드"(placeholder "license_bonus", 최대 64자) / "월 금액" / "메모 (선택)" / "시작일" / "종료일 (선택 · 비우면 무기한)"
• 코드 도움말(원문): "시트 열 설정의 「반복 고정 수당」 원천에서 이 코드로 거를 수 있어요(영문 소문자·숫자·밑줄)."
recurring_allowance_definitions미래 시작일 정의도 즉시 저장("예정")
ㄴ21추가Button• 클릭 → 즉시 실행(create), 성공: 폼 초기화 + 목록 재조회
 - CASE01 [필수 누락·금액 0 이하]: 알림 "수당 이름·코드·시작일을 채우고 금액을 0보다 크게 입력해 주세요."
 - CASE02 [실패]: "고정 수당 저장 실패: {오류}"
sdk.recurringAllowance.create()코드는 소문자로 정규화

⑥ 계정·보안 사양표 (부분 — 비밀번호 직접 설정) ​

번호항목/기능명타입사양 및 기능 설명연관/영향 범위비고
10비밀번호 변경 › 직접 설정Radio• "직접 설정"(설명 "관리자가 새 비밀번호를 직접 입력합니다.") 선택 시 새 비밀번호·확인 입력 + "비밀번호 변경" 버튼
• 규칙 안내(원문): "{min}자 이상, 또는 임시 비밀번호 형식({format})으로 입력할 수 있어요." — {min} = 병원 설정 일반 비밀번호 최소 길이(4~20, 기본 8), {format} 예 "고정값 0000" / "숫자 4자"
• 입력칸 안내: "새 비밀번호 ({min}자 이상)" · 문자 구성(대문자·숫자 등)은 직원이 바꿀 때 검사하고 직접 설정은 길이만 본다
employees · 조직 임시 비밀번호 정책 [[HBAD270_설정 (조직 설정·내 정보)]]규칙 확장 (코드 반영: 01d3cc5b, #948, CS-OKBEST-260929-0001) · 최소 길이 병원 설정 연동(#995) · TBU: 라이브 실사 이월
ㄴ11임시 형식 판정Rule• {min}자 이상 → 종전처럼 저장(변경 강제 없음)
 - CASE01 [{min}자 미만 + 조직 임시 형식 일치]: 안내 "임시 비밀번호 형식이에요. 저장하면 직원이 첫 로그인 때 비밀번호를 바꿔야 해요." + 확인 "임시 비밀번호 형식으로 설정할까요? 직원은 첫 로그인 때 비밀번호를 바꿔야 해요." → 저장, mustChangePassword=true
 - CASE02 [형식 불일치]: 오류 "{min}자 이상이거나 조직의 임시 비밀번호 형식과 같아야 해요." + 버튼 비활성(서버도 같은 문구로 거부)
employees.mustChangePassword · core matchesTemporaryPasswordPolicy확인 문구 노출 시점 TBU
20패스키·기기 키 전용 로그인 해제Button• (10/13, #1227 d35e4e3) 직원이 인증/보안 설정에서 「패스키·기기 키로만 로그인」을 켠 경우, 계정·보안 탭에서 관리자가 해제할 수 있음(overview.passkeyOnly) — 해제하면 비밀번호·SMS 로그인 복구
 - CASE01 [직원 미설정]: 해제 컨트롤 비활성/미노출(관리자가 켤 수는 없음)
employees.passkeyOnlyLogin · security.setPasskeyOnly · [[HBEA100_로그인]] ㄴ63신설 (#1227) · TBU: 라이브 실사(패널 탭 내부 미도달)

공통 하단·이탈 가드 사양표 ​

번호항목/기능명타입사양 및 기능 설명연관/영향 범위비고
90하단 버튼Button• 모달 하단 액션 버튼 묶음: "취소" / "미리보기" / "등록"
• "취소" 클릭 시: 이탈 가드 후 모달 닫기
• "미리보기" 클릭 시: 등록 내용 미리보기
• "등록" 클릭 시: "등록 중..." 표기 + 버튼 disabled → 4 생성물 트랜잭션, 기본 상태 비활성(activation gate)
 - CASE01 [저장 실패]: 트랜잭션 실패 시 처리(토스트/롤백)
sdk.employee.create()권한 "직원 관리" · TBU: 저장 실패 동작
ㄴ90-1시트 자동 추가 미리보기 안내Notice• (직원 추가) 조직 설정 「신규 입사자 시트 자동 추가」가 켜져 있을 때만 미리보기(검토) 모달에 안내. 입사일이 바뀌면 다시 계산
 - CASE01 [대상 있음]: "저장하면 이 직원 행이 다음 시트에 자동으로 추가돼요: {시트명 (YYYY.MM)} · …"(상시 시트는 이름만)
 - CASE02 [대상 없음]: "「신규 입사자 시트 자동 추가」가 켜져 있지만 지금 입사일로 들어갈 시트가 없어요." (+ 입사일 가드 해당 시 "(입사일이 시트 기간 이후인 시트는 제외돼요)")
sdk.employee.previewNewEmployeeSheets() · [[HBAD270_설정 (조직 설정·내 정보)]] ㄴ33신설 (코드 반영: 6ea0ac58, #908) · 설정 꺼짐 시 미노출 · TBU: 라이브 실사 이월
ㄴ90-2시트 자동 추가 결과 (완료 화면)Notice• 등록 완료 화면에 결과 표시(설정 켜짐일 때만)
 - CASE01 [추가됨]: "시트 {N}개에 이 직원 행을 추가했어요: {시트명} · …"
 - CASE02 [0건]: "신규 입사자 시트 자동 추가가 켜져 있지만 이번에 행이 들어간 시트는 없어요."
employee.create 응답 sheetAutoAdd · [[HBHR202_직원 추가]]코드 반영: 6ea0ac58, #908 · 엑셀 대량 추가는 결과 미표시
91미저장 이탈 가드Alert• 변경 후 취소/닫기 시 노출되는 확인 얼럿 (원문 카피): "변경된 내용을 저장하지 않고 나가시겠어요?" (버튼 "계속 편집" / "나가기")원문 카피

4 생성물 · activation gate ​

생성물엔티티초기 상태
① Employeeemployees비활성 (activation gate)
② 소속·역할team_members (n:m)팀·역할 배정
③ 근로계약·급여 seedemployment_contracts급여 원천 (정본 아님)
④ 자격증 요건employee_certifications파일 미제출

권한 / 상태 요약 ​

시나리오트리거결과비고
CASE01 [직원 생성]"등록""등록 중..." → 4 생성물 트랜잭션, 상태 비활성activation gate
CASE02 [전화번호 입력]저장 (전화번호 有)SMS 임시비밀번호 발송mustChangePassword
CASE03 [자격증 요구]자격증/면허 요구 선택자격증 화면 "파일 미제출" 등록
CASE04 [미저장 이탈]변경 후 취소/닫기"변경된 내용을 저장하지 않고 나가시겠어요?" (계속 편집/나가기)
CASE05 [퇴직 취소]퇴직자 → 상태 "퇴직 취소(재직 복귀)"/"재직" + 사유 → 저장퇴사 기록 무효(사유 기록) · 재직 · 팀 단톡방 복귀정산 완료 기록이면 거절 (#959)
CASE06 [임시 형식 비밀번호]직접 설정에 조직 임시 형식 값저장 + 첫 로그인 변경 강제#948
CASE07 [수습 종료 후 입력]직원 추가 ④ 수습 종료일 + 수습 후 금액 → 등록계약 v1 생성 + 종료일+1일 시행 계약 변경 예약(SCHEDULED) — 수습 달 시트는 등록 계약 값, 다음 달부터 예약 값#965 · 예약 목록은 계약급여내역 행 메뉴 「계약 시행일 변경…」에서 확인 · (10/8, #1084) 같은 시행일 계약 변경 예약이 이미 있으면 등록 거부(원문은 Data I/O 「수습 종료 후 계약 예약」 행) — 등록 트랜잭션 전체 롤백 여부 TBU(실사 대기)

Open Question ​

구분미확인 항목
하단·저장저장 실패(트랜잭션 실패) 시 처리(토스트/롤백) 동작
수습 예약직원 수정(편집) 모달에도 「수습 종료 후」 블록이 있는지 — 코드상 추가 패널(AddEmployeePanel)만 확인. 조직 전체 예약 확인처 admin 「급여 관리 › 예약된 변경」(#980, 10/7 #1084 로 상태별 서브탭·전→후 표·상세 창 재구성, 열람 = 급여 조회(전체)) = 신규 화면 채번 대기(제안 HBAD275, 10/8)