@feelflow/ffid-sdk 12.0.0 → 12.1.0

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/README.md CHANGED
@@ -888,6 +888,9 @@ import { createFFIDAnnouncementsClient } from '@feelflow/ffid-sdk/announcements'
888
888
 
889
889
  // Webhook 署名検証・ハンドラー(※ Node.js crypto が必要)
890
890
  import { createFFIDWebhookHandler, verifyWebhookSignature } from '@feelflow/ffid-sdk/webhooks'
891
+
892
+ // 製品側 DB 用の短命トークン(ES256)
893
+ import { createDbTokenMinter } from '@feelflow/ffid-sdk/server'
891
894
  ```
892
895
 
893
896
  > **Note**: `webhooks` モジュールは Node.js の `crypto` モジュールと `Buffer` を使用します。Cloudflare Workers で利用する場合は [`nodejs_compat` 互換フラグ](https://developers.cloudflare.com/workers/runtime-apis/nodejs/)を有効にしてください。
@@ -940,6 +943,36 @@ module.exports = {
940
943
 
941
944
  > **Note**: サーバーサイドで bundler を使わずに実行する場合、**subpath exports(`@feelflow/ffid-sdk/legal` 等)を使用すれば** external 設定なしで React がインストールされていなくても動作します。メインエントリ(`@feelflow/ffid-sdk`)を ESM で import する場合は、モジュールグラフが静的に解決されるため React が必要です。
942
945
 
946
+ ### 製品側 DB 用トークン(createDbTokenMinter)
947
+
948
+ FFID でログインする製品が、自分の Supabase に supabase-js でアクセスするときの短命トークン(ES256)を作ります(12.1.0 以降)。サーバー専用で、React には依存しません。製品のサーバーが FFID のセッションを確認した後に呼び、RLS は `private.current_ffid_user_id()` から利用者を読みます。
949
+
950
+ ```typescript
951
+ import { createDbTokenMinter } from '@feelflow/ffid-sdk/server'
952
+
953
+ // プロセスで 1 回
954
+ const minter = createDbTokenMinter({
955
+ signingKey: process.env.SUPABASE_JWT_SIGNING_KEY?.trim() ?? '', // 私有 JWK(JSON 文字列)
956
+ })
957
+
958
+ // リクエストごと
959
+ const { token, expiresAt } = await minter.mint({
960
+ userId: session.user.id, // sub(UUID)
961
+ organizationId: session.organization?.id, // 任意。organization_id claim
962
+ })
963
+ // createClient(url, key, { global: { headers: { Authorization: `Bearer ${token}` } } })
964
+ ```
965
+
966
+ - 設定: `signingKey`(必須。私有 P-256 JWK で `kid` が必要)/ `kid`(任意の上書き)/ `ttlSeconds`(既定 300、上限 900)/ `issuer`(任意)
967
+ - 入力: `userId`、`organizationId`、`claims`(製品固有。`sub` / `role` / `aud` / `iss` / `iat` / `exp` / `nbf` / `jti` / `organization_id` は予約済み)
968
+ - エラー: `FFIDDbTokenError`。`code` は `INVALID_SIGNING_KEY` / `INVALID_TTL` / `INVALID_USER_ID` / `INVALID_ORGANIZATION_ID` / `RESERVED_CLAIM` / `INVALID_CLOCK`。取り込み失敗は message に原因、`cause` に元のエラー(鍵材料は含まれません)
969
+ - `supabase gen signing-key --algorithm ES256` の出力(`use` / `key_ops` / `ext` 付き)をそのまま渡せます。SDK が EC パラメータだけを取り込みます
970
+ - 環境変数は読みません。鍵は設定として渡します。追加の依存はありません
971
+
972
+ > **Warning**: 私有鍵とトークンは **ブラウザに渡さず、ログにも出さないでください**。鍵が無いときは 503 で止め、service role に黙って切り替えないでください。
973
+
974
+ 鍵の登録手順、RLS の SQL、確認項目は [DB_USER_IDENTITY_STANDARD.md](../../docs/06-reference/DB_USER_IDENTITY_STANDARD.md) を参照してください。
975
+
943
976
  ### `peerDependencies` は optional です
944
977
 
945
978
  SDK の `package.json` で `react` / `react-dom` は `optional: true` に設定済みです(利用者側での設定は不要)。React をインストールしなくても `npm install` 時に warning は発生しません。
@@ -28,6 +28,13 @@ interface FFIDAgencyLogger {
28
28
  error: (...args: unknown[]) => void;
29
29
  }
30
30
  type FFIDAgencyStatus = 'active' | 'suspended' | 'inactive';
31
+ /**
32
+ * 代理店の課金方式。
33
+ *
34
+ * `'markup'` は非推奨(FFID #6507)。既存データの値として残している。`updateBilling()` は
35
+ * 互換のため今も `'markup'` を受け付けるが、新しく設定しないこと。受け取った値を網羅的に
36
+ * 扱う箇所では引き続き `'markup'` を扱うこと。
37
+ */
31
38
  type FFIDAgencyBillingType = 'direct' | 'consolidated' | 'markup';
32
39
  type FFIDAgencyMemberRole = 'owner' | 'admin' | 'sales' | 'support';
33
40
  type FFIDAgencyMemberStatus = 'active' | 'invited' | 'suspended';
@@ -99,7 +106,9 @@ interface FFIDAgencyOrganization {
99
106
  organizationSlug: string;
100
107
  billingOverride: FFIDAgencyBillingOverride;
101
108
  commissionRate: number | null;
109
+ /** @deprecated markup 課金方式は非推奨(FFID #6507)。帳票用の既存値を読むだけで、更新する API は無い。 */
102
110
  markupRate: number | null;
111
+ /** @deprecated markup 課金方式は非推奨(FFID #6507)。帳票用の既存値を読むだけで、更新する API は無い。 */
103
112
  markupFixed: number | null;
104
113
  /** 組織単位の卸割引率 override(%、0〜100)。null = 代理店デフォルトに従う。 */
105
114
  wholesaleDiscountRate: number | null;
@@ -192,7 +201,9 @@ interface FFIDAgencyBillingConfig {
192
201
  stripeCustomerId: string | null;
193
202
  invoiceEmail: string | null;
194
203
  paymentTerms: number | null;
204
+ /** @deprecated markup 課金方式は非推奨(FFID #6507)。帳票用の既存値を読むだけで、更新する API は無い。 */
195
205
  defaultMarkupRate: number | null;
206
+ /** @deprecated markup 課金方式は非推奨(FFID #6507)。帳票用の既存値を読むだけで、更新する API は無い。 */
196
207
  defaultMarkupFixed: number | null;
197
208
  /** 代理店デフォルト卸割引率(%、0〜100)。null = 未設定(定価請求)。 */
198
209
  wholesaleDiscountRate: number | null;
@@ -201,7 +212,15 @@ interface FFIDUpdateAgencyBillingRequest {
201
212
  billingType?: FFIDAgencyBillingType;
202
213
  invoiceEmail?: string;
203
214
  paymentTerms?: number;
215
+ /**
216
+ * @deprecated FFID はこの項目を受け付けず、送っても黙って捨てる(FFID #6507)。
217
+ * markup 課金方式は非推奨で、値を更新する手段は無い。
218
+ */
204
219
  defaultMarkupRate?: number;
220
+ /**
221
+ * @deprecated FFID はこの項目を受け付けず、送っても黙って捨てる(FFID #6507)。
222
+ * markup 課金方式は非推奨で、値を更新する手段は無い。
223
+ */
205
224
  defaultMarkupFixed?: number;
206
225
  /** 代理店デフォルト卸割引率(%、0〜100)。null で未設定に戻す。 */
207
226
  wholesaleDiscountRate?: number | null;
@@ -28,6 +28,13 @@ interface FFIDAgencyLogger {
28
28
  error: (...args: unknown[]) => void;
29
29
  }
30
30
  type FFIDAgencyStatus = 'active' | 'suspended' | 'inactive';
31
+ /**
32
+ * 代理店の課金方式。
33
+ *
34
+ * `'markup'` は非推奨(FFID #6507)。既存データの値として残している。`updateBilling()` は
35
+ * 互換のため今も `'markup'` を受け付けるが、新しく設定しないこと。受け取った値を網羅的に
36
+ * 扱う箇所では引き続き `'markup'` を扱うこと。
37
+ */
31
38
  type FFIDAgencyBillingType = 'direct' | 'consolidated' | 'markup';
32
39
  type FFIDAgencyMemberRole = 'owner' | 'admin' | 'sales' | 'support';
33
40
  type FFIDAgencyMemberStatus = 'active' | 'invited' | 'suspended';
@@ -99,7 +106,9 @@ interface FFIDAgencyOrganization {
99
106
  organizationSlug: string;
100
107
  billingOverride: FFIDAgencyBillingOverride;
101
108
  commissionRate: number | null;
109
+ /** @deprecated markup 課金方式は非推奨(FFID #6507)。帳票用の既存値を読むだけで、更新する API は無い。 */
102
110
  markupRate: number | null;
111
+ /** @deprecated markup 課金方式は非推奨(FFID #6507)。帳票用の既存値を読むだけで、更新する API は無い。 */
103
112
  markupFixed: number | null;
104
113
  /** 組織単位の卸割引率 override(%、0〜100)。null = 代理店デフォルトに従う。 */
105
114
  wholesaleDiscountRate: number | null;
@@ -192,7 +201,9 @@ interface FFIDAgencyBillingConfig {
192
201
  stripeCustomerId: string | null;
193
202
  invoiceEmail: string | null;
194
203
  paymentTerms: number | null;
204
+ /** @deprecated markup 課金方式は非推奨(FFID #6507)。帳票用の既存値を読むだけで、更新する API は無い。 */
195
205
  defaultMarkupRate: number | null;
206
+ /** @deprecated markup 課金方式は非推奨(FFID #6507)。帳票用の既存値を読むだけで、更新する API は無い。 */
196
207
  defaultMarkupFixed: number | null;
197
208
  /** 代理店デフォルト卸割引率(%、0〜100)。null = 未設定(定価請求)。 */
198
209
  wholesaleDiscountRate: number | null;
@@ -201,7 +212,15 @@ interface FFIDUpdateAgencyBillingRequest {
201
212
  billingType?: FFIDAgencyBillingType;
202
213
  invoiceEmail?: string;
203
214
  paymentTerms?: number;
215
+ /**
216
+ * @deprecated FFID はこの項目を受け付けず、送っても黙って捨てる(FFID #6507)。
217
+ * markup 課金方式は非推奨で、値を更新する手段は無い。
218
+ */
204
219
  defaultMarkupRate?: number;
220
+ /**
221
+ * @deprecated FFID はこの項目を受け付けず、送っても黙って捨てる(FFID #6507)。
222
+ * markup 課金方式は非推奨で、値を更新する手段は無い。
223
+ */
205
224
  defaultMarkupFixed?: number;
206
225
  /** 代理店デフォルト卸割引率(%、0〜100)。null で未設定に戻す。 */
207
226
  wholesaleDiscountRate?: number | null;
@@ -577,7 +577,8 @@ function createBillingMethods(deps) {
577
577
  subscriptionId: params.subscriptionId,
578
578
  successUrl: params.successUrl,
579
579
  cancelUrl: params.cancelUrl,
580
- ...params.planId ? { planId: params.planId } : {}
580
+ ...params.planId ? { planId: params.planId } : {},
581
+ ...params.quantity !== void 0 ? { quantity: params.quantity } : {}
581
582
  })
582
583
  }
583
584
  );
@@ -1390,7 +1391,7 @@ var FFID_ORGANIZATION_PROFILE_ERROR_CODES = {
1390
1391
  };
1391
1392
 
1392
1393
  // src/client/version-check.ts
1393
- var SDK_VERSION = "12.0.0";
1394
+ var SDK_VERSION = "12.1.0";
1394
1395
  var SDK_USER_AGENT = `FFID-SDK/${SDK_VERSION} (TypeScript)`;
1395
1396
  var SDK_VERSION_HEADER = "X-FFID-SDK-Version";
1396
1397
  function sdkHeaders() {
@@ -4077,7 +4078,9 @@ var FFID_SUBSCRIPTION_ERROR_CODES = {
4077
4078
  SUBSCRIPTION_NOT_CANCELABLE: "SUBSCRIPTION_NOT_CANCELABLE",
4078
4079
  SUBSCRIPTION_ALREADY_CANCELED: "SUBSCRIPTION_ALREADY_CANCELED",
4079
4080
  FREE_DOWNGRADE_NOT_ALLOWED: "FREE_DOWNGRADE_NOT_ALLOWED",
4080
- PAYMENT_METHOD_REQUIRED: "PAYMENT_METHOD_REQUIRED"
4081
+ PAYMENT_METHOD_REQUIRED: "PAYMENT_METHOD_REQUIRED",
4082
+ SEAT_ABOVE_MAX: "SEAT_ABOVE_MAX",
4083
+ SEAT_BELOW_MIN: "SEAT_BELOW_MIN"
4081
4084
  };
4082
4085
  var FFID_CREDITS_ERROR_CODES = {
4083
4086
  CREDITS_INSUFFICIENT: "CREDITS_INSUFFICIENT",
@@ -579,7 +579,8 @@ function createBillingMethods(deps) {
579
579
  subscriptionId: params.subscriptionId,
580
580
  successUrl: params.successUrl,
581
581
  cancelUrl: params.cancelUrl,
582
- ...params.planId ? { planId: params.planId } : {}
582
+ ...params.planId ? { planId: params.planId } : {},
583
+ ...params.quantity !== void 0 ? { quantity: params.quantity } : {}
583
584
  })
584
585
  }
585
586
  );
@@ -1392,7 +1393,7 @@ var FFID_ORGANIZATION_PROFILE_ERROR_CODES = {
1392
1393
  };
1393
1394
 
1394
1395
  // src/client/version-check.ts
1395
- var SDK_VERSION = "12.0.0";
1396
+ var SDK_VERSION = "12.1.0";
1396
1397
  var SDK_USER_AGENT = `FFID-SDK/${SDK_VERSION} (TypeScript)`;
1397
1398
  var SDK_VERSION_HEADER = "X-FFID-SDK-Version";
1398
1399
  function sdkHeaders() {
@@ -4079,7 +4080,9 @@ var FFID_SUBSCRIPTION_ERROR_CODES = {
4079
4080
  SUBSCRIPTION_NOT_CANCELABLE: "SUBSCRIPTION_NOT_CANCELABLE",
4080
4081
  SUBSCRIPTION_ALREADY_CANCELED: "SUBSCRIPTION_ALREADY_CANCELED",
4081
4082
  FREE_DOWNGRADE_NOT_ALLOWED: "FREE_DOWNGRADE_NOT_ALLOWED",
4082
- PAYMENT_METHOD_REQUIRED: "PAYMENT_METHOD_REQUIRED"
4083
+ PAYMENT_METHOD_REQUIRED: "PAYMENT_METHOD_REQUIRED",
4084
+ SEAT_ABOVE_MAX: "SEAT_ABOVE_MAX",
4085
+ SEAT_BELOW_MIN: "SEAT_BELOW_MIN"
4083
4086
  };
4084
4087
  var FFID_CREDITS_ERROR_CODES = {
4085
4088
  CREDITS_INSUFFICIENT: "CREDITS_INSUFFICIENT",
@@ -1,34 +1,34 @@
1
1
  'use strict';
2
2
 
3
- var chunkXRWDTYA7_cjs = require('../chunk-XRWDTYA7.cjs');
3
+ var chunk62MINYOA_cjs = require('../chunk-62MINYOA.cjs');
4
4
 
5
5
 
6
6
 
7
7
  Object.defineProperty(exports, "FFIDAnnouncementBadge", {
8
8
  enumerable: true,
9
- get: function () { return chunkXRWDTYA7_cjs.FFIDAnnouncementBadge; }
9
+ get: function () { return chunk62MINYOA_cjs.FFIDAnnouncementBadge; }
10
10
  });
11
11
  Object.defineProperty(exports, "FFIDAnnouncementList", {
12
12
  enumerable: true,
13
- get: function () { return chunkXRWDTYA7_cjs.FFIDAnnouncementList; }
13
+ get: function () { return chunk62MINYOA_cjs.FFIDAnnouncementList; }
14
14
  });
15
15
  Object.defineProperty(exports, "FFIDInquiryForm", {
16
16
  enumerable: true,
17
- get: function () { return chunkXRWDTYA7_cjs.FFIDInquiryForm; }
17
+ get: function () { return chunk62MINYOA_cjs.FFIDInquiryForm; }
18
18
  });
19
19
  Object.defineProperty(exports, "FFIDLoginButton", {
20
20
  enumerable: true,
21
- get: function () { return chunkXRWDTYA7_cjs.FFIDLoginButton; }
21
+ get: function () { return chunk62MINYOA_cjs.FFIDLoginButton; }
22
22
  });
23
23
  Object.defineProperty(exports, "FFIDOrganizationSwitcher", {
24
24
  enumerable: true,
25
- get: function () { return chunkXRWDTYA7_cjs.FFIDOrganizationSwitcher; }
25
+ get: function () { return chunk62MINYOA_cjs.FFIDOrganizationSwitcher; }
26
26
  });
27
27
  Object.defineProperty(exports, "FFIDSubscriptionBadge", {
28
28
  enumerable: true,
29
- get: function () { return chunkXRWDTYA7_cjs.FFIDSubscriptionBadge; }
29
+ get: function () { return chunk62MINYOA_cjs.FFIDSubscriptionBadge; }
30
30
  });
31
31
  Object.defineProperty(exports, "FFIDUserMenu", {
32
32
  enumerable: true,
33
- get: function () { return chunkXRWDTYA7_cjs.FFIDUserMenu; }
33
+ get: function () { return chunk62MINYOA_cjs.FFIDUserMenu; }
34
34
  });
@@ -1 +1 @@
1
- export { FFIDAnnouncementBadge, FFIDAnnouncementList, FFIDInquiryForm, FFIDLoginButton, FFIDOrganizationSwitcher, FFIDSubscriptionBadge, FFIDUserMenu } from '../chunk-OL7KVPQ4.js';
1
+ export { FFIDAnnouncementBadge, FFIDAnnouncementList, FFIDInquiryForm, FFIDLoginButton, FFIDOrganizationSwitcher, FFIDSubscriptionBadge, FFIDUserMenu } from '../chunk-3MYUVPLD.js';
@@ -1164,6 +1164,15 @@ interface FFIDCreateCheckoutParams {
1164
1164
  cancelUrl: string;
1165
1165
  /** Optional plan ID for upgrade or resubscription */
1166
1166
  planId?: string;
1167
+ /**
1168
+ * Seat count after the plan change (#5755). Use together with `planId` (a
1169
+ * different plan); seat-only changes go through the seats API. Omit to carry
1170
+ * over the current seat count. Must fit the target plan's seat range
1171
+ * (fixed-seat plans need their fixed count) and, when decreasing, the seats in
1172
+ * use — otherwise 422 `SEAT_QUANTITY_OUT_OF_RANGE`. Raising the plan while
1173
+ * lowering seats (or vice versa) is 400 `INVALID_UPGRADE_PLAN`.
1174
+ */
1175
+ quantity?: number;
1167
1176
  }
1168
1177
  /**
1169
1178
  * Parameters for creating a billing portal session
@@ -1164,6 +1164,15 @@ interface FFIDCreateCheckoutParams {
1164
1164
  cancelUrl: string;
1165
1165
  /** Optional plan ID for upgrade or resubscription */
1166
1166
  planId?: string;
1167
+ /**
1168
+ * Seat count after the plan change (#5755). Use together with `planId` (a
1169
+ * different plan); seat-only changes go through the seats API. Omit to carry
1170
+ * over the current seat count. Must fit the target plan's seat range
1171
+ * (fixed-seat plans need their fixed count) and, when decreasing, the seats in
1172
+ * use — otherwise 422 `SEAT_QUANTITY_OUT_OF_RANGE`. Raising the plan while
1173
+ * lowering seats (or vice versa) is 400 `INVALID_UPGRADE_PLAN`.
1174
+ */
1175
+ quantity?: number;
1167
1176
  }
1168
1177
  /**
1169
1178
  * Parameters for creating a billing portal session