SimpleDetail
📖 3 menit baca

データベース テーブル

一般的な規則

  • 主キーは uuid を使用し、デフォルトは gen_random_uuid() です。
  • 時刻は timestamptz を使用し、UTC で保存します。
  • 金額は bigint を使用し、単位はミニ (50,000 Rupiah = 50000 ) です。浮動小数点数を使用しないようにします。
  • パスワード、トークン、クライアント シークレットはハッシュのみで保存します。
  • 主要なビジネス エンティティには created_atupdated_at があります。

主要テーブル

テーブル 機能 主キーと主な制約
members メンバーと管理者のアカウント email が一意; ロールが member / super_admin です。
products SaaS アプリケーションのカタログ code が一意; 例: NTO
plans 各製品のパッケージ (product_id, code) が一意; 価格は負でない必要があります。
licenses メンバーが製品にアクセスするライセンス license_key が一意; 1 つのライセンスは 1 つのメンバーと製品に対して有効です。
orders チェックアウト/再契約のセッション order_number が一意; チェックアウトの値を保存します。
payments 支払いの試行と結果 ゲートウェイのトランザクション ID が一意です。
webhook_events ゲートウェイのコールバック (Audit/Retry) ペイロードは jsonb です; イベントは idempotent です。

members

Null 説明
id uuid なし 主キー。
email varchar(320) なし 大文字小文字を区別しない一意の値。
full_name varchar(120) なし メンバーの表示名。
password_hash varchar(255) 有効 Argon2/bcrypt のハッシュ値。
status member_status なし unverifiedactivesuspendeddeleted のいずれか。
role member_role なし member (デフォルト) または super_admin のいずれか。
avatar_url text 有効 アバター URL (存在する場合)。
last_login_at timestamptz 有効 最後のログイン成功時刻。
created_atupdated_at timestamptz なし ライフサイクル メタデータ。

インデックス: lower(email) の一意インデックスと status のインデックス。

productsplans

テーブル 主要な列 説明
products idcodenamedescriptionwebsite_urlsso_redirect_uriis_activegrace_period_days code は 2-4 文字の大文字です; グレース パリオドはデフォルトで 7 日です。
plans idproduct_idcodenametypebilling_intervalprice_amountcurrencyduration_daysfeaturesis_active featuresjsonb です; 無料のパッケージは 0 の値と無期限です。

billing_interval: nonemonthly、または yearly のいずれかです。非アクティブな製品は再アクティブ化できず、非アクティブなパッケージは新規購入できません。

licenses

Null 説明
id uuid なし 主キー。
member_idproduct_idplan_id uuid なし 所有者、製品、パッケージの外部キー。
license_key varchar(32) なし 例: NTO-A1B2-C3D4-E5F6; グローバルで一意です。
tier varchar(50) なし パッケージのコード/階層のスナップショット。
status license_status なし activeactive_freegrace_periodsuspendedcancelled のいずれか。
started_atexpired_at timestamptz 有効 expired_at は無期限の場合に null です。
grace_period_ends_at timestamptz 有効 有料のライセンスのみがグレース パリオド内です。
cancelled_at timestamptz 有効 永久的なキャンセル時刻。
created_atupdated_at timestamptz なし ライフサイクル メタデータ。

インデックス: license_key の一意インデックス; (member_id, product_id) のインデックス; (member_id, product_id) の部分一意インデックス WHERE status <> 'cancelled'

orderspaymentswebhook_events

テーブル 主要な列 説明
orders idorder_numbermember_idproduct_idplan_idlicense_idstatusamountcurrencygatewayexpires_atpaid_at ステータス: pending_paymentpaidfailedexpiredcancelledduplicate のいずれか; license_id は最初のオーダーに null です。
payments idorder_idgatewaygateway_transaction_idgateway_referencestatusamountcurrencypaid_atraw_response ステータス: pendingsettlementfailedexpiredcancelledrefunded のいずれか。
webhook_events idpayment_idgatewayexternal_event_idevent_typesignature_validprocessed_atpayloadreceived_at ペイロードは jsonb です; 無効なイベントは記録されますが、ライセンスの有効化には影響しません。

paymentswebhook_events(gateway, gateway_transaction_id)(gateway, external_event_id) の一意インデックスは、ゲートウェイがイベント ID を提供する場合にのみ作成されます。ウェブホック ワーカーは、1 つのデータベース トランザクションで paymentorderlicenseaudit を更新します。

ID テーブルと OAuth2

テーブル 主要な列 説明
email_verification_tokens idmember_idtoken_hashexpires_atused_atcreated_at 新しいトークンは古いトークンを無効にします; 有効で未使用のトークンのみが受け入れられます。
password_reset_tokens idmember_idtoken_hashexpires_atused_atcreated_at ライフサイクルはトークン検証と同じです。
oauth_clients idclient_idclient_secret_hashnameredirect_urisallowed_scopesis_active URI とスコープは jsonb です; client_id は一意です。
authorization_codes idcode_hashmember_idoauth_client_idproduct_idlicense_idredirect_uriscopecode_challengecode_challenge_method、`expires