GH GambleHub

DDD dans le noyau iGaming

La plate-forme iGaming est un système de domaine complexe à la jonction de la finance, du divertissement et de la conformité. DDD aide à retenir la complexité : il met en évidence les contextes boundés, enregistre la langue ubiquitous, protège les invariants avec des agrégats, simplifie les intégrations à travers les couches anticorruption et rend le comportement du système transparent grâce aux événements de domaine.

1) Carte des domaines et des contextes boundés (conception stratégique)

Décomposition recommandée :
  • Player/KYC Context - inscription, vérification, limites du jeu responsable, statuts KYC/AML.
  • Wallet/Ledger Context - balances, réservations, câblage, multi-devises, cours.
  • Betting Context - paris/tickets, couple/résultats, cotations, calcul (settlement), annulation.
  • Casino/Game Round Context - sessions, tours, dos, contrôle RTP, limites de mise.
  • Bonus/Promo Context - règles de bonus, wagon, équairing de bonus, anti-abyse.
  • Risk/Fraud Context - scoring, signaux comportementaux, déclencheurs de verrouillage/temporisation.
  • Payments Context - dépôts/retraits, statuts de passerelles de paiement, événements chargeback.
  • Conformité/Reporting Context - rapports aux régulateurs, listes de sanctions, audit.
  • Content/Provider Integration Context - intégration avec les fournisseurs de jeux, catalogues, techniques. les statuts.
  • Analytics/Read Models - projections et vitrines sous les lectures de produits.
💡 Relations inter-contours - via des événements de domaine et des commandes asynchrones ; appels synchrones - seulement lorsque c'est vraiment un contrat de domaine et qu'une stricte cohérence est nécessaire.

2) Langue ubiquitous : le noyau des termes

Player (Joueur), Session (Session), GameRound (Round), Bet/Ticket (Parier),

Ledger Entry (câblage), Hold/Reserve (Réserve), Settlement (Calcul),

Bonus Credit / Bonus Balance, Wagering Requirement (Вейджер),

KYC Tier, Limit (dépôt/session/perte), Self-Exclusion,

Provider Game, RTP Window, Risk Flag, Compliance Case.

Ces noms sont également utilisés dans le code, les bases de données, la documentation, les tests et les interfaces.

3) Agrégats et invariants (conception tactique)

3. 1 Wallet (Aggregate: `Wallet`)

Invariants :
  • L'équilibre ne va pas dans le négatif.
  • Réserve + disponible ≤ solde total.
  • Le câblage est atomique et idempotent (par "opération _ id').
Commandes/événements :
  • `Wallet. Reserve(amount, reason, op_id)` → `WalletReserved`
  • `Wallet. Commit(op_id)` → `WalletCommitted`
  • `Wallet. Rollback(op_id)` → `WalletRolledBack`

Frontière : Wallet ne connaît pas Bet/Bonus ; il sert les opérations de câblage et de réserve.

3. 2 Bet/Ticket (Aggregate: `Bet`)

Invariants :
  • Le taux ne peut être accepté que dans la fenêtre de cotation active ; le montant ≤ la limite joueur/session.
  • Après 'Settled', le statut est « finalisé » ; le recalculage n'est autorisé que par des opérations de compensation (void/recalc) avec un audit clair.
Commandes/événements :
  • `Bet. Place(player_id, amount, price, op_id)` → `BetPlaced` (требует Wallet. Reserve)
  • `Bet. Settle (outcome, payout) '→' BetSettled '(nécessite Wallet. Commit/Release)
  • `Bet. Void(reason)` → `BetVoided`

Bordure : Bet ne « s'accroche » pas à Wallet - s'adresse via les commandes de domaine/orchestration.

3. 3 GameRound (Aggregate: `Round`)

Invariants :
  • Chaque spin/round a un 'round _ id' unique et un montant de pari/gain associé.
  • La fenêtre RTP ne dépasse pas les seuils spécifiés (au niveau du fournisseur + règles locales).
Événements :
  • `Round. Started`, `Round. Staked`, `Round. Resulted`, `Round. Closed`.

3. 4 Bonus (Aggregate: `BonusGrant`)

Invariants :
  • Le Wager ne diminue que par rapport au chiffre d'affaires validé, le prélèvement du bonus ne passe pas au débit.
  • Vous ne pouvez pas débiter le bonus en même temps et les fonds réels ne sont pas soumis à la règle de priorité.
Événements :
  • `BonusGranted`, `BonusWagered`, `BonusExpired`, `BonusConverted`.

4) Orchestrations, sagas et cohérence

Synchrone (CP) : accepter le taux et la réserve de fonds est une voie unique : 'Bet. Place` → `Wallet. Reserve '(via la commande de domaine/orchestrateur avec deadline).
Asynchrone (EC) : calcul du taux, calcul des primes, analyse - à travers les événements + outbox.
Option TCC : 'TryReserve' (hold), 'Confirm' (commit),' Cancel '(rollback) pour les effets monétaires.
Idempotence : toutes les commandes portent « opération _ id », les consumers portent « inbox ».

5) Couches anticorruption (ACL) et intégration

Provider ACL : diffusion des événements providentiels 'SpinResult', 'BonusWin' dans le round interne. Resulted`, `BonusWagered`. Schémas et versions - à l'intérieur de l'ACL.
PSP ACL : normalisation des statuts de paiement, idempotence par 'psp _ tx _ id', transfert dans' LedgerEntry '.
Compliance ACL : intégration avec les listes de sanctions/RER dans un contexte externe ; seuls les 'ScreeningUpdated' normalisés entrent dans le domaine.

Règle : Les dictionnaires/formats externes ne s'infiltrent pas à l'intérieur du noyau.

6) Projections et modèles de lecture

