다크모드
근로계약 백엔드 핸드오프
범위와 소유권
근로계약 생성, 검토 요청, 승인·반려는 Human Capital 단독 핵심 흐름이다. 정본 forward migration은 supabase/migrations/20260717160116_workforce_local_decision_ledgers.sql이며 기존 migration은 배포 이력으로 유지한다.
Approval은 후속 선택 adapter다. Human Capital RPC·RLS·trigger는 Approval 테이블·함수·private outbox를 직접 참조하지 않는다.
데이터 모델
public.workforce_employment_contracts
- 상태는 호환상
draft | approval_pending | approved | rejected | cancelled를 유지한다.approval_pending의 사용자 의미는 인사 검토 중이다. - 신규 생성에는
office_id가 필수이며 해당 Office의human-capitalentitlement를 검사한다. - 과거 Office-null 초안은 최초 검토 요청에서 Office를 한 번 확정할 수 있다.
public.workforce_employment_contract_revisions
- 검토 요청 시 계약 조건 snapshot을 보존한다.
approval_document_id는 nullable이고 provider FK가 없다.- 기존 UUID는 감사용 opaque legacy reference일 뿐 상태 전이 권위가 아니다.
public.workforce_employment_contract_decisions
Human Capital 소유 append-only decision ledger다.
(contract_id, contract_revision, event_sequence)유일- sequence 1:
review_requested - sequence 2:
approved | rejected - actor, opinion, subject snapshot, request key, occurred time 보존
integration_status:not_connected | legacy_linked | pending | linked | failed- update/delete는
workforce_local_decision_history_append_only로 거부
기존 revision은 review event로 backfill하고, 기존 terminal 상태는 두 번째 event로 backfill한다. provider 테이블을 조회하지 않는다.
상태와 RPC
text
draft --request_workforce_employment_contract_review--> approval_pending(검토 중)
approval_pending --decide_workforce_employment_contract(approve)--> approved
approval_pending --decide_workforce_employment_contract(reject)--> rejectedcreate_workforce_employment_contract_draft: actor, HR 관리자, Office,human-capitalentitlement, 직원·계약조건·멱등키를 검증한다.request_workforce_employment_contract_review:expected_revision을 검증하고 revision snapshot과 review event를 같은 트랜잭션에 저장한다.decide_workforce_employment_contract: pending revision을 잠그고 local terminal event, revision 상태, 계약 상태, 감사를 한 트랜잭션에 저장한다.
private.workforce_local_decision_commands는 subject/command/request key별 입력과 응답을 보존한다. 같은 키의 동일 payload는 기존 응답을 반환하고 다른 payload는 충돌로 거부한다.
권한과 RLS
- public RPC는 authenticated/service role만 실행한다.
- 내부 SECURITY DEFINER는 private schema,
search_path='',auth.uid()확인, 정확한 signature grant를 사용한다. - 모든 mutation은
private.require_office_product(..., 'human-capital')을 통과한다. - authenticated direct insert/update/delete는 없다.
- 계약 당사자 또는 HR 관리자만 읽으며 RLS에서도 entitlement를 확인한다.
- decision ledger는 부모 계약 read helper를 재사용한다.
감사 이벤트
workforce.employment_contract_createdworkforce.employment_contract_review_requestedworkforce.employment_contract_approvedworkforce.employment_contract_rejected
선택 Approval seam
신규 review event는 integration_status='not_connected'와 opaque adapter metadata만 기록한다. 후속 adapter는 로컬 커밋 뒤 outbox로 전달해야 하며, unavailable/실패가 계약 상태를 롤백해서는 안 된다. 양쪽 product table에는 FK를 추가하지 않는다.
검증
- JS:
employmentContractMigration.spec.js,employmentContractRepo.spec.js,employmentContractUiContract.spec.js - SQL rollback:
supabase/tests/workforce_local_decision_ledgers_smoke.sql - 경계: strict audit에서 신규
human-capital -> approval참조 0
초안 수정·새 Revision 재검토, 계약 원문·전자서명·교부, optional Approval adapter는 후속 범위다.