Skip to content

HR 급여 페이지 (FE 메인테이너)

2026-07-18 as-built. payroll-owned input snapshot → 급여 확정 v2 서버 seam까지 연결했다. 근태는 선택 provider다.

라우트와 컴포넌트

  • /human-capital/compensation/payroll/general: 월별 run 목록과 상태 배지.
  • /human-capital/compensation/payroll/general/console/wage-salary: 직원별 지급·공제·실지급 표.
  • 양쪽 MainOrg.vueuseAccountContext()의 Company/Office를 configurePayrollRunScope()에 전달한다.

콘솔 오버레이:

  • DialogConfirmPayrollArt: 입력 출처·revision과 합계를 확인하고, 필요하면 수동 입력을 준비한 뒤 비동기 confirm.
  • DialogRevertPayrollArt: 5자 이상 사유를 받고 비동기 revert.
  • DialogPaidPayrollArt: 비동기 mark-paid.
  • SheetTransferPayrollArt: snapshot 기반 이체 목록과 CSV.
  • SheetWithholdingPayrollArt: snapshot 기반 원천세 요약.

데이터 흐름

text
useAccountContext Company/Office
  ├─ payrollRepo.loadInputReadiness ─▶ payrollInputReadiness
  └─ payrollRepo.loadAll ────────────▶ usePayrollRun state

payrollMock liveLines ──draft──────────────┤
server/local snapshot ──confirmed/paid────┘
  • draft: employees × payslip() live 계산.
  • confirmed/paid: 확정 당시 snapshot만 사용한다.
  • linesOf, totalsOf, transferRows, transferCsv, withholdingSummary가 같은 snapshot을 소비한다.
  • PAYROLL_CALCULATION_VERSION을 confirm payload와 snapshot에 함께 보낸다.

저장소 seam

payrollRepo.js:

  • local adapter: leyve.payroll.runs localStorage, 비동기 인터페이스.
  • Supabase adapter: payroll input readiness/capture + payroll_runs read + confirm_payroll_run_v2, revert_payroll_run, mark_payroll_run_paid RPC.
  • 서버 adapter는 table upsert를 하지 않는다. authenticated direct write가 막혀 있기 때문이다.
  • normalizePayrollRun()이 snake_case run과 nested snapshot을 기존 UI shape로 변환한다.
  • 오류는 payrollErrorMessage()에서 사용자 문구로 변환한다.

usePayrollRun.js:

  • scope/hydration: configurePayrollRunScope, refreshPayrollInputReadiness.
  • input: captureManualPayrollInput, payrollInputReadiness.
  • state: statusOf, runOf, linesOf, totalsOf.
  • transition: async confirmRun, revertRun, markPaid.
  • derived: transferRows, transferCsv, withholdingSummary.
  • test only: resetRuns, setPayrollInputReadinessForTest.

UI 게이트

상태입력허용 UI
draftmissing급여 입력 필요, 수동 입력 준비 가능
draftready급여 확정 가능, 출처·선택 provider revision 표시
draftinvalidated입력 갱신 필요, 새 수동/연동 입력 준비
confirmedsnapshot 고정확정 취소·이체 의뢰·원천세
paidsnapshot 고정이체 내역·원천세; 취소 불가

확정 버튼을 누를 때 payroll 입력 준비도를 다시 조회하고, confirm-v2 RPC도 scope·hash·무효화 여부를 DB에서 재검사한다. UI 배지는 안내이고 DB가 최종 권위다. usePayrollRun.js는 time repo를 import하지 않는다.

확장 시 주의

  • 서버 path의 employeeId는 UUID여야 한다. 현재 데모 contractMock 문자열 ID는 local Prototype 전용이다.
  • 상용 계산 엔진이 서버로 이동하면 liveLines()를 서버 draft preview로 교체하되 line shape와 snapshot 소비자는 유지한다.
  • 계좌 마스킹, export 권한, 재인증, 조회 감사 UI는 별도 보안 slice로 추가한다.
  • 급여 회계 분개는 paid 이벤트 소비자로 붙이고 급여 화면에서 직접 전표를 만들지 않는다.

테스트

  • usePayrollRun.test.js: async 전이, missing/invalidated reject, manual capture, snapshot clone, paid 불가역, CSV/원천세.
  • payrollRepo.test.js: local roundtrip, nested snapshot normalize, RPC payload.
  • payrollInputSnapshotMigration.spec.js: schema/RLS/entitlement/time 무참조/immutable history 계약.
  • payroll_local_input_snapshots_smoke.sql, time_payroll_input_provider_smoke.sql: 실제 Postgres rollback smoke.