Player Profile Read Model : statuts KYC, limites, bonus actifs, transactions récentes.
Balances Read Model : lectures rapides pour l'IU/marketing ; la source est « Wallet » de l'événement.
Bet History Read Model : pagination par date/jeu ; la source est 'BetPlaced/Settled'.
Rapports de conformité : représentations matérialisées par tenant/région.

Toutes les projections sont idempotent upsert's versioning et 'as _ of/freshness'.

7) Multi-tenant et multi-région

Toutes les entités clés portent "tenant _ id'et (si nécessaire)" region ".
Limites de données : joueur, portefeuille, paris - région « maison » ; seulement les agrégats/rapports croisés.
Fairness/quotas : limites par équipe/seconde et redrave par tenants.
Résidence/conformité : les données personnelles et les affiches ne quittent pas la région.

8) Sélection de cohérence (PACELC) par contexte

Wallet/Ledger - Strong/CP : câblage linéarisable, quorum des enregistrements.
Bet acceptation - confirmation synchrone (CP) + modèles de lecture rapide pour l'interface utilisateur.
Settlement/Bonus/Analytics - EC avec merge/compensation déterministe.
KYC/Conformité - Il peut y avoir un EC pour les statuts, mais les règles de « blocage » s'appliquent de manière synchrone.

9) Événements de domaine : Contrats et version

Jeu minimum de champs :
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"
}
Règles :
  • Back/forward-compat de schémas ; évolution par 'schema _ version'.
  • « outbox » dans une transaction avec des modifications de domaine ; publication de battes avec backoff.

10) Exemple de flux « Parier avec un bonus » (séquence verbale)

1. `Bet. Place '(commande) → vérifie les limites du joueur et les règles de bonus →' Wallet. Reserve(real+bonus_equiv, op_id)`

2. 'BetPlaced' (événement) → Read Model met à jour « Paris ouverts »

3. Le fournisseur publie le résultat → ACL → 'Round. Resulted`

4. L'orchestrateur calcule : 'Bet. Settle(outcome,payout)` → `Wallet. Commit (op_id) 'et, si vous gagnez,' BonusWagered '→ la conversion possible du bonus en réel.
5. 'BetSettled' → projections de l'histoire et des bilans, rapports.

11) Invariants et politique de test

Invariants clés :
  • La somme de tous les 'LedgerEntry' par portefeuille est égale au solde ; il n'y a pas de résidus négatifs.
  • Vous ne pouvez pas accepter un pari avec un statut KYC auto-exclusion/gelé actif.
  • Wager ne peut que diminuer et ne pas basculer dans le négatif.
  • Settlement ne change pas le statut d'un pari déjà finalisé - seulement par "Void/Recalc' + câblage compensatoire.
Tests :
  • Property-based tests invariants portefeuille et paris.
  • Contours de chaos : retards du fournisseur, pannes PSP, redraves outbox/DLQ.
  • Contrôle des schémas : migration d'événements, backfill de projections.

12) Télémétrie et audit

