2025年12月31日·1分で読めます

顧客階層のエンタイトルメントモデル:プラン、制限、フラグ

プラン、リミット、フラグの明確なスキーマを備えたエンタイトルメントモデルを設計し、管理者やサポートがエンジニアに依存せずに顧客のアクセスを安全に調整できるようにします。

顧客階層のエンタイトルメントモデル:プラン、制限、フラグ

なぜチームにエンタイトルメントモデルが必要か

複数の階層を販売しているなら、いずれ同じサポートチケットが来ます:「顧客XはProを購入したはずなのに、機能Yにアクセスできない」。明確な仕組みがなければ、サポートは直接修正できず、単純なアクセス変更がエンジニアリング作業になってしまいます。

もっと大きな問題は一貫性の欠如です。アクセスルールがプロダクトのあちこちに散らばり、管理画面のチェックボックス、APIのハードコードされたチェック、スプレッドシートのメモ、前四半期の一度限りのDB更新のようになります。顧客は場所によって異なる挙動を見て、どのルールが正しいのか誰も確信が持てません。

エンタイトルメントモデルは、プランと承認された例外に基づいて「誰が何をできるか」の単一の真実の源を与えます。これにより階層は予測可能になり(価格設定の信頼性も保たれる)、一方で現実的な運用上の柔軟性(期限つきアップグレード、クオータの一時的増加、特定アカウント向けのパイロット機能など)は残せます。

「エンジニアリング不要で調整できる」は具体的であるべきです。実務では次のようになります:

  • サポートはデプロイを依頼するのではなく、管理ツールでデータを編集してアクセスを変更する。
  • プロダクトのあらゆる場所(バックエンド、Webアプリ、モバイル)が同じエンタイトルメントデータを参照する。
  • 例外は期限付きで元に戻せるものとし、永続的なハックにしない。
  • 誰がいつ何のために変更したかを記録する。

例えば、Business階層の顧客が繁忙期にアクティブユーザ数の上限に達したとします。サポートは14日間だけ席を+10付与でき、期間終了後に自動で戻るべきです。エンジニアが関わるのはまったく新しい機能を追加するときだけで、日常的なアクセス調整のときではありません。

基本要素:顧客、プラン、エンタイトルメント

良いエンタイトルメントモデルは、いくつかの明確なオブジェクトと所有権から始まります。これらが曖昧だと、サポートは毎週「もう一つだけ例外を」とエンジニアに頼ることになります。

シンプルな構成要素のセットは次の通りです:

  • 顧客(account/tenant): あなたのプロダクトを使う会社や個人。
  • サブスクリプション: 商業的な関係(トライアル、アクティブ、キャンセル済み)で、しばしば課金システムに紐づく。
  • プラン: デフォルトのアクセスを定義する名前付き階層(Free、Pro、Enterprise)。
  • エンタイトルメント: プランとオーバーライドから導出される、実際の許可される振る舞い。

エンタイトルメントの評価は請求ではありません。請求は「いついくら請求するか」に答え、エンタイトルメントは「この顧客は今何ができるか」に答えます。顧客が未払いでも猶予期間にいる場合や、支払い済みだがコンプライアンスで一時的にブロックされている場合もあります。これらを分離しておけば、経理が請求書を修正してもプロダクトアクセスを誤って変更することを避けられます。

このセットアップに依存するグループは複数あります:

  • プロダクトはプランの意味を定義する。
  • サポートはアクセスを付与・削除する安全なコントロールを必要とする。
  • セールスオペレーションはディールや更新に一貫したルールを必要とする。
  • ファイナンスは売った内容と提供したアクセスの間の信頼できるマッピングを必要とする。

早い段階で境界を設定してください。プランの内容と顧客のオーバーライドは設定可能にして(サポートが操作できるように)、コアの振る舞いはコードで保持します。コアの振る舞いの例には、残りクオータの計算方法、期限切れトライアルの扱い、監査しなければならないアクションなどが含まれます。

フラグ、リミット、クオータ:適切なタイプを選ぶ

