앱 매니페스트
sayren.app.json의 모든 필드, 권한·외부 호스트·이벤트·설정 규칙, 검증 오류
sayren.app.json은 앱이 무엇을 요청하는지 선언하는 파일입니다. 설치 동의 화면·상점 플랫폼의 앱 정보·실행 제한이 모두 이 파일에서
나옵니다. 아는 키만 받습니다. 모르는 키가 있으면 app verify·app deploy가 실패합니다.
{
"handle": "order-slack",
"name": "주문 알림",
"description": "결제된 주문을 Slack 채널로 보냅니다",
"icon": "icon.png",
"readme": "README.md",
"supportEmail": "help@example.com",
"scopes": ["order:r", "product:r"],
"network": { "hosts": ["hooks.slack.com", "*.example.com"] },
"events": ["ORDER.PAID", "ORDER.CANCELED"],
"ui": { "adminPage": { "entry": "ui/index.html" } },
"settings": {
"webhookUrl": { "type": "string", "label": "Slack 웹훅 주소", "secret": true, "required": true },
"minAmount": { "type": "number", "label": "알림 최소 금액", "default": 0 },
"channel": {
"type": "select",
"label": "채널",
"options": [{ "value": "ops", "label": "운영" }, { "value": "cs", "label": "고객센터" }],
"default": "ops"
}
},
"secrets": ["SLACK_SIGNING_SECRET"]
}필드
| 필드 | 필수 | 뜻 |
|---|---|---|
handle | 예 | 앱 식별자. 소문자·숫자·하이픈 3~40자, 전 세계에서 하나. 앱 화면 주소의 라벨입니다. 한 번 정하면 바꿀 수 없습니다 |
name | 예 | 앱 이름(60자). 동의 화면·상점 플랫폼에 보입니다 |
description | 소개(500자). 상점 앱 목록 카드에 한 줄로 보입니다 | |
icon | 앱 폴더의 아이콘 파일(.png·.svg). 아래 목록 정보 | |
readme | 앱 상세에 보일 README(.md). 적지 않으면 앱 폴더의 README.md를 씁니다 | |
iconUrl | 아이콘 이미지 주소(https://). icon이 있으면 icon이 먼저입니다 | |
supportEmail | 셀러가 문의할 주소. 상점 플랫폼 앱 상세에 보입니다 | |
scopes | 관리 API 권한(32개까지). 아래 권한 | |
network.hosts | 앱 코드가 호출할 외부 호스트(20개까지). 아래 외부 호스트 | |
events | 받을 이벤트(50개까지). 이벤트 | |
ui.adminPage.entry | 상점 플랫폼 앱 화면의 진입 HTML. ui/ 아래 .html 파일 | |
settings | 셀러 설정 필드(30개까지). 아래 설정 필드 | |
secrets | 개발자 비밀 값 이름(20개까지). 대문자·숫자·밑줄. 값은 sayren app secret put으로 넣습니다 |
handle로 쓸 수 없는 이름이 있습니다: www·api·app·apps·admin·accounts·store·mcp·docs·sayren·preview·runner·
static·cdn, 그리고 -preview로 끝나는 이름.
목록 정보
상점 플랫폼 앱 › 앱 목록의 카드와 앱 상세에 보이는 값입니다. 앱 폴더에 두고 sayren app deploy로 코드와 함께 올립니다. 버전마다 남고,
상점에는 현재 버전(release한 버전)의 값이 보입니다. developer.sayren.app › {앱} › 목록 정보에서 미리 봅니다.
| 항목 | 규칙 |
|---|---|
아이콘(icon) | PNG 또는 SVG, 정사각형. PNG는 512×512 이상. 256KB 이하 |
설명(description) | 카드에는 한 줄만 보입니다. 앞 문장에 하는 일을 씁니다 |
README(readme, 기본 README.md) | 마크다운 64KB 이하. 제목·문단·목록·코드 블록·굵게·https:// 링크를 보여 줍니다. 이미지와 HTML은 보여 주지 않습니다 |
규칙을 벗어나면 app verify·app deploy가 올리기 전에 멈추고, 서버 빌드도 VERIFY 단계에서 MANIFEST_INVALID로 실패합니다.
sayren app init은 README.md 틀을 만듭니다.
권한
scopes에 적은 권한을 설치할 때 셀러가 한 번에 전부 동의합니다. 일부만 허락하는 선택은 없습니다. 앱은 동의한 권한만 쓸 수 있고,
설치한 사람의 역할이 가진 권한을 넘는 앱은 설치할 수 없습니다(예: 관리자는 settlement:r 앱을 설치하지 못합니다).
| 권한 | 동의 화면 문장 |
|---|---|
product:r · product:rw | 상품 정보를 읽습니다 · 상품을 만들고 수정합니다 |
category:r · category:rw | 카테고리를 읽습니다 · 카테고리를 만들고 수정합니다 |
order:r · order:rw | 주문을 읽습니다 · 주문 상태를 바꿉니다(발송·배송완료·취소 등) |
claim:r · claim:rw | 취소·반품·교환 요청을 읽습니다 · 취소·반품·교환을 처리합니다 |
inquiry:r · inquiry:rw | 상품 문의를 읽습니다 · 상품 문의에 답합니다 |
review:r · review:rw | 리뷰를 읽습니다 · 리뷰를 관리합니다 |
customer:r · customer:rw | 고객 정보(이름·연락처·주소)를 읽습니다 · 고객 정보를 수정합니다 |
promotion:r · promotion:rw | 쿠폰·적립금 설정을 읽습니다 · 쿠폰을 발급하고 적립금을 지급합니다 |
flow:r · flow:rw | 주문 흐름 설정을 읽습니다 · 주문 흐름을 만들고 수정합니다 |
store:r | 상점 정보를 읽습니다 |
settlement:r | 매출 리포트를 읽습니다 |
analytics:r | 방문·구매 분석 데이터를 읽습니다 |
앱이 요청할 수 없는 권한이 있습니다. 구성원(member:*), 상점 설정 수정(store:rw), 웹훅(webhook:*), 스토어프론트(storefront:*),
감사 로그(audit:r)입니다. 이런 권한이 필요한 연동은 액세스 토큰으로 합니다. 또 권한이 있어도 결제 설정·구성원·
액세스 토큰 발급처럼 상점 플랫폼에서만 하는 작업은 앱이 할 수 없습니다.
외부 호스트
앱 코드의 fetch는 network.hosts에 적은 호스트와 sayren API(api.sayren.app)에만 나갑니다. 그 밖의 요청은 403으로 막힙니다.
동의 화면에 「이 앱이 데이터를 보내는 곳」으로 그대로 보입니다.
- 소문자 호스트명만.
https://·경로·포트는 쓰지 않습니다. 실제 요청은https://·443 포트만 나갑니다 - 와일드카드는 한 단계만:
*.example.com은a.example.com에 맞고a.b.example.com·example.com에는 맞지 않습니다 - IP 주소,
localhost, sayren 플랫폼 호스트(sayren.app·sayren.co·avarlabs.com아래)는 쓸 수 없습니다 - 리다이렉트를 따라가지 않습니다. 허용 호스트가 다른 호스트로 보내면 그 응답(
3xx)을 그대로 받습니다
설정 필드
settings의 각 키가 상점 플랫폼 앱 상세의 설정 폼 한 줄이 됩니다. 키는 영문자로 시작하는 영문·숫자·밑줄 40자입니다.
| 속성 | 뜻 |
|---|---|
type | string · number · boolean · select |
label | 폼 라벨(60자) |
description | 라벨 아래 설명(200자) |
required | 필수. 필수 필드가 비어 있으면 이벤트 함수를 부르지 않습니다 |
secret | 비밀 값. 암호화해 저장하고 화면·API에 가려서 보입니다. string만 됩니다 |
options | select의 선택지 [{ value, label }](50개까지). select에는 필수입니다 |
default | 기본값. 형식이 type과 같아야 하고 select는 options의 값이어야 합니다 |
값은 앱 코드에서 ctx.settings.{키}로 읽습니다. 비어 있는 필드는 없거나 null입니다.
검증
npx sayren app verify가 올리지 않고 검사만 합니다. app deploy도 같은 검사를 거치고 통과해야 올립니다.
| 오류 | 뜻 |
|---|---|
EVENT_SCOPE_MISSING | events의 이벤트에 필요한 권한이 scopes에 없습니다. 이벤트의 표를 참고하십시오 |
SELECT_OPTIONS_REQUIRED | select 필드에 options가 없습니다 |
SECRET_FIELD_TYPE | 비밀 필드가 string이 아닙니다 |
DEFAULT_TYPE_MISMATCH | default가 필드 형식과 맞지 않습니다 |
DUPLICATE | 같은 값이 두 번 있습니다 |
HANDLER_MISSING | events에 적은 이벤트의 함수가 코드에 없습니다(빌드에서 확인) |
형식 오류(모르는 키, 글자 수, 호스트 형식)는 해당 경로와 함께 보고합니다.