본문으로 건너뛰기
가이드

Resource Transfer

Resource 내보내기 소스를 공개하고 App 소유 가져오기에 검증된 recipe 또는 pipeline을 선택합니다.

SDK transfer 계약과 공통 host 작업 공간으로 App Resource의 가져오기·내보내기를 연결합니다.

App은 공통 Import·Export 기반을 그대로 사용할 수 있습니다. Core는 파일 형식·업로드·mapping·preview·orchestration·polling·공통 UI를 제공하고 선언된 권한을 적용합니다. App은 schema·권한 선언·scope filtering·export rows·업무 검증·저장·retry 규칙을 소유합니다. Core의 공통 gate가 App의 행 가시성이나 업무 저장 권한을 대신하지 않습니다.

전송 동작 연결

내보내기는 ResourceTransferExportSourceContribution에 TransferSchema, 범위, 필수 권한, App 소유 source 클래스를 선언합니다. 실제 조회는 허가된 레코드만 선택하고 보호 필드를 가려야 합니다. 아래 People Operating Unit 사례가 이 판단을 App 안에 두는 방식입니다.

가져오기는 선언형 행 처리라면 recipe, 별도 분석·미리보기·실행이 필요하면 ResourceImportPipelineContribution을 선택합니다. 화면에 동작을 노출하기 전에 권한과 업로드·스키마 제한을 정하세요. 미리보기에 성공했더라도 실행 시점과 각 업무 변경에서 다시 권한을 검사합니다.

결과 확인

허가된 사용자는 지정 범위만 내보내거나 유효한 파일을 미리 보고 적용할 수 있습니다. 잘못된 입력, 접근 불가 레코드, 중복 실행은 거절하거나 안전하게 재처리해야 합니다. 패키지 검사는 App 테스트하기를 따릅니다.

내보내기·가져오기·백그라운드 실행

Resource Transfer는 검토 가능한 export와 import를 위한 플랫폼 경로입니다. App은 export source를 선언하고, 일반 Resource 생성이 올바른 write boundary가 아닐 때 import recipe 또는 pipeline을 선택합니다. 호스트가 파일 처리와 orchestration을 소유하고, 선언된 source나 pipeline은 App의 인가와 도메인 규칙을 유지합니다.

packages/people/src/Contribution/OperatingUnitWorkerExportContribution.php는 실제 export-only projection을 다음처럼 공개합니다.

코드 예시
PHP
use Amuzcorp\Nexia\PeopleCore\Domain\WorkerDirectory\OperatingUnitWorkerDirectoryExportSource;
use Nexia\ResourceTransfer\Contracts\ResourceTransferDefinition;
use Nexia\ResourceTransfer\ResourceTransferExportSourceDefinition;
use Nexia\ResourceTransfer\TransferSchema;

new ResourceTransferExportSourceDefinition(
    resourceKey: 'people.operating_unit_worker',
    labelKey: 'people.operating_unit_worker.resource_label',
    sourceClass: OperatingUnitWorkerDirectoryExportSource::class,
    schema: TransferSchema::make()
        ->exportOnly('worker_number', 'people.workforce_export.columns.worker_number')
        ->exportOnly('display_name', 'people.workforce_export.columns.display_name'),
    scope: ResourceTransferDefinition::SCOPE_OPERATING_UNIT,
    permissionKeys: [
        'people.operating_unit_worker.read',
        'people.workforce_export.execute',
    ],
);

위 코드는 생성자 발췌입니다. Manifest contribution 경로의 ResourceTransferExportSourceContribution::resourceTransferExportSources()에서 반환하고, 나열한 권한은 PermissionContribution으로 공개합니다. sourceClass는 아래 row source 계약을 구현합니다. People의 전체 클래스에서 두 interface 연결을 확인하세요.

전체 구조: 각 단계의 소유자 선택

단계App이 제공호스트가 제공
ExportSchema, 권한, 인가된 lazy row, scope filtering, 감사 근거선언된 권한 gate, format, row limit, file response
Generic importResource schema와 선언된 create actionMapping, 검토, 승인된 create 호출
Recipe importDataset graph와 providerResource action을 통한 transactional prerequisite 실행
Pipeline importSchema, 권한, 검증, batch lifecycle, 업무 저장과 retry 규칙Upload, mapping, preview, 확인, orchestration, polling

Export contribution

ResourceTransferExportSourceDefinition은 resourceKey, labelKey, sourceClass, schema, scope, permissionKeys를 지정합니다. formats 기본값은 CSV, XLSX, JSON, text이고 rowLimit 기본값은 10,000입니다. 데이터를 표현하지 못하는 format은 제거하고 streaming 비용에 맞춰 row limit을 정하세요. Read를 재사용하지 말고 전용 export permission을 사용합니다.

Source는 정확히 다음 SDK 계약을 구현합니다.

코드 예시
PHP
interface ResourceTransferExportSource
{
    public function rows(ResourceTransferExportRequest $request): iterable;
    public function evidence(ResourceTransferExportRequest $request): array;
}

Row는 yield하거나 lazy collection으로 반환합니다. rows() 안에서 request가 전달한 actor의 record visibility와 해석된 Legal Entity 또는 Operating Unit scope를 적용하고, 선택된 column과 유효 row limit을 지키세요. evidence()에는 실제 query shape, filter, scope를 기록합니다.

Import recipe 또는 pipeline

