본문으로 건너뛰기
가이드

전자 서명

Core 경계를 넘지 않으면서 App 소유 업무 레코드를 불변 문서, 서명 요청, 종료 결과에 연결합니다.

App 레코드에 연결된 서명 문서를 Signature SDK로 만듭니다. 보호된 Resource와 이벤트와 비동기 작업 처리하기를 먼저 준비하세요.

문서 생성부터 서명 요청까지

  1. 아래 등록 예시에 따라 양식 바인딩과 대상 Resource resolver를 공개합니다. 요청받은 정확한 참조마다 다시 권한을 확인하세요. Party나 Resource를 선택했다는 사실만으로 읽기를 허용하지 않습니다.
  2. 전자 서명 계약의 입력 형식으로 App 트랜잭션 밖에서 SignatureDocumentHost::createCurrentBound()를 호출합니다. 반환된 식별자를 저장하고 signature.document.outcome.v1을 기다립니다.
  3. 준비 완료 문서를 다시 읽은 뒤 정확한 public id·revision·SHA-256, 확정 참여자, 동의·만료 정책, 내구성 있는 멱등성 키를 SignatureHost에 제출합니다. 문서 생성 수락과 렌더링 완료는 별개입니다.
  4. 대상과 요청 식별자를 대조하고 현재 권한을 복원한 뒤 최종 결과를 한 번만 반영합니다. App handoff 로그에 PDF 원문, 인증정보, 초대 주소, 서명 증거를 복사하지 않습니다.

결과 확인

문서가 준비된 뒤에만 서명 요청이 제출되어야 합니다. 재시도해도 수락된 식별자는 하나이고 중복 이벤트가 업무 효과를 반복하지 않아야 합니다. 권한 회수와 revision 불일치는 거절되어야 합니다. 기존 검증 사례는 packages/people/tests/Feature/EmploymentContractSignatureBridgeTest.php, 실행 절차는 App 테스트하기에 있습니다.

App 바인딩과 데이터 Resource 등록

양식 바인딩 등록

서명 바인딩과 그 바인딩이 가리키는 업무 Resource는 서로 다른 contribution입니다. Resource Module이 canonical Resource key와 권한을 게시하고, ResourceReferenceResolutionContribution이 Core가 정확한 ResourceRef를 다시 인가할 수 있게 합니다. 그다음 서명 contribution이 이미 존재하는 Resource를 재사용 가능한 양식 family 하나에 연결합니다. 서명 descriptor의 resourceKey만 채운다고 Resource가 등록되지는 않습니다.

구성 요소People 예시등록되는 것
발견 rootPeopleCoreAppManifest::contributionLocations()에 src/Contribution 포함생성된 contribution manifest가 클래스와 하위 디렉터리를 스캔할 수 있음
업무 ResourceContribution/Resources/EmploymentContractModule.php가 people.employment_contract와 권한 게시바인딩이 지칭할 subject identity 확립
Subject 해석Contribution/ReferenceResolution/PeopleEmploymentContractReferenceResolver.php가 Resource Reference 해석 구현현재 actor와 Legal Entity에 맞춰 정확한 subject record 재인가
서명 familyContribution/PeopleSignatureDescriptors.php가 SignatureTemplateBindingDescriptor 반환App 소유 바인딩을 Signature catalog에 등록
App 데이터 ResourceDescriptors/PeopleSignatureDocumentDataSources.php가 source descriptor와 provider를 연결정보 추가에 제시할 Resource 기반 데이터 등록

바인딩 클래스는 App Manifest가 선언한 contribution 위치 아래에 있어야 하며 Nexia\AppDescriptors\Contracts\AppDescriptorContribution을 구현해야 합니다. 별도의 서명 바인딩 interface나 service provider 등록은 없습니다. Host는 AppDescriptorContribution을 발견하고 클래스가 속한 App을 provenance로 보존한 뒤, 반환된 AppDescriptorSet에서 SignatureTemplateBindingDescriptor만 고릅니다.

아래는 실제 People 선언의 식별자와 계약 필드로 만든, constructor 검증을 통과하는 축약형입니다.

코드 예시
PHP
<?php

namespace Amuzcorp\Nexia\PeopleCore\Contribution;

use Nexia\AppDescriptors\Contracts\AppDescriptorContribution;
use Nexia\AppDescriptors\AppDescriptorSet;
use Nexia\AppDescriptors\DescriptorStatus;
use Nexia\AppDescriptors\SignatureSignatoryRoleDescriptor;
use Nexia\AppDescriptors\SignatureTemplateBindingDescriptor;
use Nexia\AppDescriptors\SignatureTemplateVariableDescriptor;
use Nexia\Signature\SignatureDataClassification;
use Nexia\Signature\SignatureVariableType;

