Aller au contenu

Garder les données cohérentes

Aussi en 28 langues

English · Español · 日本語 · Português (Brasil) · Deutsch · Italiano · 한국어 · 简体中文 · Português (Portugal) · 繁體中文 · Bahasa Indonesia · Türkçe · Polski · Tiếng Việt · ไทย · Nederlands · العربية · עברית · Українська · हिन्दी · Русский · Svenska · Dansk · Norsk bokmål · Suomi · Español (México) · Français (Canada) · Deutsch (Schweiz)

An old five-rung wooden ladder against a barn wall, its lowest rungs worn smooth from use and its top rungs barely touched.
Image générée par IA

Module 9 sur 10 du chapitre L’architecture de données Salesforce, chapitre 3 du cours Data Architect. Chaque module se suffit à lui-même. Précédent : Propriété et cycle de vie · Suivant : Concevoir le modèle physique Salesforce

La question à laquelle répond ce module : comment garder les données cohérentes, et que coûte chaque couche ?

Tout le monde veut des données propres. Je ne suis jamais entré dans une réunion d’exigences où quelqu’un disait : « Ce que nous voudrions vraiment, ce sont des données incohérentes. » Le désaccord vient après : où appliquons-nous les règles ? À l’écran ? Un champ obligatoire ? Une liste de sélection, une règle de validation, une règle de doublons, un flow, de l’Apex ? Tous aident. Ils ne sont pas interchangeables, et chaque couche a un coût.

Ma règle générale est de placer la règle aussi bas que raisonnablement possible. Si une valeur ne peut être que l’une de cinq choses, ne laissez pas les gens taper n’importe quoi pour nettoyer ensuite avec de l’automatisation. Si deux enregistrements ne doivent jamais partager un identifiant, ne comptez pas sur quelqu’un pour le repérer dans un rapport. Si une règle doit tenir que l’enregistrement vienne d’un écran, d’une API, d’une intégration, d’un chargement de données ou d’un agent, ne l’appliquez pas seulement dans l’interface. Plus la règle est proche des données, plus elle est difficile à contourner. J’appelle cela l’échelle de cohérence.

Premier barreau : le type de champ et le vocabulaire

Section intitulée « Premier barreau : le type de champ et le vocabulaire »

La première règle de cohérence est celle du module 6 : choisissez le bon type. Une date est une Date, un instant est une Date/Heure, de l’argent est une Devise. C’est de la cohérence avant même que quiconque écrive une règle.

Faites du statut d’une livraison un champ texte et vous obtiendrez Delivered, delivered, DELIVERED, Complete, Done et Dropped off, et quelqu’un devra déterminer si ces six-là veulent dire la même chose. Ou définissez le vocabulaire une fois : Delivered, une valeur, un sens. Faites-en une liste de sélection restreinte pour qu’elle rejette tout ce qui n’est pas dans la liste, même via l’API, et un ensemble de valeurs global quand plusieurs champs partagent la liste (le module 6 donne les détails).

Mais n’utilisez pas une liste de sélection juste pour empêcher les gens de taper. Est-ce vraiment une valeur, ou une autre entité ? Neuf centres de distribution avec chacun un nom peuvent ressembler à une liste de sélection ; neuf avec des adresses, des responsables, une capacité et des camions sont des enregistrements. La règle doit renforcer le modèle, pas compenser un mauvais modèle. Et si c’est vraiment un vocabulaire contrôlé, contrôlez-le au niveau du champ. N’autorisez pas le chaos pour construire ensuite un flow qui transforme AZ, Arizona, Ariz et Phoenix area en la valeur que vous vouliez dès le départ.

Obligatoire et Unique sont séduisants parce qu’ils sont simples : cochez la case, problème résolu. Parfois. Si chaque camion a un numéro de parc dès sa création, et que deux camions n’en partagent jamais un, les deux cases expriment de vraies règles métier. C’est une cohérence forte.

