BlackgradeSystems

Note de terrain Grand livre

Concevoir un grand livre pour la monnaie électronique

Un solde est une conséquence, pas un champ que l’on met à jour.

La description la plus courte d'un grand livre correct, c'est qu'il ne contient aucun solde. Il contient des mouvements, et les soldes sont ce qu'on obtient en les additionnant.

01

Pourquoi un solde stocké finit toujours par dériver

Un solde stocké est le cache d'un calcul, et comme tout cache il peut diverger de ce qu'il met en cache. La divergence ne suppose pas une erreur d'arithmétique. Un rejeu qui écrit deux fois, une transaction qui valide le mouvement mais échoue avant la mise à jour du solde, un script de réparation lancé par quelqu'un de bien intentionné, une migration de schéma qui réordonne les écritures : chacun produit un solde qu'aucune suite de mouvements n'explique.

Une fois que c'est arrivé, le système a perdu la capacité de répondre à la seule question qui compte, à savoir pourquoi. Vous voyez qu'un utilisateur a quarante euros. Vous ne savez pas d'où ils viennent, et personne d'autre non plus.

Calculer le solde supprime le mode de défaillance en supprimant la seconde copie. Il n'y a qu'une représentation de la vérité, et la lire est une requête.

02

L'écriture est l'atome

Tout ce que le grand livre sait s'exprime en écritures immuables, chacune un montant signé sur un compte, groupées en transactions dont la somme doit être nulle.

Les montants sont des entiers en unités mineures. La virgule flottante dans un grand livre n'est pas un raccourci, c'est la décision d'être faux d'un montant imprévisible. Si vous gérez des devises à exposants différents, portez l'exposant explicitement plutôt que de supposer deux décimales.

Le champ motif est une valeur énumérée, pas de la prose. C'est lui qui permet de répondre à « combien avons-nous bougé du fait des impayés le trimestre dernier » sans faire une recherche plein texte.

ChampSensNote
transaction_id Groupe les écritures qui doivent réussir ou échouer ensemble. Immuable
compte Quel compte interne ou utilisateur ce côté touche. Issu du plan de comptes
montant Unités mineures signées, avec une devise explicite. Entiers uniquement
temps_evenement Quand le fait sous-jacent s'est produit. Monde extérieur
temps_enregistrement Quand le grand livre l'a appris. Ordre d'ajout
date_de_valeur La date à laquelle l'écriture prend effet comptable. Reporting
cle_idempotence Référence fournie par l'appelant, unique par opération logique. Sûreté au rejeu
motif L'événement métier qui justifie le mouvement. Pas du texte libre
03

Rien n'est jamais supprimé ni modifié

Une erreur dans un grand livre se corrige par une écriture de contrepassation, jamais en modifiant ou en supprimant l'originale. Cela semble du gaspillage la première fois et évident la dixième, parce que l'alternative détruit la propriété qui rend le grand livre utile : la stabilité du passé.

Une contrepassation porte un lien vers ce qu'elle annule et son propre motif. Un utilisateur qui voit un mouvement et son annulation comprend davantage qu'un utilisateur qui ne voit rien, et un auditeur qui voit les deux apprend que l'établissement détecte et corrige ses propres erreurs, ce qui vaut mieux démontrer que cacher.

04

Le plan de comptes est la conception

L'essentiel de l'intelligence d'un grand livre vit dans la structure des comptes, parce que les invariants s'expriment comme des énoncés sur des groupes de comptes. Si la somme des comptes de dettes envers les utilisateurs doit égaler la somme des comptes d'actifs cantonnés, cette égalité n'est vérifiable que si les comptes sont classés.

Donnez à chaque compte un type, un sens normal, et une place dans une hiérarchie. Les vérifications d'invariants deviennent alors des requêtes sur la hiérarchie plutôt que des listes tenues à la main qui se périment quand quelqu'un ajoute un compte pour un nouveau prestataire.

Les comptes internes méritent autant de soin que les comptes utilisateurs. Argent en transit, commissions acquises mais non prélevées, flottant chez le prestataire, arrondis, compte d'attente : chacun est un endroit réel où de la valeur peut se trouver, et s'il n'a pas de compte, la valeur sera poussée dans un compte où elle n'a rien à faire et l'invariant échouera pour une raison introuvable.

Le compte d'attente n'est pas une poubelle Un compte d'attente est légitime et doit rester petit, daté et surveillé. Une écriture qui y séjourne depuis soixante jours est une question non résolue sur de l'argent réel. Alertez sur l'ancienneté du plus vieil élément, pas sur le total.
05

La performance sans renoncer au calcul

L'objection habituelle aux soldes calculés, c'est qu'additionner des millions d'écritures à chaque lecture est impossible. La réponse tient dans les instantanés, qui sont un cache avec une règle : un instantané enregistre le solde d'un compte à un numéro de séquence donné, et lire un solde courant revient à prendre le dernier instantané et à lui appliquer les écritures suivantes.

La différence avec un solde stocké, c'est qu'un instantané est reproductible. Il peut être supprimé et recalculé depuis le journal à tout moment, et une tâche de fond peut vérifier les anciens instantanés contre un calcul frais et alerter au moindre désaccord. Le cache est vérifiable, donc le cache ne peut pas mentir en silence.

En pratique un instantané par compte et par jour suffit à la plupart des charges, et la tâche de vérification devient l'une des alertes les plus utiles que vous possédiez, parce qu'un écart d'instantané signifie en général que quelque chose en amont a écrit de l'historique qu'il n'aurait pas dû écrire.

06

Autorisation et capture sont deux mouvements

Les flux carte et virement sont rarement atomiques. Une autorisation réserve de la disponibilité sans transférer de valeur, une capture la transfère, une expiration ou une annulation libère la réservation. Modéliser cela avec un solde unique doté d'un montant disponible mutable réintroduit exactement la dérive que le journal devait éliminer.

Modélisez les réservations comme des écritures sur un compte dédié. Le solde disponible devient le solde réglé moins les réservations actives, ce qui reste une somme sur le journal. L'expiration est un mouvement daté, pas un drapeau que quelqu'un bascule.

Le gain se voit pendant les incidents. Quand un prestataire rejoue six heures de webhooks, un système avec réservations en écritures et clés d'idempotence absorbe le rejeu sans rien changer. Un système avec des montants disponibles mutables passe la soirée à reconstituer ce que le solde aurait dû être.

07

La propriété qui vaut d’être protégée

Toutes les règles ci-dessus existent pour préserver une seule propriété : tout solde, à tout instant, s'explique par les écritures qui l'ont produit, et cette explication ne change pas quand on la regarde à nouveau.

Les systèmes qui gardent cette propriété sont ennuyeux à exploiter pendant des années. Ceux qui l'échangent contre une première livraison plus rapide passent ces années à se rapprocher d'eux-mêmes.

Contact

Un chantier sur ce terrain ?

Infrastructure financière, systèmes régulés, IA en environnement contrôlé, cryptographie, plateformes à grande échelle.

Écrire