多くの階層問題は、エンタイトルメントに正しい名前を付けることで簡単になります。よく使われる3タイプはそれぞれ異なる問いに答えます:

  • ブールフラグ: オンかオフか?例:export_enabled = true
  • 数値リミット: 同時にどれだけ許されるか?例:max_seats = 10
  • クオータ: 一定期間でどれだけ使えるか?例:api_calls_per_month = 100000

フラグは部分的に動作すべきでない機能に最適です。エクスポートがオフなら、ボタンを隠し、エンドポイントでもブロックします。リミットはリセットされない「容量」設定に向きます(席数、プロジェクト数、保存ビューなど)。

クオータは時間が関係するため注意が必要です。リセットルールが管理画面に明示されているとサポートチケットが減ります。

スコープも混乱を防ぐ重要な決定です。例えば「SAML SSO 有効」は通常アカウントレベルです。「最大プロジェクト数」はワークスペースレベルかもしれません。「レポートを実行できるか」はロールベースの追加販売があるならユーザーレベルかもしれません。

クオータについては、クオータごとに1つのリセットルールを選んでそれを守ってください:

  • Never(ライフタイムクレジット)
  • Monthly(暦月)
  • Rolling window(過去30日間)
  • Per billing period(請求サイクルに合わせる)

もしリセットルールがプランによって変わるなら、そのルール自体をエンタイトルメントの一部として扱ってください。慣習的な知識に頼らないこと。

エンタイトルメントの実用的なデータベーススキーマ

サポートにやさしいエンタイトルメントモデルは、地味でも構わない:いくつかのテーブル、明確なキー、監査可能な期間付きレコードです。目標は管理者がデータを編集してアクセスを変えられることで、コードを出荷する必要がないようにすることです。

まずは4つのコアテーブルから始めます:plansplan_entitlementscustomerscustomer_overrides

  • Plans は階層(Free、Pro、Enterprise)を説明します。
  • Plan entitlements は各プランが何を含むかを記述します。
  • Customers はプランを指します。
  • Overrides は全員のプランを変えずに単一顧客の例外を扱います。

実用的なリレーショナルな形は次のようになります:

  • plans: id, name, description, is_active
  • plan_entitlements: id, plan_id, key, type, value, unit, reset_policy, effective_from, effective_to, created_by
  • customers: id, name, plan_id, status, created_at
  • customer_overrides: id, customer_id, key, type, value, unit, reset_policy, effective_from, effective_to, created_by

エンタイトルメントのフィールドはテーブル間で一貫させます。seatsapi_callssso_enabled のような安定した key を使い、評価を簡単にするために type を(例:flag, limit, quota)保持します。unit を明示して(例:users, requests, GB)保存してください。クオータには reset_policy を曖昧さなく(例:monthly, daily, never)保持します。

オーバーライドは期間付きの許可として挙動すべきです。顧客が sso_enabled=true のアクティブなオーバーライドを持っている場合、それはプランの値に優先して有効になりますが、effective_fromeffective_to の期間内に限られます。これにより「14日間だけ席を+10する」といった操作が1行の変更で済み、期限切れで自動的に戻ります。

エンタイトルメント評価の仕組み

階層を安定したキーに変える
フラグ、制限、クオータを共通のエンタイトルメントカタログで実装します。
アプリを作成

エンタイトルメント評価は「この顧客は今これを実行できるか?」という質問に答える小さなコードまたはサービスです。これが予測可能なら他の運用も簡単になります。

明確な優先順位を使い、逸脱しないでください:customer override > plan value > system default。これによりサポートは一時的な例外を与えやすくなり、エンジニアは何も設定されていないときの安全なデフォルトを持てます。

実用的な評価フロー:

  • 認証されたセッションから顧客/アカウントを特定する(リクエストボディから取らない)。
  • 顧客のアクティブなプランとアクティブなオーバーライドを読み込む。
  • 指定したキーについて、オーバーライドがあればそれを返し、なければプランの値、それもなければシステムデフォルトを返す。
  • どこにもキーが見つからない場合は、アクセスチェックでは失敗(deny)し、表示専用UIには適切なデフォルトを使う。
  • キーがレジストリに存在しない未知のものであれば設定エラーとして扱い、失敗させてログに残す。

