본문으로 건너뛰기
참조

설치 콘텐츠

테넌트 설치 라이프사이클과 초기화 상태, 그리고 테넌트 행을 만드는 콘텐츠 출처 셋입니다.

설치 콘텐츠

테넌트 데이터를 추가하기 전에 설치 필수 데이터, 선택 적용 콘텐츠, 폐기 가능한 데모 데이터를 구분하세요. 선택 콘텐츠의 CopyableTemplateContribution::templates()와 apply() 구현은 Copyable Template을 따르세요. 호스트 활성화와 테넌트 설치는 별도이며 dry-run은 데이터를 쓰지 않고 설치 계획을 보여 줍니다.

시그니처

다음 명령이 라이프사이클을 처리합니다. 호스트 활성화와 테넌트 설치는 별개 연산입니다.

코드 예시
Shell
task artisan -- nexia-apps:activate-package-app {package} [--build-assets] [--dry-run]
task artisan -- nexia-apps:install-tenant-app {app} [--dry-run] [--with-prerequisites]
task artisan -- nexia-apps:repair-tenant-app {app}
task artisan -- nexia-apps:install-dev-app {app} --tenant= [--dry-run] [--with-prerequisites]

요청에 따라 테넌트 행을 만드는 명령이 둘 더 있습니다.

코드 예시
Shell
task artisan -- nexia-apps:apply-template {app} {template} --tenant= --actor= [--legal-entity=]
task artisan -- nexia-demo:seed-demo --tenant= [--force]

최소 예시

호스트 활성화 후 tenants:list에서 대상 로컬 테넌트 ID를 확인합니다. 설치가 초기화 전에 미적용 App migration을 실행합니다. 개발 명령은 APP_ENV=local에서만 동작하며 게시 상태와 readiness는 바꾸지 않습니다.

코드 예시
Shell
task artisan -- tenants:list
nexia_tenant=REPLACE_WITH_TENANT_ID
task artisan -- nexia-apps:install-dev-app workshop --tenant="$nexia_tenant" --dry-run
task artisan -- nexia-apps:install-dev-app workshop --tenant="$nexia_tenant" --with-prerequisites

--dry-run은 App과 그 전제 폐포 전체에 대한 정렬된 설치·재활성화·이미활성 계획을 출력하고 아무것도 쓰지 않습니다.

인자: 무엇이 테넌트 행을 만드는가

설치 콘텐츠는 아래 세 경로를 구분합니다. 가드가 있는 테넌트 migration이나 일반 App 명령도 행을 만들 수 있으며, 이 표의 콘텐츠 적용 경로와는 별개입니다.

출처실행 시점만드는 것건너뛸 수 있는가
App initializer테넌트 설치 중App이 동작하는 데 필요한 최소 행아니오
Copyable template행위자가 적용할 때편집 가능한 테넌트 소유 사본예
데모 데이터명시적 nexia-demo:seed-demo버려도 되는 샘플 레코드항상

다음 선언만으로 테넌트 업무 행이 생성되지는 않습니다.

개념테넌트 행에 대한 효과
Descriptor없음. 타입 있는 기능 메타데이터
Registry없음. 런타임 조회 계층
Catalog그 자체로는 없음 — 코드 소유 정의
Process Template descriptor편집기 문서만 바꾸고, 저장·게시가 영속화
Template 적용 원장출처를 기록하고 결코 소스가 되지 않음

Catalog를 읽어 행을 만드는 별도 명령도 있습니다. 예를 들어 nexia-access:sync-permissions는 코드의 Permission Catalog를 테넌트 Permission 행으로 동기화합니다. 이는 Catalog 선언 자체가 아니라 명령 실행의 효과입니다.

결과 또는 반환: 설치 라이프사이클

nexia-apps:install-tenant-app은 App마다 행 하나를 tenant_app_installations에 쓰고, 운영 상태와 초기화 상태를 함께 담습니다.

초기화 상태의미
pending행은 쓰였고 initializer는 아직 완료되지 않음
initializedInitializer가 성공적으로 완료됨
failedInitializer가 실패하고, 행이 오류 메시지를 담고 있음