경로선택할 때Commit 소유자
Generic Resource TransferResource 하나에 안전한 match key와 선언된 create action이 있음Core
ImportRecipeContribution파일 하나가 여러 Resource에 걸치지만 App batch state machine은 없음선언된 Resource action을 통한 Core
ResourceImportPipelineContributionApp이 batch state, tolerance, 고정 근거, retry를 소유App pipeline

Recipe는 Core model class가 아니라 Resource key와 provider 계약을 선언합니다. Core는 각 action을 인가하고 host transaction·ownership gate 안에서 prerequisite graph를 실행합니다.

Pipeline definition은 container에서 해석하는 ResourceImportPipeline을 더합니다. receive(), validateRows(), apply(), retry()가 App lifecycle을 보존합니다. ImportBatchState.applyEligible, 고정 normalized row, rejection, 검토 가능한 fill proposal을 따르세요. ImportSourceProfile은 이름 있는 vendor workbook 형식을 분리합니다. 선택한 profile은 definition-wide column alias를 대체하며 서로 섞이지 않습니다.

큰 workbook은 ChunkedResourceImportPipeline을 구현하고 반복 가능한 ResourceImportRowSource를 chunks()로 처리합니다. 전체 source를 메모리에 만들지 마세요. 제한된 rowDispositions가 row별 이력을 생략해도 정확한 dispositionCounts는 전체 건수를 유지합니다. 기존 pipeline은 validateRows()를 계속 사용할 수 있습니다.

ImportPlan은 고유한 ChoiceOption 값에서 MultipleChoiceDecision을 요청할 수 있습니다. 호스트는 알 수 없거나 중복된 답을 거부하고 허용된 부분집합을 선언 순서로 반환합니다.

인쇄된 값이 다른 Resource를 식별하면 TransferSchema::reference()를 사용합니다. 호스트가 승인 전에 해석하고 pipeline은 자기 Legal Entity 경계에서 식별자를 다시 검사합니다. 제한된 bulk 해석은 ResourceReferences::resolveMany()를 한 번 호출합니다. Dispatcher는 owner의 batch capability 또는 권한 적용 단건 fallback을 사용합니다. 제한 없는 N+1 loop를 만들지 마세요.

사용자 정의 백그라운드 import capability

AuthorizedImportFileStore::claim()은 clean upload를 actor, Legal Entity, Resource에 결속합니다. find()는 AuthorizedImportFile metadata 권한을 다시 검사하고, withLocalCopy()는 checksum 검증 임시 경로를 제공한 뒤 callback 종료 시 삭제합니다. Host storage 좌표나 전체 파일 bytes는 노출하지 않습니다.

BackgroundOperationStore는 open(), progress(), complete(), fail(), failIfPending()으로 actor 소유 임시 ticket을 제공합니다. 두 capability 모두 pipeline 인가, idempotency, transaction을 대체하지 않습니다.

선언과 프런트엔드 gate

App package에서 ImportContributionValidator::recipes(), pipelines(), portfolio()를 실행합니다. Core는 discovery 중 내재 검증을 반복하고 활성 permission, Resource 소유권, operational App 상태 같은 host 사실을 더합니다. .nexia/resource-import-coverage.json은 설치된 모든 App을 분류해야 하며 php artisan nexia-resources:validate-resource-import-coverage가 누락과 runtime drift를 거부합니다.

Mapping이 있는 human import는 resourceKey 하나로 NxDatasetImportWorkspace를 mount합니다. Workspace가 upload, mapping, preview, commit, ticket polling을 소유하지만 선택한 recipe나 pipeline의 write authority를 가져가지는 않습니다. Dataset Import는 Agent capability가 아니며 Agent는 공통 data.* 계약을 계속 사용합니다.

공통 프런트엔드 연결

컴포넌트는 @nexia/sdk/host에서, props 타입은 @nexia/sdk에서 가져옵니다.

공개 컴포넌트용도App이 전달하는 값
NxResourceTransferActions사용 가능한 동작에서 공통 transfer 화면으로 이동인가된 Resource 응답의 transferMeta와 필수 onImported prop (화면 이동에서는 호출하지 않음)
NxResourceImportDialog일반 Resource import의 업로드·preview·실행·상태 확인 dialogopen, onClose, transfer URL과 완료 callback
NxDatasetImportWorkspaceRecipe 또는 pipeline의 mapping·preview·commit·polling 작업 공간resourceKey; 조직 문맥은 호스트에서 읽음
NxDatasetExportWorkspace기여한 dataset의 metadata 조회, format·column 선택과 exportresourceKey와 허용된 조직 target 문맥

서버 metadata와 실행 gate에 따라 사용 가능 여부가 달라집니다. 컴포넌트를 mount한 것만으로 권한이 생기지 않습니다. Props와 관련 registry는 React 컴포넌트와 훅을 참고하세요.

경계

  • Export는 일반 list read가 아니라 보호된 bulk action입니다.
  • Row limit은 pagination이 아닌 truncation guardrail이며 도달 사실을 알려야 합니다.
  • Request에 scope가 있어도 실제 filtering은 rows() 안에서 수행합니다.
  • 감사 근거에는 일반 event label이 아니라 실제 실행한 query를 기록합니다.
  • Pipeline은 host upload, 검토, operational gate를 우회할 권한이 아닙니다.
  • 저장 mapping은 같은 Resource, header shape, source profile, schema version에만 재사용합니다. Decision, fill, reference, exclusion은 현재 파일 사실입니다.
원본 위치: docs/developers/content/ko/platform-extensions/resource-transfer.md