キャッシュは重要です。エンタイトルメントは頻繁にチェックされます。顧客ごとに解決済みのエンタイトルメントを短いTTLと明示的なバージョン番号でキャッシュし、次の変更で無効化してください:プラン割当て、プラン定義、顧客オーバーライド、顧客ステータス(トライアル、猶予、ブロック)。簡単なパターンは「customer_id + entitlements_version でキャッシュする」ことです。サポートの編集でバージョンが上がれば変更がすぐに反映されます。

マルチテナントの安全性は必須です。すべてのクエリは現在の顧客/アカウントIDでフィルタリングし、キャッシュエントリもそのIDでキー化してください。メールやドメイン、プラン名だけで検索しないようにします。

ステップバイステップ:サポート向けの安全なアクセス調整ワークフロー

エンタイトルメントを適切に構築する
プランと顧客ごとのオーバーライドをデータとしてモデル化し、すべてのアプリで同じルールを適用します。
AppMaster を試す

サポートにやさしいワークフローはモデルを柔軟に保ちながら、あらゆる例外をエンジニアリング案件に変えないことを目指します。目標は安全に変更を行い、記録を残し、顧客体験を検証することです。

安全なサポートフロー

まず正しい顧客レコードを見つけ、彼らが何を求めているかとその理由を確認します。「1週間だけ席を2つ増やしたい」と「上位プランへの変更で契約を結んだ」は異なります。優れた管理UIは、現在のプラン、顧客ステータス、アクティブなオーバーライドを一か所で見やすくします。

何かを変更する前に、現在の使用量が上限に達しているかを確認してください。実際にはアカウントがキャップに達していない、または使用量トラッキングが更新されていないだけ、ということがよくあります。

アクセスを調整する必要がある場合は、プランを編集するより明示的なオーバーライドを優先してください。オーバーライドは狭く(一つのフラグまたは一つのリミット)、オーナーと理由を含め、デフォルトで有効期限を設定します。一時的な例外は一般的で忘れられやすいので、期限を設定することが重要です。

管理ツール内の簡単なチェックリストで十分なことが多いです:

  • 顧客の本人確認、現在のプラン、リクエストの理由を確認する。
  • 現行の使用量と関連する上限を比較する。
  • スコープを限定したオーバーライドを適用し、有効期限を設定する。
  • メモとチケット/ケース参照を追加する。
  • インパーソネーションやテストアカウントを使い、プロダクトUIで結果を検証する。

顧客が体験する方法で必ず変更を検証してください。インパーソネーションをサポートするなら、それが有効なときは分かりやすく表示し、ログに残してください。

アップグレード、ダウングレード、トライアル、猶予期間

多くのエンタイトルメント問題は変更時に発生します:顧客が期間中にアップグレードする、カード決済が失敗する、トライアルが週末に終了する、など。ルールが曖昧だとサポートは推測し、エンジニアが引きずり出されます。

アップグレードではシンプルにしておきましょう:アクセスは通常即時に変わり、金銭処理は請求側で扱います。エンタイトルメントモデルは「プランが変更された」などの請求イベントを受けて、新しいプランのエンタイトルメントをすぐに適用するべきです。請求で日割りがあるならそれは歓迎ですが、エンタイトルメントに日割り計算を組み込まないでください。

ダウングレードは驚きが生じやすい領域です。明確なダウングレード動作を選んでサポートに見えるようにしましょう:

  • 猶予期間: 支払い済み期間の終了まで上位アクセスを維持する。
  • 読み取り専用: データの閲覧やエクスポートは許可するが、新規書き込みをブロックする。
  • 即時停止: 機能を直ちにブロックする(リスクの高い機能向け)。
  • オーバーリミットの挙動: 使用は許すが、作成は上限を超えている場合にブロックする。
  • データ保持: データは保持するが、アップグレードまでアクセスを無効化する。

