전자 결재
바인딩과 문서 스키마, 슬롯 위젯을 함께 배포해 App 레코드 동작을 Nexia 전자 결재에 연결합니다.
App 레코드를 전자결재에 제출하고, 결재 결과를 해당 업무에 반영합니다. 먼저 Resource 만들기에서 레코드와 권한이 있는 제출 동작을 준비하세요.
업무 동작 연결
AppDescriptorContribution::appDescriptors()에서ApprovalFormBindingDescriptor와ApprovalDocumentSchema를 공개합니다. 기존 레코드를 제출하면link, 제출 시 생성하면create를 선택합니다. 문서 스키마에는 결재자가 판단할 근거를 담습니다.approval.composer.business_form에 Slot Widget 추가를 적용합니다.ApprovalBusinessFormSlotPropsV2를 사용하고 위젯 키를formWidgetKey와 맞추세요. 연결된 프런트엔드 컴포넌트도 등록해야 합니다.- 전자 결재 계약에 따라 App 제출 API를 구현합니다. Host 호출 전에 대상 레코드, 현재 사용자, 조직, 입력값, 멱등성 식별자를 검사합니다. App과 host의 트랜잭션이 분리된다면 재시도 가능한 handoff를 남깁니다.
- 커밋된 결과를 App 이벤트 핸들러에서 처리합니다. 대상과 현재 업무 상태를 다시 확인하고 효과는 한 번만 적용하세요. 결재 결과를 기록하는 일과 App 레코드를 전이시키는 일은 각 소유자가 수행합니다.
packages/assets/src/Descriptors/AssetApprovalDescriptors.php는 동작 식별자를 양식과 제출 권한에 함께 사용합니다. 그중 asset_movement/submit 쌍을 펼친 생성 예시입니다.
new \Nexia\AppDescriptors\ApprovalFormBindingDescriptor(
appKey: 'assets',
resourceKey: 'asset_movement',
actionKey: 'submit',
labelKey: 'assets.approval.asset_movement.submit.label',
entryModes: ['link'],
formWidgetKey: 'assets.asset_movement.submit',
documentSchemaKey: 'assets.asset_movement',
descriptionKey: 'assets.approval.asset_movement.submit.description',
);이 선언만으로 스키마·컴포넌트·제출 API가 생기지는 않습니다. 세 구현을 함께 제공해야 합니다. submitPermissionKey를 생략하면 바인딩 키인 assets.asset_movement.submit이 제출 권한으로 쓰입니다.
결과 확인
운영 가능한 테넌트에서 권한이 있는 사용자가 발행된 업무 양식을 고르고 App 폼을 열어 제출할 수 있어야 합니다. 결재자에게는 제출 시점의 근거가 보입니다. 같은 제출을 재시도해도 handoff가 중복되지 않고, 결과를 재처리해도 업무 효과가 반복되지 않아야 합니다. 권한 없는 사용자의 직접 API 요청도 거절되는지 확인하세요.
기존 연동 사례는 packages/assets/tests/Feature/AssetBoundApprovalSubmissionTest.php입니다. 실행 절차는 App 테스트하기, 내구성 있는 전달 구현은 이벤트와 비동기 작업 처리하기를 참고하세요.
양식과 수명주기, Process
코드의 바인딩은 App 기능을 공개합니다. 테넌트 소유 Approval Form Template은 바인딩을 선택하고 표시·결재 경로 설정을 관리합니다. 양식을 발행해도 App 설치나 권한 부여가 이루어지지는 않습니다. 결재 양식 프리셋은 테넌트 범위입니다.
바인딩을 없애기 전 Deprecated로 바꾸면 새 선택은 막고 기존 참조는 해석할 수 있습니다. Removed는 기존 참조의 해석도 중단합니다. 세부 필드, 재시도, 문서 스냅샷, 첨부 근거, host 반환 계약은 전자 결재 계약에서 확인합니다.
결재 뒤의 BPMN 업무는 업무 프로세스, 수신자가 확정 문서에 서명하는 흐름은 전자 서명으로 연결하세요. 바인딩은 발견되는데 폼이 비어 있으면 권한 변경보다 바인딩·위젯·컴포넌트 키의 연결을 먼저 확인합니다.
결재 필수 설정까지 연결하기
바인딩 등록만으로 직접 실행이 금지되지는 않습니다. 같은 업무 동작의 직접 API와 결재 제출 경로가 모두 ApprovalRequirements::required(bindingKey, legalEntityKey, default, contextKey)를 적용하고, 필수일 때 미승인 업무 효과를 차단한 뒤에만 supportsRequirementPolicy: true를 선언합니다. 브라우저가 보내는 approval_required 값을 믿거나 Resource마다 별도 정책 테이블을 만들지 않습니다.
Procurement의 구매 요청 제출을 예로 들면 ProcurementApprovalDescriptors는 procurement.purchase_request.submit 바인딩을 공개하고, SubmitProcurementApproval::required()는 공통 요구 사항을 읽습니다. 직접 처리와 Process handler가 같은 제출 서비스를 사용합니다. 신규 작성은 create, 기존 문서 상신은 link로 진입할 수 있지만 승인 전에 확정된 업무 효과를 적용해서는 안 됩니다. 내부 초안 저장과 업무 확정은 구분합니다.
관리자 설정 순서
- 전자결재 → 결재 양식에서 해당 동작의 업무 양식을 생성합니다. 적용 범위를 기업 공통 또는 법인 전용으로 정합니다.
- 양식의 결재선 선택 방식을 지정 결재선 또는 상신자 선택으로 정하고 게시합니다. 결재선을 고르는 것은 결재 필요 여부를 정하는 일이 아닙니다.
- 전자결재 → 업무별 결재 설정에서 App과 적용 범위를 선택합니다. 게시 양식과 사용 가능한 결재선 선택 방식이 있어야 전자결재 필수를 켤 수 있습니다. 준비가 부족하면 그 업무에 표시된 결재 양식 설정 링크로 이동합니다.
- 같은 사용자·같은 업무를 직접 화면과 Process에서 실행해 아래 결과를 비교합니다. 설정 변경 뒤에는 새 실행으로 확인하고 진행 중 결재를 새 정책으로 덮어쓰지 않습니다.
설정을 읽는 순서와 결과
조건이 있는 업무는 법인별 조건 → 법인 기본 → 기업 공통 조건 → 기업 공통 기본 → App 업무 기준 순서로 직접 지정된 최신 값을 찾습니다. 직접 지정 해제는 이전 값으로 돌아가는 것이 아니라 다음 적용 기준으로 내려가는 새 이력입니다. 화면은 적용 근거와 현재 결과를 보여줍니다.
| 설정 | 새 업무 실행 | 결재 작성기와 기존 이력 |
|---|---|---|
| 전자결재 필수 | App이 미승인 업무 효과를 차단하고 정규 상신 경로 사용 | 호환 업무 양식으로 상신, 확정 효과는 승인 결과에 따라 적용 |
| 전자결재 불필요 | App의 권한·업무 규칙을 검사한 직접 처리 경로 사용 | 해당 신규 작성 진입은 숨김; 기존 case·진행 중 snapshot은 보존 |
| 직접 지정 없음 | 위 우선순위로 상속하고 최종적으로 App 기준 사용 | 조건별 필수 여부가 다르면 좁은 필수 조건의 진입은 유지 |
App에 조건별 업무 기준이 있으면 ApprovalRequirementContextProvider로 설정 가능한 조건과 기본값을 제공합니다. 법인 소유 조건은 그 법인에서만 제공하세요. 기업 공통 업무는 requirementPolicyLegalEntityScoped: false, 조건별 설정만 허용하는 업무는 requirementPolicyContextsOnly: true를 사용합니다. 정확한 계약은 전자 결재 계약에 있습니다.
Process에서 결재선을 정하는 시점
양식의 지정 결재선은 상신 시 실제 실행 문맥으로 해석합니다. 상신자 선택 방식이라 결재선이 없고 Work Action이 supportsLinePreparation을 제공하면, Core가 실행자에게 결재선 준비 Task를 만들고 완료 후 같은 업무 작업을 재개합니다. 준비 완료 자체는 승인이 아닙니다. handler는 실제 case를 상신하고 waitingForApproval(...)로 결과를 기다립니다. 필요한 문맥이나 담당자를 찾지 못하면 자동 통과하지 않습니다.
실제 구매 제안부터 입력 검토·초안 생성·결재 결과 분기까지 이어지는 설정 예는 업무 프로세스의 구매 흐름을 따라가세요. 취소·변경은 신규 업무 동작과 별도 결재로 설계하고, 기존 case의 승인 증거를 고쳐 쓰지 않습니다.