Command Palette 검색
검색 가능한 목적지와 명령은 App이 기여하고, 권한이 검증된 레코드 결과는 통제된 Resource Search가 공급하는 방식.
Cmd+K에서 App 화면을 찾도록 만듭니다. 검색 가능한 App Menu 목적지 추가가 이미 이 기능을 제공하므로 별도 등록은 필요 없습니다.
목적지 공개와 검색
기존 navigation 항목의 searchable을 true로 두고 번역 labelKey와 읽기 권한을 지정합니다. true가 기본값입니다. 새 contribution 클래스는 discovery를 갱신한 뒤, 권한 있는 사용자로 팔레트를 열어 해당 locale의 화면 이름을 검색합니다.
결과 확인
검색 결과를 선택하면 등록한 App 화면이 열립니다. 권한 없는 사용자는 항목을 발견할 수 없고, API 직접 접근도 거절되어야 합니다. searchable: false는 검색만 제외하며 권한을 바꾸지 않습니다.
레코드 검색은 Resource 만들기의 일반 메타데이터와 모델 검색 필드를 사용합니다. 후보 조회와 재인가를 Core가 수행합니다. 실행 명령이 필요할 때는 SDK PaletteCommandContribution, 에이전트 화면 이동은 아래 locate helper를 사용하세요.
제공할 수 있는 기능
| 기능 | App Package가 쓸 수 있는가 | 수단 |
|---|---|---|
| 목적지 검색 | 예 | 내비게이션 항목의 searchable |
레코드 검색 (find Order #123) | 공개된 Resource를 통해 가능 | 대상 Resource 모델을 조회하는 Core의 통제된 Search |
| 실행 명령 | 예 | SDK PaletteCommandContribution |
| 에이전트 locate 동작 | 예 | ShellNavigationLocateAction |
실행 명령 계약은
Nexia\Palette에서 import하세요.App\Palette\*는 Core 구현 namespace이며 App Package 경계가 아닙니다. App이 구현하는 Palette 레코드 검색 contribution은 없습니다.
레코드 결과는 확장 Search 화면과 같은 통제 경로인 CoreSearchService에서
옵니다. Core가 대상 Resource 모델을 고르고, 설정된 후보 gateway에는
식별자만 요청합니다. 그런 다음 테넌트 데이터베이스에서 레코드를 다시 읽어
현재 가시성과 Policy를 적용합니다. App은 일반 Resource 계약과 모델의 검색
필드를 공개하고, 대상 선정·App 설치 상태·최종 authorization은 Core가
소유합니다.
NexiaEntityModel은 이미 UsesFilterableScoutSearch를 사용합니다. 모델의
resourceListFields()에서 searchable: true로 표시한 필드가 Search
projection의 기준이며, 외부 index 반출은
Core의 Resource allowlist 뒤에서 fail-closed로 동작합니다. Palette 전용
쿼리를 하나 더 만들거나 외부 engine의 표시 데이터를 그대로 반환하지 마세요.
명령 payload는 PaletteCommand::make()로 만드세요. 개별 명령에 App
Family, App key, 계층을 선언하지 마세요. Core가 등록된 contribution
location에서 소유자를 계산합니다.
결과 묶음
Core는 모든 내비게이션, 명령, 엔티티 결과에 명시적 placement를
반환합니다. client는 id, route, context, 현재 결과 집합에서 소유자를
추론하지 않고 이 필드를 직접 사용합니다.
| 결과 출처 | 그려지는 형태 |
|---|---|
| App 소유 | App Family → App → 목적지, 명령 또는 레코드 |
| 플랫폼 | 지역화된 Platform 분류 |
App은 composer.json에서 app_family 소속과 Family 내부
launcher_order를 기여합니다. Core는 App Launcher, App Catalog와
공유하는 AppFamilyCatalog를 통해 Family label과 Family 순서를
기여합니다. App overview 목적지는 overview_navigation_id로 식별되므로
검색 결과에 App catalog 일부만 있어도 항상 먼저 옵니다.
에이전트 locate 동작
locate 동작은 에이전트가 목록을 열면서 검색·필터·정렬을 적용하게 합니다. 기존 NavigationContribution 클래스에 Nexia\Navigation\Concerns\ContributesNavigationDestinationActions trait을 사용하고 Nexia\Navigation\ShellNavigationLocateAction을 import하세요. 아래 메서드는 그 클래스 안에 넣는 발췌입니다. Trait이 이를 agentNavigationActions()로 공개합니다.
protected static function agentNavigationActionDefinitions(): array
{
return [
ShellNavigationLocateAction::make(
action: 'assets.asset.locate',
url: '/apps/assets/assets',
permission: 'assets.asset.read',
),
];
}헬퍼는 아래 기본값을 채웁니다. 올바른 경로와 권한은 App에서 지정해야 합니다.
| 필드 | 고정 값 |
|---|---|
intent | locate |
effect | read_only |
requires_user_submit | false |
input_schema | q(자유 텍스트), filters(선언된 키만), sort(내림차순은 - 접두) |
동작은 agent-navigation i18n prefix로 만든 label_key와 description_key를 담습니다. 문구가 아니라 카탈로그 키입니다.
구조상 읽기 전용입니다. locate 동작은 아무것도 변경할 수 없고 권한이 여전히 게이팅합니다. filters는 선언된 필터 키만 받으므로, 정확한 키와 옵션 값은 등록된 locate 동작 스키마를 읽으세요.
경계 규칙
searchable은 색인이지 권한이 아닙니다. palette 결과도 목적지의 권한 게이트를 따르고, 권한 없는 행위자는 항목을 아예 보지 못합니다. searchable: false는 잡음 조절이고 보안 통제가 아닙니다.
권한상 보이는 항목만 색인됩니다. palette는 필터된 스트림을 색인하므로 행위자가 쓸 수 없는 목적지의 존재조차 드러낼 수 없습니다.
목적지 라벨은 로케일 카탈로그에서 옵니다. 하드코딩된 라벨은 모든 로케일에서 운영자가 검색하는 대상이 됩니다. 정확한 카탈로그 키를 labelKey로 넘기세요.
Workbench 계층은 평평하게 유지됩니다. 백엔드가 모든 자식을 독립적으로 권한 필터링하고 palette가 모든 목적지를 색인할 수 있도록 그렇습니다. 필요하지 않은 깊이를 모델링하지 마세요.
Locate 동작 예시는 packages/assets/src/Contribution/Resources/AssetModule.php를 따릅니다. 실행 명령의 정확한 필드는 packages/app-sdk/packages/laravel/src/Palette/PaletteCommand.php에 있습니다.