Skip to content

엑셀 자료 이관과 시트 탭 등록 ​

제품 개발 기록으로 · 급여 시트 · HR 원천 기록 · 조직과 권한

CLI·파서·DB 쓰기 구현을 대조한 운영용 안내입니다. 병원 엑셀을 읽거나 DB 이관을 실행한 검증은 아닙니다. 웹 앱에서 파일을 고르는 시트 가져오기와 구분됩니다.

대상과 준비 ​

현재 등록된 조직별 파서는 BESTRH 하나입니다. 다른 병원 파일을 형식 확인 없이 이 파서에 넣으면 동일한 의미로 이관된다고 보장할 수 없습니다. --org는 파서 종류, --target은 저장할 조직 코드이며 서로 다릅니다. DB 권한은 .env 연결 정보로 결정되고 사용자 UI의 역할 선택 단계는 없습니다.

현재 조직별 구현의 급여 기간은 2026년 1월, 정산 연도는 2025년으로 상수화돼 있습니다. 임의 연월을 받는 옵션은 없습니다. 현재 월 자료 이관기로 오해하지 않습니다. 원본을 수정하기 전에 기간·원천 탭·조직 매핑을 검토하고 급여 시트의 월별 자료 구조와 맞춰야 합니다.

필요한 준비는 암호가 해제된 지원 워크북, 대상 조직과 DB 백업/복구 경로, 현재 스키마, 실행 계정입니다. 파일 경로를 생략하면 저장소 루트 non-password.xlsx를 사용합니다. 상대 경로도 앱 폴더가 아니라 저장소 루트 기준으로 해석합니다.

옵션과 실제 분기 ​

입력필수·기본값현재 결과
--org=BESTRH필수, 대소문자 정규화BESTRH 파서 선택. 미등록 코드는 오류 종료
--target=DOCS_TEST선택, 파서의 기본 조직 코드해당 코드 조직 조회, 없으면 생성
--sheet=all선택, 기본 all지원 원천과 설정된 시트 전체 처리
--sheet=sheets선택설정된 워크북 탭을 SheetView/행/셀로 기록
--sheet=employees, teams, payroll, overtime, nursing, rehab, sports선택먼저 직원 파싱·이관 후 지정 원천 분기
--sheet=grades, education, settlement, resignation문자열로 받지만 현재 단독 실행 문제 있음분기가 직원 처리 조건 안에 있으나 바깥 조건에 이 값이 없어 단독 지정 시 해당 이관에 진입하지 않음. all에서는 실행
마지막 위치 인자선택, 기본 non-password.xlsx읽을 워크북

알 수 없는 --sheet 값은 허용 목록 검증으로 거절되지 않습니다. 빈 작업인데 전체 완료 로그가 나올 수 있습니다. 쉼표로 여러 필터를 지정하는 기능, 연월 옵션, dry-run 옵션은 없습니다. --sheet=sheets도 시작 시 「사번」·「급여대장(전체)」를 읽는 코드가 먼저 실행됩니다.

실행하고 결과 확인하기 ​

아래 명령은 사용 예이며 이번 문서 작성에서 실행하지 않았습니다. DOCS_TEST는 검증용 대상 조직 코드 예시로 실제 운영 조직 코드로 자동 대체하지 않습니다.

  1. 저장소 루트에서 .env의 DB 대상, 파일 경로, 대상 조직, 현재 고정 기간을 확인합니다. 대상 조직이 없으면 자동 생성되므로 철자 오타도 기존 조직 선택 실패가 아닌 새 조직 생성이 될 수 있습니다.
  2. 새 테스트 데이터로 시트만 검증할 경우, 사번 연결에 필요한 직원이 대상 조직에 있는지 먼저 확인합니다. 필요 원천이 없다면 직원 이관을 선행합니다.
  3. 필요한 범위를 지정해 실행합니다.
bash
pnpm --filter @hereby/importer start -- --org=BESTRH --target=DOCS_TEST --sheet=employees ./fixtures/import-sample.xlsx
pnpm --filter @hereby/importer start -- --org=BESTRH --target=DOCS_TEST --sheet=sheets ./fixtures/import-sample.xlsx

전체 이관은 옵션을 --sheet=all로 바꿉니다. 현재 단독 필터 문제가 있는 원천을 위해 운영 DB에 전체 이관을 우회 실행하지 않습니다. 해당 분기 수정·검증이 먼저입니다.

  1. 시작 로그의 Importer·Target org·File·Filter를 확인하고 탭별 시트/행/셀 수를 수집합니다. 파일을 열지 못하거나 DB 연결이 실패하면 오류 종료합니다.
  2. '탭 없음', '하위 테이블 0개', '수식 참조 미해결' 경고를 별도로 확인합니다. 최종 성공 로그만으로 모든 탭이 들어간 것은 아닙니다.
  3. DB에서 대상 조직과 기간의 시트별 행·셀 수, 사번 미연결 행, 수식 참조를 조회하고 원본의 표별 수와 대조합니다. 조회 예시는 표준 이관 가이드에 있습니다. 조직·기간 조건 없이 전체 수치만 비교하지 않습니다.
  4. 급여 시트를 대상 조직으로 열어 설정 그룹·시트·행·원천 연결을 확인하고 새로고침 후 유지되는지 확인합니다. 시트 저장은 급여 확정이나 직원 명세서 발송이 아닙니다.