トライアルは顧客のブール値として扱うのではなく、独自のプランとして扱うのが最も扱いやすいです。トライアルプランには明示的なフラグと制限、そして自動失効ルールを与えます。トライアル終了時には顧客をデフォルトプラン(多くは「Free」)に移し、定義したダウングレード動作を適用します。

請求失敗時の猶予期間も実用的です。短い「延滞」ウィンドウ(例:3〜7日)は支払いを修正する時間を与えます。猶予期間は時間限定のオーバーライドとして扱い、カスタムプラン名にしないでください。

実用的なヒント:エンタイトルメントをマーケティング用のティア名(「Pro」「Enterprise」)に結び付けないこと。内部では安定したプランID(例:plan_basic_v2)を使い、ティア名を変えてもルールが壊れないようにします。

監査性と安全対策

エンタイトルメントの変更を追跡可能にする
変更履歴を監査対応にして、誰が何を変えたか常に把握できるようにします。
今すぐ開始

サポートがエンジニアを介さずにアクセスを変更できるなら、必ず活動の記録が必要です。良いエンタイトルメントモデルはあらゆる変更を記録された決定として扱い、サイレントな調整にしません。

各オーバーライドについて、操作した人物、業務上の理由、タイムスタンプを必ず保存してください。組織上必要なら、敏感な変更には承認ステップを追加します。

変更ごとに記録すべき項目

ログを使いやすくシンプルに保ちましょう:

  • created_bycreated_at
  • approved_byapproved_at(任意)
  • reason(短いテキスト:例「有料アドオン」「インシデント補填」)
  • previous_valuenew_value
  • expires_at

安全対策は事故を生じる前に止めます。管理UIやDB側でガードレールを置き、最大値の上限、負の値のブロック、大きな変更には有効期限を必須にする(例:APIコールを10倍にする変更は期限を要求する)などの制約をつけましょう。

ロールバックと監査準備

サポートは間違えます。顧客レベルのオーバーライドをクリアしてプランに戻す「プランデフォルトに戻す」アクションを一つ用意しておくと、ミスの巻き戻しが簡単になります。

監査のために、顧客別・期間別にエクスポートしやすくしてください。理由と承認者を含む基本的なCSVエクスポートがあれば、多くの質問に対してエンジニアを呼ばずに答えられます。

例:Proの顧客がイベントのために1週間だけ席を30増やす必要があるとします。サポートは seats_override=60expires_at を来週金曜に設定して追加し、理由に「イベント」と記録します。期限後は自動的に元の30に戻り、請求で問題になった場合でも完全な履歴が残ります。

エンタイトルメントを厄介にする一般的なミス

エンタイトルメントモデルを壊す最速の方法は、意図せず拡張させることです。初期のいくつかの手抜きが数ヶ月分のサポートチケットと「なぜこの顧客がそれをできるのか?」という火消しにつながります。

よくある問題の一つは機能チェックをあちこちに散らすことです。アプリの各所が異なる方法でアクセスを決めると矛盾が生じます。エンタイトルメント評価を1つの関数かサービスに集中させ、UIとAPIのすべてがそれを使うようにしてください。

もう一つの落とし穴は請求状態とアクセスを混同することです。PaidAllowed と同じではありません。請求にはリトライ、チャージバック、トライアル、後から精算される請求などがあり得ます。請求イベントをエンタイトルメントに翻訳する明確なルール(猶予期間を含む)を持ち、辺境ケースがユーザを不当にロックアウトしたり無期限にアクセスを許したりしないようにしてください。

単一の tier 文字列(例:basicpro)だけに頼るのも避けてください。ティアは時間とともに変わり、例外は発生します。明示的なフラグとリミットを保存しておけば、サポートは一つの能力だけを付与して誤ってティア全体の権利を与えることを避けられます。

無制限のオーバーライドを許すとそれ自体が見えない負債になります。オーナー、理由、チケット参照を必須にし、有効期限やレビュー日を推奨してください。オーバーライドは狭く保ち(一度に一つのキー)、監査しやすくします。