Mais une fois que la plateforme applique une règle, peu lui importe que votre processus ait une exception le mardi après-midi. J’utilise cet exemple en cours depuis des années. Un objet existe depuis un moment, avec beaucoup d’enregistrements. Quelqu’un ajoute un champ et coche Obligatoire. Il teste la création d’un enregistrement : ça marche parfaitement. Puis samedi soir, déploiement, les tests s’exécutent, et une vieille classe de test crée l’objet sans le nouveau champ. Boum. Ou quelqu’un modifie un vieil enregistrement antérieur au champ. Ou l’intégration envoie la même charge utile qu’elle envoie depuis cinq ans. Boum. « Mais on n’a pas touché à ce champ. » La plateforme s’en moque : vous avez changé le contrat de ce qu’est un enregistrement valide. Une nouvelle règle n’affecte pas seulement les nouvelles données ; elle change ce que vous pouvez faire avec les anciennes.

Les règles de validation permettent de dire des choses bien plus riches. Si le statut est Livrée, l’heure réelle de livraison doit être renseignée. Si l’arrêt comporte une installation, la liste de contrôle doit être complète avant que l’arrêt puisse être clôturé. Elles s’exécutent à l’enregistrement, donc elles protègent l’enregistrement qu’il soit enregistré depuis une page, l’API, un chargement de données, une intégration ou un agent. C’est tout l’intérêt. Si la règle doit protéger l’enregistrement, mettez-la là où chaque écriture la rencontre.

Elles ont aussi des dents. C’est leur force et leur coût.

C’est là que ça se gâte. Vous avez un million d’enregistrements, et aujourd’hui vous ajoutez une règle : l’heure de livraison ne peut pas précéder le départ de la tournée. Raisonnable. Mais vingt mille anciens enregistrements l’enfreignent, à cause d’une migration d’il y a sept ans. Un utilisateur ouvre l’un d’eux et change le numéro de téléphone. Enregistrer. La règle se déclenche. « J’ai changé un numéro de téléphone. Pourquoi me parlez-vous d’une heure de livraison de 2019 ? » Bonne question.

Une règle de validation ne devrait donc pas seulement dire ce qui doit être vrai. Elle devrait dire quand l’appliquer. Des fonctions comme ISNEW() et ISCHANGED() permettent de limiter une règle aux nouveaux enregistrements, ou aux enregistrements dont les champs concernés changent réellement (Validation Rule Considerations (opens in a new tab), en anglais).

Mais un enregistrement ne change pas seulement quand une personne le modifie, et beaucoup des raisons vous échappent. L’intégration met à jour le statut pendant la nuit. Un flow inscrit une date. Un responsable réattribue un territoire et le propriétaire change sur dix mille enregistrements. Quelqu’un modifie un article de livraison, le cumul sur la livraison se recalcule, ce qui enregistre la livraison, et la règle de validation de la livraison se déclenche pour un utilisateur qui ne l’a jamais touchée (Roll-Up Summary Field (opens in a new tab), en anglais, prévient que les erreurs de validation peuvent apparaître sur l’enregistrement détail ou sur le principal). Chacun de ces enregistrements rencontre votre nouvelle règle. Alors, pour chaque nouvelle règle, demandez-vous : cette règle doit-elle s’appliquer à cet enregistrement-là ?

Voici les choix, et vous les intégrez dans la règle :

  • Toujours, à chaque enregistrement. C’est juste quand la règle porte vraiment sur l’enregistrement et que les anciennes données la respectent. Mais sachez ce que veut dire « chaque enregistrement » : un traitement par lots qui ne change que le propriétaire, ou la moindre petite modification de n’importe quel champ de l’enregistrement, doit la passer aussi.
  • Seulement pour les nouveaux enregistrements, avec ISNEW(). La règle vérifie l’enregistrement une fois, à sa création, et plus jamais. Le passé reste tel qu’il était, mais l’avenir aussi : une modification ultérieure peut faire enfreindre la règle à un nouvel enregistrement sans que personne ne l’arrête. Si c’est important, associez-la à l’option suivante.
  • Seulement quand les champs concernés changent, avec ISCHANGED(). Modifier le numéro de téléphone ne réveille pas la règle sur l’heure de livraison.
  • Pas pour certains auteurs d’écritures. Une autorisation personnalisée, vérifiée dans la formule avec $Permission, laisse passer l’utilisateur d’intégration ou une migration de données tandis que les personnes restent soumises à la règle (How to Reference a Custom Permission in a Validation Rule (opens in a new tab), en anglais). Accordez-la volontairement et à peu de monde.
  • À partir d’une date, en comparant CreatedDate au jour où la règle est entrée en vigueur, quand « nouveau » veut dire « depuis que nous appliquons cette règle ». Contrairement à ISNEW(), elle continue de vérifier ces enregistrements à chaque enregistrement ultérieur, donc le même avertissement s’applique : un changement mineur, comme une mise à jour du propriétaire par lots, peut échouer sur un enregistrement qui a dérivé.