Métriques : p95/p99 sur PlaceBet/Reserve/Commit, taux d'échec par limite/CUS, taux DLQ, redrive success, lag projections.
Tracing : spans « komanda→agregat→outbox→konsyumer→proyektsiya », balises 'tenant _ id', 'opération _ id', 'saga _ id'.
Audit : Journal des activités de domaine inchangé, comparable aux exigences réglementaires.

13) Schéma de stockage (simplifié)

Wallet:

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:

bet(id, tenant_id, player_id, amount, price, status, placed_at, settled_at, operation_id)
Bonus:

bonus_grant(id, tenant_id, player_id, amount, wager_left, status, expires_at)

Le versioning sur les agrégats ('version') protège contre la perte de mise à jour lors de l'écriture concurrentielle.

14) Exemple d'API de commande (pseudo)

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":"..." }

Toutes les commandes sont avec 'opération _ id' pour l'idempotence, les réponses sont avec 'as _ of '/' version'.

15) Sécurité et conformité

RLS/ACL : toutes les requêtes sont dans le contexte "tenant _ id', accès par rôle.
PII-minimisation : séparer les événements de domaine des données personnelles ; déguisement dans DLQ/logs.
Rapports réglementaires : projections avec signatures hachées immuables à travers les fenêtres du temps.

16) Erreurs typiques

Forte connectivité entre les contextes (Wallet connaît directement Bet/Bonus).
Dual-write dans des contextes différents sans sag/outbox → accord sur les soldes et les statuts.
L'absence d'idempotence des commandes et des consumers → les prises de câblage/de calcul.
Passer des contrats de fournisseurs dans un modèle de domaine (plus difficile à migrer).
Une unité « géante » (Player inclut tout) → verrouillage, faible throughput.
Il n'y a pas d'invariants évidents - ils ne peuvent pas être testés et surveillés.

17) Recettes rapides

Début : fixez la langue Ubiquitous et les limites contextuelles ; documenter les invariants.
Argent : Wallet/Ledger - CP, enregistrements de quorum, TCC pour les effets externes.
Tarifs : réception synchrone + calcul asynchrone, tout via événements et outbox ; l'idempotence est partout.
Bonus : une unité séparée avec une priorité claire des prélèvements et un vader.
Intégrations : toujours via ACL + schémas/versions ; pas de « matière première » payload's dans le noyau.
Lectures : projections/vitrines sur les besoins du produit ; SLA de fraîcheur + 'as _ of'.
Opération : métriques invariantes, DLQ/Pleybooks redrive, vitrine rebuild.

18) Chèque-liste avant la vente

  • Les soumissions boundées et leurs contrats (commandes/événements) sont définis.
  • Les agrégats ont des invariants, des versionnages et des commandes idempotentes explicites.
  • Transactions monétaires - par le biais de STS/transaction rigoureuse ; l'audit est inclus.
  • Intégrations - via ACL avec versioning des schémas et tests d'évolution.
  • Mis en œuvre outbox/inbox, DLQ et sécurisé redrive.
  • Les projections réalisent un SLA de fraîcheur, il y a des métriques lag/staleness.
  • Les quotas/limites multi-tenants et la résidence de données ont été respectés.
  • Observabilité : tracing « komanda→sobytiye→proyektsiya », alertes par invariants.
  • Documentation : langue du domaine, diagrammes de contexte, pleybooks d'incidents.

Conclusion

DDD dans le noyau iGaming est une discipline de partage de la complexité : limites claires des contextes, agrégats avec invariants, événements comme source de vérité, ACL pour les intégrations externes et choix de cohérence éclairé. Cette approche rend la plate-forme évolutive, fiable et adaptée à la réglementation, accélère le développement de la fiche et réduit les risques opérationnels - même avec une croissance rapide du trafic, de la géographie et de la gamme de produits.

Contact

Prendre contact

Contactez-nous pour toute question ou demande d’assistance.Nous sommes toujours prêts à vous aider !

Telegram
@Gamble_GC
Commencer l’intégration

L’Email est obligatoire. Telegram ou WhatsApp — optionnels.

Votre nom optionnel
Email optionnel
Objet optionnel
Message optionnel
Telegram optionnel
@
Si vous indiquez Telegram — nous vous répondrons aussi là-bas.
WhatsApp optionnel
Format : +code pays et numéro (ex. +33XXXXXXXXX).

En cliquant sur ce bouton, vous acceptez le traitement de vos données.