final class PeopleSignatureDescriptors implements AppDescriptorContribution
{
    public static function appDescriptors(): AppDescriptorSet
    {
        return AppDescriptorSet::of(new SignatureTemplateBindingDescriptor(
            appKey: 'people',
            bindingKey: 'people.employment_contract',
            resourceKey: 'people.employment_contract',
            labelKey: 'people.signature_bindings.employment_contract.label',
            descriptionKey: 'people.signature_bindings.employment_contract.description',
            createPermissionKey: 'people.employment_contract.create_document',
            variables: [
                new SignatureTemplateVariableDescriptor('worker.full_name', 'people.signature_bindings.employment_contract.variables.worker_full_name', SignatureVariableType::String, true, SignatureDataClassification::Restricted),
                new SignatureTemplateVariableDescriptor('contract.starts_on', 'people.signature_bindings.employment_contract.variables.contract_starts_on', SignatureVariableType::Date, true, SignatureDataClassification::Internal),
            ],
            signatoryRoles: [
                new SignatureSignatoryRoleDescriptor('worker', 'people.signature_bindings.employment_contract.roles.worker', 1, 1),
            ],
            syntheticSample: [
                'worker.full_name' => 'Alex Kim',
                'contract.starts_on' => '2026-09-01',
            ],
            templateKeys: ['people.employment_contract.new_hire'],
            version: '1.0',
            status: DescriptorStatus::Active,
        ));
    }
}

appKey, bindingKey, createPermissionKey, 모든 templateKeys 항목은 소유 App namespace에 두세요. resourceKey는 제출하는 subject reference의 canonical key와 같아야 하고, 게시 양식이나 문서가 고정할 수 있게 된 version은 불변입니다. 모든 label key를 App locale catalog에 추가하고 syntheticSample에는 합성 값만 넣으세요.

Contribution을 바꾼 뒤에는 생성된 runtime cache를 갱신하고 발견과 descriptor 검증을 각각 확인합니다.

코드 예시
Shell
task artisan -- nexia-runtime:refresh-runtime-caches --if-route-cached --no-ansi
task artisan -- nexia-apps:doctor-package-app people --no-ansi
task artisan -- nexia-apps:validate-app-descriptors people --no-ansi

발견됐다는 사실만으로 바인딩을 사용할 수 있는 것은 아닙니다. 소유 App이 그 테넌트에서 operational이고, descriptor가 Active이며, actor에게 createPermissionKey가 있고, 요청한 key·locale·유효일에 맞는 게시 양식이 있어야 합니다. 운영 binding에는 사용자 대표 역할과 나머지 근로계약 변수가 더 들어갑니다. 완전한 constructor와 host signature는 전자 서명 계약에서 확인하세요.

App 데이터 Resource 등록

App 소유 모델 데이터를 정보 추가에 표시하려면 SignatureDocumentDataSourceContribution을 구현합니다. 정적 appDescriptors()는 source마다 SignatureDocumentDataSourceDescriptor 하나를 게시하고, signatureDocumentDataSourceProviders()는 같은 contributor 클래스에서 요청 시점 provider를 반환합니다. Core는 정확한 App key, source key, source version, contributor class, 발견된 App owner가 모두 같은 descriptor/provider만 연결합니다. Descriptor에 맞는 provider가 없거나 provider에 맞는 descriptor가 없으면 fail closed합니다.

새로운 모델 기반 source에는 resourceKey로 그 모델의 canonical Resource key를 지정하세요. 같은 App이 소유하고 비어 있지 않은 labelKey를 가진 ResourceDescriptor가 이미 있어야 하며, 작성 catalog에는 그 Resource label이 표시됩니다. supportedSubjectResourceKeys는 이 source를 사용할 수 있는 문서 subject를 별도로 선언할 뿐 그 subject Resource를 등록하지는 않습니다. Provider는 값을 해석할 때 현재 actor, tenant, Legal Entity, 정확한 source record, 요청 field, subject 관계를 다시 인가해야 합니다.

실제 구현은 People의 PeopleSignatureDocumentDataSources입니다. 이 클래스의 디렉터리는 Manifest의 src/Descriptors contribution 위치에 포함되고, 아래 네 개의 정확한 descriptor/provider 쌍을 게시합니다.

Source identity표시 ResourceLookup허용하는 문서 subject
people.worker_employment@1people.employment_contractdirect_subject, onedirectory.party, people.employment_contract
people.worker@1people.workerderived_ref의 worker, onepeople.employment_contract
people.employment@1people.employmentderived_ref의 employment, onepeople.employment_contract
people.worker_assignments@1people.worker_assignmentderived_ref의 worker, effective_from 순서의 manypeople.employment_contract

이 클래스는 appDescriptors()에서 descriptor 네 개를, 정확한 source identity가 일치하는 SignatureDocumentDataSourceProvider 네 개를 signatureDocumentDataSourceProviders()에서 반환합니다. People이 operational이면 Core registry가 이 source를 Signature 작성 화면에 공개합니다. Core는 People model을 import하거나 그 model에서 field를 추론하지 않습니다.

원본 위치: docs/developers/content/ko/platform-extensions/electronic-signature.md