Vous ajoutez une règle à des enregistrements qui existent déjà ? Réfléchissez aux conséquences avant de l’activer. Chaque enregistrement existant doit désormais la passer à son prochain enregistrement, et cet enregistrement peut venir d’un endroit inattendu : une intégration nocturne, un changement de propriétaire par lots, un cumul, une mise à jour en masse depuis une vue de liste. Lesquels vont la rencontrer, et qu’arrive-t-il à ce traitement quand un enregistrement échoue ? La section Avant de l’activer donne la séquence que j’utilise.

Ne réécrivez pas l’historique pour satisfaire la règle

Section intitulée « Ne réécrivez pas l’historique pour satisfaire la règle »

Et les vingt mille anciens enregistrements ? Si les données sont fausses et que vous connaissez les bonnes valeurs, corrigez-les. Mais j’ai vu une autre sorte de « correction » : personne ne connaît la vérité historique, il faut juste que les enregistrements passent, alors on les met à jour avec des valeurs qui satisfont la règle d’aujourd’hui. Je n’aime pas ça. Mettre à jour d’anciens enregistrements pour qu’ils soient conformes change LastModifiedDate et détruit des informations historiques clés, et inventer des valeurs revient à prétendre connaître sur le passé quelque chose que nous ne savons pas. Donnez à la règle une dérogation pour les enregistrements qui la précèdent plutôt que de réécrire l’historique. Ce n’est peut-être pas joli, mais c’est honnête.

La validation dans l’interface n’est pas une validation des données

Section intitulée « La validation dans l’interface n’est pas une validation des données »

Rendez un champ obligatoire dans une présentation de page et les utilisateurs ne peuvent pas enregistrer sans lui. Puis l’intégration de nuit insère 50 000 enregistrements. A-t-elle utilisé votre page ? Non. Le chargement en masse, le client API et l’agent non plus. Une exigence d’interface protège cet écran, pas les données. La validation de champ sur les formulaires dynamiques peut être contournée de la même façon. Alors demandez : par où ces données peuvent-elles entrer ? Lightning, le portail, le mobile, l’intégration, l’API, un chargement en masse, un flow, de l’Apex, un agent. Plus il y a de portes, moins je fais confiance à une règle qui n’en garde qu’une.

Nous passons maintenant de la cohérence à l’intérieur d’un enregistrement à la cohérence entre enregistrements. Acme Corporation, ACME Corp, Acme Inc. : quatre clients ou un seul ? Aucune règle de champ ne peut répondre. Les règles de correspondance définissent comment les enregistrements sont comparés ; les règles de doublons décident de ce qui se passe quand un doublon probable est trouvé : autoriser avec un avertissement, bloquer, ou signaler. Vous pouvez avoir jusqu’à cinq règles de doublons actives par objet et jusqu’à trois règles de correspondance dans chacune, et les clés de correspondance limitent chaque comparaison aux 100 doublons les plus probables (Things to Know About Duplicate Rules (opens in a new tab), en anglais).

