본문으로 건너뛰기
문제 해결

경계 위반 해결

거부된 플랫폼·App 간 import를 예외 추가가 아니라 가장 작은 중립 SDK 계약 공개로 해결합니다.

패키지 경계 위반

이 문서는 비공개 호스트 환경에 이미 접근 권한이 있는 Nexia 유지관리자를 위한 참고 자료입니다. Core는 외부 개발자에게 배포하지 않습니다. 아래 호스트 명령은 공개 CLI·클라우드 샌드박스의 선행 조건이 아닙니다. 외부 개발자는 빠른 시작을 따라주세요.

coupling ratchet이 App Package에서 플랫폼이나 다른 App으로 향하는 참조를 거부합니다. 깨끗한 App에는 baseline 파일이 없고, 기존 예외가 남은 경우에만 해당 App의 .nexia/coupling-baseline.json에 기록된 파일·심볼 쌍을 허용합니다.

먼저 SDK 계약에서 기존 기능을 찾아 거부된 import를 공개 계약으로 바꿉니다. App 업무라면 App 안에 두고, 플랫폼 책임인데 공개 계약이 없는 경우에만 SDK 확장을 검토하세요.

증상 색인

증상절
ratchet이 새 파일·심볼 쌍을 거부App*로 향하는 PHP import
Module not found: @/…, @shell/…, @shared/ui프런트엔드 플랫폼 별칭 import
다른 App의 클래스 importApp 간 import
로컬 SDK 변경이 런타임에 반영되지 않음로컬 SDK가 선택되지 않음
Target [Nexia\…] is not instantiable.계약은 있는데 바인딩이 없음
필요한 기능에 SDK 계약이 없음아직 계약이 없음
baseline 파일이 그 패턴이 괜찮다는 증거처럼 보임baseline은 선례가 아니다

App*로 향하는 PHP import

New PHP app-to-core coupling detected.

원인. App Package가 플랫폼 구현 클래스를 import했습니다. PHP App 코드는 Nexia\*에서만 호스트용 계약을 import할 수 있습니다.

해결. 그 기능의 공개 계약을 찾으세요.

손을 뻗은 것대신 import할 것
플랫폼 권한 서비스Nexia\Laravel\Access\Contracts\ResourceAuthorization
Actor·Party 조회Nexia\Identity\Contracts\ActorDirectory, Nexia\Laravel\Identity\Contracts\PartyDirectory
Legal Entity·Operating Unit 조회Nexia\Organization\Contracts\OrganizationDirectory
모든 테넌트 순회Nexia\Tenancy\Contracts\TenantRunner
이벤트 발행Nexia\Events\Contracts\Outbox
Command Palette 명령Nexia\Palette\Contracts\PaletteCommandContribution
검색 가능한 Resource 레코드Resource 모델의 resourceListFields()에서 필드를 searchable: true로 선언하고, 통제된 Search allowlist와 authorization 경로는 Core에 둠
호스트 identity 또는 organization 참조ActorDirectory, PartyDirectory, 또는 OrganizationDirectory

플랫폼이 구현을 공급하도록 컨테이너에서 해석하세요.

코드 예시
PHP
use Nexia\Laravel\Access\Contracts\ResourceAuthorization;

// $query is the generated Note model query inside the authenticated tenant request.
$query = app(ResourceAuthorization::class)->scopeVisible($query, 'workshop.note');

확인. ratchet이 통과합니다.

코드 예시
Shell
php scripts/coupling-ratchet.php check quality

doctor는 결합을 검사하지 않습니다. 발견과 등록, 권한, 프런트엔드 엔트리, 번역을 봅니다.

예방. import를 쓰기 전에 SDK 계약의 네임스페이스 맵을 확인하세요.

프런트엔드 플랫폼 별칭 import

Module not found: Can't resolve '@shell-primitives/resources/list'

원인. App 프런트엔드 코드가 플랫폼 소스 폴더로 해석되는 import를 했습니다. 금지 접두는 @/, @core/, @hooks/, @lib/, @shared/, @shell/, @shell-primitives/입니다.

해결. 같은 심볼을 SDK에서 import하세요.

코드 예시
TypeScript
import {
    ResourceTable,
    ResourcePrimaryCell,
    NxButton,
    api,
    can,
    useResourceListParams,
} from "@nexia/sdk/host";

SDK는 레이아웃·폼·테이블·데이터 훅·inspector와 Approval composer registry를 공개합니다. 각 import 위치와 사용법은 React 컴포넌트와 훅에서 확인하세요.

확인. 플랫폼 별칭을 거부하는 것은 ratchet입니다. 의존성 검증기는 로컬·별칭 지정자를 건너뛰어 아예 보지 못합니다.

코드 예시
Shell
php scripts/coupling-ratchet.php check quality

예방. 공개 import는 App 화면 만들기를 따릅니다. 과거 baseline은 기록된 파일·심볼 쌍에만 적용되며 생성기가 Core 별칭을 써도 된다는 뜻은 아닙니다.

App 간 import

An App Package imports a class or frontend module from another App Package.

원인. App이 다른 App의 클래스를 import했거나 패키지 의존성으로 선언했습니다. App 간 import와 패키지 의존성은 예외 없이 금지입니다.

해결. 실제로 필요한 것에 따라 고르세요.

필요수단
다른 App의 레코드를 지금 읽기Nexia\ResourceReference — Resource Key와 public_id를 저장하고 플랫폼이 해석
다른 App의 변경에 반응Nexia\Events — 플랫폼이 Tenant 안에서 소비자를 호출하고, delegated listener만 사용자를 복원해 권한을 재검사
기능 공유플랫폼이 바인딩하는 새 App 중립 SDK 계약