명령의 순서는 고정돼 있습니다.

  1. 전제 폐포와 Central 게시 상태, private 테넌트 허용을 검증하고 계획을 출력합니다.
  2. 선행 App부터 폐포의 미적용 migration을 실행합니다.
  3. pending 설치 행을 씁니다.
  4. 테넌트의 Permission 카탈로그와 기준 Core Role을 동기화합니다.
  5. App마다 initializer를 각각 자기 트랜잭션에서 실행합니다.
  6. 계획을 initialized로 표시합니다.

Initializer마다 자기 트랜잭션에서 돌기 때문에 이미 커밋된 작업은 되돌려지지 않습니다. 다만 순서는 실패 지점에서 멈추고, 실패한 항목과 그 계획에서 아직 대기 중인 모든 항목이 같은 오류로 failed 표시됩니다.

InstalledAppResolver는 설치가 활성이고 초기화가 완료되고 모든 전제도 operational일 때만 App을 노출합니다.

app.installed:{app_key}가 닫힘 방향으로 실패하는 이유가 그 규칙입니다. pending이나 failed인 App은 테넌트 런타임에서 사용할 수 없습니다. PHP 경로가 등록되어 있더라도 app.installed가 요청을 거부합니다.

nexia-apps:repair-tenant-app {app}이 실패하거나 낡은 App에 대해 설치 계획을 다시 실행합니다. 손으로 행을 편집하는 것이 아니라 이것이 지원되는 복구 경로입니다.

일반 HTTP·CLI·가입 설치는 같은 배포 게이트를 통과합니다. 로컬 콘솔 개발 명령만 게시·테넌트 허용·preview 제한을 건너뛰며 선행 App, descriptor, migration, 초기화, 사용자 권한 검사는 유지합니다. 미게시 로컬 App의 복구·재활성화에도 개발 명령을 다시 사용합니다. 허용이 철회되거나 게시가 중단된 App도 기존 설치가 활성인 동안에는 계속 동작하지만 새 설치와 재활성화는 거부됩니다. 따라서 Central의 일시 장애가 평상시 App 요청을 중단시키지 않으면서 라이프사이클 쓰기가 열린 방향으로 실패하지 않습니다.

4단계는 권한 정의를 동기화합니다. User 자격을 바꾸지 않습니다. 보호된 App 연산에는 적용 가능한 Access Grant가 필요하며 설치만으로는 부여되지 않습니다.

App initializer

이 인터페이스는 호스트 전용입니다. App Package가 import할 수 없는 App\* 아래에 있습니다. 새 패키지는 대신 가드 있는 테넌트 마이그레이션으로 필수 행을 배포합니다. 필수 설치 콘텐츠를 따르세요.

코드 예시
PHP
namespace App\AppRuntime;

interface TenantAppInitializerContribution
{
    public const DEFAULT_VERSION = '1';

    public function appKey(): string;
    public function initialize(TenantAppInitializationContext $context): void;
}

interface VersionedTenantAppInitializerContribution extends TenantAppInitializerContribution
{
    public function version(): string;
}
요건이유
멱등nexia-apps:repair-tenant-app이 다시 실행함
최소 운영 기본값만 생성데이터 로딩 장치가 아님
운영자가 편집한 콘텐츠를 덮어쓰지 않음재실행이 의도적인 변경을 파괴함
데모 레코드를 만들지 않음그것은 데모 데이터의 몫
복사된 Template을 덮어쓰지 않음그것은 테넌트 소유

호스트가 관리하는 initializer는 기본값 구조가 바뀔 때 버전이 있는 인터페이스로 구분합니다. 기본 버전은 '1'입니다.

Copyable template

CopyableTemplateContributionRegistry가 코드로 정의된 출처를 발견합니다. 데이터베이스 카탈로그가 아닙니다. CopyableTemplateFacade가 그것들을 현재 ApprovalFormPresetCatalog 어댑터와 결합합니다.

