Skip to content

계산 파이프라인 레퍼런스

급여 시스템은 설정 기반 계산 파이프라인을 사용하여 수당과 공제를 계산합니다. 각 소스 모듈은 전용 계산기를 가지고 있으며, 도메인 데이터를 읽고 금액을 산출합니다. 항목별 설정(항목 코드, 소스 모듈, value key, 요율/배수 파라미터)은 시트 컬럼 메타데이터 + 조직 파라미터 저장소에 보관됩니다. 파이프라인은 커밋된 시트가 구동하며, 레코드는 시트 커밋(commitSheet) 시에만 삽입됩니다. 참고: Payroll Schema Refactor.

아키텍처

파이프라인 흐름

AllowancePipeline (수당)

  1. sourceModule별로 설정 그룹화
  2. 필요한 모듈별 벌크 데이터 로드 (calculator.loadData())
  3. 직원 x 설정 조합별 계산 (calculator.calculate())
  4. 저장 가능한 AllowanceRecord 부분 데이터 반환

DeductionPipeline (공제)

  1. sourceModule별로 설정 그룹화
  2. 필요한 모듈별 벌크 데이터 로드
  3. 직원별 계산 (grossPaypriorDeductions 맵 수신)
  4. DeductionRecord 부분 데이터 반환

인터페이스

CalculatorContext

초기화 시 각 계산기에 전달:

필드타입설명
dbDataSourceTypeORM 연결
orgIdstring조직 ID
employeeIdsstring[]계산 대상 직원 목록
periodobject{ year, month }
periodStartDate기간 시작일
periodEndDate기간 종료일

EmployeeData

직원별 계산 시 사용:

필드타입설명
idstring직원 UUID
baseSalarynumber계약서 기본급
hourlyRatenumber산출 시급
allowancesRecord설정 코드별 기존 수당 금액
hobongAmountnumber호봉 금액
longevityAmountnumber근속수당 금액

KeyDescription

계산기가 반환할 수 있는 키를 설명. UI에서 시트 컬럼의 value key 설정 시 힌트로 사용(시트 컬럼 메타데이터에 저장).

필드타입설명
keystring값 키 식별자
labelstring표시 라벨
descriptionstring사람이 읽을 수 있는 설명
unitstring단위 ("원", "시간", "건", "%")

InputDescription

특정 계산기의 설정 입력값(unitPrice, multiplier)이 무엇을 의미하는지 설명.

필드타입설명
unitPriceobject{ label, description, defaultValue }
multiplierobject{ label, description, defaultValue }

AllowanceCalculator (수당 계산기)

각 계산기는 직원별로 Record<string, number>를 반환하며, 키는 getKeyDescriptions()로 문서화됩니다. 파이프라인은 config.valueKey를 읽어 적절한 값을 선택합니다.

메서드설명
sourceModuleSourceModule 열거형과 일치하는 문자열 식별자
getKeyDescriptions()사용 가능한 출력 키와 라벨, 단위 반환
getParameterSchema()설정 파라미터(단가/배수 등) 스키마 반환
getDefaultParameters()파라미터 기본값 반환
loadData(ctx)기간 내 전체 직원의 도메인 데이터 벌크 로드
calculate(employee)계산된 값의 Record<string, number> 반환

DeductionCalculator (공제 계산기)

AllowanceCalculator와 동일한 키-값 패턴. grossPay 파라미터로 세금 계산기가 총 소득 기반으로 계산 가능.

메서드설명
sourceModuleSourceModule 열거형과 일치하는 문자열 식별자
getKeyDescriptions()사용 가능한 출력 키와 라벨, 단위 반환
getParameterSchema()설정 파라미터(단가/배수 등) 스키마 반환
getDefaultParameters()파라미터 기본값 반환
loadData(ctx)기간 내 전체 직원의 도메인 데이터 벌크 로드
calculate(employee, grossPay, priorDeductions)공제 값의 Record<string, number> 반환

계산기 목록

수당 계산기

계산기소스 모듈설명
EmploymentContractCalculatoremployment_contract근로계약서 기반 기본급
OvertimeRecordCalculatorovertime_record기간 내 승인된 연장근무 수당 합계
FixedIncentiveCalculatorfixed_incentive기간 내 승인된 고정 인센티브 합계
EducationSubsidyCalculatoreducation_subsidy기간 내 승인된 교육보조금 합계
ResignationRecordCalculatorresignation_record퇴직정산 금액 — TERMINATED 직원에만 적용(아래 게이팅 주의 참고)
YearEndSettlementCalculatoryear_end_settlement연말정산 환급/추징을 수당 항목으로 반영

7개 계산기(+ ManualCalculator)는 모두 createCalculatorRegistry()에 등록됩니다 — packages/api/src/calculators/pipeline.ts:42-50.

공제 계산기

계산기소스 모듈설명
InsuranceCalculatorpayroll_rate_config4대보험 (국민연금, 건강보험, 고용보험, 산재보험)
TaxBracketCalculatortax_bracket_config근로소득세 + 지방소득세

수동 모듈

sourceModule = "manual" 설정은 계산 파이프라인을 우회합니다. unitPrice x multiplier가 직접 금액으로 사용됩니다.

새 계산기 추가 방법

  1. packages/api/src/calculators/my-module.calculator.ts 생성
  2. AllowanceCalculator 또는 DeductionCalculator 인터페이스 구현 (getKeyDescriptions(), getParameterSchema(), getDefaultParameters() 포함)
  3. pipeline.tscreateCalculatorRegistry()에 등록
  4. 새 소스 모듈에 바인딩된 시트 컬럼 추가(항목 코드, value key, 파라미터는 컬럼 메타데이터 + 조직 파라미터 저장소에 보관).
  5. 계산기의 getKeyDescriptions() 키는 시트 컬럼 설정 UI에 노출됩니다.

모듈 레지스트리

module-registry 라우터는 등록된 모든 모듈의 메타데이터를 노출합니다:

typescript
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"] 하나뿐이라, YearEndSettlementCalculatorTERMINATED가 아닌 모든 직원에 대해 실행됩니다. 주석이 게이트를 과장한 것인지, 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개)와 공제 집합은 서로 다른 파일에서 읽어야 합니다.