クオータはリセットルールが曖昧だと失敗します。「月あたり」とは暦月かロールイング30日か、アップグレード時にどうするか、未使用分は繰り越せるかを定義してください。これらのルールはUIだけでなくバックエンドロジックで強制して、サポートの変更がWebとモバイルで不整合な振る舞いを生まないようにします。

出荷前の簡易チェックリスト

スキーマを素早く出荷する
視覚的モデリングで数分でプランとオーバーライドのPostgreSQLスキーマを設計します。
始める

エンタイトルメントモデルを展開する前に、毎日使う人たち(サポート、カスタマーサクセス、オンコール担当)と最終チェックを行ってください。

各機能が一つの安定したエンタイトルメントキーにマップされ、責任者が明確であることを確認します。重複したキー(例:reports_enabledreporting_enabled)は避けます。出荷するキーごとに各プランのデフォルトを明示してください。キーが欠けている場合は安全側に倒す(通常アクセス拒否)と同時に内部でアラートを上げ、修正されるようにします。

運用面では、ワークフローが本当に使えるか確認します:

  • サポートがSQLを書かずに有効なアクセス(プランデフォルト+オーバーライド)を表示できる。
  • オーバーライドは誰が何をいつ期限付きで変更したかログに残る。
  • クオータはリセットルールが見える形で表示され、現在の使用量を明確に示せる。

現実的なテスト:サポートに14日間のアドオンを単一顧客に付与し、その後取り消してもらってください。2分以内に自信を持って実行できるなら、かなり良い状態です。

例:一時的な例外を伴う階層

サポートフローを迅速にテストする
エンタイトルメントワークフローをエンドツーエンドでプロトタイプし、書き直しなしで反復します。
プロトタイプを作る

あなたが3つの階層を提供しており、それぞれの階層がプロダクトに表示されバックエンドで強制されるいくつかのエンタイトルメントを設定していると想像してください。

  • Free: プロジェクト1、ユーザー3人、月200エクスポート、基本APIレート制限、監査ログ7日。
  • Team: プロジェクト10、ユーザー25人、月2,000エクスポート、より高いAPIレート制限、監査ログ30日。
  • Business: 無制限プロジェクト、ユーザー200人、月10,000エクスポート、最高のAPIレート制限、監査ログ180日、SSO有効。

ここでTeam顧客が「今月は期末対応で月間8,000エクスポートが必要。30日間だけ助けてほしい」と言ってきたとします。これは新しいプランに移すより一時的なオーバーライドが適している典型例です。

サポートは顧客レコードを開き、export_monthly_limit = 8000 のオーバーライドを追加し、有効期限を今日から30日に設定します。メモに「Alex(Sales)承認、Q4レポーティングのため30日例外」と記録します。

顧客側では次のことが起こるはずです:

  • UI は新しい上限を反映する(使用量メーターや「残りエクスポート」ラベルが更新される)。
  • 月間8,000に達するまではエクスポートが機能し続ける。

もし上回った場合は明確なメッセージが表示されます:「エクスポート上限に達しました(8,000/月)。サポートに連絡するかアップグレードしてください。」

有効期限後、オーバーライドは自動的に無効になり、顧客は誰も操作することなくTeamプランの上限に戻ります。

次のステップ:サポートを遅らせずに実装と反復を行う

まず「機能」を小さなエンタイトルメントカタログに変換してください。各アイテムに明確なキー、タイプ(フラグ/リミット/クオータ)、およびプランごとのデフォルト値を与えます。このカタログはプロダクト、サポート、エンジニア間の共通言語になるので、名前は具体的で安定させてください。

どこで強制するかを決めます。安全なルールはこうです:データを変更したりコストが発生する操作はAPIで強制し、長時間実行される処理はバックグラウンドジョブで停止させ、UIは(無効化ボタンや親切なメッセージで)案内を提供するが唯一のゲートにしない。

最初のバージョンは小さく絞ってください。最も多く質問が来るエンタイトルメントに注力し、リスクの高いアクションにチェックを追加し、顧客、プラン、オーバーライド、履歴が一画面で見える管理ビューを出荷します。