Leur coût, c’est la friction. Si chaque compte créé par un commercial affiche Doublon possible détecté, c’est parfois exactement ce que vous voulez, et parfois les gens apprennent à cliquer sans lire. Des enregistrements légitimes peuvent se ressembler, et une intégration peut avoir besoin d’un comportement différent de celui d’une personne. Et l’avertissement appartient à Salesforce : son alerte et sa liste de doublons possibles ne s’intégreront pas forcément à un écran personnalisé que vous avez construit, et quand l’enregistrement est sans interface (headless), une intégration, un chargement de données, un agent, il n’y a aucun écran où l’afficher. Décidez donc comment un doublon se manifeste sur chaque chemin : un avertissement pour une personne, un enregistrement bloqué et une erreur pour l’API, ou l’option Signaler et les ensembles d’enregistrements en double pour que quelqu’un les examine plus tard. Une bonne architecture, ce n’est pas l’application maximale ; c’est la bonne application.

Et vérifiez quelles portes une règle de doublons garde réellement (Things to Know About Duplicate Rules (opens in a new tab), en anglais). Via l’API et les outils d’importation de données, personne ne voit l’avertissement : une règle configurée pour alerter bloque simplement l’enregistrement. Certains chemins contournent entièrement les règles : la création rapide (Quick Create), le bouton de restauration (Undelete), une fusion manuelle, les enregistrements ajoutés par Lightning Sync ou Einstein Activity Capture. Et les enregistrements sauvegardés au même moment ne sont pas comparés entre eux, seulement avec les enregistrements déjà présents dans Salesforce. Chargez un fichier où le même client apparaît deux fois, et les deux lignes peuvent passer. Une règle de doublons est un bon filet. Ce n’est pas un verrou sur la porte.

À savoir pour l’examen. Les règles de doublons ne comparent pas entre eux les enregistrements sauvegardés au même moment, seulement avec les enregistrements déjà présents dans Salesforce. Via l’API et les outils d’importation, il n’y a pas d’alerte : un doublon détecté par la règle n’est tout simplement pas enregistré. Et un enregistrement et tout ce qu’il déclenche s’exécutent en une seule transaction : si une partie échoue, tout est annulé.

Une limite. Les règles de doublons gardent une organisation propre. Elles ne résolvent pas l’identité à l’échelle de l’entreprise. Si Salesforce a Acme Corporation, l’ERP a ACME-10382 et la facturation a le client 77193, une règle de doublons ne peut pas vous dire qu’il s’agit de la même entreprise. Ce sont les données de référence, le chapitre 6.

Certaines règles sont trop complexes pour les barreaux inférieurs : elles ont besoin d’enregistrements liés, d’un autre système, d’enregistrements dépendants, d’un processus en plusieurs étapes. C’est le flow, l’Apex, parfois la logique d’intégration. (Pas les règles de workflow ni Process Builder ; ils ne sont plus pris en charge.) L’automatisation est puissante et plus coûteuse : plus de pièces mobiles, plus de tests, plus de gestion d’erreurs, plus de façons pour une automatisation de trébucher sur une autre. Et le code apporte ses propres erreurs. Si le type de champ peut l’appliquer, je n’écris pas d’Apex. Si une règle de validation le dit clairement, je ne construis pas de flow juste parce que Flow est là. Ne résolvez pas un problème de champ avec un moteur de processus.

Tout ou rien : quand des enregistrements changent ensemble

Section intitulée « Tout ou rien : quand des enregistrements changent ensemble »

Jusqu’ici, chaque barreau protège un enregistrement. Mais les enregistrements changent ensemble : une livraison et ses articles, une commande et ses lignes, un flow qui met à jour trois objets. Ici, la plateforme vous donne une garantie forte. Un enregistrement et tout ce qu’il déclenche, les déclencheurs, les flows, les classes qu’ils appellent, s’exécutent en une seule transaction : si une partie échoue, l’ensemble est annulé et rien n’est validé (Apex Transactions (opens in a new tab), en anglais). Vous n’obtenez pas une demi-livraison.

