Schémas de données et leur évolution
1) Pourquoi est-ce la plate-forme iGaming
Fiabilité : les modifications apportées aux données ne brisent pas les rapports, les API et les modèles.
Vitesse Fich : Ajouter des champs en toute sécurité (KYC/RG/PSP) sans arrêter les strimes.
Réglementation : traçabilité et reproductibilité (audit/lineage, DSAR, Legal Hold).
Coût : minimiser les « débordements » et les backfils downtime.
2) Types de régimes et où ils vivent
Événements (strims) : 'payments. deposit_accepted`, `game. round_finished`.
OLTP/DDL : tables normalisées (KYC, comptes, limites).
DWH/vitrines (Gold) : unités dénormalisées sous BI/ML.
Feature Store : réseaux de fiches en ligne/offline avec des garanties de cohérence.
Contrats avec des partenaires externes : PSP, fournisseurs de jeux, sources de marketing.
Notations : Avro/Protobuf (strimes), JSON Schema (intégration), SQL DDL (DWH), Parquet schema (lac).
3) Compatibilité (noyau de l'évolution)
Backward-compatible : nouveaux vendeurs → anciens consumers (ajout d'un champ c default/nullable).
Forward-compatible : les anciens vendeurs → de nouveaux consumers (le nouveau lecteur ignore le superflu).
Full-compatible : les deux (objectif souhaitable pour les événements).
Breaking-changes : renommer/supprimer un champ, changer de type/sémantique, changer de clé/partitioning.
Règle 1 : les événements évoluent par addition, pas par modification.
Règle 2 : supprimer - seulement dans la version MAJOR du schéma après la période de déprécation.
4) Versions et politiques sémantiques
`MAJOR. MINOR. PATCH 'pour chaque schéma/vitrine/fich set.
MAJOR - Incompatible (nouveau topic/table/fich set, dual-run).
MINOR - Compatible (nouveaux champs nullables/par défaut, nouvelles valeurs enum).
PATCH - orthographe des descriptions/limites/commentaires.
Cycle de vie du champ : 'experimental → active → deprecated → removed' (avec dates et propriétaire).
5) Registre des schémas et contrats de données
Schema Registry : stocke les versions, la compatibilité, l'évolution et les propriétaires.
Contrat de données : fixe le schéma + SLO de qualité + vie privée (voir Validation des données).
json
{
"type":"record","name":"deposit_accepted","namespace":"payments",
"fields":[
{"name":"event_id","type":"string"},
{"name":"occurred_at","type":{"type":"long","logicalType":"timestamp-micros"}},
{"name":"user_id","type":"string"},
{"name":"brand","type":"string"},
{"name":"country","type":"string"},
{"name":"psp","type":"string"},
{"name":"method","type":"string"},
{"name":"amount","type":{"type":"bytes","logicalType":"decimal","precision":18,"scale":2}},
{"name":"currency","type":{"type":"enum","name":"Currency","symbols":["EUR","USD","TRY","BRL"]}},
{"name":"risk_score","type":["null","int"],"default":null}, // MINOR+
{"name":"kyc_level","type":["null",{"type":"enum","name":"Kyc","symbols":["L0","L1","L2","L3"]}],"default":null}
],
"compatibility":"FULL","owner":"team-payments"
}
6) Modèles de migration
6. 1 Événements (strimes)
Additive-only : nous ajoutons des champs avec default/nullable ; les anciens consumers ne se cassent pas.
Extensions enum : les nouveaux caractères sont considérés comme MINOR, les consumers sont tenus d'avoir une branche 'else/unknown'.
Migration MAJOR : le nouveau topic 'payments. deposit_accepted. v2 ', dual-write, shadow-reads, puis commutation consumers.
6. 2 DWH/vitrines
Tableau Bleu-Vert : 'gold. revenue_v2' à côté de « v1 » ; nous matérialisons, nous vérifions, nous changeons de BI.
Backfill : repliez sur snapshots + idempotent merge (par clés/versions).
SCD : type 2 pour les attributs qui changent lentement (limites, KYC, statuts VIP).
6. 3 Feature Store
Dual-serve : L'ancien fich set est entretenu parallèlement au nouveau ; le modèle est entretenu via un routeur.
Cohérence point-in-time : l'évolution ne doit pas briser les joyaux PITA (timestamp/granularité inchangée sous MINOR).
7) Taxonomie des changements (chèque-liste)
Sécurité (MINOR) :- ajout d'un champ 'nullable/default' ;
- extension enum (avec « unknown » - branche chez le consommateur) ;
- ajout d'un index/commentaire/description non personnalisé.
- changement d'échelle/unités (par exemple, amount en cents → en monnaie principale) - seulement en MAJOR ;
- transfert du manuel/référentiel - à travers la couche de représentation.
- renommer/supprimer le champ ;
- changement de type/format/clé/partition ;
- changement de sémantique (par exemple, 'bonus _ amount'de « facturé » → « débité »).
8) Circuits Linters et tests de compatibilité
Schema-lint : style de noms ('snake _ case'), étiquettes obligatoires ('owner', 'doc', 'pii'), format date/devises.
Compat-tests : nous vérifions la nouvelle version contre le registre (backward/forward/full).
Consumer-contract-tests : chaque service fournit un « exemple de charge utile » et des attentes ; on le propulse sur CI lors du changement de schéma.
Golden-datasets : ensemble d'exemples réels et « méchants » (nouveaux enum, champs vides/tardifs, valeurs limites des montants).
9) Manuels, enum et localisation
Référence-données (pays/devises/PSP/fournisseurs) : versions séparées et mises à jour SLA ; ne pas mettre dans le code des événements.
Local/fuseaux horaires : stocker UTC dans événements + local explicite pour la présentation.
Règles des juridictions : drapeaux d'âge, restrictions promotionnelles - sous forme de guides avec dates de validité.
10) Multibrand/multijuridictions et PII
Isolation tenante : 'brand', 'country', 'license' sont des champs obligatoires avec enum ; l'itinérance par eux.
Politique PII au niveau du schéma : on marque les champs 'pii = true', on applique des masques/tokenization ; dans les événements, ce ne sont que des jetons.
DSAR : présence de 'source _ id/trace _ id' pour supprimer/rechercher ; Legal Hold sur les migrations MAJOR.
11) Versioning DDL et Lake
Migrations DDL : migrations déclaratives (Liquibase/Flyway/dbt), stockage dans le VCS, par le propriétaire du domaine.
Formats dans le lac : Avro/Parquet - nous enregistrons l'évolution des champs ; sous MAJOR, une nouvelle table/chemin '.../v2/'.
Partitioning : modification des lots (par exemple, 'date'→'date,brand') - uniquement via MAJOR et double enregistrement.
12) Exemples iGaming
12. 1 PSP a élargi les méthodes
Ajout de 'method =' MEFETE 'dans enum.
Version MINOR du schéma 'deposit _ accepted v1. 8. 0`; les consumers qui ne connaissent pas MEFETE envoient à la branche 'unknown _ method'.
12. 2 Le fournisseur de jeux a ajouté des champs
Dans 'game. round_finished' 'jackpot _ id' (nullable) a été ajouté.
Vitrine 'gold. game_rounds_v3' reçoit une MINOR ; les anciens rapports fonctionnent, les nouveaux comptent les jackpots.
12. 3 attributs RG
Passer du booléen 'self _ excluded' au status 'rg _ state ∈ {none, limit, cooldown, self_excluded}' - MAJOR, nouvelle migration topique + dual-write + vitrines et modèles.
13) Processus d'évolution (de l'idée au changement)
1. Proposal (ADR) : pourquoi changer, le type de compatibilité, l'évaluation des risques et les consommateurs touchés.
2. Conception et contrat : schéma dans le registre, semver, politique d'interopérabilité.
3. Tests : linters, compat, consumer-contracts, repli sur les réseaux golden.
4. Déploiement : dual-write/blue-green/shadow-reads ; alerte.
5. Rapprochement : bilans d'affaires/invariants (voir Validation des données).
6. Switch : commuter consumers/BI/fichi.
7. Deprecate : freeze de l'ancien schéma, grace-period, suppression et archive.
14) Métriques et SLO de l'évolution
Taux de réussite des migrations, temps de double exécution, proportion d'événements du nouveau format, volume backfill, lag/freshness.
Incidents de compatibilité (P1/P2), qualité des vitrines après commutation.
Cost : $/TB débordement, $/heure dual-write, chargement de cluster.
Conformité : 0 fuites PII, SLA DSAR/Legal Hold respecté.
15) Outils et artefacts
15. 1 Politique d'interopérabilité (registre)
yaml schema: payments. deposit_accepted compatibility: FULL default_nulls: true enums:
currency: {allow_new_symbols: true, require_consumer_unknown_branch: true}
pii: false owners: ["team-payments"]
reviewers: ["data-governance","security-dpo"]
15. 2 Passeport de migration (modèle)
yaml change_id: MIG-2025-041 scope: game. round_finished -> v3 type: MAJOR plan:
dual_write: true shadow_reads: consumers: ["gold-rounds","rg-models"]
backfill: {from: "2025-01-01", mode: "idempotent-merge"}
validation:
invariants: ["sum_bets = sum_wins + margin + bonuses"]
freshness_delta_p95_max: "PT5M"
switch_criteria:
error_rate_max: 0. 1%
kpi_diff_pp_max: 0. 5 deprecate_after: "2025-12-31"
15. 3 Linter noms et types (règles)
'snake _ case ', UTC timestamps, DECIMAL (18,2) pour les montants,' country 'par ISO-3166-1 alpha-2,' currency 'par ISO-4217.
Pas de 'free _ text'pour les champs enum ; les manuels sont extérieurs.
16) Feuille de route pour la mise en œuvre
0-30 jours (MVP)
1. Activer Schema Registry + politique de compatibilité pour les événements clés (payments, game_rounds, user).
2. Linters/compat-tests en CI ; annuaire des propriétaires et avis SLA.
3. Modèles ADR et passeport de migration ; chèque MAJOR.
30-90 jours
1. Bleu-Vert pour les vitrines Gold ; dual-write pour les sujets critiques.
2. Consumer-contract-tests pour les services essentiels ; golden-datasets.
3. Des rapprochements diff automatiques et des alertes lors des commutations ; rapports de valeur.
3-6 mois
1. Un seul processus deprecate/remove avec grace-period ; archivage et Legal Hold.
2. Des circuits géo/tenants spécifiques et des clés de cryptage ; Options DP pour les marchés sensibles.
3. Répertoire de la sémantique des champs (data dictionary) et diagrammes de lignage en direct.
17) RACI
Data Governance (A/R) : normes, registre, revues des migrations, publication.
Domaine Owners (R) : sens des champs, manuels, invariants d'affaires.
Data Platform (R) : outils de registre, compat-test, dual-run/backfill.
Sécurité/DPO (A/R) : Politiques PII, geo/tenant, DSAR/Legal Hold.
SRE/Observability (C) : alertes, SLO des évolutions, capacity.
Product/Finance (C) : validation KPI, fenêtres de commutation.
18) Anti-modèles
« Je règle le champ à la volée » sans version et dual-run.
Renommer au lieu d'ajouter un nouveau champ → les pannes massives.
Enum rigide sans branche 'unknown' → chute à de nouvelles valeurs.
Un manuel unique « en code » pour toutes les juridictions.
Backfill sans idempotent-merge et chèques-balances.
Logs avec PII et sans trace_id pour la recherche/DSAR.
19) Sections connexes
Validation des données, Origine et chemin des données, Pratiques DataOps, API analytiques et métriques, Audit et versionalité, Sécurité des données et cryptage, Contrôle d'accès, MLOps : exploitation des modèles.
Résultat
L'évolution des schémas est un processus et non une migration ponctuelle : registre, versions et interopérabilité ; dual-run et blue-green au lieu de « commutateurs à minuit » ; tests de compatibilité et invariants d'affaires au lieu de bonne chance. C'est ainsi que les données restent stables, les modèles prévisibles, les rapports corrects et les régulateurs calmes.