手作業で書き切るのではなく管理パネルと基盤ロジックを素早く作りたいなら、AppMaster (appmaster.io) はこうした作業に実用的な選択肢です:プランとオーバーライドをデータとしてモデリングし、ビジネスプロセスとしてチェックを実装し、バックエンドとアプリ全体で一貫したサポートUIを提供できます。

よくある質問

エンタイトルメントモデルとは何ですか、またなぜ必要ですか?

エンタイトルメントモデルは、顧客のプランと承認された例外に基づいて「今この顧客が何をできるか」を一貫して判断する仕組みです。プロダクトのすべての部分が同じルールを参照することで「UIでは動くがAPIでは失敗する」といった状況を防ぎます。

明確なエンタイトルメントシステムがないと何が問題になりますか?

明確なエンタイトルメントがないと、サポートは小さなアクセス変更のたびにエンジニアに依頼することになり、顧客は画面やエンドポイントごとに矛盾する挙動を目にします。やがてルールはコード、管理画面のチェックボックス、スプレッドシート、ワンオフのDB更新に散在し、障害や請求トラブルを招きます。

エンタイトルメントは請求状況とどう違いますか?

請求は「いつ、いくら請求するか」に答え、エンタイトルメントは「今この瞬間に何が許可されているか」に答えます。これらを分離しておけば、経理が請求やリトライを処理しても意図せず製品アクセスが変更されることを防げます。

フラグ、リミット、クオータはいつ使い分けるべきですか?

フラグは機能が完全にオン/オフであるべきとき(例: SSO を有効化)。リミットはリセットされない容量設定(例: 最大席数、プロジェクト数)。クオータは期間中の使用量(例: 月あたりのエクスポート数)で、リセットルールを明確にする必要があります。

エンタイトルメントはアカウントレベル、ワークスペースレベル、ユーザーレベルのどれにするべきですか?

販売方法と運用方法に合わせてスコープを選びます。SSO のようなものはアカウント(全体)レベル、プロジェクトの上限はワークスペースレベル、レポートの実行権限などはユーザーレベルになることが多いです。重要なのは、エンタイトルメントをチェックする場所すべてで同じスコープを使うことです。

エンタイトルメント評価はどのような優先順位で行うべきですか?

一般的な優先順位は「顧客のオーバーライド > プランの値 > システムデフォルト」です。キーがどこにもなければアクセスは拒否(fail closed)し、未知のキーは設定エラーとしてログに残します。これによりサポートは一時的な例外を与えつつ、エンジニアは安全なデフォルトを持てます。

プランと顧客オーバーライドの実用的なデータ設計はどうなりますか?

plans にプランのデフォルトを保存し、顧客ごとの例外は別テーブルに保管します。両方で同じ安定したキーとタイプを使い、オーバーライドは effective_from / effective_to のように期間を持たせると、サポートが自動的に期限切れになる一時的なアクセスを付与できます。

エンタイトルメントチェックを高速にしつつ古いルールを出さないにはどうすればよいですか?

顧客ごとに解決済みのエンタイトルメントを短い TTL とバージョン番号でキャッシュします。プラン割当て、プラン定義、顧客オーバーライド、顧客ステータスが変わったらバージョンをインクリメントしてキャッシュを無効化すると、更新が素早く反映されつつ高速なチェックを維持できます。

「14日間 +10 席」のような一時的アクセスを付与する最も安全な方法は?

狭いオーバーライドを作り、有効期限を設定し、理由を記録して検証するのが安全です。プランを直接編集すると、その変更は同一ティアの全員に影響するため、ワンオフの要望にはオーバーライドが望ましいです。

サポートがエンタイトルメントを変更したときに何をログすべきですか?

変更を行った人、日時、理由、変更前の値と変更後の値、そして失効日時を記録します。加えて「プランデフォルトに戻す」アクションを一括で用意しておくと、誤操作のロールバックが簡単になります。

始めやすい
何かを作成する 素晴らしい

無料プランで AppMaster を試してみてください。
準備が整ったら、適切なサブスクリプションを選択できます。

始める