Le travail en masse est l’exception que vous choisissez. Un chargement de données ou une méthode Apex Database peut autoriser le succès partiel : les bons enregistrements sont sauvegardés, les mauvais reviennent avec leurs erreurs, et quelqu’un doit s’en occuper (DML Statements vs. Database Class Methods (opens in a new tab), en anglais). C’est souvent le bon choix pour un chargement d’un million de lignes, mais la cohérence devient alors un processus : qui lit le fichier d’erreurs, et qu’arrive-t-il aux enregistrements qui ont échoué ?

Et puis il y a le moment. Deux enregistrements au même instant peuvent tous deux passer une vérification que chacun échouerait seul. Un flow qui cherche une commande existante puis en crée une peut en laisser passer deux, et nous venons de voir que les règles de doublons ne comparent pas les enregistrements sauvegardés au même moment. Un champ marqué Unique, ou un ID externe, est vérifié par la plateforme à chaque enregistrement, donc un seul des deux l’emporte. C’est une raison de plus de descendre l’unicité jusqu’au champ. Les verrous, la contention et les nouvelles tentatives sont un sujet à part entière ; le chapitre 11, Transactions, concurrence et fiabilité, va en profondeur.

Descendez la règle, jusqu’à ce qu’elle n’ait plus sa place là

Section intitulée « Descendez la règle, jusqu’à ce qu’elle n’ait plus sa place là »

« Aussi bas que raisonnablement possible » ne veut pas dire « toujours le plus bas ». Si un champ n’est obligatoire qu’une fois qu’une opportunité atteint une certaine étape, le rendre obligatoire dans le schéma est faux ; la règle est conditionnelle, donc une règle de validation est le bon barreau. Si un doublon doit avertir une personne mais qu’une intégration approuvée a son propre rapprochement, concevez pour les deux chemins. Le but : la couche la plus basse qui représente correctement la règle métier.

L'échelle de cohérence L'échelle de cohérence sous forme de matrice, barreau le plus bas en premier, face à quatre tests : chaque chemin d'écriture, conditions riches, entre enregistrements, et facile à vivre. Barreau 1, type de champ et liste de sélection : tient sur chaque chemin, UI, API, chargement et agent, et il est facile à vivre, mais ne dit que ce qu'un champ peut dire ; le plus solide. Barreau 2, obligatoire et unique : chaque chemin, et Unique fonctionne entre enregistrements, mais c'est toujours actif, sans exception ; sans nuance. Barreau 3, règle de validation : chaque chemin et des conditions riches, qui regardent l'enregistrement et ses parents, mais il faut la cibler pour les anciens enregistrements ; à cibler. Barreau 4, règle de doublons : une correspondance approximative entre enregistrements, mais elle ignore la fusion et la restauration et ajoute de la friction, sans alerte via l'API ; un filet. Barreau 5, l'automatisation en Flow ou Apex : tout, si elle est déclenchée par un enregistrement, mais les tests, les erreurs et la maintenance sont pour vous ; le dernier recours. Et le contraste, une exigence de présentation de page : ne protège que cet écran ; pas les données. En dessous : descendez la règle jusqu'au barreau le plus bas qui la représente correctement. CHAQUE CHEMIN D'ÉCRITURE CONDITIONS RICHES ENTRE ENREGISTREMENTS FACILE À VIVRE C'EST Type de champ et liste de sélection barreau 1 : le vocabulaire UI, API, chargement, agent seulement ce qu'un champ dit LE PLUS SOLIDE Obligatoire et Unique barreau 2 : le champ toujours, sans exception Unique : un seul gagne SANS NUANCE Règle de validation barreau 3 : une formule l'enregistrement et ses parents ciblez-la : anciens enregistrements À CIBLER Règle de doublons barreau 4 : la correspondance ignore fusion, restauration correspondance approximative friction, pas d'alerte via l'API UN FILET Automatisation barreau 5 : Flow, Apex si déclenchée par un enregistrement tests, erreurs, maintenance DERNIER RECOURS Obligatoire dans la présentation de page le contraste : un écran cet écran seulement PAS LES DONNÉES Descendez la règle jusqu'au barreau le plus bas qui la représente correctement. © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

