Subscriptionsについて
alias Bright.Accounts
alias Bright.Subscriptions
Brightにおける有料サービスの概念
有料サービスに関する概念については概念ER図を参照
Subscriptionsコンテキストのデータモデル
SubscriptionsコンテキストはBrightにおける定額契約プランおよびプラン事に利用可能となる機能群(Service)から構成される。
erDiagram
"SubscriptionPlan"||--|{"SubscriptionPlanService" : "利用可能なサービス群"
"SubscriptionPlan"||--o{"SubscriptionUserPlan" : ""
"SubscriptionUserPlan"}o--o{"User" : "契約したプラン(過去分を含む)"
以下、subscription_plans
とsubscription_user_plans
のカラムである。
erDiagram
subscription_plans {
string plan_code "プランを表すコード 一意"
string name_jp "プラン表示名"
integer free_trial_priority "無料トライアルの優先度 小さい方が優先 nilは対象外"
integer authorization_priority "プランの採用優先度 大きい方が優先 上位プランが大"
integer create_teams_limit "通常チームの作成数上限"
integer team_members_limit "チームのメンバー数上限"
integer create_enable_hr_functions_teams_limit "育成・支援チームの作成数上限"
datetime available_contract_end_datetime "契約そのものの終了日時"
}
-
特に
authorization_priority
は重ならないように設定する。
erDiagram
subscription_user_plans {
id user_id FK
id subscription_plan FK
string subscription_status "enum(free_trial: 無料トライアル中, subscribing: 契約中, subscription_ended: 契約終了)"
datetime subscription_start_datetime "契約の開始日時"
datetime subscription_end_datetime "契約の終了日時 (未完了の場合はnil)"
datetime trial_start_datetime "無料トライアルの開始日時 (トライアル未利用の場合はnil)"
datetime trial_end_datetime "無料トライアルの終了日時 (トライアル未利用または未完了の場合はnil)"
}
- 過去の契約履歴を含むため複数のsubscription_user_plansレコードが存在しうる。
-
通常1ユーザーには複数のsubscription_status: subscribingなレコードは存在しない。
- 上位プランが下位プランの機能(権限及び制限)を包含する。
- ただし、システム上は発生を想定して上位プランを優先して適用する。
-
一方で、トライアル中に、subscription_status: subscribingとfree_trialのレコードは同時に存在する。
- この場合は、上位プランを優先して適用する。
-
subscription_start_datetime
に値があり、subscription_end_datetime
に値がない場合に「契約中」である。-
subscription_start_datetime
が未来日時のときはその日時より契約中となる。 -
subscription_end_datetime
が未来日時であっても値があれば契約完了として扱われる。
-
-
trial_start_datetime
に値があり、trial_end_datetime
に値がない場合に「トライアル中」である。-
trial_start_datetime
が未来日時のときはその日時よりトライアル中となる。 -
trial_end_datetime
が未来日時であっても値があればトライアル完了として扱われる。
-
プラン・サービス・機能の要件
Brightのサービス・機能と利用可能なプランのマッピングについてはサービス/機能/課金プラン/権限チェック(個人、チーム)を参照
表中のサービス分類と対応する初期データのservice_codeは下表参照
サービス分類 | service_code |
---|---|
スキルアップ | skill_up |
チームアップ | team_up |
採用・育成共通 | hr_basic |
採用 | hr_recruitment |
育成 | hr_training |
拡張プランについて
チーム数制限などを一般的なプランよりも大きく設定するプランを作る際には下記に注意する。
-
plan_codeをそれとわかるようにすること
-
hr_plan
であればhr_plan_extended_
のような命名とする
-
-
authorization_priority
を同じ機能を使えるプランよりも大きく、上位プランよりも小さくすること -
free_trial_priority
を設定しないこと- 無料トライアル対象外にするため
無料トライアルで利用可能なプラン
ユーザーはプランの無料トライアルを利用できる。ただし、利用可能かどうかはユーザー状況やプランで条件がある。
-
個者(社)対応として作成されているプランは利用できない。
-
データ上は、
subscription_plans.free_trial_priority
がnilなデータが該当する。
-
データ上は、
-
同一プランで、既にトライアル中か契約中がある(完了含む)場合は利用できない。
-
同一とは、データ上では
subscription_plans.plan_code
を指す。 - 上位プランのトライアルや契約が完了している場合は、利用できる。あくまで同一かどうかをみる。
-
同一とは、データ上では
-
より上位のプランのトライアル中か契約中であれば、利用できない。
- まず画面上において誘導しない。データ上は問題としない。
- 逆に、下位プランの無料トライアル中か契約中のときは利用できる。
-
個者(社)対応として作成されているプランは利用できない。
-
データ上は、
subscription_plans.free_trial_priority
がnilなデータが該当する。
-
データ上は、
サブスクリプションプランとサービスの初期データ登録
priv/repo/seed_dummy_data.exsに収録すみの下記関数でサービスタリフに即した初期データを登録できる。 収録データについてはSeedsファイル参照
Bright.Seeds.SubscriptionPlan.delete()
Bright.Seeds.SubscriptionPlan.insert()
Bright.Seeds.SubscriptionPlanService.insert()
Bright.Seeds.SubscriptionPlan.delete()
は、ユーザー毎の契約履歴も削除するので注意すること。
Subscriptions関数
前提情報の取得
# ユーザーID
Accounts.get_user_by_name_or_email("takuto4devops@gmail.com")
# プラン情報
Subscriptions.get_subscription_plan_with_enable_services_by_plan_code("team_up_plan")
登録系
※ 現状用意している関数では契約の重複チェックなど業務よりのバリデーションは未実装
# 無料トライアルの開始
Subscriptions.start_free_trial(user_id, subscription_plan_id)
# 即時有料プランの開始
Subscriptions.start_subscription(user_id, subscription_plan_id)
判定系
# サービスコードをキーに該当サービスの利用有無を返す
Subscriptions.service_enabled?(user_id, service_code)
# サービスコードをキーに該当サービスが利用可能な最も優先度の高いサブスクリプションプランを返す
Subscriptions.get_most_priority_free_trial_subscription_plan(service_code)
# 現在契約中のプランがあれば指定が必要
Subscriptions.get_most_priority_free_trial_subscription_plan(service_code, current_plan)
# サービスではなく、チーム数やチームメンバー数の上限で探す場合は下記
Subscriptions.get_most_priority_free_trial_subscription_plan_by_teams_limit(create_teams_limit, current_plan)
Subscriptions.get_most_priority_free_trial_subscription_plan_by_members_limit(team_members_limit, current_plan)
# プランコードをキーに該当プランのフリートライアル利用可否を返す
# ある場合、利用不可
Subscriptions.free_trial_available?(user_id, plan_code)
取得系
# ユーザーIDと基準時刻をキーに有効な契約内容を取得する
Subscriptions.get_users_subscription_status(user_id, NaiveDateTime.utc_now())
# ユーザーIDから現在有効な最上位のプラン(トライアル/契約を問わない)を取得する
Subscriptions.get_user_subscription_user_plan(user_id)
# フリートライアル済のプラン一覧を返す
Subscriptions.get_users_trialed_plans(user_id)