iGamingコアのDDD
iGamingプラットフォームは、金融、エンターテイメント、コンプライアンスの交差点にある複雑なドメインシステムです。DDDは複雑さを保つのに役立ちます:境界のあるコンテキストを強調し、ユビキタス言語をキャプチャし、不変量を集約で保護し、破損防止層を通じて統合を簡素化し、ドメインイベントを通じてシステム動作を透明化します。
1)ドメインマップと境界コンテキスト(戦略設計)
推薦された分解:- プレイヤー/KYCコンテキスト-登録、検証、責任あるゲーム制限、KYC/AMLステータス。
- ウォレット/元帳コンテキスト-残高、予約、トランザクション、マルチカレンシー、為替レート。
- 賭けコンテキスト-賭け/チケット、ペア/結果、引用符、和解、キャンセル。
- カジノ/ゲームラウンドコンテキスト-セッション、ラウンド、バック、RTPコントロール、賭け制限。
- ボーナス/プロモーションコンテキスト-ボーナスルール、賭け、ボーナスファンドの取得、不正使用防止。
- Risk/Fraud Context-スコアリング、行動シグナル、ロック/タイムアウトトリガー。
- 支払いコンテキスト-入金/出金、支払いゲートウェイのステータス、チャージバックイベント。
- コンプライアンス/報告コンテキスト-規制当局への報告、制裁リスト、監査。
- コンテンツ/プロバイダ統合コンテキスト-ゲームプロバイダ、カタログ、技術との統合。ステータスを指定します。
- Analytics/Read Models-製品の読み取りのための予測とショーケース。
2)ユビキタス言語: 用語のコア
プレイヤー、セッション、GameRound、ベット/チケット、
レジャーエントリー、ホールド/リザーブ、和解、
ボーナスクレジット/ボーナス残高、賭け要件(Вейджер)、
KYC層、限界(沈殿物/セッション/損失)、自己排除、
プロバイダーゲーム、RTPウィンドウ、リスクフラグ、コンプライアンスケース。
これらの名前は、コード、データベース、ドキュメント、テスト、インターフェイスでも同様に使用されます。
3)集計・不変量(戦術設計)
3.1 Wallet(集計:'Wallet')
不変量:- バランスは負の領域に入りません。
- 予約+合計残高≤利用できます。
- 配線はatomicとidempotent ('operation_id'による)です。
- '財布。予約(金額、理由、op_id)'→'WalletReserved'
- '財布。Commit (op_id)'→'WalletCommitted'
- '財布。ロールバック(op_id)'→'WalletRolledBack'
ボーダー:ウォレットはBet/Bonusについて知りません。それは投稿と予約取引を提供します。
3.2ベット/チケット(集計:'ベット')
不変量:- レートはアクティブな見積ウィンドウでのみ受け付けることができます。プレイヤー/セッション≤制限額。
- 'Settled'の後、ステータスは'finalised';再計算は、明確な監査でオペレーション(void/recalc)を補償することによってのみ許可されます。
- 'ベット。Place (player_id、金額、価格、op_id)'→'BetPlacted'ウォレット。リザーブ)
- 'ベット。Settle (result、 payout)'→'BetSettled'(ウォレットが必要です。コミット/リリース)
- 'ベット。Void (reason)'→'BetVoided'
ボーダー:ベットはウォレットに「登る」ことはありません-ドメインコマンド/オーケストレーションを通じて呼び出します。
3.3 GameRound(集計:'Round')
不変量:- 各スピン/ラウンドには固有の'round_id'と関連するベット/勝利金額があります。
- RTPウィンドウは指定されたしきい値(プロバイダレベル+ローカルルール)を超えません。
- 'ラウンド。開始'、'ラウンド。Staked'、'Round。結果'、'ラウンド。「閉まった」
3.4ボーナス(集計:'BonusGrant')
不変量:- ベージャーは有効な売上高からのみ減少し、ボーナスライトオフはデビットには入りません。
- 優先ルールではなく、ボーナスとリアルファンドを同時に書くことはできません。
- 「ボーナス付与」、「ボーナス賭け」、「ボーナス期限切れ」、「ボーナス変換」。
4)オーケストレーション、サガ、コヒーレンス
同期(CP):ベットと資金の準備金の受け入れ-一方の方法:'賭け。Place'→'Wallet。リザーブ'(ドメインチーム/オーケストレーターによる期限付き)。
非同期(EC):レート計算、ボーナス発生、分析-イベントを通じて+アウトボックス。
TCCバリアント:"TryReserve" (hold)、 "Confirm' (commit)、" Cancel "(rollback)。
Idempotence:すべてのコマンドは'operation_id'、消費者-'inbox'を実行します。
5)腐敗防止層(ACL)と統合
プロバイダACL:プロバイダイベント'SpinResult'、 'BonusWin'を内部'Round'に翻訳します。結果'、'BonusWagered'。スキーマとバージョンはACL内にあります。
PSP ACL:支払いステータスの正規化、'psp_tx_id'によるidempotency、 'LedgerEntry'への転送。
コンプライアンスACL:制裁リスト/RAPとの統合-外部コンテキストで;正規化された'ScreeningUpdated'のみがドメイン内に入ります。
ルール:外部辞書/フォーマットはカーネルに「漏れ」しません。
6)予測と読み取りモデル
プレイヤープロフィール読むモデル:KYCのステータス、制限、アクティブボーナス、フレッシュトランザクション。
Balances Read Model: UI/マーケティングの高速読み取り;source-'Wallet'イベント。
ベット履歴読み取りモデル:日付/ゲームによるページネーション;ソースは'BetPlained/Settled'です。
コンプライアンスレポート-テナント/地域別のマテリアライズされたビュー。
すべての投影は、バージョン管理機能と「as_of/freshness」を備えたidempotent upsertです。
7)複数のテナントおよび複数の地域
すべてのキーエンティティには'tenant_id'と(必要に応じて)'region'があります。
データ境界:プレーヤー、ウォレット、ベット-「ホーム」領域。クロスリージョンアグリゲート/レポートのみ。
公平性/クォータ:チーム/秒の制限とテナントの再利用。
居住/コンプライアンス:個人データと取引は地域を離れません。
8)コンテキストによる一貫性の選択(PACELC)
Wallet/Ledger-Strong/CP: linearizable transactions、 quorum of records。
Bet acceptance-UIの同期確認(CP)+高速読み取りモデル。
決済/ボーナス/アナリティクス-決定的なマージ/補償を伴うEC。
KYC/Compliance-ステータスはECになりますが、「ブロック」ルールは同期して適用されます。
9)ドメインイベント: 契約とバージョン
フィールドの最小セット:json
{
"event_id": "uuid",
"event_type": "BetPlaced",
"occurred_at": "timestamp",
"tenant_id": "T123",
"aggregate_id": "BET-...-UUID",
"version": 7,
"payload": { "...domain fields..." },
"schema_version": "v3"
}
ルール:
- バック/フォワードコンパットスキーム;'schema_version'による進化。
- ドメインが変更されたトランザクションの'outbox';バックオフ付きのバッチによる出版。
10) 「Bet with Bonus」フローの例(ワードシーケンス)
1。'賭け。Place'(チーム)→checking player limits and→'Walletボーナスルール。Reserve (real+bonus_equiv、 op_id)'
2.'BetPlacted'→モデルの更新を読む'Open Wagers'
3.プロバイダは、結果→the→'Round ACLを公開します。「結果」(Resulted')
4.オーケストレーターは次のように計算します。Settle (result、 payout)'→'Wallet。コミット(op_id)'と、勝った場合、'BonusWagered'→実際のボーナスへの変換の可能性。
5.「BetSettled」→歴史とバランスシートの予測、レポート。
11)不変量およびテストポリシー
主な不変量:- ウォレット内のすべての'LedgerEntry'の合計はバランスに等しいです。負の残差はありません。
- アクティブな自己排除/凍結KYCステータスのベットは受け付けられません。
- 賭け金は「マイナスで」振ることはなく、減少することしかできません。
- 決済は「Void/Recalc」+オフセット取引を通じてのみ、既に確定したレートのステータスを変更しません。
- ウォレット不変量とベットのプロパティベースのテスト。
- カオスの輪郭:プロバイダの遅延、PSPの障害、outbox/DLQの再送。
- スキーマ制御:イベントマイグレーション、バックフィル投影。
12)テレメトリーと監査
メトリクス:PlaceBet/Reserve/Commitのp95/p99、 limits/ACCによる失敗のシェア、DLQレート、redrive success、 lag projections。
トレース:「komanda→agregat→outbox→konsyumer→proyektsiya」、タグ'tenant_id'、 'operation_id'、 'saga_id'にまたがる。
監査:規制要件に匹敵するドメイン活動の変更のないログ。
13)ストレージスキーム(簡略化)
ウォレット:
wallet(id, tenant_id, currency, balance, reserved, version)
ledger(id, wallet_id, amount, type, operation_id, occurred_at)
holds(id, wallet_id, amount, operation_id, expires_at, status)
ベット:
bet(id, tenant_id, player_id, amount, price, status, placed_at, settled_at, operation_id)
ボーナス:
bonus_grant(id, tenant_id, player_id, amount, wager_left, status, expires_at)
aggregates ('version')でのバージョン管理は、競合レコーディング中に失われたアップデートから保護されます。
14) コマンドAPIの例(擬似)
http
POST /bets. place
{
"tenant_id":"T1",
"player_id":"P42",
"amount":"10. 00",
"price":"2. 1",
"operation_id":"op-uuid",
"context":{"game_id":"g777","channel":"web"}
}
→ 202 Accepted + BetPlaced
POST /wallets. reserve
{ "wallet_id":"W1", "amount":"10. 00", "operation_id":"op-uuid", "reason":"bet" }
→ 200 { "reserved_balance":"..." }
すべてのコマンドはidempotencyのために'operation_id'で、応答は'as_of'/'version'である。
15)安全性とコンプライアンス
RLS/ACL:すべてのリクエスト-'tenant_id'のコンテキストで、ロールごとにアクセスします。
PII最小化:ドメインイベントと個人データの分離;DLQ/ログのマスキング。
規制レポート:時間ウィンドウに変更のないハッシュ署名を持つ投影。
16)典型的なエラー
コンテキスト間の強力な接続性(ウォレットはBet/Bonusを直接知っています)。
sagas/outbox→balancesとstatusesの不一致なしで、異なるコンテキストへの二重書き込み。
コマンドと消費者の独自性の欠如→重複したトランザクション/計算。
ドメインモデルへのプロバイダ契約の流れ(移行がより困難です)。
1つの「巨大な」集計(プレーヤーはすべて含んでいます)ロック→、低いスループット。
明白な不変量はありません-それらをチェックして監視することはできません。
17)クイックレシピ
開始:ユビキタス言語とコンテキストの境界を修正します。ドキュメントインバリアント。
お金:財布/元帳-CP、クォーラムエントリ、外部効果のTCC。
ベット:同期受信+非同期計算、すべてイベントとアウトボックスを介して;idempotencyはどこでもあります。
ボーナス:明確なwrite-ofs優先度とvagerを持つ個別のユニット。
統合:常にACL+スキーム/バージョン;コアに「生」のペイロードはありません。
読書:プロダクト必要性の投影/表示;SLA freshness+'as_of'。
操作:不変量のメトリック、DLQ/リドレーブプレイブック、ショーケースの再構築。
18)売り上げ前のチェックリスト
- 境界コンテキストとそのコントラクト(コマンド/イベント)が定義されます。
- 集計には明示的な不変量、バージョン管理、およびidempotentコマンドがあります。
- 金融取引-TCCを通じて/厳格なトランザクション;監査が有効になっています。
- 統合-スキーマバージョニングおよび進化テストを含むACLを介して。
- outbox/inbox、 DLQ、 secure redrawを実装。
- 投影はSLAの鮮度を実装し、ラグ/ステールネス指標があります。
- マルチテナント・クォータ/リミットとデータ・レジデンシーを満たしています。
- 観測可能性:「komanda→sobytiye→proyektsiya」のトレース、不変量によるアラート。
- ドキュメント:ドメイン言語、コンテキスト図、インシデントプレイブック。
結論
iGamingコアのDDDは、明確なコンテキスト境界、不変量との集約、真実の源としてのイベント、外部統合のためのACL、および情報に基づいた整合性の選択など、複雑さの分離の分野です。このアプローチにより、プラットフォームはスケーラブルで信頼性が高く、規制に準拠し、機能の開発をスピードアップし、トラフィック、地域、製品ラインの急速な成長に伴い、運用上のリスクを軽減します。