Voici le compromis que je veux vous faire voir. Les types de champ et les valeurs contrôlées sont simples et forts, mais seulement pour ce qu’un champ peut exprimer. Obligatoire et Unique sont brutaux : une fois activés, chaque écriture doit les satisfaire. Les règles de validation expriment des conditions plus riches mais peuvent bloquer la modification d’anciens enregistrements et surprendre un déploiement. Les règles de doublons protègent entre enregistrements mais ajoutent de la friction pour les utilisateurs et les intégrations. L’automatisation gère tout, mais vous oblige à porter l’orchestration, les erreurs, les tests et la performance. Aucune couche n’est gratuite. Choisissez la couche de chaque règle en sachant comment elle échoue.

Ajouter une règle à une organisation existante est un déploiement, pas une case à cocher. Combien d’enregistrements l’enfreignent aujourd’hui, et pourquoi ? Sont-ils vraiment faux ? Pouvons-nous connaître la bonne valeur ? La règle est-elle vraie historiquement, ou seulement à partir de maintenant ? Quelles intégrations, quels tests et quelles automatisations vont la rencontrer ? Une bonne séquence : mesurer, nettoyer ce dont vous pouvez prouver que c’est faux, cadrer la règle, ajouter une dérogation délibérée pour l’historique légitime, tester chaque chemin d’écriture, puis appliquer. Mesurer et nettoyer sont des disciplines à part entière, le profilage, la standardisation, la surveillance, la gestion des données (stewardship), et le chapitre 5, Qualité et gouvernance des données, les couvre. Bien mieux que cocher une case le vendredi et découvrir les conséquences le samedi soir.

Au-delà de l’examen : ce que l’IA change. Un agent peut créer des enregistrements plus vite que n’importe quelle personne, et de mauvais enregistrements tout aussi vite. « Les utilisateurs savent qu’il ne faut pas faire ça » n’est pas une protection quand l’utilisateur est un agent. Mettez les règles importantes dans la couche de données, là où chaque auteur d’écriture les rencontre, pour que l’agent n’ait pas à se souvenir des règles non écrites de l’entreprise.

Prenons une livraison. Son statut vient d’un vocabulaire unique : une liste de sélection, restreinte. La référence de commande du partenaire distributeur doit être unique par partenaire, donc c’est un ID externe, marqué unique, utilisé pour faire l’upsert du manifeste. L’heure réelle de livraison est obligatoire une fois le statut Livrée : une règle de validation, limitée à ce changement. Un arrêt avec installation ne peut pas être clôturé tant que sa liste de contrôle n’est pas complète et que ses photos obligatoires n’ont pas été prises (pour un lave-vaisselle, l’arrivée d’eau, l’évacuation et le niveau) : une règle de validation, ou de l’automatisation si elle doit vérifier des photos stockées hors plateforme. La même commande qui arrive deux fois à cause d’un manifeste renvoyé est interceptée par l’ID externe ; deux commandes différentes qui se ressemblent sont une question de correspondance.

Remarquez que je n’ai pas dit « mettez-les toutes dans un flow ». Chaque règle est sur son propre barreau. Pour chaque règle, demandez : quelle est la couche la plus basse qui l’applique correctement pour chaque chemin d’écriture qui compte ?

  • Sur quel barreau chaque règle a sa place : type de champ, vocabulaire contrôlé, obligatoire ou unique, règle de validation, règle de doublons ou automatisation.
  • Quels chemins d’écriture doivent être protégés : interface, portail, mobile, intégrations, chargements en masse, API, automatisation et agents.
  • Si une nouvelle règle s’applique aux enregistrements historiques, ou se limite aux données nouvelles et modifiées avec une dérogation pour le passé.
  • Si les mauvaises données existantes peuvent être corrigées à partir de preuves, plutôt que réécrites pour passer.
  • Combien de friction, de complexité et de maintenance une règle mérite.

Des données propres ne viennent pas du fait de demander aux gens de saisir de bonnes données. Elles viennent d’une architecture qui rend la bonne chose facile, la mauvaise chose difficile, et les règles importantes difficiles à contourner. Ensuite, nous rassemblons le chapitre sur une tranche de Steve Trucking.