새 엑셀 탭을 추가하는 사용법 ​

이 단계는 개발자가 이관 구성을 확장할 때 사용합니다. 설정 필드의 상세 정본은 SHEET-IMPORT-GUIDE.md입니다.

  1. 탭의 정확한 이름과 공백, 헤더/데이터 시작 행, 사번 열, 합계 행, 가로/세로 배치를 읽습니다. 행·열 번호는 0부터 시작합니다.
  2. 단일 표는 none, *제목으로 나누는 표는 star-prefix, 단일 제목 행으로 나누는 표는 section-header, 가로 병렬 표는 side-by-side를 선택합니다. 가로 병렬 표에는 시작·끝 열 범위가 필요합니다.
  3. sheet-configs.ts의 SHEET_TAB_CONFIGS에 tabName, groupId, 유일한 slug, detection을 넣습니다. 사번 연결이 필요하면 rowBasis: employee와 실제 사번 열을 지정합니다. 날짜 축은 date, 자유 표는 free이며 rowDate 필드는 없습니다.
  4. 수식 열이 필요하면 formulas에 실제 열 키와 수식을 추가합니다. @slug 참조는 같은 대상 조직·기간에서 생성한 시트 ID로 해석됩니다. 누락된 참조는 경고 후 미해결 문자열로 남을 수 있으므로 배포 전에 검증합니다.
  5. 참고/임시 탭은 SKIP_TABS로 명시합니다. 워크북의 모든 탭이 자동 등록되는 것이 아니라 설정 배열을 순회합니다.
  6. 파서 테스트와 importer 빌드로 형식·타입을 확인한 뒤 복제된 DB에서 이관합니다. 반복 열·전치·중복 헤더·합계 제거·사번 미연결을 원본과 비교합니다.

transpose가 켜졌다고 모든 표를 뒤집지 않습니다. 파서의 이름 형태·개수·비율 조건을 충족한 하위 표에 적용됩니다. 사번 매칭 실패 행은 건너뛰는 것이 아니라 employeeId = null로 남습니다.

재실행·중단·실패 ​

시트 이관은 SheetView 메타데이터를 갱신하고 기존 행을 삭제한 뒤 행·셀을 다시 넣습니다. 이관 후 웹에서 편집한 행을 보존하면서 병합하는 방식이 아닙니다. 전체 과정의 일괄 트랜잭션이나 화면상 되돌리기 버튼이 없으므로 중단 시 이미 처리된 자료가 남을 수 있습니다. 동일 조직·기간에 재실행하기 전 데이터 차이를 확인합니다.

파일 누락과 빈 하위 표는 건너뛰지만 DB 쓰기 오류는 상위로 전달돼 실행을 실패시킵니다. 사번/급여대장의 최초 읽기는 탭별 skip 처리와 위치가 다릅니다. 실패 원인과 마지막 성공 시트를 확인하고 복구 또는 대상별 재실행 범위를 결정합니다.

연결과 현재 등록 범위 ​

직원·팀은 조직 관리, 근로계약·교육·정산 원천은 HR 기록, 계산과 반영은 급여 시트, 직원 노출은 급여 배포에서 이어집니다.

아래는 검사한 SHEET_TAB_CONFIGS의 등록 탭입니다. 한 탭이 여러 하위 시트로 분리될 수 있어 탭 수와 생성 시트 수는 같지 않습니다.

엑셀 탭그룹기준 slug
급여대장(전체)급여payroll_ledger
사번급여employee_numbers
Sheet1급여special_detail
재활_경력호봉rehab_career
기능직_호봉호봉functional_grade
간호부_호봉호봉nursing_grade
행정시간외시간외ot_admin
간호부-시간외근무시간외ot_nursing
스포츠치료-시간외시간외ot_sports
치료시간외 (토요일)시간외ot_rehab_sat
치료시간외 (토외)시간외ot_rehab_weekday
NDT(토요일)시간외ndt_saturday
영양,미화 휴일시간외nutrition_cleaning_holiday
스포츠치료(인센)인센티브sports_incentive
스포츠치료(체외충격파)인센티브eswt_incentive
재활인센티브rehab_incentive
간호부인센티브nursing_allowance
간호간병인센티브수당nursing_care_incentive
특별수당수당special_allowance
기타수당수당other_allowance
조정수당수당adjustment_allowance
내일채움공제기여금수당tomorrow_fund
공제내역공제deduction_detail
써티교육비지급교육education_subsidy
연말정산연말정산year_end_settlement
연말정산 (분할납부) (2)연말정산year_end_installment
퇴사자퇴사resigned_payroll
퇴사자(연차수당)퇴사resigned_leave_pay
퇴직정산퇴사retirement_settlement
단기근무자기타short_term_worker
당직의기타on_call_doctor
건보정산(곽초희)기타health_insurance_settlement

근거와 변경 기록 ​

기존 앱 소개의 '전체 엑셀을 한 번에 이관'을 파서·고정 기간·실제 필터 조건으로 구체화했습니다. 범용 가져오기와 CLI 이관을 분리하고, 필터 미진입 및 재실행 덮어쓰기를 문서화했습니다. 새 실행·캡처는 없으며 필요한 증거는 비식별 샘플 워크북, 대상 조직 로그, DB 수량 대조, HR 시트 재진입 화면입니다.