계산 파이프라인 레퍼런스
급여 시스템은 설정 기반 계산 파이프라인을 사용하여 수당과 공제를 계산합니다. 각 소스 모듈은 전용 계산기를 가지고 있으며, 도메인 데이터를 읽고 금액을 산출합니다. 항목별 설정(항목 코드, 소스 모듈, value key, 요율/배수 파라미터)은 시트 컬럼 메타데이터 + 조직 파라미터 저장소에 보관됩니다. 파이프라인은 커밋된 시트가 구동하며, 레코드는 시트 커밋(commitSheet) 시에만 삽입됩니다. 참고: Payroll Schema Refactor.
아키텍처
파이프라인 흐름
AllowancePipeline (수당)
sourceModule별로 설정 그룹화- 필요한 모듈별 벌크 데이터 로드 (
calculator.loadData()) - 직원 x 설정 조합별 계산 (
calculator.calculate()) - 저장 가능한
AllowanceRecord부분 데이터 반환
DeductionPipeline (공제)
sourceModule별로 설정 그룹화- 필요한 모듈별 벌크 데이터 로드
- 직원별 계산 (
grossPay와priorDeductions맵 수신) DeductionRecord부분 데이터 반환
인터페이스
CalculatorContext
초기화 시 각 계산기에 전달:
| 필드 | 타입 | 설명 |
|---|---|---|
db | DataSource | TypeORM 연결 |
orgId | string | 조직 ID |
employeeIds | string[] | 계산 대상 직원 목록 |
period | object | { year, month } |
periodStart | Date | 기간 시작일 |
periodEnd | Date | 기간 종료일 |
EmployeeData
직원별 계산 시 사용:
| 필드 | 타입 | 설명 |
|---|---|---|
id | string | 직원 UUID |
baseSalary | number | 계약서 기본급 |
hourlyRate | number | 산출 시급 |
allowances | Record | 설정 코드별 기존 수당 금액 |
hobongAmount | number | 호봉 금액 |
longevityAmount | number | 근속수당 금액 |
KeyDescription
계산기가 반환할 수 있는 키를 설명. UI에서 시트 컬럼의 value key 설정 시 힌트로 사용(시트 컬럼 메타데이터에 저장).
| 필드 | 타입 | 설명 |
|---|---|---|
key | string | 값 키 식별자 |
label | string | 표시 라벨 |
description | string | 사람이 읽을 수 있는 설명 |
unit | string | 단위 ("원", "시간", "건", "%") |
InputDescription
특정 계산기의 설정 입력값(unitPrice, multiplier)이 무엇을 의미하는지 설명.
| 필드 | 타입 | 설명 |
|---|---|---|
unitPrice | object | { label, description, defaultValue } |
multiplier | object | { label, description, defaultValue } |
AllowanceCalculator (수당 계산기)
각 계산기는 직원별로 Record<string, number>를 반환하며, 키는 getKeyDescriptions()로 문서화됩니다. 파이프라인은 config.valueKey를 읽어 적절한 값을 선택합니다.
| 메서드 | 설명 |
|---|---|
sourceModule | SourceModule 열거형과 일치하는 문자열 식별자 |
getKeyDescriptions() | 사용 가능한 출력 키와 라벨, 단위 반환 |
getParameterSchema() | 설정 파라미터(단가/배수 등) 스키마 반환 |
getDefaultParameters() | 파라미터 기본값 반환 |
loadData(ctx) | 기간 내 전체 직원의 도메인 데이터 벌크 로드 |
calculate(employee) | 계산된 값의 Record<string, number> 반환 |
DeductionCalculator (공제 계산기)
AllowanceCalculator와 동일한 키-값 패턴. grossPay 파라미터로 세금 계산기가 총 소득 기반으로 계산 가능.
| 메서드 | 설명 |
|---|---|
sourceModule | SourceModule 열거형과 일치하는 문자열 식별자 |
getKeyDescriptions() | 사용 가능한 출력 키와 라벨, 단위 반환 |
getParameterSchema() | 설정 파라미터(단가/배수 등) 스키마 반환 |
getDefaultParameters() | 파라미터 기본값 반환 |
loadData(ctx) | 기간 내 전체 직원의 도메인 데이터 벌크 로드 |
calculate(employee, grossPay, priorDeductions) | 공제 값의 Record<string, number> 반환 |
계산기 목록
수당 계산기
| 계산기 | 소스 모듈 | 설명 |
|---|---|---|
EmploymentContractCalculator | employment_contract | 근로계약서 기반 기본급 |
OvertimeRecordCalculator | overtime_record | 기간 내 승인된 연장근무 수당 합계 |
FixedIncentiveCalculator | fixed_incentive | 기간 내 승인된 고정 인센티브 합계 |
EducationSubsidyCalculator | education_subsidy | 기간 내 승인된 교육보조금 합계 |
ResignationRecordCalculator | resignation_record | 퇴직정산 금액 — TERMINATED 직원에만 적용(아래 게이팅 주의 참고) |
YearEndSettlementCalculator | year_end_settlement | 연말정산 환급/추징을 수당 항목으로 반영 |
7개 계산기(+ ManualCalculator)는 모두 createCalculatorRegistry()에 등록됩니다 — packages/api/src/calculators/pipeline.ts:42-50.
공제 계산기
| 계산기 | 소스 모듈 | 설명 |
|---|---|---|
InsuranceCalculator | payroll_rate_config | 4대보험 (국민연금, 건강보험, 고용보험, 산재보험) |
TaxBracketCalculator | tax_bracket_config | 근로소득세 + 지방소득세 |
수동 모듈
sourceModule = "manual" 설정은 계산 파이프라인을 우회합니다. unitPrice x multiplier가 직접 금액으로 사용됩니다.
새 계산기 추가 방법
packages/api/src/calculators/my-module.calculator.ts생성AllowanceCalculator또는DeductionCalculator인터페이스 구현 (getKeyDescriptions(),getParameterSchema(),getDefaultParameters()포함)pipeline.ts→createCalculatorRegistry()에 등록- 새 소스 모듈에 바인딩된 시트 컬럼 추가(항목 코드, value key, 파라미터는 컬럼 메타데이터 + 조직 파라미터 저장소에 보관).
- 계산기의
getKeyDescriptions()키는 시트 컬럼 설정 UI에 노출됩니다.
모듈 레지스트리
module-registry 라우터는 등록된 모든 모듈의 메타데이터를 노출합니다:
const result = await client.moduleRegistry.list.query();
// 반환: { key, name, type, description, sourceEntities, targetEntities,
// calculatorClass, formula, configCount }관리자 UI에서 어떤 모듈이 활성화되어 있고 설정되어 있는지 표시하는 데 사용됩니다.
⚠️ 구현 모호점 · 하드닝 후보 (2026-08-13)
terminatedOnlyModules게이트가resignation_record만 포함하고year_end_settlement는 빠져 있음 —packages/api/src/calculators/pipeline.ts:118-124. 주석은 "Resignation/settlement modules only apply to terminated employees"라 되어 있으나 배열은["resignation_record"]하나뿐이라,YearEndSettlementCalculator는TERMINATED가 아닌 모든 직원에 대해 실행됩니다. 주석이 게이트를 과장한 것인지,year_end_settlement가 의도적으로 비게이팅인지 연말정산 동작 의도와 대조 필요.- 알 수 없는
sourceModule은 조용히MANUAL로 매핑됨 —toSourceType()(pipeline.ts:31-35)는 enum에 없는sourceModule을 전부PayrollSourceType.MANUAL로 반환합니다. 오타나 개명된 시트 컬럼 소스 모듈은 에러 없이manual타입AllowanceRecord가 되어 provenance를 잃습니다. - 공제 계산기는
pipeline.ts에 없음 — 공제 계산기 2개(InsuranceCalculator,TaxBracketCalculator)는 별도deduction-pipeline.ts에 등록되므로, 수당 레지스트리(7개)와 공제 집합은 서로 다른 파일에서 읽어야 합니다.