현재 사용법 (2026-09-10,
6fbaee7f): 급여 시트·수식·반영·확정 · 기능 마스터. 아래는 작성 당시의 변경 설명이며 현재 전체 동작·재측정 결과를 뜻하지 않습니다.
UP-009 — 시트 특징 기반 생성: 카테고리·디폴트 수식 선택
새 시트를 만들 때 「이 시트의 특징」(근무기록형·실적형·명부형·기준형 4종)을 고르면, 그 특징에 맞는 컬럼 골격과 검증된 디폴트 수식이 미리 깔린 시트가 생성됩니다. 지금까지는 빈 그리드에서 열 설정을 열어 수식을 처음부터 작성해야 했습니다.
핵심 아이디어는 하나입니다: 수식은 처음부터 짜지 않습니다. 병원 급여 실무에서 실증된 수식이 기본 체크된 채 제안되고, 사용자는 필요 없는 것을 빼거나 참조 컬럼을 연결만 합니다.
배경 / 지금 동작
hr-system 급여 워크북의 「+ 새 시트 만들기」 모달에는 4개 탭(새 시트 만들기·내 템플릿·추천 템플릿·업로드)이 있습니다. 첫 탭(내부 키 scratch)은 시트 이름과 공개 여부만 받아, A~Z 26개의 빈 텍스트 열(FALLBACK_LAYOUT)로 시트를 만들었습니다. 생성된 시트는 UP-008 수명주기에 따라 「설정 중」(서버 sheet_views.setupCompletedAt = null) 상태로 시작하며, 이 상태에서만 구조(컬럼·열 수식)를 바꿀 수 있습니다.
수식 열을 만들려면 생성 후 열 설정에서 종류를 「수식」으로 바꾸고 =IF([퇴근]-[출근]<0, …) 같은 식을 직접 작성해야 했습니다. 빈 시트에서 수식을 처음부터 짜는 것이 온보딩의 가장 큰 장벽이었습니다.
이 변경에서 쓰는 용어를 정의합니다. 카탈로그는 특징 4종별 {컬럼 골격, 디폴트 수식 목록}을 담은 프론트 상수(sheet-category-catalog.ts)입니다. 슬롯은 수식 텍스트 안의 [참조명] 토큰 하나이며, 어떤 컬럼을 읽을지 바인딩하는 단위입니다.
변경 전 / 변경 후
변경 전
변경 후
개념 흐름별 변경
① 카테고리 카탈로그 — 목업 수식을 엔진 실측으로 교정했습니다 (apps/hr-system/src/sheets/sheet-category-catalog.ts)
특징 4종의 골격과 수식을 정의합니다. 기획 목업은 엑셀 문법이었으나 이 레포의 수식 엔진과 세 곳이 달라 그대로 쓰면 틀린 값이 나옵니다. time 형식 셀은 엔진이 이미 시(hours) 숫자로 평가하므로 엑셀식 ×24 날짜 시리얼 보정을 제거했고(IF([퇴근]-[출근]<0, 24+…)), 엔진에 없는 QUOTIENT는 양수에서 동치인 ROUNDDOWN(a/b, 0)으로 바꿨으며, 명부형의 =ROW()-1 순번 수식은 그리드에 이미 있는 # 열이 같은 역할을 하므로 도입하지 않았습니다(2026-08-10 결정).
② 슬롯 바인딩 — 이름 자동 매칭, 미연결은 차단이 아니라 제외입니다 (같은 파일의 buildCategoryLayout/defaultSelections + 단위 테스트 8건)
슬롯은 세 종류입니다. column 슬롯은 골격 컬럼에 이름으로 자동 매칭되고, 실패하면 ⚠ 미연결 표시와 함께 그 수식만 생성에서 제외됩니다 — [만들기]를 막지 않습니다. formula 슬롯은 다른 수식의 결과를 괄호로 감싸 인라인 치환합니다(근무시간 수식이 인정시간 수식 안에 들어가므로, 최종 시트에는 목업 그대로 수식 열 2개만 생깁니다). system 슬롯은 사용자가 바꿀 수 없는 고정 주입입니다 — [통상시급]은 계약의 시급을 읽는 identity 컬럼(refField: "hourlyRate")을 골격에 자동 추가해 참조하고, [최저시급]은 조직 상수 토큰 [$급여.최저시급]으로 치환됩니다. 야간 가산의 [야간시간]과 기준형의 [월 근로시간]은 골격에 없어 기본 미연결인데, 이는 미연결→직접 연결→「+ 새 컬럼 만들기」 경로를 보여주는 의도된 시연입니다(2026-08-10 결정).
③ 모달 2단계 — 특징 카드에서 수식 선택으로 (new-sheet-modal.ts, modals/new-sheet.html)
1단계는 이름 아래 특징 카드 4종(단일 선택)입니다. 특징을 고르지 않으면 기존과 동일한 「특징 없이 빈 시트로 만들기」만 유효하고, 고르면 [다음 — 수식 고르기]가 나타납니다. 2단계는 좌측 골격 미리보기(더블클릭으로 이름 변경 — 바인딩이 컬럼 key 기준이라 연결된 슬롯이 자동으로 따라옵니다)와 우측 수식 칩 목록(기본 전부 체크, ⚠ 연결 필요 뱃지, 「참조 연결」 펼침에서 슬롯별 드롭다운)입니다. 다른 세 탭은 변경이 없습니다.
④ 생성 경로와 특징 저장 (sheet-crud.ts, sheet_views.category + 마이그레이션 1882, grid.html 설정 중 띠)
createSheetFromForm이 선택적 두 번째 인자로 카탈로그 빌드 결과를 받아, FALLBACK_LAYOUT 대신 골격 columnLayout으로 생성하고 특징 값을 sheet_views.category(varchar, null=빈 시트)에 저장합니다. 골격·수식 주입은 기존 columnLayout 생성 경로를 그대로 사용하므로 서버에 새 로직이 없고, category는 표시용 저장뿐이라 생성 후 변경 경로(update 스키마)에 넣지 않았습니다. 생성 직후 시트는 UP-008 그대로 「설정 중」으로 시작하며, 설정 중 안내 띠가 특징 시트에서는 "특징 「근무기록형」으로 만들어졌어요…"로 바뀝니다. 미연결로 제외된 수식은 토스트로 안내합니다("설정에서 연결할 수 있어요").
⑤ 검증
빌더 단위 테스트 8건이 자동 매칭·인라인 치환·미연결 제외·연결 시 부활·상수 치환을 잠급니다. 라이브로는 근무기록형 기본 빌드로 시트를 생성해 category 저장과 「설정 중」 시작을 확인하고, 자정 넘김 케이스(22:00→02:00, 휴게 1)를 입력해 인정시간이 3으로 계산되는 것을 확인했습니다. 시급이 연결되지 않은 행의 수당액은 0으로 떨어집니다(fail-safe).