@sayren/store-sdk 0.30.10 → 0.30.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -2806,221 +2806,544 @@ function appManifestWidens(previous, next) {
2806
2806
  return APP_CAPABILITIES.filter((c) => c.widens(previous, next)).map((c) => c.key);
2807
2807
  }
2808
2808
  //#endregion
2809
- //#region src/schemas/apps.ts
2810
- /**
2811
- * 설치 앱 관리 API 계약 (이슈 #22) — `/v1/apps/installations/**`(상점이 설치한 앱), `/v1/app/installation`(설치 토큰 자기 조회).
2812
- * 개발자 API(`/platform/v1/developer/**`)는 플랫폼 플레인이라 여기 두지 않는다.
2813
- */
2814
- /** 배포 범위 — `PRIVATE_OWN` 개발자 조직 구성원이 OWNER·ADMIN인 상점과 개발 상점(A1) · `PRIVATE_LINK` 설치 링크(A2) · `LISTED` 공개 목록(A3) */
2815
- const appDistributionSchema = z.enum([
2816
- "PRIVATE_OWN",
2817
- "PRIVATE_LINK",
2818
- "LISTED"
2819
- ]);
2820
- const appRuntimeSchema = z.enum(["CODE", "EXTERNAL"]);
2821
- /** 앱 상태 — `SUSPENDED`는 운영자 정지(모든 설치 토큰·실행 거부, 설치 행은 그대로) */
2822
- const appStatusSchema = z.enum([
2823
- "ACTIVE",
2824
- "SUSPENDED",
2825
- "DELETED"
2826
- ]);
2827
- const appInstallationStatusSchema = z.enum([
2828
- "ACTIVE",
2829
- "UNINSTALLED",
2830
- "SUSPENDED"
2831
- ]);
2832
- /** 설치 앱의 앱 정보 — 상점이 보는 범위만(개발자 비밀 값·소스·빌드는 없다) */
2833
- const appInstallationAppSchema = z.object({
2834
- appId: z.string(),
2835
- handle: z.string().describe("앱 handle. 앱 화면 주소의 라벨"),
2836
- name: z.string(),
2837
- iconUrl: z.string().nullable(),
2838
- description: z.string().nullable(),
2839
- developerName: z.string().describe("개발자 조직 이름"),
2840
- supportEmail: z.string().nullable(),
2841
- distribution: appDistributionSchema,
2842
- runtime: appRuntimeSchema,
2843
- status: appStatusSchema
2809
+ //#region src/schemas/misc.ts
2810
+ const inquirySchema = z.object({
2811
+ inquiryId: z.string(),
2812
+ productId: z.string(),
2813
+ productName: z.string(),
2814
+ orderItemId: z.string().nullable(),
2815
+ category: z.enum([
2816
+ "PRODUCT",
2817
+ "DELIVERY",
2818
+ "RETURN",
2819
+ "EXCHANGE",
2820
+ "ETC"
2821
+ ]),
2822
+ content: z.string(),
2823
+ secret: z.boolean(),
2824
+ writerMaskedName: z.string(),
2825
+ answered: z.boolean(),
2826
+ answer: z.object({
2827
+ content: z.string(),
2828
+ answeredAt: z.string(),
2829
+ modifiedCount: z.number().int().max(1)
2830
+ }).nullable(),
2831
+ createdAt: z.string()
2844
2832
  });
2845
- const settingsValueSchema = z.union([
2846
- z.string(),
2847
- z.number(),
2848
- z.boolean(),
2849
- z.null()
2833
+ const customerInquiryCategorySchema = z.enum([
2834
+ "DELIVERY",
2835
+ "RETURN",
2836
+ "EXCHANGE",
2837
+ "PAYMENT",
2838
+ "ETC"
2850
2839
  ]);
2851
- /** 설치 설정 — 비밀 필드 값은 가려서 준다(앞 4자 + `…`). 비어 있는 필드는 null */
2852
- const appInstallationSettingsSchema = z.object({
2853
- fields: z.record(z.string(), appSettingFieldSchema).describe("실행 버전 매니페스트의 설정 필드"),
2854
- values: z.record(z.string(), settingsValueSchema),
2855
- /** 필수 설정이 모두 채워졌는가 — 아니면 이벤트 함수를 부르지 않는다 */
2856
- configured: z.boolean(),
2857
- updatedAt: z.string().nullable()
2858
- });
2859
- /** 설정 저장 — 비밀 필드를 생략하면 현재 값을 유지한다. null은 비운다 */
2860
- const appInstallationSettingsUpdateSchema = z.object({ values: z.record(z.string(), settingsValueSchema) });
2861
- const appInstallationSchema = z.object({
2862
- installationId: z.string(),
2863
- storeId: z.string(),
2864
- app: appInstallationAppSchema,
2865
- status: appInstallationStatusSchema,
2866
- versionNumber: z.number().int().describe("실행 중인 앱 버전"),
2867
- pendingVersionNumber: z.number().int().nullable().describe("재동의가 필요한 새 버전. 없으면 null"),
2868
- grantedScopes: z.array(z.string()).describe("동의한 스코프"),
2869
- grantedNetworkHosts: z.array(z.string()).describe("동의한 외부 호출 호스트"),
2870
- events: z.array(appEventTypeSchema).describe("이 설치가 받는 이벤트"),
2871
- adminPage: z.boolean().describe("상점 플랫폼 앱 화면이 있는가"),
2872
- /** 설치 결과의 캐시가 아니라 실행 버전 매니페스트의 요약 */
2873
- settings: appInstallationSettingsSchema,
2874
- installedBy: z.object({
2875
- userId: z.string(),
2876
- name: z.string().nullable()
2840
+ /** 셀러 뷰 1:1 문의 — 작성자 마스킹명 + 답변 수정횟수 포함 */
2841
+ const sellerCustomerInquirySchema = z.object({
2842
+ inquiryId: z.string(),
2843
+ memberMaskedName: z.string(),
2844
+ category: customerInquiryCategorySchema,
2845
+ title: z.string(),
2846
+ content: z.string(),
2847
+ orderItemId: z.string().nullable(),
2848
+ answered: z.boolean(),
2849
+ answer: z.object({
2850
+ content: z.string(),
2851
+ answeredAt: z.string(),
2852
+ modifiedCount: z.number().int().max(1)
2877
2853
  }).nullable(),
2878
- installedAt: z.string(),
2879
- uninstalledAt: z.string().nullable(),
2880
- updatedAt: z.string()
2854
+ createdAt: z.string()
2881
2855
  });
2882
- /**
2883
- * `POST /v1/apps/installations`(상점 플랫폼 전용) — 둘 중 하나다.
2884
- * - `{ result }`: accounts 설치 동의 결과(1회용 JWT). 개발자 포털 [내 상점에 설치]가 이 길로 온다
2885
- * - `{ appId, settings }`: 상점 플랫폼 앱 목록 › 설치 화면에서 동의하고 설정까지 채워 바로 설치한다
2886
- */
2887
- const appInstallRequestSchema = z.union([z.object({ result: z.string().min(1).describe("accounts가 발급한 설치 결과 JWT(`typ: sayren-install+jwt`)") }), z.object({
2888
- appId: z.string().min(1),
2889
- settings: z.record(z.string(), settingsValueSchema).default({}).describe("설치와 함께 저장할 설정. 비밀 필드도 여기서 넣는다")
2890
- })]);
2891
- /** 앱 목록 정보 — 현재 버전이 올린 아이콘·README(없으면 매니페스트 `iconUrl`) */
2892
- const appListingSchema = z.object({
2893
- description: z.string().nullable(),
2894
- iconUrl: z.string().nullable().describe("아이콘 주소. 앱 폴더에서 올린 아이콘은 data URI, 매니페스트 `iconUrl`은 https 주소"),
2895
- readme: z.string().nullable().describe("README 마크다운 원문")
2856
+ const answeredQuery = z.enum(["true", "false"]).optional().describe("답변 여부 필터. `true`면 답변된 문의만, `false`면 미답변만, 생략하면 전부");
2857
+ /** `GET /v1/inquiries` 쿼리(상품 문의) — OpenAPI 문서용 형태(값은 쿼리 문자열). 최신순이다 */
2858
+ const inquiryListQuerySchema = z.object({
2859
+ answered: answeredQuery,
2860
+ productId: z.string().optional().describe("상품 id 필터"),
2861
+ from: z.string().optional().describe("작성 시각 조회 시작 (ISO 8601, 포함)"),
2862
+ ...pageQueryShape()
2896
2863
  });
2897
- /** `GET /v1/apps/catalog` — 이 상점에 설치할 수 있는 앱(A1: 내가 속한 개발자 조직의 앱) */
2898
- const storeAppSchema = z.object({
2899
- appId: z.string(),
2900
- handle: z.string(),
2901
- name: z.string(),
2902
- description: z.string().nullable(),
2903
- iconUrl: z.string().nullable(),
2904
- developerName: z.string(),
2905
- versionNumber: z.number().int().describe("현재 버전"),
2906
- installationId: z.string().nullable().describe("이 상점에 설치돼 있으면 설치 id")
2864
+ /** `GET /v1/customer-inquiries` 쿼리(1:1 문의) — OpenAPI 문서용 형태(값은 쿼리 문자열). 최신순이다 */
2865
+ const customerInquiryListQuerySchema = z.object({
2866
+ answered: answeredQuery,
2867
+ category: customerInquiryCategorySchema.optional().describe("문의 유형 필터"),
2868
+ from: z.string().optional().describe("작성 시각 조회 시작 (ISO 8601, 포함)"),
2869
+ ...pageQueryShape()
2907
2870
  });
2908
- /** `GET /v1/apps/catalog/{appId}` — 앱 상세·설치 화면 */
2909
- const storeAppDetailSchema = storeAppSchema.extend({
2910
- readme: z.string().nullable(),
2911
- supportEmail: z.string().nullable(),
2912
- scopes: z.array(z.string()).describe("설치 때 동의하는 스코프(Scope)"),
2913
- events: z.array(appEventTypeSchema).describe("받는 이벤트(Hook)"),
2914
- networkHosts: z.array(z.string()).describe("앱이 데이터를 보내는 외부 호스트"),
2915
- settings: z.record(z.string(), appSettingFieldSchema).describe("설치 때 채우는 설정 필드"),
2916
- updatedAt: z.string().nullable().describe("현재 버전을 release한 시각")
2871
+ const settlementStatusSchema = z.enum([
2872
+ "SCHEDULED",
2873
+ "PAID",
2874
+ "HELD"
2875
+ ]);
2876
+ const settlementSummarySchema = z.object({
2877
+ settlementId: z.string(),
2878
+ settlementDate: z.string(),
2879
+ payoutDate: z.string().nullable(),
2880
+ status: settlementStatusSchema,
2881
+ totalPaymentAmount: z.number().int(),
2882
+ totalCommission: z.number().int(),
2883
+ totalDeliveryFee: z.number().int(),
2884
+ adjustmentAmount: z.number().int(),
2885
+ settlementAmount: z.number().int(),
2886
+ itemCount: z.number().int()
2917
2887
  });
2918
- /** `POST /v1/apps/installations/{id}/session` — 앱 화면 iframe이 쓸 세션 토큰(5분) */
2919
- const appSessionSchema = z.object({
2920
- token: z.string(),
2921
- expiresAt: z.string(),
2922
- appOrigin: z.url().describe("iframe 주소의 origin(`https://{handle}.{앱 도메인}`)")
2888
+ const settlementDetailSchema = z.object({
2889
+ orderItemId: z.string(),
2890
+ productName: z.string(),
2891
+ settlementType: z.enum([
2892
+ "SALE",
2893
+ "REFUND_DEDUCTION",
2894
+ "ADJUSTMENT"
2895
+ ]),
2896
+ paymentAmount: z.number().int(),
2897
+ salesCommission: z.number().int(),
2898
+ paymentCommission: z.number().int(),
2899
+ commissionRate: z.number(),
2900
+ deliveryFee: z.number().int(),
2901
+ settlementAmount: z.number().int(),
2902
+ purchaseDecidedAt: z.string().nullable()
2923
2903
  });
2924
- /** `GET /v1/app/installation` — 설치 토큰으로 보는 자기 설치 */
2925
- const appInstallationSelfSchema = z.object({
2926
- installationId: z.string(),
2927
- appId: z.string(),
2928
- storeId: z.string(),
2929
- storeName: z.string(),
2930
- versionNumber: z.number().int(),
2931
- grantedScopes: z.array(z.string()),
2932
- installedAt: z.string()
2904
+ /** `GET /v1/settlements/{settlementId}` 응답 — 정산 요약 + 상세 내역(`size`건까지) */
2905
+ const settlementWithDetailsSchema = settlementSummarySchema.extend({ details: z.array(settlementDetailSchema).optional() });
2906
+ /** `GET /v1/settlements` 쿼리 — OpenAPI 문서용 형태(값은 쿼리 문자열). 정산일 최신순이다 */
2907
+ const settlementListQuerySchema = z.object({
2908
+ from: z.string().describe("정산일 조회 시작 (ISO 8601, 포함). 필수"),
2909
+ to: z.string().optional().describe("정산일 조회 끝 (ISO 8601, 포함). 생략하면 from부터 31일. 기간은 최대 31일"),
2910
+ status: settlementStatusSchema.optional().describe("정산 상태 필터"),
2911
+ ...pageQueryShape()
2933
2912
  });
2934
- const developerOrgSchema = z.object({
2935
- orgId: z.string(),
2936
- name: z.string(),
2937
- role: z.enum(["OWNER", "MEMBER"])
2913
+ /** `GET /v1/settlements/{settlementId}` 쿼리 — `size`는 돌려줄 상세 내역 건수다(`page`는 무시) */
2914
+ const settlementDetailQuerySchema = z.object(pageQueryShape({
2915
+ defaultSize: 100,
2916
+ maxSize: 300
2917
+ }));
2918
+ const eventTypeSchema = z.enum([
2919
+ "ORDER.PAID",
2920
+ "ORDER.CONFIRMED",
2921
+ "ORDER.DISPATCHED",
2922
+ "ORDER.DELIVERED",
2923
+ "ORDER.PURCHASE_DECIDED",
2924
+ "ORDER.ADDRESS_CHANGE_REQUESTED",
2925
+ "ORDER.CANCELED",
2926
+ "ORDER.FULFILLED",
2927
+ "CLAIM.CANCEL_REQUESTED",
2928
+ "CLAIM.RETURN_REQUESTED",
2929
+ "CLAIM.EXCHANGE_REQUESTED",
2930
+ "CLAIM.COMPLETED",
2931
+ "INQUIRY.CREATED",
2932
+ "REVIEW.CREATED",
2933
+ "PRODUCT.OUT_OF_STOCK",
2934
+ "ORDER.FLOW_NOTIFICATION",
2935
+ "ORDER.FLOW_STATE_CHANGED"
2936
+ ]).describe("웹훅 이벤트 타입. `ORDER.ADDRESS_CHANGE_REQUESTED`는 현재 발송하지 않음(호환을 위해 값만 남았고, 구독해도 이벤트가 오지 않는다)");
2937
+ const webhookStatusSchema = z.enum(["ACTIVE", "SUSPENDED"]).describe("구독 상태. `ACTIVE`=발송 대상, `SUSPENDED`=24시간 이상 연속 전송 실패로 발송이 정지된 상태. 정지 중 발생한 이벤트는 적재하지 않는다. 재개(`POST /webhooks/{id}/resume`)하거나 구독을 수정하면 ACTIVE로 돌아간다");
2938
+ const webhookSchema = z.object({
2939
+ webhookId: z.string(),
2940
+ url: z.url(),
2941
+ eventTypes: z.array(eventTypeSchema),
2942
+ status: webhookStatusSchema,
2943
+ secretPrefix: z.string().describe("서명 시크릿 앞부분(식별용, 서명 검증에 사용할 수 없음). 예: `whsec_1a2b`"),
2944
+ suspendedAt: z.string().nullable().describe("발송이 정지된 일시 (ISO 8601). `ACTIVE`면 null"),
2945
+ createdAt: z.string()
2938
2946
  });
2939
- const appVersionStatusSchema = z.enum([
2940
- "BUILDING",
2941
- "READY",
2942
- "FAILED",
2943
- "REVOKED"
2944
- ]);
2945
- /** 빌드 단계(매뉴얼 「앱 버전과 배포 › 빌드」). 로컬 번들(A1)은 `DEPENDENCIES`·`VERIFY`·`BUNDLE`·`UPLOAD`를 서버가 돈다 */
2946
- const appBuildStageSchema = z.enum([
2947
- "DEPENDENCIES",
2948
- "VERIFY",
2949
- "INSTALL",
2950
- "TYPECHECK",
2951
- "BUILD",
2952
- "BUNDLE",
2953
- "UPLOAD"
2954
- ]);
2955
- const appBuildSchema = z.object({
2956
- buildId: z.string(),
2957
- status: z.enum([
2958
- "QUEUED",
2959
- "RUNNING",
2960
- "SUCCEEDED",
2961
- "FAILED",
2962
- "TIMED_OUT"
2963
- ]),
2964
- stages: z.array(z.object({
2965
- stage: z.string(),
2966
- ok: z.boolean(),
2967
- durationMs: z.number()
2968
- })),
2969
- failureStage: z.string().nullable(),
2970
- errorCode: z.string().nullable(),
2971
- logTail: z.string().nullable(),
2972
- /** 의존성 검사 결과(거절·경고). 검사 전이면 null */
2973
- dependencies: z.object({
2974
- rejected: z.array(z.record(z.string(), z.unknown())),
2975
- warnings: z.array(z.record(z.string(), z.unknown()))
2976
- }).nullable(),
2977
- createdAt: z.string(),
2978
- finishedAt: z.string().nullable()
2947
+ /** 등록 응답 — 서명 시크릿 평문은 이 응답에서만 노출된다 */
2948
+ const webhookCreatedSchema = webhookSchema.extend({ secret: z.string().describe("서명 시크릿 평문. 등록 응답에서만 노출되며 다시 조회할 수 없다") });
2949
+ /** 시크릿 교체 응답 */
2950
+ const webhookSecretRotatedSchema = z.object({
2951
+ secret: z.string().describe("새 서명 시크릿 평문. 이 응답에서만 노출된다"),
2952
+ oldSecretExpiresAt: z.string().describe("기존 시크릿의 병행 유효 종료 일시 (ISO 8601). 이때까지는 기존 시크릿 서명도 함께 붙는다")
2979
2953
  });
2980
- const appVersionSchema = z.object({
2981
- versionId: z.string(),
2982
- number: z.number().int(),
2983
- status: appVersionStatusSchema,
2984
- current: z.boolean().describe("앱의 현재 버전(release한 버전)인가"),
2985
- message: z.string().nullable(),
2986
- capabilities: z.object({
2987
- scopes: z.array(z.string()),
2988
- events: z.array(z.string()),
2989
- networkHosts: z.array(z.string()),
2990
- adminPage: z.boolean(),
2991
- requiredSettings: z.array(z.string()),
2992
- secretSettings: z.array(z.string())
2993
- }),
2994
- build: appBuildSchema.nullable(),
2995
- listing: appListingSchema.nullable().optional().default(null).describe("이 버전이 올린 아이콘·설명·README"),
2996
- releasedAt: z.string().nullable(),
2997
- revokedAt: z.string().nullable(),
2954
+ const webhookDeliveryStatusSchema = z.enum([
2955
+ "PENDING",
2956
+ "PENDING_RETRY",
2957
+ "SUCCESS",
2958
+ "FAILED"
2959
+ ]).describe("전송 상태. `PENDING`=첫 시도 전, `PENDING_RETRY`=실패 후 재시도 대기, `SUCCESS`=2xx 응답 수신, `FAILED`=재시도를 모두 소진했거나 구독 정지로 종료");
2960
+ const webhookDeliveryErrorCodeSchema = z.enum([
2961
+ "TIMEOUT",
2962
+ "CONNECTION_FAILED",
2963
+ "BLOCKED_ADDRESS",
2964
+ "NON_2XX",
2965
+ "WEBHOOK_SUSPENDED",
2966
+ "APP_ERROR",
2967
+ "APP_LIMIT_EXCEEDED",
2968
+ "APP_REJECTED",
2969
+ "APP_UNCONFIGURED",
2970
+ "APP_INACTIVE",
2971
+ "APP_RUNNER_UNAVAILABLE"
2972
+ ]).describe("전송 실패 사유. `TIMEOUT`=10초 안에 응답 없음, `CONNECTION_FAILED`=연결 실패(DNS·TLS 포함), `BLOCKED_ADDRESS`=사설·루프백 등 전송이 허용되지 않는 주소, `NON_2XX`=2xx가 아닌 응답(리다이렉트 포함), `WEBHOOK_SUSPENDED`=구독 정지로 대기 중인 전송이 종료됨. 설치 앱(#22): `APP_ERROR`=앱 코드 예외, `APP_LIMIT_EXCEEDED`=CPU·요청·시간 한도 초과, `APP_REJECTED`=앱·버전 정지 등으로 거부, `APP_UNCONFIGURED`=필수 설정이 비어 보내지 않음, `APP_INACTIVE`=설치가 제거됨, `APP_RUNNER_UNAVAILABLE`=실행 환경 호출 실패");
2973
+ /**
2974
+ * 실패 원인 분류의 **현재** 값. 응답 스키마(`webhookFailureReasonSchema`)는 문자열로 열려 있다 —
2975
+ * 서버가 값을 더해도 이전 SDK가 목록 파싱에 실패하지 않게 한다(택배 추적 `stage`와 같은 이유).
2976
+ * 모르는 값은 `errorCode`로 판단한다.
2977
+ */
2978
+ const WEBHOOK_FAILURE_REASONS = [
2979
+ "DNS",
2980
+ "TLS",
2981
+ "TIMEOUT",
2982
+ "CONNECTION",
2983
+ "HTTP_4XX",
2984
+ "HTTP_5XX",
2985
+ "HTTP_OTHER",
2986
+ "SSRF_BLOCKED",
2987
+ "SUSPENDED"
2988
+ ];
2989
+ const webhookFailureReasonSchema = z.string().describe("실패 원인 분류(진단용). 현재 값은 `DNS`=호스트 이름을 주소로 바꾸지 못함, `TLS`=인증서·핸드셰이크 실패, `TIMEOUT`=10초 안에 응답 없음, `CONNECTION`=연결 거부·끊김, `HTTP_4XX`·`HTTP_5XX`=그 대역의 응답, `HTTP_OTHER`=2xx·4xx·5xx가 아닌 응답(리다이렉트 등), `SSRF_BLOCKED`=사설·루프백 등 전송이 허용되지 않는 주소, `SUSPENDED`=구독 정지로 대기 중인 전송이 종료됨. `errorCode`보다 잘게 나눈 값이며 둘은 함께 쓸 수 있다. 값이 추가될 수 있으므로 모르는 값은 `errorCode`로 판단한다");
2990
+ /**
2991
+ * 대상 리소스 종류의 **현재** 값. 응답 스키마는 문자열로 열려 있다(새 이벤트가 새 리소스를 가리킬 수 있다).
2992
+ */
2993
+ const WEBHOOK_RESOURCE_TYPES = [
2994
+ "ORDER",
2995
+ "CLAIM",
2996
+ "PRODUCT",
2997
+ "REVIEW",
2998
+ "INQUIRY"
2999
+ ];
3000
+ const webhookResourceTypeSchema = z.string().describe("이벤트가 가리키는 리소스 종류. 현재 값은 `ORDER`·`CLAIM`·`PRODUCT`·`REVIEW`·`INQUIRY`이고 값이 추가될 수 있다");
3001
+ /** 이벤트가 가리키는 대상 리소스 — 전송 기록을 주문·상품과 잇는 키 */
3002
+ const webhookDeliveryResourceSchema = z.object({
3003
+ type: webhookResourceTypeSchema,
3004
+ id: z.string().describe("리소스 ID. 전송 기록 조회의 `resourceId`, API 로그 조회의 `q`로 그대로 넣을 수 있다")
3005
+ });
3006
+ /** 발송 요청 헤더 한 줄 (값 마스킹) */
3007
+ const webhookRequestHeaderSchema = z.object({
3008
+ name: z.string().describe("헤더 이름"),
3009
+ value: z.string().nullable().describe("헤더 값. 서명(`Sayren-Signature`)처럼 비밀이 섞이는 헤더는 이름만 주고 값은 null이다")
3010
+ });
3011
+ /** 웹훅 전송 기록 한 건 (전송 기록 조회 항목) */
3012
+ const webhookDeliverySchema = z.object({
3013
+ deliveryId: z.string().describe("전송 기록 ID. 수신 요청의 `Sayren-Delivery-Id` 헤더 값"),
3014
+ eventId: z.string().describe("이벤트 ID. 재시도·재전송해도 같은 이벤트면 같은 값이다. 수신 측 중복 제거 키로 쓴다"),
3015
+ eventType: eventTypeSchema,
3016
+ url: z.string().describe("전송 시점의 대상 URL"),
3017
+ status: webhookDeliveryStatusSchema,
3018
+ responseStatusCode: z.number().int().nullable().describe("마지막 시도의 HTTP 응답 코드. 미시도·연결 실패·타임아웃·차단이면 null"),
3019
+ responseTimeMs: z.number().int().nullable().describe("마지막 시도의 응답 시간(ms). 미시도·연결 실패면 null"),
3020
+ responseBodyExcerpt: z.string().nullable().describe("마지막 시도의 응답 본문 앞부분(최대 4,096자). 응답이 없으면 null. 가린 뒤에 자른다. 키 이름에 `authorization`·`token`·`secret`·`password`·`key`·`signature`·`credential`·`cookie`가 **들어 있으면**(부분 일치, 대소문자 무시. 예: `apiKey`·`access_token`·`keyword`) 그 값을 `***`로 가린다. 값이 객체·배열이면 통째로 가린다. 평문 `Authorization: …` 같은 헤더 줄, `Bearer <토큰>`, 쿼리 형식 `access_token=…`, 끝에서 잘려 닫히지 않은 값도 가린다"),
3021
+ errorCode: webhookDeliveryErrorCodeSchema.nullable().describe("마지막 시도의 실패 사유. 성공했거나 미시도면 null"),
3022
+ failureReason: webhookFailureReasonSchema.nullable().describe("마지막 시도의 실패 원인 분류. 성공했거나 미시도면 null. `errorCode`를 더 잘게 나눈 진단 값이다"),
3023
+ resource: webhookDeliveryResourceSchema.nullable().describe("이벤트가 가리키는 대상 리소스. 리소스를 특정할 수 없는 이벤트면 null. 이 값으로 전송 기록(`resourceId`)과 API 로그(`q`)를 오갈 수 있다"),
3024
+ attemptCount: z.number().int().min(0).describe("지금까지 전송을 시작한 횟수. 최초 시도 1회 + 재시도 최대 4회. 전송 도중 장애로 결과를 기록하지 못한 시도도 센다"),
3025
+ createdAt: z.string().describe("전송 기록이 적재된 일시 (ISO 8601)"),
3026
+ attemptedAt: z.string().nullable().describe("마지막 시도 일시 (ISO 8601). 미시도면 null"),
3027
+ nextAttemptAt: z.string().nullable().describe("다음 시도 예정 일시 (ISO 8601). `PENDING`·`PENDING_RETRY`일 때만 값이 있다"),
3028
+ redeliveryOf: z.string().nullable().describe("수동 재전송으로 생긴 기록이면 원본 전송 기록 ID. 아니면 null"),
3029
+ redeliveredAs: z.string().nullable().describe("이 기록을 원본으로 수동 재전송해 생긴 기록의 전송 기록 ID. 아직 재전송하지 않았으면 null. 재전송은 원본당 1회다")
3030
+ });
3031
+ /** 발송 본문 최대 노출 길이(바이트). 넘으면 잘라 주고 `payloadTruncated`가 true다 */
3032
+ const WEBHOOK_PAYLOAD_EXCERPT_MAX_BYTES = 16384;
3033
+ /** 웹훅 전송 기록 상세 — `GET /webhooks/{id}/deliveries/{deliveryId}`. 목록 항목 + 요청 본문·헤더 */
3034
+ const webhookDeliveryDetailSchema = webhookDeliverySchema.extend({
3035
+ payload: z.string().describe(`수신 서버로 보낸 요청 본문 그대로(JSON 문자열). 서명은 이 문자열을 대상으로 계산한다. 최대 ${WEBHOOK_PAYLOAD_EXCERPT_MAX_BYTES / 1024}KB까지 주고 넘으면 잘라 준다`),
3036
+ payloadTruncated: z.boolean().describe("본문이 길어서 잘렸으면 true. true면 `payload`는 유효한 JSON이 아니다"),
3037
+ payloadMasked: z.boolean().describe("민감 키 마스킹(`responseBodyExcerpt`와 같은 키 이름 규칙)이 본문을 바꿨으면 true. true면 `payload`는 보낸 본문과 달라 서명을 맞춰 볼 수 없다. 이벤트 본문에는 보통 민감 키가 없어 false다"),
3038
+ requestHeaders: z.array(webhookRequestHeaderSchema).describe("발송 요청에 실은 헤더. 값은 전송 시점 그대로이나 서명 헤더는 이름만 주고 값은 null이다. `Content-Length`는 실제로 보낸 본문(마스킹·자르기 전)의 바이트 수다. 매 시도가 같은 헤더 집합을 쓰고 서명·타임스탬프만 달라진다")
3039
+ });
3040
+ /** 전송 기록 조회 쿼리 — `GET /webhooks/{id}/deliveries` */
3041
+ const webhookDeliveryListQuerySchema = z.object({
3042
+ status: webhookDeliveryStatusSchema.optional().describe("전송 상태 필터. 생략하면 전체"),
3043
+ eventType: eventTypeSchema.optional().describe("이벤트 타입 필터. 생략하면 전체"),
3044
+ resourceId: z.string().optional().describe("대상 리소스 ID 필터(정확히 일치). 주문·클레임·상품·리뷰·문의 id를 넣으면 그 리소스의 이벤트만 남는다. 같은 id로 API 로그를 `q`로 검색하면 그 리소스를 건드린 API 요청을 볼 수 있다"),
3045
+ limit: z.coerce.number().int().min(1).max(100).optional().describe("최대 건수 (1~100, 기본 50). 최신 적재순으로 반환하며 보관 기간은 30일이다")
3046
+ });
3047
+ /** 실패 건 일괄 재전송 응답 — `POST /webhooks/{id}/deliveries/redeliver-failed` */
3048
+ const webhookRedeliverFailedResultSchema = z.object({ queued: z.number().int().min(0).describe("재전송 대기열에 올린 건수. 최근 72시간의 `FAILED` 중 아직 재전송되지 않은 건이 대상이며 최대 500건이다") });
3049
+ const webhookTestRequestSchema = z.object({ eventType: eventTypeSchema.describe("샘플 페이로드로 보낼 이벤트 타입") });
3050
+ /** 테스트 이벤트 발송 결과 (동기 반환). 재시도·정지 판정·전송 기록이 없다 */
3051
+ const webhookTestResultSchema = z.object({
3052
+ responseStatusCode: z.number().int().nullable().describe("수신 서버의 HTTP 응답 코드. 연결 실패·타임아웃·차단이면 null"),
3053
+ responseTimeMs: z.number().int().nullable().describe("응답 시간(ms). 연결 실패면 null"),
3054
+ errorCode: webhookDeliveryErrorCodeSchema.nullable().describe("실패 사유. 2xx 응답이면 null"),
3055
+ failureReason: webhookFailureReasonSchema.nullable().describe("실패 원인 분류. 2xx 응답이면 null"),
3056
+ responseBodyExcerpt: z.string().nullable().describe("응답 본문 앞부분(최대 4,096자). 규칙은 전송 기록의 `responseBodyExcerpt`와 같다. 응답이 없으면 null"),
3057
+ requestHeaders: z.array(webhookRequestHeaderSchema).describe("보낸 요청 헤더. 서명 헤더는 이름만 주고 값은 null이다"),
3058
+ payload: z.string().describe("보낸 요청 본문 그대로(JSON 문자열). 샘플 이벤트다")
3059
+ });
3060
+ const webhookRequestSchema = z.object({
3061
+ url: z.url().startsWith("https://", "웹훅 URL은 HTTPS만 허용됩니다"),
3062
+ eventTypes: z.array(eventTypeSchema).min(1)
3063
+ });
3064
+ const reviewSchema = z.object({
3065
+ reviewId: z.string(),
3066
+ productId: z.string(),
3067
+ productName: z.string(),
3068
+ orderItemId: z.string(),
3069
+ optionName: z.string().nullable(),
3070
+ rating: z.number().int().min(1).max(5),
3071
+ content: z.string(),
3072
+ images: z.array(z.url()),
3073
+ writerMaskedName: z.string(),
3074
+ blinded: z.boolean(),
3075
+ reply: z.object({
3076
+ content: z.string(),
3077
+ repliedAt: z.string(),
3078
+ updatedAt: z.string().nullable()
3079
+ }).nullable(),
2998
3080
  createdAt: z.string()
2999
3081
  });
3000
- const developerAppSchema = z.object({
3082
+ const reviewSortSchema = z.enum([
3083
+ "createdAt.desc",
3084
+ "createdAt.asc",
3085
+ "rating.asc",
3086
+ "rating.desc"
3087
+ ]);
3088
+ /** `GET /v1/reviews` 쿼리 — OpenAPI 문서용 형태(값은 쿼리 문자열) */
3089
+ const reviewListQuerySchema = z.object({
3090
+ productId: z.string().optional().describe("상품 id 필터"),
3091
+ rating: z.enum([
3092
+ "1",
3093
+ "2",
3094
+ "3",
3095
+ "4",
3096
+ "5"
3097
+ ]).optional().describe("별점 필터 (일치)"),
3098
+ replied: z.enum(["true", "false"]).optional().describe("답글 여부 필터. `true`면 답글 단 리뷰만, `false`면 답글 없는 리뷰만"),
3099
+ hasImage: z.enum(["true", "false"]).optional().describe("`true`면 이미지가 있는 리뷰만"),
3100
+ from: z.string().optional().describe("작성 시각 조회 시작 (ISO 8601, 포함)"),
3101
+ sort: reviewSortSchema.optional().describe("정렬 (기본 createdAt.desc)"),
3102
+ ...pageQueryShape()
3103
+ });
3104
+ /** `POST /v1/reviews/{reviewId}/report` 응답(202) — 신고 접수 */
3105
+ const reviewReportResultSchema = z.object({
3106
+ reviewId: z.string(),
3107
+ status: z.literal("PENDING_REVIEW")
3108
+ });
3109
+ //#endregion
3110
+ //#region src/schemas/apps.ts
3111
+ /**
3112
+ * 설치 앱 관리 API 계약 (이슈 #22) — `/v1/apps/installations/**`(상점이 설치한 앱), `/v1/app/installation`(설치 토큰 자기 조회).
3113
+ * 개발자 API(`/platform/v1/developer/**`)는 플랫폼 플레인이라 여기 두지 않는다.
3114
+ */
3115
+ /** 배포 범위 — `PRIVATE_OWN` 개발자 조직 구성원이 OWNER·ADMIN인 상점과 개발 상점(A1) · `PRIVATE_LINK` 설치 링크(A2) · `LISTED` 공개 목록(A3) */
3116
+ const appDistributionSchema = z.enum([
3117
+ "PRIVATE_OWN",
3118
+ "PRIVATE_LINK",
3119
+ "LISTED"
3120
+ ]);
3121
+ const appRuntimeSchema = z.enum(["CODE", "EXTERNAL"]);
3122
+ /** 앱 상태 — `SUSPENDED`는 운영자 정지(모든 설치 토큰·실행 거부, 설치 행은 그대로) */
3123
+ const appStatusSchema = z.enum([
3124
+ "ACTIVE",
3125
+ "SUSPENDED",
3126
+ "DELETED"
3127
+ ]);
3128
+ const appInstallationStatusSchema = z.enum([
3129
+ "ACTIVE",
3130
+ "UNINSTALLED",
3131
+ "SUSPENDED"
3132
+ ]);
3133
+ /** 설치 앱의 앱 정보 — 상점이 보는 범위만(개발자 비밀 값·소스·빌드는 없다) */
3134
+ const appInstallationAppSchema = z.object({
3001
3135
  appId: z.string(),
3002
- orgId: z.string(),
3003
- handle: z.string(),
3136
+ handle: z.string().describe("앱 handle. 앱 화면 주소의 라벨"),
3004
3137
  name: z.string(),
3005
- description: z.string().nullable(),
3006
3138
  iconUrl: z.string().nullable(),
3139
+ description: z.string().nullable(),
3140
+ developerName: z.string().describe("개발자 조직 이름"),
3007
3141
  supportEmail: z.string().nullable(),
3008
3142
  distribution: appDistributionSchema,
3009
3143
  runtime: appRuntimeSchema,
3010
- status: appStatusSchema,
3011
- suspendedReason: z.string().nullable(),
3012
- currentVersionNumber: z.number().int().nullable(),
3013
- installations: z.object({
3014
- active: z.number().int(),
3015
- pendingReconsent: z.number().int()
3016
- }),
3017
- createdAt: z.string(),
3018
- updatedAt: z.string()
3144
+ status: appStatusSchema
3019
3145
  });
3020
- const developerAppCreateSchema = z.object({
3021
- handle: appHandleSchema,
3022
- name: z.string().trim().min(1).max(60),
3023
- description: z.string().trim().max(500).optional()
3146
+ const settingsValueSchema = z.union([
3147
+ z.string(),
3148
+ z.number(),
3149
+ z.boolean(),
3150
+ z.null()
3151
+ ]);
3152
+ /** 설치 설정 — 비밀 필드 값은 가려서 준다(앞 4자 + `…`). 비어 있는 필드는 null */
3153
+ const appInstallationSettingsSchema = z.object({
3154
+ fields: z.record(z.string(), appSettingFieldSchema).describe("실행 버전 매니페스트의 설정 필드"),
3155
+ values: z.record(z.string(), settingsValueSchema),
3156
+ /** 필수 설정이 모두 채워졌는가 — 아니면 이벤트 함수를 부르지 않는다 */
3157
+ configured: z.boolean(),
3158
+ updatedAt: z.string().nullable()
3159
+ });
3160
+ /** 설정 저장 — 비밀 필드를 생략하면 현재 값을 유지한다. null은 비운다 */
3161
+ const appInstallationSettingsUpdateSchema = z.object({ values: z.record(z.string(), settingsValueSchema) });
3162
+ const appInstallationSchema = z.object({
3163
+ installationId: z.string(),
3164
+ storeId: z.string(),
3165
+ app: appInstallationAppSchema,
3166
+ status: appInstallationStatusSchema,
3167
+ versionNumber: z.number().int().describe("실행 중인 앱 버전"),
3168
+ pendingVersionNumber: z.number().int().nullable().describe("재동의가 필요한 새 버전. 없으면 null"),
3169
+ pendingVersion: z.object({
3170
+ number: z.number().int(),
3171
+ scopes: z.array(z.string()),
3172
+ networkHosts: z.array(z.string()),
3173
+ events: z.array(appEventTypeSchema)
3174
+ }).nullable().optional().describe("재동의가 필요한 새 버전이 요청하는 권한·외부 호스트·이벤트(전체). 없으면 null"),
3175
+ grantedScopes: z.array(z.string()).describe("동의한 스코프"),
3176
+ grantedNetworkHosts: z.array(z.string()).describe("동의한 외부 호출 호스트"),
3177
+ events: z.array(appEventTypeSchema).describe("이 설치가 받는 이벤트"),
3178
+ adminPage: z.boolean().describe("상점 플랫폼 앱 화면이 있는가"),
3179
+ /** 설치 결과의 캐시가 아니라 실행 버전 매니페스트의 요약 */
3180
+ settings: appInstallationSettingsSchema,
3181
+ installedBy: z.object({
3182
+ userId: z.string(),
3183
+ name: z.string().nullable()
3184
+ }).nullable(),
3185
+ installedAt: z.string(),
3186
+ uninstalledAt: z.string().nullable(),
3187
+ updatedAt: z.string()
3188
+ });
3189
+ /** 실행 기록 한 줄 — 앱에 보낸 이벤트 하나의 전송 결과. 로그 본문은 개발자만 본다(매뉴얼 「앱 설치와 관리」) */
3190
+ const appInstallationRunSchema = z.object({
3191
+ deliveryId: z.string(),
3192
+ eventType: z.string().describe("이벤트 이름(`ORDER.PAID`·`APP.INSTALLED` 등)"),
3193
+ status: webhookDeliveryStatusSchema,
3194
+ errorCode: webhookDeliveryErrorCodeSchema.nullable(),
3195
+ attemptCount: z.number().int(),
3196
+ createdAt: z.string(),
3197
+ attemptedAt: z.string().nullable(),
3198
+ nextAttemptAt: z.string().nullable()
3199
+ });
3200
+ /** `GET /v1/apps/installations/{id}/activity` — 최근 이벤트 전송 결과(50건)와 최근 7일 관리 API 호출 수 */
3201
+ const appInstallationActivitySchema = z.object({
3202
+ runs: z.array(appInstallationRunSchema),
3203
+ apiCalls7d: z.number().int().describe("최근 7일 이 설치가 부른 관리 API 수")
3204
+ });
3205
+ /**
3206
+ * `POST /v1/apps/installations`(상점 플랫폼 전용) — 둘 중 하나다.
3207
+ * - `{ result }`: accounts 설치 동의 결과(1회용 JWT). 개발자 포털 [내 상점에 설치]가 이 길로 온다
3208
+ * - `{ appId, settings }`: 상점 플랫폼 앱 목록 › 설치 화면에서 동의하고 설정까지 채워 바로 설치한다
3209
+ */
3210
+ const appInstallRequestSchema = z.union([z.object({ result: z.string().min(1).describe("accounts가 발급한 설치 결과 JWT(`typ: sayren-install+jwt`)") }), z.object({
3211
+ appId: z.string().min(1),
3212
+ settings: z.record(z.string(), settingsValueSchema).default({}).describe("설치와 함께 저장할 설정. 비밀 필드도 여기서 넣는다")
3213
+ })]);
3214
+ /** 앱 목록 정보 — 현재 버전이 올린 아이콘·README(없으면 매니페스트 `iconUrl`) */
3215
+ const appListingSchema = z.object({
3216
+ description: z.string().nullable(),
3217
+ iconUrl: z.string().nullable().describe("아이콘 주소. 앱 폴더에서 올린 아이콘은 data URI, 매니페스트 `iconUrl`은 https 주소"),
3218
+ readme: z.string().nullable().describe("README 마크다운 원문")
3219
+ });
3220
+ /** `GET /v1/apps/catalog` — 이 상점에 설치할 수 있는 앱(A1: 내가 속한 개발자 조직의 앱) */
3221
+ const storeAppSchema = z.object({
3222
+ appId: z.string(),
3223
+ handle: z.string(),
3224
+ name: z.string(),
3225
+ description: z.string().nullable(),
3226
+ iconUrl: z.string().nullable(),
3227
+ developerName: z.string(),
3228
+ versionNumber: z.number().int().describe("현재 버전"),
3229
+ installationId: z.string().nullable().describe("이 상점에 설치돼 있으면 설치 id")
3230
+ });
3231
+ /** `GET /v1/apps/catalog/{appId}` — 앱 상세·설치 화면 */
3232
+ const storeAppDetailSchema = storeAppSchema.extend({
3233
+ readme: z.string().nullable(),
3234
+ supportEmail: z.string().nullable(),
3235
+ scopes: z.array(z.string()).describe("설치 때 동의하는 스코프(Scope)"),
3236
+ events: z.array(appEventTypeSchema).describe("받는 이벤트(Hook)"),
3237
+ networkHosts: z.array(z.string()).describe("앱이 데이터를 보내는 외부 호스트"),
3238
+ settings: z.record(z.string(), appSettingFieldSchema).describe("설치 때 채우는 설정 필드"),
3239
+ updatedAt: z.string().nullable().describe("현재 버전을 release한 시각")
3240
+ });
3241
+ /** `POST /v1/apps/installations/{id}/session` — 앱 화면 iframe이 쓸 세션 토큰(5분) */
3242
+ const appSessionSchema = z.object({
3243
+ token: z.string(),
3244
+ expiresAt: z.string(),
3245
+ appOrigin: z.url().describe("iframe 주소의 origin(`https://{handle}.{앱 도메인}`)")
3246
+ });
3247
+ /** `GET /v1/app/installation` — 설치 토큰으로 보는 자기 설치 */
3248
+ const appInstallationSelfSchema = z.object({
3249
+ installationId: z.string(),
3250
+ appId: z.string(),
3251
+ storeId: z.string(),
3252
+ storeName: z.string(),
3253
+ versionNumber: z.number().int(),
3254
+ grantedScopes: z.array(z.string()),
3255
+ installedAt: z.string()
3256
+ });
3257
+ const developerOrgSchema = z.object({
3258
+ orgId: z.string(),
3259
+ name: z.string(),
3260
+ role: z.enum(["OWNER", "MEMBER"])
3261
+ });
3262
+ const appVersionStatusSchema = z.enum([
3263
+ "BUILDING",
3264
+ "READY",
3265
+ "FAILED",
3266
+ "REVOKED"
3267
+ ]);
3268
+ /** 빌드 단계(매뉴얼 「앱 버전과 배포 › 빌드」). 로컬 번들(A1)은 `DEPENDENCIES`·`VERIFY`·`BUNDLE`·`UPLOAD`를 서버가 돈다 */
3269
+ const appBuildStageSchema = z.enum([
3270
+ "DEPENDENCIES",
3271
+ "VERIFY",
3272
+ "INSTALL",
3273
+ "TYPECHECK",
3274
+ "BUILD",
3275
+ "BUNDLE",
3276
+ "UPLOAD"
3277
+ ]);
3278
+ const appBuildSchema = z.object({
3279
+ buildId: z.string(),
3280
+ status: z.enum([
3281
+ "QUEUED",
3282
+ "RUNNING",
3283
+ "SUCCEEDED",
3284
+ "FAILED",
3285
+ "TIMED_OUT"
3286
+ ]),
3287
+ stages: z.array(z.object({
3288
+ stage: z.string(),
3289
+ ok: z.boolean(),
3290
+ durationMs: z.number()
3291
+ })),
3292
+ failureStage: z.string().nullable(),
3293
+ errorCode: z.string().nullable(),
3294
+ logTail: z.string().nullable(),
3295
+ /** 의존성 검사 결과(거절·경고). 검사 전이면 null */
3296
+ dependencies: z.object({
3297
+ rejected: z.array(z.record(z.string(), z.unknown())),
3298
+ warnings: z.array(z.record(z.string(), z.unknown()))
3299
+ }).nullable(),
3300
+ createdAt: z.string(),
3301
+ finishedAt: z.string().nullable()
3302
+ });
3303
+ const appVersionSchema = z.object({
3304
+ versionId: z.string(),
3305
+ number: z.number().int(),
3306
+ status: appVersionStatusSchema,
3307
+ current: z.boolean().describe("앱의 현재 버전(release한 버전)인가"),
3308
+ message: z.string().nullable(),
3309
+ capabilities: z.object({
3310
+ scopes: z.array(z.string()),
3311
+ events: z.array(z.string()),
3312
+ networkHosts: z.array(z.string()),
3313
+ adminPage: z.boolean(),
3314
+ requiredSettings: z.array(z.string()),
3315
+ secretSettings: z.array(z.string())
3316
+ }),
3317
+ build: appBuildSchema.nullable(),
3318
+ listing: appListingSchema.nullable().optional().default(null).describe("이 버전이 올린 아이콘·설명·README"),
3319
+ releasedAt: z.string().nullable(),
3320
+ revokedAt: z.string().nullable(),
3321
+ createdAt: z.string()
3322
+ });
3323
+ const developerAppSchema = z.object({
3324
+ appId: z.string(),
3325
+ orgId: z.string(),
3326
+ handle: z.string(),
3327
+ name: z.string(),
3328
+ description: z.string().nullable(),
3329
+ iconUrl: z.string().nullable(),
3330
+ supportEmail: z.string().nullable(),
3331
+ distribution: appDistributionSchema,
3332
+ runtime: appRuntimeSchema,
3333
+ status: appStatusSchema,
3334
+ suspendedReason: z.string().nullable(),
3335
+ currentVersionNumber: z.number().int().nullable(),
3336
+ installations: z.object({
3337
+ active: z.number().int(),
3338
+ pendingReconsent: z.number().int()
3339
+ }),
3340
+ createdAt: z.string(),
3341
+ updatedAt: z.string()
3342
+ });
3343
+ const developerAppCreateSchema = z.object({
3344
+ handle: appHandleSchema,
3345
+ name: z.string().trim().min(1).max(60),
3346
+ description: z.string().trim().max(500).optional()
3024
3347
  });
3025
3348
  /** `PUT /platform/v1/developer/apps/{appId}/versions` — CLI `app deploy`가 올리는 번들 */
3026
3349
  const appArtifactUploadSchema = z.object({
@@ -4734,612 +5057,311 @@ const couponSchema = z.object({
4734
5057
  perMemberIssueLimit: z.number().int().nullable(),
4735
5058
  perMemberUseLimit: z.number().int().nullable(),
4736
5059
  issuedCount: z.number().int().describe("발급 수 — 회수한 발급도 센다. 총 발급 한도(`totalIssueLimit`)가 이 값과 비교된다"),
4737
- reservedCount: z.number().int().describe("결제 중인 예약 수 — 결제가 끝나거나 만료되면 풀린다"),
4738
- usedCount: z.number().int().describe("사용 수 — 전량 취소로 복원되면 줄어든다"),
4739
- status: couponStatusSchema,
4740
- locked: z.boolean().describe("발급·사용이 시작돼 혜택·조건·대상·사용 시작일을 바꿀 수 없는가"),
4741
- lockedAt: z.string().nullable(),
4742
- createdAt: z.string(),
4743
- updatedAt: z.string()
4744
- });
4745
- /** `GET /v1/coupons` 쿼리 */
4746
- const couponListQuerySchema = z.object({
4747
- status: couponStatusSchema.optional(),
4748
- kind: couponKindSchema.optional(),
4749
- issueMethod: couponIssueMethodSchema.optional(),
4750
- q: z.string().optional().describe("이름·코드 검색(포함)"),
4751
- ...pageQueryShape()
4752
- });
4753
- /** 발급 쿠폰 상태 — 만료는 저장 상태가 아니라 조회 시각으로 판정한 값이다 */
4754
- const couponIssueStatusSchema = z.string().describe("발급 쿠폰 상태. 현재 값은 `AVAILABLE`(사용 가능)·`RESERVED`(결제 중)·`USED`(사용함)·`REVOKED`(회수)·`EXPIRED`(유효 기간 지남)이고 값이 추가될 수 있어 문자열로 받는다");
4755
- const couponIssueSchema = z.object({
4756
- issueId: z.string(),
4757
- couponId: z.string(),
4758
- customerId: z.string(),
4759
- customerName: z.string().nullable().describe("구매자 이름. 탈퇴한 구매자는 null"),
4760
- source: z.string().optional().describe("발급 경로(이슈 #110). 현재 값은 `MANUAL`(셀러 지급)·`DOWNLOAD`(구매자가 받음)·`SIGNUP`(회원가입 자동 지급)이고 값이 추가될 수 있다. 서버는 항상 싣는다"),
4761
- status: couponIssueStatusSchema,
4762
- validFrom: z.string(),
4763
- validUntil: z.string().nullable(),
4764
- usedOrderId: z.string().nullable(),
4765
- issuedAt: z.string(),
4766
- revokedAt: z.string().nullable()
4767
- });
4768
- const couponIssueListQuerySchema = z.object({
4769
- status: z.enum([
4770
- "AVAILABLE",
4771
- "RESERVED",
4772
- "USED",
4773
- "REVOKED"
4774
- ]).optional(),
4775
- ...pageQueryShape()
4776
- });
4777
- /** `POST /v1/coupons/{couponId}/issues` — 셀러 지급. 한 번에 1,000명까지 */
4778
- const issueCouponRequestSchema = z.strictObject({ customerIds: z.array(z.string().min(1)).min(1).max(1e3).refine((ids) => new Set(ids).size === ids.length, "같은 구매자를 두 번 넣었습니다").describe("지급할 구매자 id(1~1,000명, 중복 불가)") });
4779
- const issueCouponResultSchema = z.object({
4780
- issued: z.array(z.object({
4781
- customerId: z.string(),
4782
- issueId: z.string()
4783
- })),
4784
- failed: z.array(z.object({
4785
- customerId: z.string(),
4786
- code: z.string().describe("실패 사유. `CUSTOMER_NOT_FOUND`(이 상점 구매자가 아님)·`COUPON_LIMIT_REACHED`(1인 발급 한도)·`COUPON_EXHAUSTED`(총 발급 한도)"),
4787
- message: z.string()
4788
- }))
4789
- });
4790
- const couponRedemptionSchema = z.object({
4791
- redemptionId: z.string(),
4792
- couponId: z.string(),
4793
- issueId: z.string().nullable(),
4794
- customerId: z.string().nullable().describe("구매자 id. 비회원 주문은 null"),
4795
- orderId: z.string().nullable().describe("주문 id. 결제가 끝나기 전의 예약·해제는 null"),
4796
- status: z.string().describe("사용 기록 상태. 현재 값은 `RESERVED`(결제 중)·`USED`(사용함)·`RELEASED`(결제 실패·만료로 해제)·`RESTORED`(전량 취소로 복원)이고 값이 추가될 수 있어 문자열로 받는다"),
4797
- discountAmount: z.number().int(),
4798
- reservedAt: z.string(),
4799
- usedAt: z.string().nullable(),
4800
- releasedAt: z.string().nullable(),
4801
- restoredAt: z.string().nullable(),
4802
- restoreSkippedReason: z.string().nullable().describe("전량 취소에도 복원하지 않은 사유 — `EXPIRED`(유효 기간 지남)·`ENDED`(종료된 쿠폰)")
4803
- });
4804
- const couponRedemptionListQuerySchema = z.object({
4805
- status: z.enum([
4806
- "RESERVED",
4807
- "USED",
4808
- "RELEASED",
4809
- "RESTORED"
4810
- ]).optional(),
4811
- ...pageQueryShape()
4812
- });
4813
- const couponStatsSchema = z.object({
4814
- couponId: z.string(),
4815
- issuedCount: z.number().int(),
4816
- revokedCount: z.number().int(),
4817
- reservedCount: z.number().int(),
4818
- usedCount: z.number().int(),
4819
- restoredCount: z.number().int(),
4820
- releasedCount: z.number().int(),
4821
- discountTotal: z.number().int().describe("사용 중(`USED`)인 기록의 할인 합계 (원)"),
4822
- orderPaymentTotal: z.number().int().describe("이 쿠폰을 쓴(`USED`) 주문의 결제 금액 합계 (원). 부분 취소·반품 환불은 빼지 않은 결제 시점 금액이다")
4823
- });
4824
- /** `GET /v1/customers/{customerId}/coupons` 항목 — 발급 쿠폰 + 쿠폰 이름·혜택 */
4825
- const customerCouponSchema = couponIssueSchema.extend({
4826
- couponName: z.string(),
4827
- kind: couponKindSchema,
4828
- benefit: couponBenefitSchema
4829
- });
4830
- //#endregion
4831
- //#region src/schemas/customer.ts
4832
- /** 구매자 목록 정렬 */
4833
- const customerSortSchema = z.enum([
4834
- "joined_desc",
4835
- "joined_asc",
4836
- "total_paid_desc",
4837
- "order_count_desc",
4838
- "last_ordered_desc"
4839
- ]).describe("정렬. `joined_desc`(기본, 최근 가입순)·`joined_asc`·`total_paid_desc`(구매 금액순)·`order_count_desc`(주문 수순)·`last_ordered_desc`(최근 주문순)");
4840
- /** `GET /v1/customers` 쿼리 */
4841
- const customerListQuerySchema = z.object({
4842
- q: z.string().optional().describe("검색어 — 이름·이메일(포함). 숫자 4자리면 휴대폰 뒤 4자리로도 찾는다"),
4843
- joinedFrom: z.string().optional().describe("가입일 시작(YYYY-MM-DD, KST, 포함)"),
4844
- joinedTo: z.string().optional().describe("가입일 끝(YYYY-MM-DD, KST, 포함)"),
4845
- marketing: z.enum(["agreed", "declined"]).optional().describe("마케팅 수신 동의 필터. 생략하면 전체"),
4846
- sort: customerSortSchema.optional(),
4847
- ...pageQueryShape()
4848
- });
4849
- /** 구매 통계 — 구매 금액은 취소된 주문 상품을 빼고, 완료된 반품은 수량 비율로 뺀 금액이다 */
4850
- const customerStatsSchema = z.object({
4851
- orderCount: z.number().int().describe("주문 수(취소 포함)"),
4852
- totalPaid: z.number().int().describe("구매 금액(원) — 취소·완료된 반품 제외"),
4853
- lastOrderedAt: z.string().nullable().describe("최근 주문 시각")
4854
- });
4855
- /** 목록 행 — 휴대폰은 가운데를 가린다(`010-****-1234`) */
4856
- const customerSummarySchema = z.object({
4857
- customerId: z.string(),
4858
- name: z.string(),
4859
- /** 소셜 가입에서 이메일을 받지 못했으면 null */
4860
- email: z.string().nullable(),
4861
- maskedPhone: z.string().nullable(),
4862
- joinedAt: z.string(),
4863
- point: z.number().int(),
4864
- marketingAgreed: z.boolean()
4865
- }).extend(customerStatsSchema.shape);
4866
- const customerAddressSchema = z.object({
4867
- addressId: z.string(),
4868
- alias: z.string(),
4869
- isDefault: z.boolean(),
4870
- receiverName: z.string(),
4871
- phone: z.string(),
4872
- zipCode: z.string(),
4873
- address1: z.string(),
4874
- address2: z.string().nullable()
4875
- });
4876
- /** 동의 종류 — 이용약관·개인정보 수집이용은 가입 필수, 마케팅 수신은 선택 */
4877
- const consentKindSchema = z.enum([
4878
- "TERMS",
4879
- "PRIVACY",
4880
- "MARKETING"
4881
- ]);
4882
- const consentActionSchema = z.enum(["AGREED", "WITHDRAWN"]);
4883
- /**
4884
- * 동의가 일어난 경로. 값이 추가될 수 있어 모르는 값은 그대로 보여 준다.
4885
- * `SIGNUP` 비밀번호 가입 · `SOCIAL_SIGNUP` 소셜 가입 · `DELEGATED` 셀러 자체 회원 연동 ·
4886
- * `RECONSENT` 약관 개정 재동의 · `MEMBER_UPDATE` 구매자가 직접 변경 · `SELLER` 셀러가 처리
4887
- */
4888
- const consentSourceSchema = z.enum([
4889
- "SIGNUP",
4890
- "SOCIAL_SIGNUP",
4891
- "DELEGATED",
4892
- "RECONSENT",
4893
- "MEMBER_UPDATE",
4894
- "SELLER"
4895
- ]);
4896
- /** 동의 이력 한 줄 — 추가만 되고 지워지지 않는다(구매자 탈퇴 시에만 함께 지워진다) */
4897
- const customerConsentSchema = z.object({
4898
- consentId: z.string(),
4899
- kind: consentKindSchema,
4900
- /** 동의한 약관 버전. 마케팅은 버전이 없어 null */
4901
- version: z.string().nullable(),
4902
- /** 동의 시점의 약관 문서 주소. 상점이 주소를 정하지 않았거나 마케팅이면 null */
4903
- documentUrl: z.string().nullable(),
4904
- action: consentActionSchema,
4905
- source: consentSourceSchema,
4906
- occurredAt: z.string()
4907
- });
4908
- /** 종류별 현재 동의 상태 */
4909
- const customerConsentStateSchema = z.object({
4910
- kind: consentKindSchema,
4911
- agreed: z.boolean(),
4912
- /** 동의한 약관 버전. 마케팅이거나 이력이 없으면 null */
4913
- agreedVersion: z.string().nullable(),
4914
- /** 상점의 현재 약관 버전. 마케팅은 null */
4915
- currentVersion: z.string().nullable(),
4916
- /** 상점이 정한 현재 약관 문서 주소. 정하지 않았거나 마케팅이면 null */
4917
- currentDocumentUrl: z.string().nullable(),
4918
- updatedAt: z.string().nullable(),
4919
- /** 약관이 개정돼 다시 받아야 하는가. 마케팅은 항상 false */
4920
- reconsentRequired: z.boolean()
4921
- });
4922
- const customerConsentsSchema = z.object({
4923
- terms: customerConsentStateSchema,
4924
- privacy: customerConsentStateSchema,
4925
- marketing: customerConsentStateSchema,
4926
- /** 필수 동의 중 하나라도 현재 버전이 아니면 true */
4927
- reconsentRequired: z.boolean()
4928
- });
4929
- /** `GET /v1/customers/{id}/consents` 쿼리 — 최근 순이다 */
4930
- const customerConsentListQuerySchema = z.object({
4931
- kind: consentKindSchema.optional().describe("동의 종류 필터. 생략하면 전체"),
4932
- ...pageQueryShape()
4933
- });
4934
- /** 구매자 상세 — 휴대폰 전체를 보여 준다 */
4935
- const customerDetailSchema = z.object({
4936
- customerId: z.string(),
4937
- name: z.string(),
4938
- email: z.string().nullable(),
4939
- phone: z.string().nullable(),
4940
- joinedAt: z.string(),
4941
- point: z.number().int(),
4942
- marketingAgreed: z.boolean(),
4943
- loginMethods: z.array(z.object({
4944
- method: z.enum([
4945
- "password",
4946
- "kakao",
4947
- "naver",
4948
- "google"
4949
- ]),
4950
- /** 소셜 연결 시각. 비밀번호는 가입 시각 */
4951
- linkedAt: z.string()
4952
- })).describe("로그인 방법 — 이메일·비밀번호(`password`)와 연결된 소셜 계정"),
4953
- consents: customerConsentsSchema.describe("약관·개인정보·마케팅 동의의 현재 상태. 이력은 `GET /v1/customers/{customerId}/consents`"),
4954
- addresses: z.array(customerAddressSchema),
4955
- stats: customerStatsSchema.extend({
4956
- canceledOrReturnedCount: z.number().int().describe("취소된 주문 상품 + 완료된 반품 수"),
4957
- reviewCount: z.number().int(),
4958
- inquiryCount: z.number().int().describe("상품 문의 + 1:1 문의")
4959
- })
4960
- });
4961
- /** 구매자의 주문 — 전체 기간 */
4962
- const customerOrderSchema = z.object({
4963
- orderId: z.string(),
4964
- orderedAt: z.string(),
4965
- totalAmount: z.number().int().describe("결제 금액"),
4966
- testPayment: z.boolean(),
4967
- items: z.array(z.object({
4968
- orderItemId: z.string(),
4969
- productName: z.string(),
4970
- optionName: z.string().nullable(),
4971
- quantity: z.number().int(),
4972
- status: orderItemStatusSchema,
4973
- claimStatus: z.enum([
4974
- "CANCEL_REQUESTED",
4975
- "RETURN_REQUESTED",
4976
- "EXCHANGE_REQUESTED"
4977
- ]).nullable()
4978
- }))
4979
- });
4980
- /** `POST /v1/customers/{id}/withdraw` 본문 */
4981
- const withdrawCustomerRequestSchema = z.object({
4982
- reason: z.enum([
4983
- "BUYER_REQUEST",
4984
- "DORMANT",
4985
- "ABUSE",
4986
- "OTHER"
4987
- ]).describe("처리 사유 — 구매자 요청·장기 미이용·부정 이용·기타. 감사 로그에 남는다"),
4988
- memo: z.string().max(200).optional().describe("사유 보충(선택)")
4989
- });
4990
- /** `WITHDRAWAL_BLOCKED`의 `error.details` — 탈퇴를 막는 항목 수(스토어프론트 탈퇴와 같다) */
4991
- const customerWithdrawalBlockedDetailsSchema = z.object({
4992
- inProgressOrderItems: z.number().int(),
4993
- openClaims: z.number().int(),
4994
- pendingPayments: z.number().int()
4995
- });
4996
- //#endregion
4997
- //#region src/schemas/login.ts
4998
- /** 소셜 로그인 공급자 */
4999
- const loginProviderSchema = z.enum([
5000
- "kakao",
5001
- "naver",
5002
- "google"
5003
- ]);
5004
- /** 공급자 연결 상태 — 비밀 값은 앞 4자리만 */
5005
- const loginProviderStatusSchema = z.object({
5006
- provider: loginProviderSchema,
5007
- connected: z.boolean(),
5008
- /** 스토어프론트에서 사용 중인지. 연결 안 됐으면 false */
5009
- enabled: z.boolean(),
5010
- clientIdPrefix: z.string().nullable().describe("클라이언트 ID(카카오 REST API 키) 앞 4자리"),
5011
- secretPrefix: z.string().nullable(),
5012
- lastTestedAt: z.string().nullable(),
5013
- lastTestOk: z.boolean().nullable(),
5014
- linkedMemberCount: z.number().int().describe("이 공급자로 연결된 구매자 수"),
5015
- /** 이 공급자로만 로그인하는 구매자 수 — 연결을 해제하면 로그인할 방법이 없어진다 */
5016
- onlyMethodMemberCount: z.number().int(),
5017
- callbackUrl: z.url().describe("공급자 개발자 콘솔에 등록할 리디렉트 URI")
5018
- });
5019
- /** `GET /v1/store/login-settings` */
5020
- const loginSettingsSchema = z.object({
5021
- passwordLoginEnabled: z.boolean(),
5022
- /** 비밀번호로만 로그인하는 구매자 수 — 이메일·비밀번호를 끄면 이들은 로그인할 수 없다 */
5023
- passwordOnlyMemberCount: z.number().int(),
5024
- storefrontOrigins: z.array(z.string()),
5025
- providers: z.array(loginProviderStatusSchema)
5026
- });
5027
- /** `PATCH /v1/store/login-settings` */
5028
- const updateLoginSettingsRequestSchema = z.object({ passwordLoginEnabled: z.boolean() });
5029
- /** `PUT /v1/store/auth-providers/{provider}` — 저장 전에 연결 테스트를 한다 */
5030
- const saveLoginProviderRequestSchema = z.object({
5031
- clientId: z.string().trim().min(1).max(200),
5032
- clientSecret: z.string().trim().min(1).max(500)
5033
- });
5034
- /** `PATCH /v1/store/auth-providers/{provider}` */
5035
- const updateLoginProviderRequestSchema = z.object({ enabled: z.boolean() });
5036
- /** 연결 테스트 결과 */
5037
- const loginProviderTestSchema = z.object({
5038
- ok: z.boolean(),
5039
- /** 실패 이유 — `INVALID_CLIENT`(키가 틀림)·`PROVIDER_UNAVAILABLE`(공급자 응답 없음) */
5040
- code: z.enum(["INVALID_CLIENT", "PROVIDER_UNAVAILABLE"]).nullable(),
5041
- testedAt: z.string()
5042
- });
5043
- //#endregion
5044
- //#region src/schemas/misc.ts
5045
- const inquirySchema = z.object({
5046
- inquiryId: z.string(),
5047
- productId: z.string(),
5048
- productName: z.string(),
5049
- orderItemId: z.string().nullable(),
5050
- category: z.enum([
5051
- "PRODUCT",
5052
- "DELIVERY",
5053
- "RETURN",
5054
- "EXCHANGE",
5055
- "ETC"
5056
- ]),
5057
- content: z.string(),
5058
- secret: z.boolean(),
5059
- writerMaskedName: z.string(),
5060
- answered: z.boolean(),
5061
- answer: z.object({
5062
- content: z.string(),
5063
- answeredAt: z.string(),
5064
- modifiedCount: z.number().int().max(1)
5065
- }).nullable(),
5066
- createdAt: z.string()
5067
- });
5068
- const customerInquiryCategorySchema = z.enum([
5069
- "DELIVERY",
5070
- "RETURN",
5071
- "EXCHANGE",
5072
- "PAYMENT",
5073
- "ETC"
5074
- ]);
5075
- /** 셀러 뷰 1:1 문의 — 작성자 마스킹명 + 답변 수정횟수 포함 */
5076
- const sellerCustomerInquirySchema = z.object({
5077
- inquiryId: z.string(),
5078
- memberMaskedName: z.string(),
5079
- category: customerInquiryCategorySchema,
5080
- title: z.string(),
5081
- content: z.string(),
5082
- orderItemId: z.string().nullable(),
5083
- answered: z.boolean(),
5084
- answer: z.object({
5085
- content: z.string(),
5086
- answeredAt: z.string(),
5087
- modifiedCount: z.number().int().max(1)
5088
- }).nullable(),
5089
- createdAt: z.string()
5060
+ reservedCount: z.number().int().describe("결제 중인 예약 수 — 결제가 끝나거나 만료되면 풀린다"),
5061
+ usedCount: z.number().int().describe("사용 수 — 전량 취소로 복원되면 줄어든다"),
5062
+ status: couponStatusSchema,
5063
+ locked: z.boolean().describe("발급·사용이 시작돼 혜택·조건·대상·사용 시작일을 바꿀 수 없는가"),
5064
+ lockedAt: z.string().nullable(),
5065
+ createdAt: z.string(),
5066
+ updatedAt: z.string()
5090
5067
  });
5091
- const answeredQuery = z.enum(["true", "false"]).optional().describe("답변 여부 필터. `true`면 답변된 문의만, `false`면 미답변만, 생략하면 전부");
5092
- /** `GET /v1/inquiries` 쿼리(상품 문의) — OpenAPI 문서용 형태(값은 쿼리 문자열). 최신순이다 */
5093
- const inquiryListQuerySchema = z.object({
5094
- answered: answeredQuery,
5095
- productId: z.string().optional().describe("상품 id 필터"),
5096
- from: z.string().optional().describe("작성 시각 조회 시작 (ISO 8601, 포함)"),
5068
+ /** `GET /v1/coupons` 쿼리 */
5069
+ const couponListQuerySchema = z.object({
5070
+ status: couponStatusSchema.optional(),
5071
+ kind: couponKindSchema.optional(),
5072
+ issueMethod: couponIssueMethodSchema.optional(),
5073
+ q: z.string().optional().describe("이름·코드 검색(포함)"),
5097
5074
  ...pageQueryShape()
5098
5075
  });
5099
- /** `GET /v1/customer-inquiries` 쿼리(1:1 문의) — OpenAPI 문서용 형태(값은 쿼리 문자열). 최신순이다 */
5100
- const customerInquiryListQuerySchema = z.object({
5101
- answered: answeredQuery,
5102
- category: customerInquiryCategorySchema.optional().describe("문의 유형 필터"),
5103
- from: z.string().optional().describe("작성 시각 조회 시작 (ISO 8601, 포함)"),
5076
+ /** 발급 쿠폰 상태 — 만료는 저장 상태가 아니라 조회 시각으로 판정한 값이다 */
5077
+ const couponIssueStatusSchema = z.string().describe("발급 쿠폰 상태. 현재 값은 `AVAILABLE`(사용 가능)·`RESERVED`(결제 중)·`USED`(사용함)·`REVOKED`(회수)·`EXPIRED`(유효 기간 지남)이고 값이 추가될 수 있어 문자열로 받는다");
5078
+ const couponIssueSchema = z.object({
5079
+ issueId: z.string(),
5080
+ couponId: z.string(),
5081
+ customerId: z.string(),
5082
+ customerName: z.string().nullable().describe("구매자 이름. 탈퇴한 구매자는 null"),
5083
+ source: z.string().optional().describe("발급 경로(이슈 #110). 현재 값은 `MANUAL`(셀러 지급)·`DOWNLOAD`(구매자가 받음)·`SIGNUP`(회원가입 자동 지급)이고 값이 추가될 수 있다. 서버는 항상 싣는다"),
5084
+ status: couponIssueStatusSchema,
5085
+ validFrom: z.string(),
5086
+ validUntil: z.string().nullable(),
5087
+ usedOrderId: z.string().nullable(),
5088
+ issuedAt: z.string(),
5089
+ revokedAt: z.string().nullable()
5090
+ });
5091
+ const couponIssueListQuerySchema = z.object({
5092
+ status: z.enum([
5093
+ "AVAILABLE",
5094
+ "RESERVED",
5095
+ "USED",
5096
+ "REVOKED"
5097
+ ]).optional(),
5104
5098
  ...pageQueryShape()
5105
5099
  });
5106
- const settlementStatusSchema = z.enum([
5107
- "SCHEDULED",
5108
- "PAID",
5109
- "HELD"
5110
- ]);
5111
- const settlementSummarySchema = z.object({
5112
- settlementId: z.string(),
5113
- settlementDate: z.string(),
5114
- payoutDate: z.string().nullable(),
5115
- status: settlementStatusSchema,
5116
- totalPaymentAmount: z.number().int(),
5117
- totalCommission: z.number().int(),
5118
- totalDeliveryFee: z.number().int(),
5119
- adjustmentAmount: z.number().int(),
5120
- settlementAmount: z.number().int(),
5121
- itemCount: z.number().int()
5100
+ /** `POST /v1/coupons/{couponId}/issues` — 셀러 지급. 한 번에 1,000명까지 */
5101
+ const issueCouponRequestSchema = z.strictObject({ customerIds: z.array(z.string().min(1)).min(1).max(1e3).refine((ids) => new Set(ids).size === ids.length, "같은 구매자를 두 번 넣었습니다").describe("지급할 구매자 id(1~1,000명, 중복 불가)") });
5102
+ const issueCouponResultSchema = z.object({
5103
+ issued: z.array(z.object({
5104
+ customerId: z.string(),
5105
+ issueId: z.string()
5106
+ })),
5107
+ failed: z.array(z.object({
5108
+ customerId: z.string(),
5109
+ code: z.string().describe("실패 사유. `CUSTOMER_NOT_FOUND`(이 상점 구매자가 아님)·`COUPON_LIMIT_REACHED`(1인 발급 한도)·`COUPON_EXHAUSTED`(총 발급 한도)"),
5110
+ message: z.string()
5111
+ }))
5122
5112
  });
5123
- const settlementDetailSchema = z.object({
5124
- orderItemId: z.string(),
5125
- productName: z.string(),
5126
- settlementType: z.enum([
5127
- "SALE",
5128
- "REFUND_DEDUCTION",
5129
- "ADJUSTMENT"
5130
- ]),
5131
- paymentAmount: z.number().int(),
5132
- salesCommission: z.number().int(),
5133
- paymentCommission: z.number().int(),
5134
- commissionRate: z.number(),
5135
- deliveryFee: z.number().int(),
5136
- settlementAmount: z.number().int(),
5137
- purchaseDecidedAt: z.string().nullable()
5113
+ const couponRedemptionSchema = z.object({
5114
+ redemptionId: z.string(),
5115
+ couponId: z.string(),
5116
+ issueId: z.string().nullable(),
5117
+ customerId: z.string().nullable().describe("구매자 id. 비회원 주문은 null"),
5118
+ orderId: z.string().nullable().describe("주문 id. 결제가 끝나기 전의 예약·해제는 null"),
5119
+ status: z.string().describe("사용 기록 상태. 현재 값은 `RESERVED`(결제 중)·`USED`(사용함)·`RELEASED`(결제 실패·만료로 해제)·`RESTORED`(전량 취소로 복원)이고 값이 추가될 수 있어 문자열로 받는다"),
5120
+ discountAmount: z.number().int(),
5121
+ reservedAt: z.string(),
5122
+ usedAt: z.string().nullable(),
5123
+ releasedAt: z.string().nullable(),
5124
+ restoredAt: z.string().nullable(),
5125
+ restoreSkippedReason: z.string().nullable().describe("전량 취소에도 복원하지 않은 사유 — `EXPIRED`(유효 기간 지남)·`ENDED`(종료된 쿠폰)")
5138
5126
  });
5139
- /** `GET /v1/settlements/{settlementId}` 응답 — 정산 요약 + 상세 내역(`size`건까지) */
5140
- const settlementWithDetailsSchema = settlementSummarySchema.extend({ details: z.array(settlementDetailSchema).optional() });
5141
- /** `GET /v1/settlements` 쿼리 — OpenAPI 문서용 형태(값은 쿼리 문자열). 정산일 최신순이다 */
5142
- const settlementListQuerySchema = z.object({
5143
- from: z.string().describe("정산일 조회 시작 (ISO 8601, 포함). 필수"),
5144
- to: z.string().optional().describe("정산일 조회 끝 (ISO 8601, 포함). 생략하면 from부터 31일. 기간은 최대 31일"),
5145
- status: settlementStatusSchema.optional().describe("정산 상태 필터"),
5127
+ const couponRedemptionListQuerySchema = z.object({
5128
+ status: z.enum([
5129
+ "RESERVED",
5130
+ "USED",
5131
+ "RELEASED",
5132
+ "RESTORED"
5133
+ ]).optional(),
5146
5134
  ...pageQueryShape()
5147
5135
  });
5148
- /** `GET /v1/settlements/{settlementId}` 쿼리 — `size`는 돌려줄 상세 내역 건수다(`page`는 무시) */
5149
- const settlementDetailQuerySchema = z.object(pageQueryShape({
5150
- defaultSize: 100,
5151
- maxSize: 300
5152
- }));
5153
- const eventTypeSchema = z.enum([
5154
- "ORDER.PAID",
5155
- "ORDER.CONFIRMED",
5156
- "ORDER.DISPATCHED",
5157
- "ORDER.DELIVERED",
5158
- "ORDER.PURCHASE_DECIDED",
5159
- "ORDER.ADDRESS_CHANGE_REQUESTED",
5160
- "ORDER.CANCELED",
5161
- "ORDER.FULFILLED",
5162
- "CLAIM.CANCEL_REQUESTED",
5163
- "CLAIM.RETURN_REQUESTED",
5164
- "CLAIM.EXCHANGE_REQUESTED",
5165
- "CLAIM.COMPLETED",
5166
- "INQUIRY.CREATED",
5167
- "REVIEW.CREATED",
5168
- "PRODUCT.OUT_OF_STOCK",
5169
- "ORDER.FLOW_NOTIFICATION",
5170
- "ORDER.FLOW_STATE_CHANGED"
5171
- ]).describe("웹훅 이벤트 타입. `ORDER.ADDRESS_CHANGE_REQUESTED`는 현재 발송하지 않음(호환을 위해 값만 남았고, 구독해도 이벤트가 오지 않는다)");
5172
- const webhookStatusSchema = z.enum(["ACTIVE", "SUSPENDED"]).describe("구독 상태. `ACTIVE`=발송 대상, `SUSPENDED`=24시간 이상 연속 전송 실패로 발송이 정지된 상태. 정지 중 발생한 이벤트는 적재하지 않는다. 재개(`POST /webhooks/{id}/resume`)하거나 구독을 수정하면 ACTIVE로 돌아간다");
5173
- const webhookSchema = z.object({
5174
- webhookId: z.string(),
5175
- url: z.url(),
5176
- eventTypes: z.array(eventTypeSchema),
5177
- status: webhookStatusSchema,
5178
- secretPrefix: z.string().describe("서명 시크릿 앞부분(식별용, 서명 검증에 사용할 수 없음). 예: `whsec_1a2b`"),
5179
- suspendedAt: z.string().nullable().describe("발송이 정지된 일시 (ISO 8601). `ACTIVE`면 null"),
5180
- createdAt: z.string()
5136
+ const couponStatsSchema = z.object({
5137
+ couponId: z.string(),
5138
+ issuedCount: z.number().int(),
5139
+ revokedCount: z.number().int(),
5140
+ reservedCount: z.number().int(),
5141
+ usedCount: z.number().int(),
5142
+ restoredCount: z.number().int(),
5143
+ releasedCount: z.number().int(),
5144
+ discountTotal: z.number().int().describe("사용 중(`USED`)인 기록의 할인 합계 (원)"),
5145
+ orderPaymentTotal: z.number().int().describe("이 쿠폰을 쓴(`USED`) 주문의 결제 금액 합계 (원). 부분 취소·반품 환불은 빼지 않은 결제 시점 금액이다")
5181
5146
  });
5182
- /** 등록 응답 — 서명 시크릿 평문은 이 응답에서만 노출된다 */
5183
- const webhookCreatedSchema = webhookSchema.extend({ secret: z.string().describe("서명 시크릿 평문. 등록 응답에서만 노출되며 다시 조회할 수 없다") });
5184
- /** 시크릿 교체 응답 */
5185
- const webhookSecretRotatedSchema = z.object({
5186
- secret: z.string().describe("새 서명 시크릿 평문. 이 응답에서만 노출된다"),
5187
- oldSecretExpiresAt: z.string().describe("기존 시크릿의 병행 유효 종료 일시 (ISO 8601). 이때까지는 기존 시크릿 서명도 함께 붙는다")
5147
+ /** `GET /v1/customers/{customerId}/coupons` 항목 — 발급 쿠폰 + 쿠폰 이름·혜택 */
5148
+ const customerCouponSchema = couponIssueSchema.extend({
5149
+ couponName: z.string(),
5150
+ kind: couponKindSchema,
5151
+ benefit: couponBenefitSchema
5188
5152
  });
5189
- const webhookDeliveryStatusSchema = z.enum([
5190
- "PENDING",
5191
- "PENDING_RETRY",
5192
- "SUCCESS",
5193
- "FAILED"
5194
- ]).describe("전송 상태. `PENDING`=첫 시도 전, `PENDING_RETRY`=실패 후 재시도 대기, `SUCCESS`=2xx 응답 수신, `FAILED`=재시도를 모두 소진했거나 구독 정지로 종료");
5195
- const webhookDeliveryErrorCodeSchema = z.enum([
5196
- "TIMEOUT",
5197
- "CONNECTION_FAILED",
5198
- "BLOCKED_ADDRESS",
5199
- "NON_2XX",
5200
- "WEBHOOK_SUSPENDED",
5201
- "APP_ERROR",
5202
- "APP_LIMIT_EXCEEDED",
5203
- "APP_REJECTED",
5204
- "APP_UNCONFIGURED",
5205
- "APP_INACTIVE",
5206
- "APP_RUNNER_UNAVAILABLE"
5207
- ]).describe("전송 실패 사유. `TIMEOUT`=10초 안에 응답 없음, `CONNECTION_FAILED`=연결 실패(DNS·TLS 포함), `BLOCKED_ADDRESS`=사설·루프백 등 전송이 허용되지 않는 주소, `NON_2XX`=2xx가 아닌 응답(리다이렉트 포함), `WEBHOOK_SUSPENDED`=구독 정지로 대기 중인 전송이 종료됨. 설치 앱(#22): `APP_ERROR`=앱 코드 예외, `APP_LIMIT_EXCEEDED`=CPU·요청·시간 한도 초과, `APP_REJECTED`=앱·버전 정지 등으로 거부, `APP_UNCONFIGURED`=필수 설정이 비어 보내지 않음, `APP_INACTIVE`=설치가 제거됨, `APP_RUNNER_UNAVAILABLE`=실행 환경 호출 실패");
5208
- /**
5209
- * 실패 원인 분류의 **현재** 값. 응답 스키마(`webhookFailureReasonSchema`)는 문자열로 열려 있다 —
5210
- * 서버가 값을 더해도 이전 SDK가 목록 파싱에 실패하지 않게 한다(택배 추적 `stage`와 같은 이유).
5211
- * 모르는 값은 `errorCode`로 판단한다.
5212
- */
5213
- const WEBHOOK_FAILURE_REASONS = [
5214
- "DNS",
5215
- "TLS",
5216
- "TIMEOUT",
5217
- "CONNECTION",
5218
- "HTTP_4XX",
5219
- "HTTP_5XX",
5220
- "HTTP_OTHER",
5221
- "SSRF_BLOCKED",
5222
- "SUSPENDED"
5223
- ];
5224
- const webhookFailureReasonSchema = z.string().describe("실패 원인 분류(진단용). 현재 값은 `DNS`=호스트 이름을 주소로 바꾸지 못함, `TLS`=인증서·핸드셰이크 실패, `TIMEOUT`=10초 안에 응답 없음, `CONNECTION`=연결 거부·끊김, `HTTP_4XX`·`HTTP_5XX`=그 대역의 응답, `HTTP_OTHER`=2xx·4xx·5xx가 아닌 응답(리다이렉트 등), `SSRF_BLOCKED`=사설·루프백 등 전송이 허용되지 않는 주소, `SUSPENDED`=구독 정지로 대기 중인 전송이 종료됨. `errorCode`보다 잘게 나눈 값이며 둘은 함께 쓸 수 있다. 값이 추가될 수 있으므로 모르는 값은 `errorCode`로 판단한다");
5153
+ //#endregion
5154
+ //#region src/schemas/customer.ts
5155
+ /** 구매자 목록 정렬 */
5156
+ const customerSortSchema = z.enum([
5157
+ "joined_desc",
5158
+ "joined_asc",
5159
+ "total_paid_desc",
5160
+ "order_count_desc",
5161
+ "last_ordered_desc"
5162
+ ]).describe("정렬. `joined_desc`(기본, 최근 가입순)·`joined_asc`·`total_paid_desc`(구매 금액순)·`order_count_desc`(주문 수순)·`last_ordered_desc`(최근 주문순)");
5163
+ /** `GET /v1/customers` 쿼리 */
5164
+ const customerListQuerySchema = z.object({
5165
+ q: z.string().optional().describe("검색어 — 이름·이메일(포함). 숫자 4자리면 휴대폰 뒤 4자리로도 찾는다"),
5166
+ joinedFrom: z.string().optional().describe("가입일 시작(YYYY-MM-DD, KST, 포함)"),
5167
+ joinedTo: z.string().optional().describe("가입일 끝(YYYY-MM-DD, KST, 포함)"),
5168
+ marketing: z.enum(["agreed", "declined"]).optional().describe("마케팅 수신 동의 필터. 생략하면 전체"),
5169
+ sort: customerSortSchema.optional(),
5170
+ ...pageQueryShape()
5171
+ });
5172
+ /** 구매 통계 — 구매 금액은 취소된 주문 상품을 빼고, 완료된 반품은 수량 비율로 뺀 금액이다 */
5173
+ const customerStatsSchema = z.object({
5174
+ orderCount: z.number().int().describe("주문 수(취소 포함)"),
5175
+ totalPaid: z.number().int().describe("구매 금액(원) — 취소·완료된 반품 제외"),
5176
+ lastOrderedAt: z.string().nullable().describe("최근 주문 시각")
5177
+ });
5178
+ /** 목록 행 — 휴대폰은 가운데를 가린다(`010-****-1234`) */
5179
+ const customerSummarySchema = z.object({
5180
+ customerId: z.string(),
5181
+ name: z.string(),
5182
+ /** 소셜 가입에서 이메일을 받지 못했으면 null */
5183
+ email: z.string().nullable(),
5184
+ maskedPhone: z.string().nullable(),
5185
+ joinedAt: z.string(),
5186
+ point: z.number().int(),
5187
+ marketingAgreed: z.boolean()
5188
+ }).extend(customerStatsSchema.shape);
5189
+ const customerAddressSchema = z.object({
5190
+ addressId: z.string(),
5191
+ alias: z.string(),
5192
+ isDefault: z.boolean(),
5193
+ receiverName: z.string(),
5194
+ phone: z.string(),
5195
+ zipCode: z.string(),
5196
+ address1: z.string(),
5197
+ address2: z.string().nullable()
5198
+ });
5199
+ /** 동의 종류 — 이용약관·개인정보 수집이용은 가입 필수, 마케팅 수신은 선택 */
5200
+ const consentKindSchema = z.enum([
5201
+ "TERMS",
5202
+ "PRIVACY",
5203
+ "MARKETING"
5204
+ ]);
5205
+ const consentActionSchema = z.enum(["AGREED", "WITHDRAWN"]);
5225
5206
  /**
5226
- * 대상 리소스 종류의 **현재** 값. 응답 스키마는 문자열로 열려 있다(새 이벤트가 새 리소스를 가리킬 수 있다).
5207
+ * 동의가 일어난 경로. 값이 추가될 수 있어 모르는 값은 그대로 보여 준다.
5208
+ * `SIGNUP` 비밀번호 가입 · `SOCIAL_SIGNUP` 소셜 가입 · `DELEGATED` 셀러 자체 회원 연동 ·
5209
+ * `RECONSENT` 약관 개정 재동의 · `MEMBER_UPDATE` 구매자가 직접 변경 · `SELLER` 셀러가 처리
5227
5210
  */
5228
- const WEBHOOK_RESOURCE_TYPES = [
5229
- "ORDER",
5230
- "CLAIM",
5231
- "PRODUCT",
5232
- "REVIEW",
5233
- "INQUIRY"
5234
- ];
5235
- const webhookResourceTypeSchema = z.string().describe("이벤트가 가리키는 리소스 종류. 현재 값은 `ORDER`·`CLAIM`·`PRODUCT`·`REVIEW`·`INQUIRY`이고 값이 추가될 수 있다");
5236
- /** 이벤트가 가리키는 대상 리소스 — 전송 기록을 주문·상품과 잇는 키 */
5237
- const webhookDeliveryResourceSchema = z.object({
5238
- type: webhookResourceTypeSchema,
5239
- id: z.string().describe("리소스 ID. 전송 기록 조회의 `resourceId`, API 로그 조회의 `q`로 그대로 넣을 수 있다")
5211
+ const consentSourceSchema = z.enum([
5212
+ "SIGNUP",
5213
+ "SOCIAL_SIGNUP",
5214
+ "DELEGATED",
5215
+ "RECONSENT",
5216
+ "MEMBER_UPDATE",
5217
+ "SELLER"
5218
+ ]);
5219
+ /** 동의 이력 한 줄 — 추가만 되고 지워지지 않는다(구매자 탈퇴 시에만 함께 지워진다) */
5220
+ const customerConsentSchema = z.object({
5221
+ consentId: z.string(),
5222
+ kind: consentKindSchema,
5223
+ /** 동의한 약관 버전. 마케팅은 버전이 없어 null */
5224
+ version: z.string().nullable(),
5225
+ /** 동의 시점의 약관 문서 주소. 상점이 주소를 정하지 않았거나 마케팅이면 null */
5226
+ documentUrl: z.string().nullable(),
5227
+ action: consentActionSchema,
5228
+ source: consentSourceSchema,
5229
+ occurredAt: z.string()
5240
5230
  });
5241
- /** 발송 요청 헤더 한 줄 (값 마스킹) */
5242
- const webhookRequestHeaderSchema = z.object({
5243
- name: z.string().describe("헤더 이름"),
5244
- value: z.string().nullable().describe("헤더 값. 서명(`Sayren-Signature`)처럼 비밀이 섞이는 헤더는 이름만 주고 값은 null이다")
5231
+ /** 종류별 현재 동의 상태 */
5232
+ const customerConsentStateSchema = z.object({
5233
+ kind: consentKindSchema,
5234
+ agreed: z.boolean(),
5235
+ /** 동의한 약관 버전. 마케팅이거나 이력이 없으면 null */
5236
+ agreedVersion: z.string().nullable(),
5237
+ /** 상점의 현재 약관 버전. 마케팅은 null */
5238
+ currentVersion: z.string().nullable(),
5239
+ /** 상점이 정한 현재 약관 문서 주소. 정하지 않았거나 마케팅이면 null */
5240
+ currentDocumentUrl: z.string().nullable(),
5241
+ updatedAt: z.string().nullable(),
5242
+ /** 약관이 개정돼 다시 받아야 하는가. 마케팅은 항상 false */
5243
+ reconsentRequired: z.boolean()
5245
5244
  });
5246
- /** 웹훅 전송 기록 한 건 (전송 기록 조회 항목) */
5247
- const webhookDeliverySchema = z.object({
5248
- deliveryId: z.string().describe("전송 기록 ID. 수신 요청의 `Sayren-Delivery-Id` 헤더 값"),
5249
- eventId: z.string().describe("이벤트 ID. 재시도·재전송해도 같은 이벤트면 같은 값이다. 수신 측 중복 제거 키로 쓴다"),
5250
- eventType: eventTypeSchema,
5251
- url: z.string().describe("전송 시점의 대상 URL"),
5252
- status: webhookDeliveryStatusSchema,
5253
- responseStatusCode: z.number().int().nullable().describe("마지막 시도의 HTTP 응답 코드. 미시도·연결 실패·타임아웃·차단이면 null"),
5254
- responseTimeMs: z.number().int().nullable().describe("마지막 시도의 응답 시간(ms). 미시도·연결 실패면 null"),
5255
- responseBodyExcerpt: z.string().nullable().describe("마지막 시도의 응답 본문 앞부분(최대 4,096자). 응답이 없으면 null. 가린 뒤에 자른다. 키 이름에 `authorization`·`token`·`secret`·`password`·`key`·`signature`·`credential`·`cookie`가 **들어 있으면**(부분 일치, 대소문자 무시. 예: `apiKey`·`access_token`·`keyword`) 그 값을 `***`로 가린다. 값이 객체·배열이면 통째로 가린다. 평문 `Authorization: …` 같은 헤더 줄, `Bearer <토큰>`, 쿼리 형식 `access_token=…`, 끝에서 잘려 닫히지 않은 값도 가린다"),
5256
- errorCode: webhookDeliveryErrorCodeSchema.nullable().describe("마지막 시도의 실패 사유. 성공했거나 미시도면 null"),
5257
- failureReason: webhookFailureReasonSchema.nullable().describe("마지막 시도의 실패 원인 분류. 성공했거나 미시도면 null. `errorCode`를 더 잘게 나눈 진단 값이다"),
5258
- resource: webhookDeliveryResourceSchema.nullable().describe("이벤트가 가리키는 대상 리소스. 리소스를 특정할 수 없는 이벤트면 null. 이 값으로 전송 기록(`resourceId`)과 API 로그(`q`)를 오갈 수 있다"),
5259
- attemptCount: z.number().int().min(0).describe("지금까지 전송을 시작한 횟수. 최초 시도 1회 + 재시도 최대 4회. 전송 도중 장애로 결과를 기록하지 못한 시도도 센다"),
5260
- createdAt: z.string().describe("전송 기록이 적재된 일시 (ISO 8601)"),
5261
- attemptedAt: z.string().nullable().describe("마지막 시도 일시 (ISO 8601). 미시도면 null"),
5262
- nextAttemptAt: z.string().nullable().describe("다음 시도 예정 일시 (ISO 8601). `PENDING`·`PENDING_RETRY`일 때만 값이 있다"),
5263
- redeliveryOf: z.string().nullable().describe("수동 재전송으로 생긴 기록이면 원본 전송 기록 ID. 아니면 null"),
5264
- redeliveredAs: z.string().nullable().describe("이 기록을 원본으로 수동 재전송해 생긴 기록의 전송 기록 ID. 아직 재전송하지 않았으면 null. 재전송은 원본당 1회다")
5245
+ const customerConsentsSchema = z.object({
5246
+ terms: customerConsentStateSchema,
5247
+ privacy: customerConsentStateSchema,
5248
+ marketing: customerConsentStateSchema,
5249
+ /** 필수 동의 중 하나라도 현재 버전이 아니면 true */
5250
+ reconsentRequired: z.boolean()
5265
5251
  });
5266
- /** 발송 본문 최대 노출 길이(바이트). 넘으면 잘라 주고 `payloadTruncated`가 true다 */
5267
- const WEBHOOK_PAYLOAD_EXCERPT_MAX_BYTES = 16384;
5268
- /** 웹훅 전송 기록 상세 — `GET /webhooks/{id}/deliveries/{deliveryId}`. 목록 항목 + 요청 본문·헤더 */
5269
- const webhookDeliveryDetailSchema = webhookDeliverySchema.extend({
5270
- payload: z.string().describe(`수신 서버로 보낸 요청 본문 그대로(JSON 문자열). 서명은 이 문자열을 대상으로 계산한다. 최대 ${WEBHOOK_PAYLOAD_EXCERPT_MAX_BYTES / 1024}KB까지 주고 넘으면 잘라 준다`),
5271
- payloadTruncated: z.boolean().describe("본문이 길어서 잘렸으면 true. true면 `payload`는 유효한 JSON이 아니다"),
5272
- payloadMasked: z.boolean().describe("민감 키 마스킹(`responseBodyExcerpt`와 같은 키 이름 규칙)이 본문을 바꿨으면 true. true면 `payload`는 보낸 본문과 달라 서명을 맞춰 볼 수 없다. 이벤트 본문에는 보통 민감 키가 없어 false다"),
5273
- requestHeaders: z.array(webhookRequestHeaderSchema).describe("발송 요청에 실은 헤더. 값은 전송 시점 그대로이나 서명 헤더는 이름만 주고 값은 null이다. `Content-Length`는 실제로 보낸 본문(마스킹·자르기 전)의 바이트 수다. 매 시도가 같은 헤더 집합을 쓰고 서명·타임스탬프만 달라진다")
5252
+ /** `GET /v1/customers/{id}/consents` 쿼리 — 최근 순이다 */
5253
+ const customerConsentListQuerySchema = z.object({
5254
+ kind: consentKindSchema.optional().describe("동의 종류 필터. 생략하면 전체"),
5255
+ ...pageQueryShape()
5274
5256
  });
5275
- /** 전송 기록 조회 쿼리 — `GET /webhooks/{id}/deliveries` */
5276
- const webhookDeliveryListQuerySchema = z.object({
5277
- status: webhookDeliveryStatusSchema.optional().describe("전송 상태 필터. 생략하면 전체"),
5278
- eventType: eventTypeSchema.optional().describe("이벤트 타입 필터. 생략하면 전체"),
5279
- resourceId: z.string().optional().describe("대상 리소스 ID 필터(정확히 일치). 주문·클레임·상품·리뷰·문의 id를 넣으면 그 리소스의 이벤트만 남는다. 같은 id로 API 로그를 `q`로 검색하면 그 리소스를 건드린 API 요청을 볼 수 있다"),
5280
- limit: z.coerce.number().int().min(1).max(100).optional().describe("최대 건수 (1~100, 기본 50). 최신 적재순으로 반환하며 보관 기간은 30일이다")
5257
+ /** 구매자 상세 — 휴대폰 전체를 보여 준다 */
5258
+ const customerDetailSchema = z.object({
5259
+ customerId: z.string(),
5260
+ name: z.string(),
5261
+ email: z.string().nullable(),
5262
+ phone: z.string().nullable(),
5263
+ joinedAt: z.string(),
5264
+ point: z.number().int(),
5265
+ marketingAgreed: z.boolean(),
5266
+ loginMethods: z.array(z.object({
5267
+ method: z.enum([
5268
+ "password",
5269
+ "kakao",
5270
+ "naver",
5271
+ "google"
5272
+ ]),
5273
+ /** 소셜 연결 시각. 비밀번호는 가입 시각 */
5274
+ linkedAt: z.string()
5275
+ })).describe("로그인 방법 — 이메일·비밀번호(`password`)와 연결된 소셜 계정"),
5276
+ consents: customerConsentsSchema.describe("약관·개인정보·마케팅 동의의 현재 상태. 이력은 `GET /v1/customers/{customerId}/consents`"),
5277
+ addresses: z.array(customerAddressSchema),
5278
+ stats: customerStatsSchema.extend({
5279
+ canceledOrReturnedCount: z.number().int().describe("취소된 주문 상품 + 완료된 반품 수"),
5280
+ reviewCount: z.number().int(),
5281
+ inquiryCount: z.number().int().describe("상품 문의 + 1:1 문의")
5282
+ })
5281
5283
  });
5282
- /** 실패 건 일괄 재전송 응답 — `POST /webhooks/{id}/deliveries/redeliver-failed` */
5283
- const webhookRedeliverFailedResultSchema = z.object({ queued: z.number().int().min(0).describe("재전송 대기열에 올린 건수. 최근 72시간의 `FAILED` 중 아직 재전송되지 않은 건이 대상이며 최대 500건이다") });
5284
- const webhookTestRequestSchema = z.object({ eventType: eventTypeSchema.describe("샘플 페이로드로 보낼 이벤트 타입") });
5285
- /** 테스트 이벤트 발송 결과 (동기 반환). 재시도·정지 판정·전송 기록이 없다 */
5286
- const webhookTestResultSchema = z.object({
5287
- responseStatusCode: z.number().int().nullable().describe("수신 서버의 HTTP 응답 코드. 연결 실패·타임아웃·차단이면 null"),
5288
- responseTimeMs: z.number().int().nullable().describe("응답 시간(ms). 연결 실패면 null"),
5289
- errorCode: webhookDeliveryErrorCodeSchema.nullable().describe("실패 사유. 2xx 응답이면 null"),
5290
- failureReason: webhookFailureReasonSchema.nullable().describe("실패 원인 분류. 2xx 응답이면 null"),
5291
- responseBodyExcerpt: z.string().nullable().describe("응답 본문 앞부분(최대 4,096자). 규칙은 전송 기록의 `responseBodyExcerpt`와 같다. 응답이 없으면 null"),
5292
- requestHeaders: z.array(webhookRequestHeaderSchema).describe("보낸 요청 헤더. 서명 헤더는 이름만 주고 값은 null이다"),
5293
- payload: z.string().describe("보낸 요청 본문 그대로(JSON 문자열). 샘플 이벤트다")
5284
+ /** 구매자의 주문 — 전체 기간 */
5285
+ const customerOrderSchema = z.object({
5286
+ orderId: z.string(),
5287
+ orderedAt: z.string(),
5288
+ totalAmount: z.number().int().describe("결제 금액"),
5289
+ testPayment: z.boolean(),
5290
+ items: z.array(z.object({
5291
+ orderItemId: z.string(),
5292
+ productName: z.string(),
5293
+ optionName: z.string().nullable(),
5294
+ quantity: z.number().int(),
5295
+ status: orderItemStatusSchema,
5296
+ claimStatus: z.enum([
5297
+ "CANCEL_REQUESTED",
5298
+ "RETURN_REQUESTED",
5299
+ "EXCHANGE_REQUESTED"
5300
+ ]).nullable()
5301
+ }))
5294
5302
  });
5295
- const webhookRequestSchema = z.object({
5296
- url: z.url().startsWith("https://", "웹훅 URL은 HTTPS만 허용됩니다"),
5297
- eventTypes: z.array(eventTypeSchema).min(1)
5303
+ /** `POST /v1/customers/{id}/withdraw` 본문 */
5304
+ const withdrawCustomerRequestSchema = z.object({
5305
+ reason: z.enum([
5306
+ "BUYER_REQUEST",
5307
+ "DORMANT",
5308
+ "ABUSE",
5309
+ "OTHER"
5310
+ ]).describe("처리 사유 — 구매자 요청·장기 미이용·부정 이용·기타. 감사 로그에 남는다"),
5311
+ memo: z.string().max(200).optional().describe("사유 보충(선택)")
5298
5312
  });
5299
- const reviewSchema = z.object({
5300
- reviewId: z.string(),
5301
- productId: z.string(),
5302
- productName: z.string(),
5303
- orderItemId: z.string(),
5304
- optionName: z.string().nullable(),
5305
- rating: z.number().int().min(1).max(5),
5306
- content: z.string(),
5307
- images: z.array(z.url()),
5308
- writerMaskedName: z.string(),
5309
- blinded: z.boolean(),
5310
- reply: z.object({
5311
- content: z.string(),
5312
- repliedAt: z.string(),
5313
- updatedAt: z.string().nullable()
5314
- }).nullable(),
5315
- createdAt: z.string()
5313
+ /** `WITHDRAWAL_BLOCKED`의 `error.details` — 탈퇴를 막는 항목 수(스토어프론트 탈퇴와 같다) */
5314
+ const customerWithdrawalBlockedDetailsSchema = z.object({
5315
+ inProgressOrderItems: z.number().int(),
5316
+ openClaims: z.number().int(),
5317
+ pendingPayments: z.number().int()
5316
5318
  });
5317
- const reviewSortSchema = z.enum([
5318
- "createdAt.desc",
5319
- "createdAt.asc",
5320
- "rating.asc",
5321
- "rating.desc"
5319
+ //#endregion
5320
+ //#region src/schemas/login.ts
5321
+ /** 소셜 로그인 공급자 */
5322
+ const loginProviderSchema = z.enum([
5323
+ "kakao",
5324
+ "naver",
5325
+ "google"
5322
5326
  ]);
5323
- /** `GET /v1/reviews` 쿼리 — OpenAPI 문서용 형태(값은 쿼리 문자열) */
5324
- const reviewListQuerySchema = z.object({
5325
- productId: z.string().optional().describe("상품 id 필터"),
5326
- rating: z.enum([
5327
- "1",
5328
- "2",
5329
- "3",
5330
- "4",
5331
- "5"
5332
- ]).optional().describe("별점 필터 (일치)"),
5333
- replied: z.enum(["true", "false"]).optional().describe("답글 여부 필터. `true`면 답글 단 리뷰만, `false`면 답글 없는 리뷰만"),
5334
- hasImage: z.enum(["true", "false"]).optional().describe("`true`면 이미지가 있는 리뷰만"),
5335
- from: z.string().optional().describe("작성 시각 조회 시작 (ISO 8601, 포함)"),
5336
- sort: reviewSortSchema.optional().describe("정렬 (기본 createdAt.desc)"),
5337
- ...pageQueryShape()
5327
+ /** 공급자 연결 상태 — 비밀 값은 앞 4자리만 */
5328
+ const loginProviderStatusSchema = z.object({
5329
+ provider: loginProviderSchema,
5330
+ connected: z.boolean(),
5331
+ /** 스토어프론트에서 사용 중인지. 연결 안 됐으면 false */
5332
+ enabled: z.boolean(),
5333
+ clientIdPrefix: z.string().nullable().describe("클라이언트 ID(카카오 REST API 키) 앞 4자리"),
5334
+ secretPrefix: z.string().nullable(),
5335
+ lastTestedAt: z.string().nullable(),
5336
+ lastTestOk: z.boolean().nullable(),
5337
+ linkedMemberCount: z.number().int().describe("이 공급자로 연결된 구매자 수"),
5338
+ /** 이 공급자로만 로그인하는 구매자 수 — 연결을 해제하면 로그인할 방법이 없어진다 */
5339
+ onlyMethodMemberCount: z.number().int(),
5340
+ callbackUrl: z.url().describe("공급자 개발자 콘솔에 등록할 리디렉트 URI")
5338
5341
  });
5339
- /** `POST /v1/reviews/{reviewId}/report` 응답(202) — 신고 접수 */
5340
- const reviewReportResultSchema = z.object({
5341
- reviewId: z.string(),
5342
- status: z.literal("PENDING_REVIEW")
5342
+ /** `GET /v1/store/login-settings` */
5343
+ const loginSettingsSchema = z.object({
5344
+ passwordLoginEnabled: z.boolean(),
5345
+ /** 비밀번호로만 로그인하는 구매자 수 — 이메일·비밀번호를 끄면 이들은 로그인할 수 없다 */
5346
+ passwordOnlyMemberCount: z.number().int(),
5347
+ storefrontOrigins: z.array(z.string()),
5348
+ providers: z.array(loginProviderStatusSchema)
5349
+ });
5350
+ /** `PATCH /v1/store/login-settings` */
5351
+ const updateLoginSettingsRequestSchema = z.object({ passwordLoginEnabled: z.boolean() });
5352
+ /** `PUT /v1/store/auth-providers/{provider}` — 저장 전에 연결 테스트를 한다 */
5353
+ const saveLoginProviderRequestSchema = z.object({
5354
+ clientId: z.string().trim().min(1).max(200),
5355
+ clientSecret: z.string().trim().min(1).max(500)
5356
+ });
5357
+ /** `PATCH /v1/store/auth-providers/{provider}` */
5358
+ const updateLoginProviderRequestSchema = z.object({ enabled: z.boolean() });
5359
+ /** 연결 테스트 결과 */
5360
+ const loginProviderTestSchema = z.object({
5361
+ ok: z.boolean(),
5362
+ /** 실패 이유 — `INVALID_CLIENT`(키가 틀림)·`PROVIDER_UNAVAILABLE`(공급자 응답 없음) */
5363
+ code: z.enum(["INVALID_CLIENT", "PROVIDER_UNAVAILABLE"]).nullable(),
5364
+ testedAt: z.string()
5343
5365
  });
5344
5366
  //#endregion
5345
5367
  //#region src/schemas/payment.ts
@@ -8519,6 +8541,10 @@ get: (params) => storeHttp.request("GET", "/sales-report", salesReportSchema, {
8519
8541
  /** 비밀 필드를 생략하면 현재 값을 유지한다. null은 비운다 */
8520
8542
  updateSettings: (installationId, body) => storeHttp.request("PUT", path`/apps/installations/${installationId}/settings`, appInstallationSchema, { body: appInstallationSettingsUpdateSchema.parse(body) }),
8521
8543
  remove: (installationId) => storeHttp.requestVoid("DELETE", path`/apps/installations/${installationId}`),
8544
+ /** 실행 기록 — 최근 이벤트 전송 결과와 최근 7일 관리 API 호출 수 */
8545
+ activity: (installationId) => storeHttp.request("GET", path`/apps/installations/${installationId}/activity`, appInstallationActivitySchema),
8546
+ /** 권한 업데이트 동의 — 넓어진 새 버전(`pendingVersion`)으로 옮긴다(상점 플랫폼 전용) */
8547
+ consent: (installationId) => storeHttp.request("POST", path`/apps/installations/${installationId}/consent`, appInstallationSchema),
8522
8548
  /** 앱 화면 iframe에 넘길 세션 토큰(5분) */
8523
8549
  session: (installationId) => storeHttp.request("POST", path`/apps/installations/${installationId}/session`, appSessionSchema)
8524
8550
  }
@@ -9230,4 +9256,4 @@ function createStoreSession(options) {
9230
9256
  };
9231
9257
  }
9232
9258
  //#endregion
9233
- export { APPROVAL_ALREADY_DECIDED_CODE, APPROVAL_REQUIRED_CODE, APP_CAPABILITIES, APP_DEPLOY_KEY_PATTERN, APP_DEPLOY_KEY_PREFIX, APP_EVENTS_MAX, APP_EVENT_SCOPES, APP_EVENT_TYPES, APP_HANDLE_PATTERN, APP_ICON_CONTENT_TYPES, APP_ICON_MAX_BYTES, APP_ICON_MIN_PX, APP_LIFECYCLE_EVENT_TYPES, APP_NETWORK_DENIED_SUFFIXES, APP_NETWORK_HOSTS_MAX, APP_README_MAX_BYTES, APP_RESERVED_HANDLES, APP_SECRETS_MAX, APP_SECRET_NAME_PATTERN, APP_SECRET_PATTERNS, APP_SERVER_BUNDLE_MAX_GZIP_BYTES, APP_SETTINGS_MAX_FIELDS, APP_SETTING_FIELD_TYPES, APP_SETTING_KEY_PATTERN, APP_UI_MAX_BYTES, APP_UI_MAX_FILES, ApiError, ApprovalPendingError, BRAND_BRIEF_MAX_REFERENCES, BUSINESS_INFO_MAX_LENGTH, BUSINESS_NUMBER_PATTERN, CASH_RECEIPT_STATUS_VALUES, COLLECTION_BEST_SELLING_DAYS, COLLECTION_PREVIEW_SIZE, COLLECTION_PRODUCT_SORTS, COLLECTION_SALES_SORT_DEFAULT_DAYS, COLLECTION_SLUG_PATTERN, COLLECTION_TYPES, COUPON_CODE_PATTERN, COUPON_CONDITIONS_DEFAULTS, COUPON_TARGET_ALL, COUPON_TARGET_LIST_MAX, CUSTOM_INPUT_FORBIDDEN_WORDS, CUSTOM_INPUT_TYPES, FULFILLMENT_METHODS, FULFILLMENT_METHODS_BY_TYPE, FULFILLMENT_METHOD_RULES, FULFILLMENT_RULES, INSTALLABLE_SCOPES, KNOWN_WEBHOOK_EVENT_TYPES, MAX_ADDON_GROUPS, MAX_ANALYTICS_ALLOWED_ORIGINS, MAX_AUTO_TRANSITION_DAYS, MAX_CALENDAR_DAYS, MAX_COLLECTIONS, MAX_COLLECTION_BEST_SELLING_TOP, MAX_COLLECTION_CREATED_WITHIN_DAYS, MAX_COLLECTION_DESCRIPTION, MAX_COLLECTION_PRODUCTS, MAX_COLLECTION_PRODUCTS_PER_ADD, MAX_COLLECTION_RULES, MAX_COLLECTION_RULE_CATEGORIES, MAX_COLLECTION_TITLE, MAX_CUSTOM_INPUTS, MAX_CUSTOM_INPUT_LENGTH, MAX_OPTION_GROUPS, MAX_PICKUP_LOCATIONS, MAX_PRODUCT_IMAGES, MAX_SAVED_OPTION_SETS, MAX_SAVED_OPTION_SET_NAME, MAX_STAY_NIGHTS, MAX_VALUES_PER_GROUP, MAX_VARIANTS, MCP_TELEMETRY_MAX_RESULTS, MIN_PAYMENT_AMOUNT, NON_INSTALLABLE_SCOPES, NO_COUPON_SETTLEMENT, NO_SHIPPING_BUNDLE_KEY, PAYMENT_ROUTING_EXCLUSION_CODES, POINT_ADJUSTMENT_MAX, POINT_EARN_RATE_BP_MAX, POINT_ENTRY_TYPES, POINT_EXPIRY_DAYS_MAX, POINT_EXPIRY_DAYS_MIN, POINT_LOT_SOURCES, POINT_POLICY_DEFAULTS, POINT_REVIEW_REWARD_MAX, POINT_USE_UNITS, PORTONE_CHANNEL_NAME_MAX_LENGTH, PORTONE_MAX_CHANNELS, PORTONE_MIN_CHANNELS, REFUND_POLICY_DEFAULTS, REFUND_POLICY_DELIVERY_FEE_KEYS, REMOTE_AREA_ZIP_RANGES, RESERVED_STOREFRONT_SLUGS, RESERVED_STORE_CODES, SCOPE_DESCRIPTIONS, SHIPPING_POLICY_DEFAULTS, STARTER_SELLER_TASKS, STARTER_STAGES, STOREFRONT_BLOCKED_PATH_SEGMENTS, STOREFRONT_BUILD_STAGES, STOREFRONT_BUILD_TERMINAL_STATUSES, STOREFRONT_CHECK_TERMINAL_STATUSES, STOREFRONT_CLOSED_SITE_HOLD_DAYS, STOREFRONT_CUSTOM_DOMAIN_LIMIT_DEFAULT, STOREFRONT_DOMAIN_DNS_GRACE_DAYS, STOREFRONT_DOMAIN_DNS_WAIT_DAYS, STOREFRONT_DOMAIN_TXT_LABEL, STOREFRONT_EDIT_ACTIVITY_TIMEOUT_MINUTES, STOREFRONT_EDIT_CAPACITY, STOREFRONT_EDIT_IDLE_MINUTES, STOREFRONT_EDIT_PREVIEW_SUFFIX, STOREFRONT_EDIT_START_STAGES, STOREFRONT_FILE_BATCH_MAX, STOREFRONT_FILE_MAX_BYTES, STOREFRONT_PATH_SEGMENT_PATTERN, STOREFRONT_PLATFORM_DOMAINS, STOREFRONT_PUBLIC_SUFFIXES, STOREFRONT_SEARCH_REGEX_MAX_LENGTH, STOREFRONT_SHOWCASE_SLUG_PREFIX, STOREFRONT_SITE_CREATE_LIMIT, STOREFRONT_SLUG_CHANGE_LIMIT, STOREFRONT_SLUG_CHANGE_WINDOW_DAYS, STOREFRONT_SLUG_HOLD_DAYS, STOREFRONT_SLUG_PATTERN, STOREFRONT_SOURCE_BLOB_BATCH_MAX, STOREFRONT_SOURCE_PART_BYTES, STOREFRONT_WORKSPACE_MAX_BYTES, STOREFRONT_WORKSPACE_MAX_FILES, STORE_CODE_PATTERN, STORE_ROLE_SCOPES, STORE_SCOPE_RESOURCES, STORE_SESSION_KEYS, TEMPLATE_STORE_LOCKED_BUSINESS_FIELDS, TOSS_WIDGET_CLIENT_KEY_PATTERN, TOSS_WIDGET_KEY_MESSAGE, TOSS_WIDGET_SECRET_KEY_PATTERN, UPLOAD_PURPOSE_LIMITS, VARIANT_COUNT_WARNING, VARIANT_STOCK_EXCLUSIVE_MESSAGE, WEBHOOK_DEFAULT_TOLERANCE_SEC, WEBHOOK_DELIVERY_ID_HEADER, WEBHOOK_EVENT_ID_HEADER, WEBHOOK_EVENT_TYPE_HEADER, WEBHOOK_FAILURE_REASONS, WEBHOOK_HEADERS, WEBHOOK_PAYLOAD_EXCERPT_MAX_BYTES, WEBHOOK_RESOURCE_TYPES, WEBHOOK_SIGNATURE_HEADER, WEBHOOK_USER_AGENT, addStorefrontDomainRequestSchema, addonGroupRequestSchema, addonGroupSchema, addonValueRequestSchema, addonValueSchema, addressChangeRequestListSchema, addressTypeSchema, agentPolicyDecisionSchema, allocateByWeight, analyticsChannelSchema, analyticsCheckoutOutcomeSchema, analyticsCheckoutSchema, analyticsDeviceRowSchema, analyticsDevicesSchema, analyticsFunnelStepSchema, analyticsOriginSchema, analyticsOverviewSchema, analyticsPagesQuerySchema, analyticsPagesSchema, analyticsProductRowSchema, analyticsProductSortSchema, analyticsProductsQuerySchema, analyticsProductsSchema, analyticsRangeQuerySchema, analyticsRealtimeSchema, analyticsSearchQuerySchema, analyticsSearchSchema, analyticsSourceGroupBySchema, analyticsSourceRowSchema, analyticsSourcesQuerySchema, analyticsSourcesSchema, analyticsTotalsSchema, apiLogErrorSchema, apiLogListQuerySchema, apiLogPageSchema, apiLogPrincipalSchema, apiLogPrincipalTypeSchema, apiLogSchema, apiLogStatusFilterSchema, apiLogSummarySchema, appArtifactUploadSchema, appBuildSchema, appBuildStageSchema, appCapabilitiesOf, appDeployKeyCreateSchema, appDeployKeyCreatedSchema, appDeployKeySchema, appDevTokenSchema, appDistributionSchema, appEventTypeSchema, appHandleSchema, appIconProblem, appInstallRequestSchema, appInstallationAppSchema, appInstallationSchema, appInstallationSelfSchema, appInstallationSettingsSchema, appInstallationSettingsUpdateSchema, appInstallationStatusSchema, appInvocationSchema, appListingSchema, appManifestProblems, appManifestSchema, appManifestWidens, appNetworkHostProblem, appNetworkHostSchema, appReleaseResultSchema, appRuntimeSchema, appScopeSchema, appSecretSummarySchema, appSessionSchema, appSettingFieldSchema, appStatusSchema, appVersionSchema, appVersionStatusSchema, approvalDecisionRequestSchema, approvalListQuerySchema, approvalPageSchema, approvalRequestSchema, approvalStatusSchema, approveClaimResultSchema, auditActorSchema, auditActorTypeSchema, auditLogListQuerySchema, auditLogOutcomeSchema, auditLogPageSchema, auditLogSchema, auditLogSourceSchema, bestSellingRuleOf, brandBriefProductSourceSchema, brandBriefReferenceSchema, brandBriefSchema, brandBriefViewSchema, buildAuthorizeUrl, buildQuery, bulkResultSchema, businessInfoPatchShape, businessInfoResponseShape, businessNumberSchema, calendarDateSchema, calendarDaySchema, calendarQuerySchema, cancelBySellerRequestSchema, cancelBySellerResultSchema, carrierSchema, cashReceiptSchema, categoryAttributeSchema, categoryCreateRequestSchema, categoryDeleteQuerySchema, categoryDeleteStrategySchema, categoryListQuerySchema, categoryPatchRequestSchema, categoryProductSortSchema, categorySchema, categorySearchResultSchema, categoryTreeNodeSchema, categoryWithPathSchema, changeStorefrontSlugRequestSchema, changeStorefrontTemplateRequestSchema, changeTypeSchema, claimDetailSchema, claimHoldResultSchema, claimListQuerySchema, claimReasonSchema, claimReturnAddressSchema, claimSchema, claimStatusSchema, claimTypeSchema, claimWebhookEventDataSchema, claimWebhookEventSchema, collectionCreateRequestSchema, collectionListQuerySchema, collectionPageSchema, collectionPatchRequestSchema, collectionPreviewRequestSchema, collectionPreviewSchema, collectionProductListQuerySchema, collectionProductSchema, collectionProductSortRequestSchema, collectionProductsAddRequestSchema, collectionProductsReplaceRequestSchema, collectionRuleCategoryIds, collectionRuleSchema, collectionRuleViewSchema, collectionRulesPredicate, collectionRulesSchema, collectionSchema, collectionStateCountsSchema, collectionStateOf, collectionStateSchema, commerceFlowCheckSchema, commerceFlowSchema, commerceFlowSummarySchema, commerceFlowVersionViewSchema, commerceNumberField, compareBySales, consentActionSchema, consentKindSchema, consentSourceSchema, couponBenefitSchema, couponConditionsInputSchema, couponConditionsSchema, couponDiscountOf, couponIssueListQuerySchema, couponIssueMethodSchema, couponIssueSchema, couponIssueStatusSchema, couponKindSchema, couponListQuerySchema, couponRedemptionListQuerySchema, couponRedemptionSchema, couponRejectReasonSchema, couponRuleSchema, couponSchema, couponStatsSchema, couponStatusSchema, couponTargetInputSchema, couponTargetSchema, createCommerceFlowRequestSchema, createCouponRequestSchema, createPkcePair, createStoreClient, createStoreSession, createStorefrontEditPreviewLinkRequestSchema, createStorefrontPreviewLinkRequestSchema, createStorefrontSiteRequestSchema, createStorefrontVersionRequestSchema, customInputLabelForbiddenWord, customInputRequestSchema, customInputSchema, customInputValueSchema, customerAddressSchema, customerConsentListQuerySchema, customerConsentSchema, customerConsentStateSchema, customerConsentsSchema, customerCouponSchema, customerDelegationRequestSchema, customerDelegationSchema, customerDetailSchema, customerInquiryCategorySchema, customerInquiryListQuerySchema, customerListQuerySchema, customerOrderSchema, customerPointsSchema, customerSortSchema, customerStatsSchema, customerSummarySchema, customerWithdrawalBlockedDetailsSchema, defaultFulfillmentMethodOf, deleteStorefrontFileRequestSchema, deliveryBundleKeyOf, deliveryFeeWaiverSchema, deliveryInfoSchema, deliveryMethodSchema, deliveryStatusSchema, deliveryTypeSchema, descendantCategoryIdsOf, describeScope, devStoreSchema, developerAppCreateSchema, developerAppSchema, developerInstallationSchema, developerOrgSchema, disableStorefrontHostingRequestSchema, discountRequestSchema, discountSchema, dispatchRequestSchema, easyPayProviderResponseSchema, easyPayProviderSchema, eventTypeSchema, exchangeAuthorizationCode, flowActionRequestSchema, flowActionResultSchema, flowActionSchema, flowFieldValueSchema, flowInputFieldSchema, flowNodeTypesSchema, flowNotificationWebhookEventDataSchema, flowNotificationWebhookEventSchema, flowPresetDetailSchema, flowPresetSummarySchema, flowRunSchema, flowRunStepSchema, flowSecretNameSchema, flowSecretSchema, flowStateChangedWebhookEventDataSchema, flowStateChangedWebhookEventSchema, flowStateSchema, formatOrderNo, fulfillBulkRequestSchema, fulfillRequestSchema, fulfillmentMethodOf, fulfillmentMethodSchema, fulfillmentMethodsOf, fulfillmentRuleOf, fulfillmentTypeOf, fulfillmentTypeResponseSchema, fulfillmentTypeSchema, holdOrderItemRequestSchema, inquiryListQuerySchema, inquirySchema, inquiryWebhookEventDataSchema, inquiryWebhookEventSchema, inventoryModeSchema, invitationDeliveryStatusSchema, invitationListQuerySchema, invitationSchema, inviteMemberRequestSchema, isCouponTargetLine, isEditableStorefrontPath, isInstallableScope, isReservedStoreCode, isReservedStorefrontSlug, isShowcaseStorefrontSlug, isStoreScope, isWebOrigin, issueCouponRequestSchema, issueCouponResultSchema, liveGateConditionCodeSchema, liveGateConditionSchema, liveGateErrorDetailsSchema, liveGateSchema, loginProviderSchema, loginProviderStatusSchema, loginProviderTestSchema, loginSettingsSchema, maskedSecretSchema, matchesCollectionRules, mcpRuleResultSchema, mcpToolEventSchema, migrateFlowVersionRequestSchema, migrateFlowVersionResultSchema, moveFlowStateRequestSchema, moveStorefrontFileRequestSchema, myAccountSchema, myStoreSchema, nightsOf, normalizeBusinessNumber, normalizeCouponCode, normalizeStorefrontHostname, normalizeStorefrontPath, oauthTokenResponseSchema, openFulfillmentUnion, optionGroupKindSchema, optionGroupRequestSchema, optionGroupSchema, optionModelRequestSchema, optionModelSchema, optionSelectionSchema, optionSortSchema, optionValueRequestSchema, optionValueSchema, orderCanceledWebhookEventDataSchema, orderCanceledWebhookEventSchema, orderDiscountSchema, orderFlowActionResultSchema, orderFulfilledWebhookEventDataSchema, orderFulfilledWebhookEventSchema, orderItemFlowSchema, orderItemFulfillmentSchema, orderItemFulfillmentSnapshotResponseSchema, orderItemFulfillmentSnapshotSchema, orderItemListQuerySchema, orderItemMemoResultSchema, orderItemPageSchema, orderItemSchema, orderItemStatusSchema, orderListQuerySchema, orderSchema, orderSummaryPageSchema, orderSummarySchema, orderWebhookEventDataSchema, orderWebhookEventSchema, pageInfoSchema, pageQueryShape, pageSchema, parseOrderNo, parseWebhookEvent, paymentAttemptRecordSchema, paymentAttemptStatusSchema, paymentCredentialSetSchema, paymentFailureWarningSchema, paymentListQuerySchema, paymentProviderSchema, paymentProviderVerificationSchema, paymentRecordDetailSchema, paymentRecordPageSchema, paymentRecordSchema, paymentRecordStatusSchema, paymentRefundRecordSchema, paymentSettingsSchema, pgEnvironmentSchema, pgPaymentMethodSchema, pgProviderSchema, pgVerificationResultSchema, pickupLocationRequestSchema, pickupLocationSchema, pickupLocationSnapshotSchema, planCodeSchema, planEntitlementsSchema, planErrorDetailsSchema, pointAdjustmentRequestSchema, pointAdjustmentResultSchema, pointEarnOf, pointEarnRateBpSchema, pointEarningEnabled, pointEntrySchema, pointExpiresAtOf, pointHistoryQuerySchema, pointLotSchema, pointPolicyNoticeSchema, pointPolicySchema, pointRestoreExpiresAtOf, pointUseOf, pointUsePolicySchema, policyDocumentUrlSchema, policyVersionSchema, portOneChannelSchema, portOneCredentialsInputSchema, productCreateRequestSchema, productFulfillmentCreateSchema, productFulfillmentResponseSchema, productFulfillmentSchema, productFulfillmentUpdateSchema, productImageRejection, productImageUrlSchema, productListQuerySchema, productOutOfStockWebhookEventDataSchema, productOutOfStockWebhookEventSchema, productPatchRequestSchema, productRefundPolicyOverride, productRefundPolicyPatchSchema, productReplaceRequestSchema, productSchema, productSortSchema, productStatusSchema, productSummarySchema, productVariantRequestSchema, productVariantSchema, proratedPaidRefundBase, proratedPointRefund, proratedRefundBase, publicPlanSchema, publicPlansSchema, publishStorefrontVersionRequestSchema, purchaseDecisionExtendResultSchema, purchaseDecisionRequestResultSchema, purchaseEarnPolicySchema, purchaseEarnRateOf, putBrandBriefRequestSchema, quoteDelivery, quotePricing, rankBestSelling, refreshUserToken, refundPolicyPatchSchema, refundPolicySchema, rejectClaimRequestSchema, remoteAreaLabelOf, remoteAreaOf, remoteAreaSchema, remoteSurchargeOf, replaceStorefrontSourceRequestSchema, replayFlowRequestSchema, replayFlowResultSchema, requiresCollection, requiresShipping, resolvePointPolicy, resolveRefundPolicy, resolveShippingPolicy, resolvedFlowSchema, responsePlanCodeSchema, responsePointEntryTypeSchema, reviewListQuerySchema, reviewReportResultSchema, reviewRewardPointOf, reviewRewardPolicySchema, reviewSchema, reviewSortSchema, reviewWebhookEventDataSchema, reviewWebhookEventSchema, rollbackStorefrontRequestSchema, runStorefrontCheckRequestSchema, salesReportGroupBySchema, salesReportQuerySchema, salesReportRowSchema, salesReportSchema, salesTotalsSchema, saveFlowDraftRequestSchema, saveFlowSecretRequestSchema, saveLoginProviderRequestSchema, savedCustomInputRequestSchema, savedCustomInputSchema, savedOptionGroupRequestSchema, savedOptionGroupSchema, savedOptionSetCompositionSchema, savedOptionSetFromProductRequestSchema, savedOptionSetFromProductResultSchema, savedOptionSetListQuerySchema, savedOptionSetRequestSchema, savedOptionSetSchema, savedOptionSetSortSchema, savedOptionValueRequestSchema, savedOptionValueSchema, scopeAccessSchema, scopesCoverEvent, searchStorefrontFilesRequestSchema, sellerAddressListQuerySchema, sellerAddressRequestSchema, sellerAddressSchema, sellerCancelPreviewSchema, sellerCustomerInquirySchema, setCalendarRequestSchema, setStorefrontVisibilityRequestSchema, settleCouponShortfall, settlementDetailQuerySchema, settlementDetailSchema, settlementListQuerySchema, settlementStatusSchema, settlementSummarySchema, settlementWithDetailsSchema, shippingAddressSchema, shippingPolicyPatchSchema, shippingPolicySchema, simulateFlowRequestSchema, simulateFlowResultSchema, simulationStepSchema, splitRefund, starterSellerTaskSchema, starterStageSchema, starterStatusSchema, starterStoreInfoFieldSchema, stayRangeSchema, staySnapshotSchema, storeAppDetailSchema, storeAppSchema, storeCodeSchema, storeIndustrySchema, storeMemberRoleUpdatedSchema, storeMemberSchema, storePointPolicySchema, storeRoleSchema, storeSchema, storeScopeResourceSchema, storeSubscriptionSchema, storeTemplateSchema, storefrontBuildDependenciesSchema, storefrontBuildListQuerySchema, storefrontBuildSchema, storefrontBuildStatusSchema, storefrontCheckSchema, storefrontCheckStatusSchema, storefrontCustomDomainStatusSchema, storefrontCustomHostnameProblem, storefrontDependencyFindingSchema, storefrontDeploymentLogSchema, storefrontDeploymentSchema, storefrontDeploymentStepSchema, storefrontDnsRecordSchema, storefrontDomainSchema, storefrontDomainTxtNameOf, storefrontEditPreviewLabelOf, storefrontEditPreviewSchema, storefrontEditSessionSchema, storefrontEditSessionStatusSchema, storefrontEditingSchema, storefrontFileConflictDetailsSchema, storefrontFileContentQuerySchema, storefrontFileContentSchema, storefrontFileDeleteResultSchema, storefrontFileEncodingSchema, storefrontFileEntrySchema, storefrontFileHashSchema, storefrontFileListQuerySchema, storefrontFileListSchema, storefrontFileMoveResultSchema, storefrontFilePathSchema, storefrontFileSearchResultSchema, storefrontFileWriteResultSchema, storefrontHostingSchema, storefrontPreviewLinkSchema, storefrontProvisioningSchema, storefrontRuleResultSchema, storefrontRuleSeveritySchema, storefrontSiteDomainSchema, storefrontSiteDomainsSchema, storefrontSiteSchema, storefrontSiteSnapshotSchema, storefrontSiteStatusSchema, storefrontSlugAvailabilityQuerySchema, storefrontSlugAvailabilitySchema, storefrontSlugSchema, storefrontSourceArchivePartSchema, storefrontSourceArchiveQuerySchema, storefrontSourceBlobsResultSchema, storefrontSourceModeSchema, storefrontSourceRefSchema, storefrontSourceReplacedSchema, storefrontSourceSchema, storefrontSuspensionSchema, storefrontTemplateSchema, storefrontVerifyReportSchema, storefrontVersionCreatedSchema, storefrontVersionSchema, storefrontVersionStatusSchema, storefrontVisibilitySchema, subscriptionLimitsSchema, subscriptionStatusSchema, subscriptionUsageSchema, tossPaymentsCredentialsInputSchema, trackingStageResponseSchema, trackingUpdateResultSchema, unknownWebhookEventSchema, updateCouponRequestSchema, updateLoginProviderRequestSchema, updateLoginSettingsRequestSchema, updateMemberRoleRequestSchema, updatePaymentProviderRequestSchema, updatePaymentSettingsRequestSchema, updatePointPolicyRequestSchema, updateStoreRequestSchema, updateStoreTemplateRequestSchema, uploadExtensionOf, uploadPurposeSchema, uploadRejection, uploadRequestSchema, uploadStorefrontSourceBlobsRequestSchema, uploadTicketSchema, upsertPortOneProviderRequestSchema, upsertTossPaymentsProviderRequestSchema, variantStockRequestSchema, variantStockSchema, verifyPaymentProviderRequestSchema, webhookCreatedSchema, webhookDeliveryDetailSchema, webhookDeliveryErrorCodeSchema, webhookDeliveryListQuerySchema, webhookDeliveryResourceSchema, webhookDeliverySchema, webhookDeliveryStatusSchema, webhookEventSchema, webhookFailureReasonSchema, webhookRedeliverFailedResultSchema, webhookRequestHeaderSchema, webhookRequestSchema, webhookResourceTypeSchema, webhookSchema, webhookSecretRotatedSchema, webhookStatusSchema, webhookTestRequestSchema, webhookTestResultSchema, withdrawCustomerRequestSchema, writeDryRunResultSchema, writePreviewSchema, writeStorefrontFilesRequestSchema };
9259
+ export { APPROVAL_ALREADY_DECIDED_CODE, APPROVAL_REQUIRED_CODE, APP_CAPABILITIES, APP_DEPLOY_KEY_PATTERN, APP_DEPLOY_KEY_PREFIX, APP_EVENTS_MAX, APP_EVENT_SCOPES, APP_EVENT_TYPES, APP_HANDLE_PATTERN, APP_ICON_CONTENT_TYPES, APP_ICON_MAX_BYTES, APP_ICON_MIN_PX, APP_LIFECYCLE_EVENT_TYPES, APP_NETWORK_DENIED_SUFFIXES, APP_NETWORK_HOSTS_MAX, APP_README_MAX_BYTES, APP_RESERVED_HANDLES, APP_SECRETS_MAX, APP_SECRET_NAME_PATTERN, APP_SECRET_PATTERNS, APP_SERVER_BUNDLE_MAX_GZIP_BYTES, APP_SETTINGS_MAX_FIELDS, APP_SETTING_FIELD_TYPES, APP_SETTING_KEY_PATTERN, APP_UI_MAX_BYTES, APP_UI_MAX_FILES, ApiError, ApprovalPendingError, BRAND_BRIEF_MAX_REFERENCES, BUSINESS_INFO_MAX_LENGTH, BUSINESS_NUMBER_PATTERN, CASH_RECEIPT_STATUS_VALUES, COLLECTION_BEST_SELLING_DAYS, COLLECTION_PREVIEW_SIZE, COLLECTION_PRODUCT_SORTS, COLLECTION_SALES_SORT_DEFAULT_DAYS, COLLECTION_SLUG_PATTERN, COLLECTION_TYPES, COUPON_CODE_PATTERN, COUPON_CONDITIONS_DEFAULTS, COUPON_TARGET_ALL, COUPON_TARGET_LIST_MAX, CUSTOM_INPUT_FORBIDDEN_WORDS, CUSTOM_INPUT_TYPES, FULFILLMENT_METHODS, FULFILLMENT_METHODS_BY_TYPE, FULFILLMENT_METHOD_RULES, FULFILLMENT_RULES, INSTALLABLE_SCOPES, KNOWN_WEBHOOK_EVENT_TYPES, MAX_ADDON_GROUPS, MAX_ANALYTICS_ALLOWED_ORIGINS, MAX_AUTO_TRANSITION_DAYS, MAX_CALENDAR_DAYS, MAX_COLLECTIONS, MAX_COLLECTION_BEST_SELLING_TOP, MAX_COLLECTION_CREATED_WITHIN_DAYS, MAX_COLLECTION_DESCRIPTION, MAX_COLLECTION_PRODUCTS, MAX_COLLECTION_PRODUCTS_PER_ADD, MAX_COLLECTION_RULES, MAX_COLLECTION_RULE_CATEGORIES, MAX_COLLECTION_TITLE, MAX_CUSTOM_INPUTS, MAX_CUSTOM_INPUT_LENGTH, MAX_OPTION_GROUPS, MAX_PICKUP_LOCATIONS, MAX_PRODUCT_IMAGES, MAX_SAVED_OPTION_SETS, MAX_SAVED_OPTION_SET_NAME, MAX_STAY_NIGHTS, MAX_VALUES_PER_GROUP, MAX_VARIANTS, MCP_TELEMETRY_MAX_RESULTS, MIN_PAYMENT_AMOUNT, NON_INSTALLABLE_SCOPES, NO_COUPON_SETTLEMENT, NO_SHIPPING_BUNDLE_KEY, PAYMENT_ROUTING_EXCLUSION_CODES, POINT_ADJUSTMENT_MAX, POINT_EARN_RATE_BP_MAX, POINT_ENTRY_TYPES, POINT_EXPIRY_DAYS_MAX, POINT_EXPIRY_DAYS_MIN, POINT_LOT_SOURCES, POINT_POLICY_DEFAULTS, POINT_REVIEW_REWARD_MAX, POINT_USE_UNITS, PORTONE_CHANNEL_NAME_MAX_LENGTH, PORTONE_MAX_CHANNELS, PORTONE_MIN_CHANNELS, REFUND_POLICY_DEFAULTS, REFUND_POLICY_DELIVERY_FEE_KEYS, REMOTE_AREA_ZIP_RANGES, RESERVED_STOREFRONT_SLUGS, RESERVED_STORE_CODES, SCOPE_DESCRIPTIONS, SHIPPING_POLICY_DEFAULTS, STARTER_SELLER_TASKS, STARTER_STAGES, STOREFRONT_BLOCKED_PATH_SEGMENTS, STOREFRONT_BUILD_STAGES, STOREFRONT_BUILD_TERMINAL_STATUSES, STOREFRONT_CHECK_TERMINAL_STATUSES, STOREFRONT_CLOSED_SITE_HOLD_DAYS, STOREFRONT_CUSTOM_DOMAIN_LIMIT_DEFAULT, STOREFRONT_DOMAIN_DNS_GRACE_DAYS, STOREFRONT_DOMAIN_DNS_WAIT_DAYS, STOREFRONT_DOMAIN_TXT_LABEL, STOREFRONT_EDIT_ACTIVITY_TIMEOUT_MINUTES, STOREFRONT_EDIT_CAPACITY, STOREFRONT_EDIT_IDLE_MINUTES, STOREFRONT_EDIT_PREVIEW_SUFFIX, STOREFRONT_EDIT_START_STAGES, STOREFRONT_FILE_BATCH_MAX, STOREFRONT_FILE_MAX_BYTES, STOREFRONT_PATH_SEGMENT_PATTERN, STOREFRONT_PLATFORM_DOMAINS, STOREFRONT_PUBLIC_SUFFIXES, STOREFRONT_SEARCH_REGEX_MAX_LENGTH, STOREFRONT_SHOWCASE_SLUG_PREFIX, STOREFRONT_SITE_CREATE_LIMIT, STOREFRONT_SLUG_CHANGE_LIMIT, STOREFRONT_SLUG_CHANGE_WINDOW_DAYS, STOREFRONT_SLUG_HOLD_DAYS, STOREFRONT_SLUG_PATTERN, STOREFRONT_SOURCE_BLOB_BATCH_MAX, STOREFRONT_SOURCE_PART_BYTES, STOREFRONT_WORKSPACE_MAX_BYTES, STOREFRONT_WORKSPACE_MAX_FILES, STORE_CODE_PATTERN, STORE_ROLE_SCOPES, STORE_SCOPE_RESOURCES, STORE_SESSION_KEYS, TEMPLATE_STORE_LOCKED_BUSINESS_FIELDS, TOSS_WIDGET_CLIENT_KEY_PATTERN, TOSS_WIDGET_KEY_MESSAGE, TOSS_WIDGET_SECRET_KEY_PATTERN, UPLOAD_PURPOSE_LIMITS, VARIANT_COUNT_WARNING, VARIANT_STOCK_EXCLUSIVE_MESSAGE, WEBHOOK_DEFAULT_TOLERANCE_SEC, WEBHOOK_DELIVERY_ID_HEADER, WEBHOOK_EVENT_ID_HEADER, WEBHOOK_EVENT_TYPE_HEADER, WEBHOOK_FAILURE_REASONS, WEBHOOK_HEADERS, WEBHOOK_PAYLOAD_EXCERPT_MAX_BYTES, WEBHOOK_RESOURCE_TYPES, WEBHOOK_SIGNATURE_HEADER, WEBHOOK_USER_AGENT, addStorefrontDomainRequestSchema, addonGroupRequestSchema, addonGroupSchema, addonValueRequestSchema, addonValueSchema, addressChangeRequestListSchema, addressTypeSchema, agentPolicyDecisionSchema, allocateByWeight, analyticsChannelSchema, analyticsCheckoutOutcomeSchema, analyticsCheckoutSchema, analyticsDeviceRowSchema, analyticsDevicesSchema, analyticsFunnelStepSchema, analyticsOriginSchema, analyticsOverviewSchema, analyticsPagesQuerySchema, analyticsPagesSchema, analyticsProductRowSchema, analyticsProductSortSchema, analyticsProductsQuerySchema, analyticsProductsSchema, analyticsRangeQuerySchema, analyticsRealtimeSchema, analyticsSearchQuerySchema, analyticsSearchSchema, analyticsSourceGroupBySchema, analyticsSourceRowSchema, analyticsSourcesQuerySchema, analyticsSourcesSchema, analyticsTotalsSchema, apiLogErrorSchema, apiLogListQuerySchema, apiLogPageSchema, apiLogPrincipalSchema, apiLogPrincipalTypeSchema, apiLogSchema, apiLogStatusFilterSchema, apiLogSummarySchema, appArtifactUploadSchema, appBuildSchema, appBuildStageSchema, appCapabilitiesOf, appDeployKeyCreateSchema, appDeployKeyCreatedSchema, appDeployKeySchema, appDevTokenSchema, appDistributionSchema, appEventTypeSchema, appHandleSchema, appIconProblem, appInstallRequestSchema, appInstallationActivitySchema, appInstallationAppSchema, appInstallationRunSchema, appInstallationSchema, appInstallationSelfSchema, appInstallationSettingsSchema, appInstallationSettingsUpdateSchema, appInstallationStatusSchema, appInvocationSchema, appListingSchema, appManifestProblems, appManifestSchema, appManifestWidens, appNetworkHostProblem, appNetworkHostSchema, appReleaseResultSchema, appRuntimeSchema, appScopeSchema, appSecretSummarySchema, appSessionSchema, appSettingFieldSchema, appStatusSchema, appVersionSchema, appVersionStatusSchema, approvalDecisionRequestSchema, approvalListQuerySchema, approvalPageSchema, approvalRequestSchema, approvalStatusSchema, approveClaimResultSchema, auditActorSchema, auditActorTypeSchema, auditLogListQuerySchema, auditLogOutcomeSchema, auditLogPageSchema, auditLogSchema, auditLogSourceSchema, bestSellingRuleOf, brandBriefProductSourceSchema, brandBriefReferenceSchema, brandBriefSchema, brandBriefViewSchema, buildAuthorizeUrl, buildQuery, bulkResultSchema, businessInfoPatchShape, businessInfoResponseShape, businessNumberSchema, calendarDateSchema, calendarDaySchema, calendarQuerySchema, cancelBySellerRequestSchema, cancelBySellerResultSchema, carrierSchema, cashReceiptSchema, categoryAttributeSchema, categoryCreateRequestSchema, categoryDeleteQuerySchema, categoryDeleteStrategySchema, categoryListQuerySchema, categoryPatchRequestSchema, categoryProductSortSchema, categorySchema, categorySearchResultSchema, categoryTreeNodeSchema, categoryWithPathSchema, changeStorefrontSlugRequestSchema, changeStorefrontTemplateRequestSchema, changeTypeSchema, claimDetailSchema, claimHoldResultSchema, claimListQuerySchema, claimReasonSchema, claimReturnAddressSchema, claimSchema, claimStatusSchema, claimTypeSchema, claimWebhookEventDataSchema, claimWebhookEventSchema, collectionCreateRequestSchema, collectionListQuerySchema, collectionPageSchema, collectionPatchRequestSchema, collectionPreviewRequestSchema, collectionPreviewSchema, collectionProductListQuerySchema, collectionProductSchema, collectionProductSortRequestSchema, collectionProductsAddRequestSchema, collectionProductsReplaceRequestSchema, collectionRuleCategoryIds, collectionRuleSchema, collectionRuleViewSchema, collectionRulesPredicate, collectionRulesSchema, collectionSchema, collectionStateCountsSchema, collectionStateOf, collectionStateSchema, commerceFlowCheckSchema, commerceFlowSchema, commerceFlowSummarySchema, commerceFlowVersionViewSchema, commerceNumberField, compareBySales, consentActionSchema, consentKindSchema, consentSourceSchema, couponBenefitSchema, couponConditionsInputSchema, couponConditionsSchema, couponDiscountOf, couponIssueListQuerySchema, couponIssueMethodSchema, couponIssueSchema, couponIssueStatusSchema, couponKindSchema, couponListQuerySchema, couponRedemptionListQuerySchema, couponRedemptionSchema, couponRejectReasonSchema, couponRuleSchema, couponSchema, couponStatsSchema, couponStatusSchema, couponTargetInputSchema, couponTargetSchema, createCommerceFlowRequestSchema, createCouponRequestSchema, createPkcePair, createStoreClient, createStoreSession, createStorefrontEditPreviewLinkRequestSchema, createStorefrontPreviewLinkRequestSchema, createStorefrontSiteRequestSchema, createStorefrontVersionRequestSchema, customInputLabelForbiddenWord, customInputRequestSchema, customInputSchema, customInputValueSchema, customerAddressSchema, customerConsentListQuerySchema, customerConsentSchema, customerConsentStateSchema, customerConsentsSchema, customerCouponSchema, customerDelegationRequestSchema, customerDelegationSchema, customerDetailSchema, customerInquiryCategorySchema, customerInquiryListQuerySchema, customerListQuerySchema, customerOrderSchema, customerPointsSchema, customerSortSchema, customerStatsSchema, customerSummarySchema, customerWithdrawalBlockedDetailsSchema, defaultFulfillmentMethodOf, deleteStorefrontFileRequestSchema, deliveryBundleKeyOf, deliveryFeeWaiverSchema, deliveryInfoSchema, deliveryMethodSchema, deliveryStatusSchema, deliveryTypeSchema, descendantCategoryIdsOf, describeScope, devStoreSchema, developerAppCreateSchema, developerAppSchema, developerInstallationSchema, developerOrgSchema, disableStorefrontHostingRequestSchema, discountRequestSchema, discountSchema, dispatchRequestSchema, easyPayProviderResponseSchema, easyPayProviderSchema, eventTypeSchema, exchangeAuthorizationCode, flowActionRequestSchema, flowActionResultSchema, flowActionSchema, flowFieldValueSchema, flowInputFieldSchema, flowNodeTypesSchema, flowNotificationWebhookEventDataSchema, flowNotificationWebhookEventSchema, flowPresetDetailSchema, flowPresetSummarySchema, flowRunSchema, flowRunStepSchema, flowSecretNameSchema, flowSecretSchema, flowStateChangedWebhookEventDataSchema, flowStateChangedWebhookEventSchema, flowStateSchema, formatOrderNo, fulfillBulkRequestSchema, fulfillRequestSchema, fulfillmentMethodOf, fulfillmentMethodSchema, fulfillmentMethodsOf, fulfillmentRuleOf, fulfillmentTypeOf, fulfillmentTypeResponseSchema, fulfillmentTypeSchema, holdOrderItemRequestSchema, inquiryListQuerySchema, inquirySchema, inquiryWebhookEventDataSchema, inquiryWebhookEventSchema, inventoryModeSchema, invitationDeliveryStatusSchema, invitationListQuerySchema, invitationSchema, inviteMemberRequestSchema, isCouponTargetLine, isEditableStorefrontPath, isInstallableScope, isReservedStoreCode, isReservedStorefrontSlug, isShowcaseStorefrontSlug, isStoreScope, isWebOrigin, issueCouponRequestSchema, issueCouponResultSchema, liveGateConditionCodeSchema, liveGateConditionSchema, liveGateErrorDetailsSchema, liveGateSchema, loginProviderSchema, loginProviderStatusSchema, loginProviderTestSchema, loginSettingsSchema, maskedSecretSchema, matchesCollectionRules, mcpRuleResultSchema, mcpToolEventSchema, migrateFlowVersionRequestSchema, migrateFlowVersionResultSchema, moveFlowStateRequestSchema, moveStorefrontFileRequestSchema, myAccountSchema, myStoreSchema, nightsOf, normalizeBusinessNumber, normalizeCouponCode, normalizeStorefrontHostname, normalizeStorefrontPath, oauthTokenResponseSchema, openFulfillmentUnion, optionGroupKindSchema, optionGroupRequestSchema, optionGroupSchema, optionModelRequestSchema, optionModelSchema, optionSelectionSchema, optionSortSchema, optionValueRequestSchema, optionValueSchema, orderCanceledWebhookEventDataSchema, orderCanceledWebhookEventSchema, orderDiscountSchema, orderFlowActionResultSchema, orderFulfilledWebhookEventDataSchema, orderFulfilledWebhookEventSchema, orderItemFlowSchema, orderItemFulfillmentSchema, orderItemFulfillmentSnapshotResponseSchema, orderItemFulfillmentSnapshotSchema, orderItemListQuerySchema, orderItemMemoResultSchema, orderItemPageSchema, orderItemSchema, orderItemStatusSchema, orderListQuerySchema, orderSchema, orderSummaryPageSchema, orderSummarySchema, orderWebhookEventDataSchema, orderWebhookEventSchema, pageInfoSchema, pageQueryShape, pageSchema, parseOrderNo, parseWebhookEvent, paymentAttemptRecordSchema, paymentAttemptStatusSchema, paymentCredentialSetSchema, paymentFailureWarningSchema, paymentListQuerySchema, paymentProviderSchema, paymentProviderVerificationSchema, paymentRecordDetailSchema, paymentRecordPageSchema, paymentRecordSchema, paymentRecordStatusSchema, paymentRefundRecordSchema, paymentSettingsSchema, pgEnvironmentSchema, pgPaymentMethodSchema, pgProviderSchema, pgVerificationResultSchema, pickupLocationRequestSchema, pickupLocationSchema, pickupLocationSnapshotSchema, planCodeSchema, planEntitlementsSchema, planErrorDetailsSchema, pointAdjustmentRequestSchema, pointAdjustmentResultSchema, pointEarnOf, pointEarnRateBpSchema, pointEarningEnabled, pointEntrySchema, pointExpiresAtOf, pointHistoryQuerySchema, pointLotSchema, pointPolicyNoticeSchema, pointPolicySchema, pointRestoreExpiresAtOf, pointUseOf, pointUsePolicySchema, policyDocumentUrlSchema, policyVersionSchema, portOneChannelSchema, portOneCredentialsInputSchema, productCreateRequestSchema, productFulfillmentCreateSchema, productFulfillmentResponseSchema, productFulfillmentSchema, productFulfillmentUpdateSchema, productImageRejection, productImageUrlSchema, productListQuerySchema, productOutOfStockWebhookEventDataSchema, productOutOfStockWebhookEventSchema, productPatchRequestSchema, productRefundPolicyOverride, productRefundPolicyPatchSchema, productReplaceRequestSchema, productSchema, productSortSchema, productStatusSchema, productSummarySchema, productVariantRequestSchema, productVariantSchema, proratedPaidRefundBase, proratedPointRefund, proratedRefundBase, publicPlanSchema, publicPlansSchema, publishStorefrontVersionRequestSchema, purchaseDecisionExtendResultSchema, purchaseDecisionRequestResultSchema, purchaseEarnPolicySchema, purchaseEarnRateOf, putBrandBriefRequestSchema, quoteDelivery, quotePricing, rankBestSelling, refreshUserToken, refundPolicyPatchSchema, refundPolicySchema, rejectClaimRequestSchema, remoteAreaLabelOf, remoteAreaOf, remoteAreaSchema, remoteSurchargeOf, replaceStorefrontSourceRequestSchema, replayFlowRequestSchema, replayFlowResultSchema, requiresCollection, requiresShipping, resolvePointPolicy, resolveRefundPolicy, resolveShippingPolicy, resolvedFlowSchema, responsePlanCodeSchema, responsePointEntryTypeSchema, reviewListQuerySchema, reviewReportResultSchema, reviewRewardPointOf, reviewRewardPolicySchema, reviewSchema, reviewSortSchema, reviewWebhookEventDataSchema, reviewWebhookEventSchema, rollbackStorefrontRequestSchema, runStorefrontCheckRequestSchema, salesReportGroupBySchema, salesReportQuerySchema, salesReportRowSchema, salesReportSchema, salesTotalsSchema, saveFlowDraftRequestSchema, saveFlowSecretRequestSchema, saveLoginProviderRequestSchema, savedCustomInputRequestSchema, savedCustomInputSchema, savedOptionGroupRequestSchema, savedOptionGroupSchema, savedOptionSetCompositionSchema, savedOptionSetFromProductRequestSchema, savedOptionSetFromProductResultSchema, savedOptionSetListQuerySchema, savedOptionSetRequestSchema, savedOptionSetSchema, savedOptionSetSortSchema, savedOptionValueRequestSchema, savedOptionValueSchema, scopeAccessSchema, scopesCoverEvent, searchStorefrontFilesRequestSchema, sellerAddressListQuerySchema, sellerAddressRequestSchema, sellerAddressSchema, sellerCancelPreviewSchema, sellerCustomerInquirySchema, setCalendarRequestSchema, setStorefrontVisibilityRequestSchema, settleCouponShortfall, settlementDetailQuerySchema, settlementDetailSchema, settlementListQuerySchema, settlementStatusSchema, settlementSummarySchema, settlementWithDetailsSchema, shippingAddressSchema, shippingPolicyPatchSchema, shippingPolicySchema, simulateFlowRequestSchema, simulateFlowResultSchema, simulationStepSchema, splitRefund, starterSellerTaskSchema, starterStageSchema, starterStatusSchema, starterStoreInfoFieldSchema, stayRangeSchema, staySnapshotSchema, storeAppDetailSchema, storeAppSchema, storeCodeSchema, storeIndustrySchema, storeMemberRoleUpdatedSchema, storeMemberSchema, storePointPolicySchema, storeRoleSchema, storeSchema, storeScopeResourceSchema, storeSubscriptionSchema, storeTemplateSchema, storefrontBuildDependenciesSchema, storefrontBuildListQuerySchema, storefrontBuildSchema, storefrontBuildStatusSchema, storefrontCheckSchema, storefrontCheckStatusSchema, storefrontCustomDomainStatusSchema, storefrontCustomHostnameProblem, storefrontDependencyFindingSchema, storefrontDeploymentLogSchema, storefrontDeploymentSchema, storefrontDeploymentStepSchema, storefrontDnsRecordSchema, storefrontDomainSchema, storefrontDomainTxtNameOf, storefrontEditPreviewLabelOf, storefrontEditPreviewSchema, storefrontEditSessionSchema, storefrontEditSessionStatusSchema, storefrontEditingSchema, storefrontFileConflictDetailsSchema, storefrontFileContentQuerySchema, storefrontFileContentSchema, storefrontFileDeleteResultSchema, storefrontFileEncodingSchema, storefrontFileEntrySchema, storefrontFileHashSchema, storefrontFileListQuerySchema, storefrontFileListSchema, storefrontFileMoveResultSchema, storefrontFilePathSchema, storefrontFileSearchResultSchema, storefrontFileWriteResultSchema, storefrontHostingSchema, storefrontPreviewLinkSchema, storefrontProvisioningSchema, storefrontRuleResultSchema, storefrontRuleSeveritySchema, storefrontSiteDomainSchema, storefrontSiteDomainsSchema, storefrontSiteSchema, storefrontSiteSnapshotSchema, storefrontSiteStatusSchema, storefrontSlugAvailabilityQuerySchema, storefrontSlugAvailabilitySchema, storefrontSlugSchema, storefrontSourceArchivePartSchema, storefrontSourceArchiveQuerySchema, storefrontSourceBlobsResultSchema, storefrontSourceModeSchema, storefrontSourceRefSchema, storefrontSourceReplacedSchema, storefrontSourceSchema, storefrontSuspensionSchema, storefrontTemplateSchema, storefrontVerifyReportSchema, storefrontVersionCreatedSchema, storefrontVersionSchema, storefrontVersionStatusSchema, storefrontVisibilitySchema, subscriptionLimitsSchema, subscriptionStatusSchema, subscriptionUsageSchema, tossPaymentsCredentialsInputSchema, trackingStageResponseSchema, trackingUpdateResultSchema, unknownWebhookEventSchema, updateCouponRequestSchema, updateLoginProviderRequestSchema, updateLoginSettingsRequestSchema, updateMemberRoleRequestSchema, updatePaymentProviderRequestSchema, updatePaymentSettingsRequestSchema, updatePointPolicyRequestSchema, updateStoreRequestSchema, updateStoreTemplateRequestSchema, uploadExtensionOf, uploadPurposeSchema, uploadRejection, uploadRequestSchema, uploadStorefrontSourceBlobsRequestSchema, uploadTicketSchema, upsertPortOneProviderRequestSchema, upsertTossPaymentsProviderRequestSchema, variantStockRequestSchema, variantStockSchema, verifyPaymentProviderRequestSchema, webhookCreatedSchema, webhookDeliveryDetailSchema, webhookDeliveryErrorCodeSchema, webhookDeliveryListQuerySchema, webhookDeliveryResourceSchema, webhookDeliverySchema, webhookDeliveryStatusSchema, webhookEventSchema, webhookFailureReasonSchema, webhookRedeliverFailedResultSchema, webhookRequestHeaderSchema, webhookRequestSchema, webhookResourceTypeSchema, webhookSchema, webhookSecretRotatedSchema, webhookStatusSchema, webhookTestRequestSchema, webhookTestResultSchema, withdrawCustomerRequestSchema, writeDryRunResultSchema, writePreviewSchema, writeStorefrontFilesRequestSchema };