테마
bp-manifest.yaml 레퍼런스
BP 산출물 디렉터리 최상단에 놓이는 설치 서술자다. 포탈이 코드를 적재하기 전에 읽는 유일한 파일이며, 그래서 여기 담기는 것은 "적재 여부를 판단하는 데 필요한 것"뿐이다.
무엇이 여기 오고 무엇이 코드에 남나
| 어디에 | 왜 | |
|---|---|---|
| 정체성(id/name/version/의존성), 산출물 위치, 호환성 | bp-manifest.yaml | 코드를 적재하기 전에 읽어야 판단할 수 있다 |
| 화면(apps) · 메뉴 배치 · 카드 · 권한 | register() 반환값 | 코드와 함께 변한다. YAML에 두면 어긋나고, 어긋나도 아무도 모른다 |
App을 하나 추가하면 그 App을 처리하는 컨트롤러도 함께 생긴다. 두 개가 다른 파일에 있으면 반드시 언젠가 갈라진다 — 그래서 능력 표면은 코드가 돌려준다.
전체 예시
yaml
apiVersion: 1 # 서술자 포맷 버전. 포탈이 모르는 값이면 그 BP를 건너뛴다
id: hello-bp # 포탈 전역 고유. 레코드 upsert 기준이므로 한 번 정하면 바꾸지 않는다
name: Hello BP
version: 1.0.0 # semver
mandatory: false # true면 관리자가 비활성화할 수 없다. 3rd-party BP는 쓰지 않는다
dependsOn: # 선택 — 다른 BP를 요구할 때만
- businessPackageId: hr
versionRange: "^2.0.0"
required: true # true면 이 BP가 비활성일 때 내 활성화가 차단된다
runtime:
hostContract: "^1.0.0" # 필수. 포탈의 HOST_CONTRACT_VERSION과 대조된다
backend:
entry: backend/index.mjs # register()를 export하는 ESM 번들(설치 디렉터리 기준 상대경로)
database:
providers: [sqlite, postgresql] # 지원 방언. 실행 중인 방언이 없으면 적재를 건너뛴다
schemaDir: backend/prisma # <schemaDir>/<provider>/schema.prisma 를 찾는다
frontend: # 선택 — 셸 안에 화면을 그리는 BP만
mode: csr-widget
bundle: frontend/bundle.js필드
최상위
| 필드 | 필수 | 내용 |
|---|---|---|
apiVersion | ✅ | 현재 1. 포탈이 모르는 값이면 그 BP를 건너뛴다 |
id | ✅ | 포탈 전역 고유 식별자. 레코드 upsert 기준이라 바꾸면 기존 설치와 이어지지 않는다 |
name | ✅ | 관리자 화면에 보이는 이름 |
version | ✅ | semver. 올리면 마이그레이션과 onInstall 훅이 다시 돈다 |
mandatory | true면 비활성화 자체가 차단된다. 포탈 내장 BP용 | |
dependsOn | 아래 참고 |
dependsOn[]
| 필드 | 내용 |
|---|---|
businessPackageId | 요구하는 BP의 id |
versionRange | semver 범위 |
required | true면 그 BP 없이는 활성화되지 않고, 그 BP를 비활성화하려 할 때 차단된다 |
runtime
| 필드 | 필수 | 내용 |
|---|---|---|
hostContract | ✅ | 이 BP가 요구하는 호스트 계약 semver 범위. 자세히는 host-contract.md §4 |
backend
| 필드 | 필수 | 내용 |
|---|---|---|
entry | ✅ | register()를 export하는 ESM 번들 경로 |
database.providers | 이 BP가 지원하는 DB 방언. 생략하면 sqlite만 지원하는 것으로 본다 | |
database.schemaDir | 방언별 스키마·마이그레이션 루트. 생략하면 포탈이 이 BP의 마이그레이션을 적용하지 않는다(내가 알아서 하겠다는 선언) |
schemaDir을 쓸 때 배치 규칙이 하나 있다 — schema.prisma와 migrations/가 같은 폴더에 있어야 한다.
backend/prisma/
sqlite/{schema.prisma, migrations/}
postgresql/{schema.prisma, migrations/}Prisma CLI에 마이그레이션 경로를 따로 지정하는 옵션이 없고 스키마 파일과 같은 디렉터리에서 찾기 때문이다. 이 배치 덕분에 포탈은 실행 중인 방언의 마이그레이션만 정확히 적용할 수 있다.
frontend
| 필드 | 필수 | 내용 |
|---|---|---|
mode | ✅ | csr-widget | iframe | external-proxy | ssr |
bundle | ✅ | csr-widget 번들 경로. 포탈이 런타임에 서빙한다 |
타입으로 확인하기
스키마는 SDK가 타입으로도 들고 있다. 매니페스트를 생성하는 스크립트를 쓴다면 이 타입에 맞추면 오탈자가 컴파일 단계에서 걸린다.
ts
import type { BpInstallManifest } from "@starj-portal/bp-backend-sdk";
import { BP_MANIFEST_API_VERSION } from "@starj-portal/bp-backend-sdk";
const manifest: BpInstallManifest = {
apiVersion: BP_MANIFEST_API_VERSION,
id: "hello-bp",
name: "Hello BP",
version: "1.0.0",
runtime: { hostContract: "^1.0.0" },
backend: { entry: "backend/index.mjs" },
};능력 표면 — register()가 돌려주는 쪽
매니페스트에 없는 것들이다. 자세히는 backend-guide.md.
| 필드 | 내용 |
|---|---|
apps[] | 화면 카탈로그 — id / name / uri(포탈 전역 고유) / moduleCode |
menu[] | 메뉴 배치 — id / parentId / appId 또는 name / sortNo. apps와 분리된 목록이다 |
cards[] | 홈 인사이트 카드 |
permissions[] | 권한 스코프 키(설명용) |
defaultAuthorities[] | 설치 시 자동 생성되는 권한 템플릿(App × 읽기/쓰기) |
frontendDeliveryMode | 매니페스트의 frontend.mode와 같은 값을 코드에서도 선언한다 |