하나를 적용하면 테넌트 안 template_applications 원장에 출처가 기록됩니다.

원장 필드내용
App key소유 App
Template 키와 버전불변 소스 정체성
범위tenant 또는 legal_entity
Legal Entitynull 가능
행위자적용한 사람
결과 상태성공 또는 실패
실패 이유실패 시
생성된 Resource 참조사본이 만들어낸 것

원장은 출처 기록일 뿐입니다. 결코 Template 소스 카탈로그가 되지 않고, 사본에 대한 이후 편집을 추적하지도 않습니다.

이것을 전제로 계획을 세우기 전에 알아둘 현재 제약이 둘 있습니다.

  • Approval form preset은 테넌트 범위이므로, nexia-apps:apply-template에 --legal-entity를 넘기면 그것들에 대해 실패합니다.
  • Process Template은 이 경로를 아예 거치지 않습니다. 하나를 선택하면 저장되지 않은 BPMN 편집기 문서가 바뀌고, 평범한 정의 저장과 게시가 영속화와 짝 결정 배포를 소유합니다.

App은 Nexia\Templates\Contracts\CopyableTemplateContribution으로 Template을 공개합니다. templates()가 소스를 선언하고 apply()는 행위자와 선택적 Legal Entity를 담은 TemplateApplicationContext를 받습니다. 발견과 실행, 출처 원장은 호스트가 소유합니다.

데모 데이터

데모 데이터는 Core가 App 소유 Nexia\Fixture\Contracts\FixtureContribution 구현을 조합하는 명시적 픽스처 세트입니다. Core는 FixtureContext로 호스트 식별자의 스칼라 값만 제공하고, App은 자기 행만 쓰며 다른 App 모델을 import하지 않고 안정된 Resource Reference를 교환할 수 있습니다. 데모 데이터는 계속 폐기 가능한 샘플이며 설치 전제 조건이 아닙니다.

코드 예시
Shell
task artisan -- nexia-demo:seed-demo --tenant="$nexia_tenant"
속성동작
프로덕션 실행--force를 넘기지 않으면 거부
순서프로덕션 기준선 먼저, 그다음 Core 데모 픽스처
App 설치 상태그대로 유지 — 시딩은 아무것도 설치하거나 활성화하지 않음
테넌트 프로비저닝결코 호출하지 않음
설치결코 의존하지 않음
App 누락 또는 비활성해당 App contribution만 건너뛰고 다른 operational App은 계속 실행

어떤 기능이 데모 시딩 뒤에만 동작한다면, 그 필수 행은 데모 데이터가 아니라 설치에 속합니다.

오류

증상원인해결
app.installed:{key}가 요청을 거부설치가 pending이나 failed, 또는 전제가 operational이 아님nexia-apps:doctor-package-app 후 nexia-apps:repair-tenant-app
행을 쓰기 전에 설치가 멈춤전제 누락, 키 중복, 순환전제 그래프 수정, 비대화형 설치에는 --with-prerequisites
활성화가 데이터베이스 연결에서 실패Manifest 동기화가 엄격함PostgreSQL에 닿는 컨테이너 안에서 실행
App이 설치됐는데 사용자에게 안 보임그 권한을 담은 Role이 없음관리자가 App Role을 만들고 배정
nexia-apps:apply-template에서 --legal-entity 거부Template이 테넌트 범위옵션 생략
신규 테넌트에서 기능이 깨지고 데모 테넌트에서는 괜찮음필수 행이 데모 데이터에 있음설치로 옮기기

실제 사용

선택 콘텐츠는 App의 CopyableTemplateContribution에서 확인하세요. 선언은 사용할 양식을 나열하고 apply()는 전달받은 문맥에서 편집 가능한 테넌트 사본을 만듭니다.

packages/payroll과 packages/talent는 Nexia\Templates\Contracts\CopyableTemplateContribution을 직접 구현합니다. 두 패키지의 templates() 선언과 멱등적인 apply()가 현재 App 쪽 실제 예시입니다.

관련 문서

원본 위치: docs/developers/content/ko/app-sdk/installation-content.md