ResourceRef는 모델을 import하지 않고 레코드를 지칭하므로, 소유 App이 노출 범위와 대상을 계속 통제하고 해석 시점에 행위자 권한이 적용됩니다.

확인. ratchet이 통과하고 어떤 packages/* 요구사항도 다른 App을 지칭하지 않습니다.

예방. 별도의 원본 데이터를 만들지 마세요. 최신 값은 허가된 Resource Reference로 읽고, 이력 스냅샷이나 이벤트 projection은 소유 계약이 허용할 때만 보관합니다.

로컬 SDK가 선택되지 않음

로컬 SDK 변경이 호스트를 다시 읽어도 반영되지 않습니다.

원인. checkout이 있어도 저장된 로컬 소스 목록에 들어 있지 않을 수 있습니다. 그 경우 호스트는 커밋된 lock이 선언한 release 패키지를 사용합니다.

수정. Core 루트에서 지원되는 helper로 SDK 소스를 추가하세요.

코드 예시
Shell
task apps:add PACKAGES=app-sdk
task apps:status -- --offline

add task는 Composer overlay, frontend 로컬 lock, SDK package metadata, frontend dependency 검증을 준비합니다. App manifest와 import에는 게시된 amuzcorp/nexia-app-sdk-laravel, @nexia/sdk identity를 사용하세요.

확인. task apps:status -- --offline에 app-sdk가 보이고 git -C packages/app-sdk rev-parse --show-toplevel가 독립 SDK 저장소를 반환해야 합니다.

예방. 저장된 선택은 task apps:add 또는 task apps:remove로만 바꿉니다. 런타임 도구는 Composer\InstalledVersions::getInstallPath()와 생성된 App map으로 설치 패키지 경로를 해석합니다.

계약은 있는데 바인딩이 없음

Target [Nexia\Laravel\Access\Contracts\ResourceAuthorization] is not instantiable.

원인. SDK가 인터페이스를 공개하는데 플랫폼이 이 컨텍스트에서 그것을 바인딩하지 않았습니다. SDK는 설계상 구현을 담지 않습니다.

해결. 이것은 App 문제가 아니라 호스트 문제입니다. 플랫폼 바인딩이 없거나 현재 컨텍스트에 등록되지 않았습니다. 플랫폼 클래스를 인스턴스화해 우회하지 마세요.

확인. 평범한 요청에서 계약이 컨테이너로 해석됩니다.

예방. 계약 순서를 따르세요. SDK 표면 공개 → 커밋을 소비자에게 반영 → 플랫폼에서 바인딩 → 소비. 바인딩 단계를 건너뛰면 정확히 이 오류가 납니다.

아직 계약이 없음

The App needs host behavior, but no app-neutral Nexia\* contract exposes it.

원인. 어떤 기능은 오늘 정말로 호스트 전용입니다.

기능호스트 전용 클래스
Site ConfigurationApp\Settings\SiteConfigRegistry
설치 initializerApp\AppRuntime\TenantAppInitializerContribution

전역 레코드 검색은 App별 Palette contribution이 아닙니다. Resource 모델에 resourceListFields()에 검색 필드를 공개하면 Core의 통제된 Search 런타임이 대상 여부를 결정하고 후보 식별자를 받은 뒤, 각 레코드를 테넌트 데이터베이스에서 다시 읽어 가시성과 Policy를 검증합니다. Palette 전용 쿼리 계약을 새로 만들지 마세요.

해결. App 안에서 필요를 모델링하거나 계약을 추가하세요.

상황접근
App 설정settings 목적지 뒤의 App Resource로 모델링
설치 시 필수 행가드 있는 테넌트 마이그레이션으로 배포
정말로 플랫폼 전역가장 작은 App 중립 SDK 계약을 공개하고 플랫폼에서 바인딩

계약을 추가할 때는 최소로 유지하세요. 플랫폼 Eloquent 모델을 노출하기보다 메서드 하나짜리 인터페이스를 선호하세요. 모델은 스키마를 유출시켜 모든 내부 변경을 파괴적 변경으로 만듭니다. 플랫폼 구현을 SDK로 절대 복사하지 마세요.

확인. App이 Nexia\*만 import하고 ratchet이 통과합니다.

예방. 기능을 전제로 설계하기 전에 가용성을 확인하세요. 확장 모델이 App Package가 구현할 수 있는 것과 없는 것을 나열합니다. 통제된 Search Runtime은 별도의 레코드 검색 경로를 설명합니다.

baseline은 선례가 아니다

The coupling ratchet rejects a new file-and-symbol pair beside an existing exception.

원인. .nexia/coupling-baseline.json을 승인된 패턴 목록으로 읽는 것입니다. 그것은 아직 제거할 수 없는 예외의 명시적 기록일 뿐 선례가 아닙니다.

해결. 기존 공개 계약을 먼저 찾습니다. 없다면 App 내부 동작인지 지속적인 플랫폼 책임인지 판단하세요. Baseline에 있다는 이유만으로 SDK API를 만들지 않습니다. SDK 계약에서 경계를 확인합니다.

확인. 새 코드가 Nexia\*와 @nexia/sdk만 import하고 baseline이 커지지 않았습니다.

예방. 커밋 전에 셋을 다 돌리세요. import 경계를 보는 것은 첫 번째뿐이고, 나머지 둘은 호환성 선언과 의존성 그래프를 봅니다.

코드 예시
Shell
php scripts/coupling-ratchet.php check quality
task artisan -- nexia-apps:validate-app-compat --app=quality --require-declarations
task artisan -- nexia-apps:validate-app-frontend-dependencies --app=quality --require-manifests

관련 문서

원본 위치: docs/developers/content/ko/troubleshooting/package-boundary-violations.md