Aller au contenu

L'automatisation pendant le chargement

Aussi en 19 langues

English · Español · 日本語 · Português (Brasil) · Français · Deutsch · Italiano · 한국어 · 简体中文 · Português (Portugal) · 繁體中文 · Bahasa Indonesia · Türkçe · Polski · Tiếng Việt · ไทย · Українська · Español (México) · Deutsch (Schweiz)

In a plant room, the valves beside a pump stand closed and its cover is off, while a bypass pipe with an open valve carries the flow around it.
Image générée par IA

Module 3 sur 5 du chapitre Migration et synchronisation, chapitre 10 du cours Data Architect. Chaque module est autonome. Précédent : Charger à grande échelle · Suivant : Le week-end de bascule

La question à laquelle répond ce module : que doit-il advenir de l’automatisation Salesforce pendant le chargement des données de migration ?

RouteDesk’s records are ready: about 707,000 of them, prepared, sorted by parent, rehearsed. You start the load, and Salesforce starts doing exactly what you configured it to do. Flows fire, triggers run, validation rules evaluate, emails send, tasks get created, rollups calculate, integrations launch, events publish. Your 707,000-record migration isn’t performing 707,000 operations anymore. It’s performing 707,000 records multiplied by everything each record causes. That’s a different migration. ⟲

Here’s the landscape again, the weekend RouteDesk retires. The migration arrow is amber. Now look at what else leaves Salesforce when a Work Order is created or changes status. ⟲

The arrows a load sets off Steve Trucking's landscape from Checkpoint 1, in the same places, the weekend RouteDesk retires. The migration arrow from RouteDesk into Salesforce is in amber. Three arrows leaving Salesforce are red with an X, because normal automation would fire them for every migrated Work Order: status events to the integration layer, delivery counts to the integration layer, and the day-before texts to the SMS and email provider. Underneath: load 196,400 Work Orders with the automation on, and three more arrows fire for every one of them: status events, delivery counts and day-before texts. {"author": "Steve Simpson", "blueprint": "1.0.1", "builder": "standard 1.54.0", "built": "2026-10-30", "id": "DGM-DA-MG-30", "rights": "\u00a9 2026 Twinshark LLC. All rights reserved.", "template": "system-landscape 0.13.0", "theme": "stevetecharc 1.4.0"} ABOVE: IDENTITY, APPEXCHANGE, WEB PEOPLE RIGHT: INTERNAL SYSTEMS BELOW: CUSTOMER CHANNELS BOTTOM RIGHT: PARTNERS AND PROVIDERS Dispatch coordinators 45, inside 9 partner DCs Delivery crews ~700 on 330 trucks Care and office staff 100: service, ops, finance Retail Partner users ~300 at 3 partners Recipients ~1 million a year Corporate IdP SSO for office staff only Retail Partner portal Tracking page INTEGRATION Snowflake status history, analytics FleetLink raw GPS stays here Finance ERP invoices partners, pays crews Photo storage 4–5 million a year, off core RouteDesk retiring: 8 years, ~5 million deliveries Phone care agents Email email-to-case SMS and email provider day-before message, with a link Redrock REST API, webhooks Keystone CSV over SFTP Brightwave EDI through a third-party network Salesforce Field Service, one US org a link, no login office staff only calls cases in manifests in status out manifests in status out manifests in status out upserts, partner key status events status events latest position only delivery counts delivery counts photos, from the crews' app day-before, with a link what's still open: migrated once Salesforce a community people identity, apps, web an internal system a customer channel the integration layer starts at the system that opens the connection; the label says what moves red with an X: fires for every migrated record unless you decide otherwise a shared certificate: trust, no direct call the migration Load 196,400 Work Orders with the automation on, and three more arrows fire for every one of them: status events, delivery counts and day-before texts. © 2026 Twinshark LLC · stevetecharc.com
Cliquer pour agrandir

One arrow in. Three more arrows out, for every record, unless we decide otherwise. ⟲

Every one of those arrows was designed in chapter 9 for a delivery that just happened: a status changed, so tell the partner and Snowflake; a delivery finished, so count it for invoicing; a delivery is tomorrow, so text the Recipient. The load creates 196,400 Work Orders in one weekend, and about 190,000 of them arrive already completed. To the automation, each one looks like a delivery that just happened. ⟲

L’automatisation ne sait pas que c’est une migration

Section intitulée « L’automatisation ne sait pas que c’est une migration »

Salesforce sees a record transaction. It doesn’t know “this is historical data loaded during a controlled cutover.” A flow sees a new Account and does what it was built to do: creates an onboarding task, sends a welcome email, publishes an event, updates a related record, calls another system. Correct when a sales rep creates one account on Tuesday afternoon. Completely wrong when a migration creates 800,000 historical accounts on Saturday night. Same operation, different business context. At Steve Trucking, a Work Order arriving with a status of Completed looks exactly like a crew finishing a delivery five minutes ago. ⟲

Alors, pour une migration importante, je pars de ceci : l’automatisation métier normale ne doit pas s’exécuter aveuglément sur le chargement. Cela ne veut pas dire « tout désactiver ». Cela veut dire que chaque automatisation importante fait l’objet d’une décision délibérée, et je ne veux pas découvrir la réponse parce que la production a envoyé 400 000 e-mails.

Trois choix : pas besoin, la simuler, la différer

Section intitulée « Trois choix : pas besoin, la simuler, la différer »

For each automation, I ask what it does and what happens if it doesn’t run, and then I put it in one of three categories. ⟲

Pas besoin (supprimer). Le comportement ne doit pas se produire pour les enregistrements migrés. Des clients que nous avons depuis huit ans n’ont pas besoin de « Bienvenue dans notre entreprise ! ». Insérez un compte, il envoie un e-mail ; chargez un million de comptes, et je n’ai pas besoin d’un million d’e-mails.

La simuler. L’automatisation ne doit pas s’exécuter, mais le résultat qu’elle produit reste nécessaire. Un flow à la création d’un compte calcule le segment client. Les comptes migrés ont besoin d’un segment valide, mais exécuter tout le flow cinq millions de fois coûte cher ou a des effets de bord. Alors nous calculons le segment dans la transformation et nous chargeons le résultat. Nous n’avons pas ignoré la règle métier ; nous avons fait le travail de l’automatisation dans le chargement.

La différer. Le résultat est nécessaire, mais pas dans la transaction de chargement. Chargez avec l’automatisation désactivée et un indicateur positionné, puis déclenchez un traitement par lots pour rattraper : recalculer, créer les enregistrements dépendants, publier ce dont les systèmes en aval ont besoin. Différer peut rendre le chargement plus rapide et plus maîtrisable sans renoncer au résultat.

Et parfois, vous la laissez active. Pour un chargement plus petit où le métier veut que son processus normal s’exécute, laissez le système faire ce qu’il fait. C’est aussi un choix, tant que c’est un choix.

Quoi que vous choisissiez, voici la règle que j’enseigne : chaque fois que vous désactivez une automatisation, vous prenez l’entière responsabilité de cette logique métier qui ne s’exécute pas. Vous devez comprendre chaque automatisation avant de décider.

Don't need it, simulate it, defer it A decision tree, read left to right, with three questions and four answers. First question: should it happen for migrated data? If no: don't need it, for example status messages to partners for deliveries they closed weeks ago. If yes, the second question: must it happen inside the load? If yes: let it run, deliberately, for example the rule that every Work Order has a partner. If no, the third question: can the preparation set the result, a value rather than a side effect? If yes: simulate it, for example the Work Order's status, mapped in the preparation data store. If no: defer it, for example status history to Snowflake, as one backfill after the load. Underneath, Steve's rule: any time you turn an automation off, you're taking full responsibility for that business logic not happening. {"author": "Steve Simpson", "blueprint": "1.0.0", "builder": "standard 1.48.0", "built": "2026-10-27", "id": "DGM-DA-MG-31", "rights": "\u00a9 2026 Twinshark LLC. All rights reserved.", "template": "cells 0.4.0", "theme": "stevetecharc 1.4.0"} THE QUESTIONS THE ANSWERS Should it happen for migrated data? ask it of every automation Must it happen inside the load? or can it come later Can the preparation set the result? a value, not a side effect Don't need it status messages to partners for deliveries closed weeks ago Let it run, deliberately the rule that every Work Order has a partner Simulate it the Work Order's status, mapped in the preparation data store Defer it status history to Snowflake: one backfill after the load no yes yes no yes no Any time you turn an automation off, you're taking full responsibility for that business logic not happening. © 2026 Twinshark LLC · stevetecharc.com
Cliquer pour agrandir

Three questions, four answers, one decision per automation. ⟲

Test knowledge. For each automation on a large load, decide: not needed for migrated data (bypass it), needed but its result can be set in the data (simulate it in the transformation), needed but not inside the load (defer it to a batch afterward), or needed inside the load (let it run). Expect a scenario where blindly running automation creates unwanted emails, tasks or integration calls, and one where turning it off silently loses a required result. ⟲

« Désactiver l’automatisation » n’est pas toute la stratégie

Section intitulée « « Désactiver l’automatisation » n’est pas toute la stratégie »

Le plan dit « désactiver l’automatisation ». Quelle automatisation ? Comment, qui, quand ? Comment savons-nous qu’elle est désactivée, et comment savons-nous qu’elle est réactivée ? Quels résultats qu’elle produit normalement doivent quand même exister après ? Que se passe-t-il si des utilisateurs sont dans le système pendant qu’elle est désactivée, ou si la migration échoue à mi-chemin ? Désactiver quelque chose est une action opérationnelle. L’architecture a besoin de tout le cycle de vie : état normal, état de migration, retour à la normale, et preuve que nous y sommes revenus.

And before you decide what to switch off, find out what’s still switched on. Old automation runs on migrated records too. Salesforce ended support for Workflow Rules and Process Builder on December 31, 2025, but “your active Workflow Rules and Process Builder processes continue to run as they did before” (Fin de la prise en charge des Règles de workflow et du Générateur de processus (s'ouvre dans un nouvel onglet), Salesforce Help, checked 2026-10-27). Well-Architected points out the cost: an org “carrying dozens of Process Builders left over from prior implementations … pays to evaluate every one of them on every relevant record save,” and its advice is to “migrate remaining Process Builders to Flow; don’t just deactivate them” (Resource and Cost Optimization (s'ouvre dans un nouvel onglet), checked 2026-10-27). A migration is a good reason to clear them out first, so 707,000 records aren’t run through automation nobody remembers. ⟲

Ma position plus ferme : une automatisation importante doit avoir un contournement maîtrisé même quand aucune migration n’est prévue. La migration n’est pas la seule raison pour laquelle vous en aurez besoin. Gros chantier de correction, rectification de données, rattrapages, réparation d’intégration, reprise d’urgence : il faut parfois exécuter une opération maîtrisée sans chaque élément de l’automatisation normale. Si le seul moyen est de modifier le flow en production, de désactiver le trigger ou de supprimer une règle de validation, nous avons rendu le travail opérationnel inutilement dangereux. Et vous ne pouvez pas simplement désactiver un trigger en production : c’est un déploiement, avec ses tests.

The standard answer is a bypass (some teams call it a kill switch): the first thing the trigger or flow does is check a switch, and skip itself if the switch is on. Decide the scope: a global switch for the whole org, one per object, one per automation, or one for particular users, such as the data load user or anyone holding a permission. Put it in your flows as well as your triggers. Flows are easy to deactivate, but a user-specific switch lets everyone else keep working. I consider flows visual programming: whether you’re writing code or programming visually, you’re still programming, and programs need this. ⟲

And here’s the part teams miss: the bypass is part of the original design. It isn’t something you build the week you need it. Every trigger and flow gets its bypass when it’s first built. It’s tested both ways, switched on and switched off, like any other behavior. And it goes to production with the automation, long before any migration, so on cutover weekend it’s already there, already tested, and ready to switch on. A bypass written in a hurry for the load is new, untested code going into production on the riskiest weekend of the project. Salesforce’s Record-Triggered Automation decision guide is just as firm: “A well-architected Salesforce organization requires a consistent and reliable mechanism to bypass automation. This is not an optional feature, but a core operational requirement” (Record-Triggered Automation (s'ouvre dans un nouvel onglet), Salesforce Architects decision guide, checked 2026-10-27). ⟲

Salesforce says the same thing in its own words. Its Well-Architected list of automation anti-patterns includes “Flows must be manually deactivated prior to bulk data loads” (Automation Patterns (s'ouvre dans un nouvel onglet), Operational Excellence, checked 2026-10-27). If your load plan says “deactivate these twelve flows on Friday night,” that’s the anti-pattern. ⟲

Test knowledge. Build a bypass into triggers and flows when they’re first built (a check of a custom permission, a custom setting or custom metadata at the start), test it on and off, and deploy it ahead of time, so large loads can skip them without editing or deactivating anything in production. Scope it: by object, by automation, or by user, such as the migration user. Deactivating flows by hand before a bulk load is an anti-pattern in Salesforce’s own Well-Architected guidance. ⟲

So what does a bypass actually look like? Three parts: a place to keep the switch, a check at the top of every trigger and flow, and the same check in the validation rules you decide to relax. Salesforce gives you three places to keep it, and each one decides who the switch applies to. ⟲

Where the switch livesWho it applies toGood for
A custom permission, granted by a permission setOnly the users who hold itThe usual migration bypass: give it to the migration user for the load, take it away after
A hierarchy custom settingThe whole org, one profile, or one userA global “automation off” for everyone, or a switch for one profile or one user
A custom metadata record per automationEveryone, for that one automationSwitching off one specific automation, deployed and versioned like code

The hierarchy custom setting is the one that does global, profile and user in one place. Salesforce’s description: it “checks the organization, profile, and user settings for the current user and returns the most specific, or lowest, value” (Define Custom Settings (s'ouvre dans un nouvel onglet), Salesforce Help, checked 2026-10-27). Set it off for the org, on for the migration user, and the migration user gets the bypass while everyone else gets normal automation. For most other configuration Salesforce now steers you to custom metadata instead, which deploys with your code; I’d use that for the per-automation switches. ⟲

In Apex, the check is the first thing the trigger does. Here’s what it could look like on the Work Order, with a hierarchy custom setting called Automation_Bypass__c and a custom permission called Bypass_Automation: ⟲

trigger WorkOrderTrigger on WorkOrder (after insert, after update) {
// The hierarchy custom setting: the user's value, else the profile's, else the org's
Automation_Bypass__c settings = Automation_Bypass__c.getInstance();
// Bypass if the setting says so, or if this user holds the custom permission
Boolean bypass = settings.Disable_Triggers__c == true
|| FeatureManagement.checkPermission('Bypass_Automation');
if (bypass) {
return; // no side effects; the record still saves
}
WorkOrderStatusOut.publish(Trigger.new, Trigger.oldMap);
}

getInstance() returns the setting “for the current user,” merged from the lowest level that’s defined (Custom Settings Methods (s'ouvre dans un nouvel onglet)), and FeatureManagement.checkPermission “checks whether a custom permission is enabled” (FeatureManagement Class (s'ouvre dans un nouvel onglet); both Apex Reference Guide, Winter ‘27, checked 2026-10-27). ⟲

And one switch per automation, so the bypass is scoped instead of “skip everything.” A custom metadata type, Automation_Switch__mdt, with one record per automation: ⟲

public with sharing class WorkOrderStatusOut {
public static void publish(List<WorkOrder> orders, Map<Id, WorkOrder> oldOrders) {
// One record per automation; switched off here, it's off everywhere it's deployed
Automation_Switch__mdt sw = Automation_Switch__mdt.getInstance('WorkOrder_Status_Out');
if (sw != null && sw.Is_Off__c) {
return;
}
// ... publish the status change for the partners
}
}

getInstance(developerName) reads one custom metadata record by its name (Custom Metadata Type Methods (s'ouvre dans un nouvel onglet), Apex Reference Guide, checked 2026-10-27). ⟲

In a flow, it’s the same idea: the first element is a decision. ⟲

A bypass at the top of a flow A record-triggered flow, top to bottom. It starts when a Work Order is created or changes. The first element is a question: is the bypass on for this user, through a custom permission or a setting for the org, a profile or one user? If yes, the flow ends and does nothing; the record still saves, with no side effects. If no, the flow carries on to its normal work, highlighted: publish the status to the partners, for everyone else. Underneath: the check comes first; switch it on for the migration user, and the flow steps aside while the record saves. {"author": "Steve Simpson", "blueprint": "1.0.0", "builder": "standard 1.48.0", "built": "2026-10-27", "id": "DGM-DA-MG-33", "rights": "\u00a9 2026 Twinshark LLC. All rights reserved.", "template": "flow/decision 0.1.0", "theme": "stevetecharc 1.4.0"} A Work Order is created or changes the record-triggered flow starts Is the bypass on for this user? a custom permission, or a setting for the org, a profile or one user End: do nothing the record still saves; no side effects Publish the status to the partners the normal work, for everyone else yes no The check comes first. Switch it on for the migration user, and the flow steps aside while the record saves. HOW TO READ IT a step the step that matters most a question an answer yes goes right to an answer; no goes down to the next question © 2026 Twinshark LLC · stevetecharc.com
Cliquer pour agrandir

The check comes first. Switched on, the flow steps aside. ⟲

The decision’s condition reads the same two switches, through flow’s global variables: $Permission is “the custom permission access of the user running the flow,” and $Setup reads hierarchy custom settings (Global Variables Resource (s'ouvre dans un nouvel onglet), Salesforce Help, checked 2026-10-27). As a formula resource: ⟲

{!$Permission.Bypass_Automation} || {!$Setup.Automation_Bypass__c.Disable_Flows__c}

In a validation rule, the bypass is one more condition. Here’s R12’s install rule, with the migration user allowed through (the field names are examples): ⟲

AND(
NOT($Permission.Bypass_Automation),
ISPICKVAL(Status, "Completed"),
Install_Required__c,
NOT(Install_Checklist_Complete__c)
)

Validation rules reference a custom permission as $Permission.Custom_Permission_Name (How to Reference a Custom Permission in a Formula, Workflow Rule, or Validation Rule (s'ouvre dans un nouvel onglet), Salesforce Help, checked 2026-10-27). ⟲

Salesforce’s decision guide calls custom permissions “the modern, scalable standard for implementing bypass logic,” and notes a bypass can be granted to one user, “or even temporarily with a specific expiration date/time” (Record-Triggered Automation (s'ouvre dans un nouvel onglet), checked 2026-10-27). That’s the migration window, built into the grant. ⟲

These are examples to adapt, not a framework to paste in: build yours, test it in a sandbox, and test that the switch turns back off. And remember what you’ve built. A bypass is a permission to skip business rules. Grant it to the migration user for the migration window, record who has it, and take it away when the load is done (module 4 puts that in the runbook). ⟲

Test knowledge. Know the three places to keep a bypass and who each applies to: a custom permission (only the users whose permission sets grant it; checked with $Permission in flows and validation rules, FeatureManagement.checkPermission in Apex), a hierarchy custom setting (the org, a profile or a user, the most specific value winning; $Setup in flows and formulas, getInstance() in Apex), and custom metadata (one switch per automation, deployable). ⟲

Un contournement, ce n’est pas « tout sauter »

Section intitulée « Un contournement, ce n’est pas « tout sauter » »

Un contournement ne veut pas dire que l’utilisateur de migration ignore toutes les règles de Salesforce. Une automatisation doit être contournée, une autre doit quand même s’exécuter ; une règle de validation qui protège un invariant fondamental compte toujours, une notification non ; une intégration en aval doit être neutralisée, une relation obligatoire doit toujours être vérifiée. Je veux donc des contournements intentionnels et délimités, pas Migration_Mode__c = true, donc plus rien ne compte. Le chemin de migration a toujours des règles, simplement celles qui conviennent à la migration.

Et le contournement doit représenter un contexte opérationnel, pas un accident. Une identité dédiée à la migration (module 2), une autorisation personnalisée, des métadonnées de configuration, un indicateur de fonctionnalité, ou une combinaison, peuvent reconnaître un travail de migration approuvé. L’identité peut faire partie du contrôle, mais je ne veux pas que chaque automatisation soit codée en dur sur User.Name = 'Migration User'. C’est fragile. Exprimez l’intention : s’il s’agit d’une opération de migration approuvée, saute cet effet de bord.

Les règles de validation demandent du jugement

Section intitulée « Les règles de validation demandent du jugement »

« La date de clôture est obligatoire quand une opportunité est gagnée » est un vrai invariant des données ; gardez-le pour les opportunités historiques. Une règle qui impose un champ du processus actuel introduit il y a trois ans, c’est différent : les enregistrements d’il y a dix ans ne l’ont jamais eu, et inventer une valeur rend les données pires. La question n’est pas « désactivons-nous les règles de validation ? ». C’est quelles règles représentent une vérité durable des données, et lesquelles représentent le processus interactif d’aujourd’hui ? C’est une question d’architecte de données.

Steve Trucking has one of each. Every Work Order must have a Retail Partner: that’s enduring truth, and it stays on for the load; a RouteDesk delivery without one goes to quarantine (module 1). But requirement R12 says an install can’t be closed without a completed checklist and specific photos, the water line, the drain line, the level. That’s today’s process, built for crews with the new mobile app. RouteDesk’s completed installs never had those photos. Bypass that rule for the migration identity, and load them as completed. Don’t invent photos. ⟲

Le signal d’alerte à surveiller : la cible exige une valeur, la source ne l’a pas, alors « mettons juste ‘Inconnu’ partout ». Si Inconnu est une valeur approuvée qui décrit vraiment l’état, très bien. Si nous insérons de fausses valeurs pour passer la validation, nous corrompons les données pour satisfaire l’application. Je préfère concevoir une exception de migration, un champ historique qui accepte les valeurs nulles, une règle de transformation ou une valeur d’état hérité plutôt que de faire semblant de savoir quelque chose que nous ne savons pas.

L’automatisation multiplie le Nombre de zéros

Section intitulée « L’automatisation multiplie le Nombre de zéros »

Chargez 2 millions de comptes ; l’automatisation crée 2 tâches pour chacun : 4 millions de tâches. Voulu, ou accidentel ? Puis chaque tâche déclenche un autre flow, l’automatisation du compte met à jour un parent, publie un événement, recalcule autre chose. La performance d’une migration, ce n’est pas la vitesse à laquelle la Bulk API insère des comptes. La vraie charge de travail, c’est le graphe de transactions que ces insertions créent. Le Nombre de zéros se multiplie à travers l’automatisation.

Now zoom in on RouteDesk’s three red arrows and count. ⟲

Automation multiplies the Number of Zeros On the left, highlighted, the load: 196,400 Work Orders, about 190,000 of them already delivered. On the right, what normal automation would reach: Snowflake, for status history; the partners, Redrock, Keystone and Brightwave; the finance ERP, which invoices the partners; and the Recipients, who get day-before texts. First, every arrow is red with an X: 196,400 change events to Snowflake, 190,000 old statuses to the partners, delivery counts already invoiced to the finance ERP, and texts for old deliveries to the Recipients. Then the controlled path: the red arrows are gone; Snowflake gets one backfill after the load, the Recipients get texts only for the open deliveries, as normal, and nothing goes to the partners or the finance ERP. Underneath: the load's real size is every record times everything each record sets off; keep only the outcomes you need. THE LOAD WHAT NORMAL AUTOMATION WOULD DO 196,400 Work Orders about 190,000 already delivered Snowflake status history The partners Redrock, Keystone, Brightwave Finance ERP invoices the partners Recipients day-before texts 196,400 change events 190,000 old statuses counts already invoiced texts for old deliveries The load's real size is every record times everything each record sets off. Keep only the outcomes you need. HOW TO READ IT the load © 2026 Twinshark LLC · stevetecharc.com
Cliquer pour agrandir

Every record, times everything it sets off. ⟲

Chapter 9 turned on Change Data Capture for Work Orders, so Snowflake’s subscriber receives a change event for every create. That’s about 196,400 events in one weekend, and without an add-on the daily allocation for delivered events is 50,000 in Performance and Unlimited Editions, counted per subscriber (Change Data Capture Allocations (s'ouvre dans un nouvel onglet), checked 2026-10-27). The partners would get status messages for about 190,000 deliveries they closed weeks ago. The finance ERP would count deliveries it has already invoiced, and the partners would be billed twice. And Recipients would get texts about deliveries that already happened. ⟲

Automation multiplies the Number of Zeros On the left, highlighted, the load: 196,400 Work Orders, about 190,000 of them already delivered. On the right, what normal automation would reach: Snowflake, for status history; the partners, Redrock, Keystone and Brightwave; the finance ERP, which invoices the partners; and the Recipients, who get day-before texts. First, every arrow is red with an X: 196,400 change events to Snowflake, 190,000 old statuses to the partners, delivery counts already invoiced to the finance ERP, and texts for old deliveries to the Recipients. Then the controlled path: the red arrows are gone; Snowflake gets one backfill after the load, the Recipients get texts only for the open deliveries, as normal, and nothing goes to the partners or the finance ERP. Underneath: the load's real size is every record times everything each record sets off; keep only the outcomes you need. {"author": "Steve Simpson", "blueprint": "1.0.0", "builder": "standard 1.48.0", "built": "2026-10-27", "id": "DGM-DA-MG-32", "rights": "\u00a9 2026 Twinshark LLC. All rights reserved.", "template": "cells 0.4.0", "theme": "stevetecharc 1.4.0"} THE LOAD WHAT NORMAL AUTOMATION WOULD DO 196,400 Work Orders about 190,000 already delivered Snowflake status history The partners Redrock, Keystone, Brightwave Finance ERP invoices the partners Recipients day-before texts one backfill, after the load open ones only, as normal The load's real size is every record times everything each record sets off. Keep only the outcomes you need. HOW TO READ IT the load © 2026 Twinshark LLC · stevetecharc.com
Cliquer pour agrandir

Keep only the outcomes you need: one backfill, texts for the open deliveries, nothing to partners or finance. ⟲

Les effets de bord externes sont pires. E-mails aux clients, demandes de facturation, événements consommés par des systèmes de production, appels à l’ERP, tickets de support, mises à jour marketing : ces systèmes ne savent pas que ce sont des données de migration, et une fois que le message a quitté Salesforce, l’annuler peut être impossible. Le chapitre 9 nous a donné le contrat de données d’intégration ; pendant la planification de la migration, décidez lesquelles de ces flèches peuvent fonctionner, lesquelles sont neutralisées, et lesquelles sont remplacées par une synchronisation après la bascule. Cette décision a sa place dans le plan de bascule.

Les données dérivées, le partage et l’objet de transit

Section intitulée « Les données dérivées, le partage et l’objet de transit »

Les récapitulatifs de cumul et autres valeurs dérivées : charger un parent, puis des millions d’enfants, et recalculer après chaque enfant ? Peut-être. Souvent, il est bien moins coûteux de tout charger puis de calculer une seule fois. La question est de savoir si le résultat dérivé doit être maintenu enregistrement par enregistrement pendant la migration, ou s’il peut être établi une fois les données dépendantes complètes. C’est la même décision : pas besoin, simuler, différer.

Le partage, c’est aussi des données dérivées. Créer et transférer des enregistrements déclenche le calcul des règles de partage, et sur un gros chargement, cela peut signifier des évaluations très longues ou des dépassements de délai. Salesforce permet à un administrateur de différer les calculs de partage (règles de partage et appartenance aux groupes) et de les reprendre ensuite, mais la fonctionnalité n’est pas activée par défaut : c’est le support Salesforce qui l’active. À la reprise, vous devez lancer un recalcul complet, et certains changements de partage sont quand même calculés immédiatement pour protéger l’intégrité des données (Defer Sharing Calculations (s'ouvre dans un nouvel onglet)). Planifiez-le, et planifiez le temps du recalcul.

Deferring has limits of its own. The catch-up usually runs as batch Apex, and that shares the org’s daily allowance of asynchronous Apex executions: “250,000 or the number of applicable user licenses in your org multiplied by 200, whichever is greater.” Only five batch jobs can be queued or active at once, with up to 100 more waiting in the flex queue (Execution Governors and Limits (s'ouvre dans un nouvel onglet), Apex Developer Guide, Winter ‘27, checked 2026-10-27). Your catch-up competes with every other batch job in the org, so schedule it, and size it. ⟲

Test knowledge. Large loads trigger sharing recalculation. Salesforce Support can enable deferred sharing calculations (sharing rules and group membership), which you resume and recalculate after the load. Deferred work usually runs as batch Apex, within the daily asynchronous Apex limit and five concurrent batch jobs. ⟲

And sometimes the logic you need is simply too slow to load through. This is the special case module 1 mentioned. A process that takes a second or two per record is fine for users; for hundreds of thousands of records in a cutover window it means days, and trying to simulate an intricate object model in the load can mean a dozen tables. The technique I use: load into a staging object first, a light custom object with no automation that holds the import fields and lookups, then let a batch process work through it, calling the platform’s own logic to build the real records. The status on each staging row lets the batch work in chunks, pause and resume, and the original import fields stay alongside the records they created for tracing. You get the data in fast and catch up on the processing afterward. ⟲

Concevez pour l’état final, et mettez-le par écrit

Section intitulée « Concevez pour l’état final, et mettez-le par écrit »

Le but n’est pas « exécuter l’automatisation de production ». C’est arriver au bon état de production, et ce n’est pas la même chose. Le traitement normal d’un nouveau compte calcule une classification, crée une tâche d’intégration du client, envoie une notification et publie vers un autre système. Pour un compte historique migré, le bon état final peut être : classification oui, tâche d’intégration non, notification de bienvenue non, publication externe peut-être, selon le plan de synchronisation. Exécuter aveuglément l’automatisation normale reproduit un processus qui n’a pas été conçu pour la migration.

Pour une migration sérieuse, mettez-le par écrit sous forme d’inventaire de l’automatisation :

AutomatisationComportement normalDécision de migrationRésultat de migration requis
Status out to partnersSend each status change to Redrock, Keystone, BrightwaveDon’t need itNone: the partners already have it
Change Data Capture to SnowflakeA change event per Work OrderDeferOne backfill of status history after the load
Delivery counts to financeCount each completed delivery for invoicingDon’t need itNone: already invoiced; reconcile the count instead
Day-before textText the Recipient with a tracking linkRun deliberately, open deliveries onlyMonday’s Recipients get the link; none for delivered ones
Work Order statusSet by the crews’ appSimulateStatus mapped in the preparation data store
Install checklist and photos (R12)Block closing an install without themBypass for the migration identityCompleted installs load as completed; no invented photos
Every Work Order has a partnerReject a Work Order without oneKeepMissing partner: quarantined before the load

La décision est maintenant visible : nous pouvons la revoir, la tester, la répéter et la vérifier après le chargement.

Ne faites pas de la production la première utilisation du mode migration. La répétition doit tester l’identité de migration, les contrôles de contournement, les automatisations qui restent actives, les résultats simulés, les processus différés et le retour au mode normal, puis vérifier : quelque chose s’est-il déclenché qui n’aurait pas dû, quelque chose ne s’est-il pas produit qui aurait dû, l’état final correspond-il à l’architecture ? C’est pour cela que la répétition a besoin de la vraie configuration d’automatisation, ou d’une configuration aussi proche que possible.

La réactivation est une étape de la bascule : explicite, avec un responsable nommé, une heure prévue et une vérification. Pas « pensez à réactiver les flows ». Le système n’est pas prêt pour les utilisateurs tant que le fonctionnement normal n’est pas rétabli et vérifié (le module 4 l’inscrit dans le runbook).

And beware the catch-up storm. We suppressed downstream synchronization while loading RouteDesk’s records; now we switch the integration back on. Does it see five million “new” records and try to send them all? Maybe the downstream system already received them another way, maybe only changes after the cutover watermark should go, maybe it needs a controlled initial sync. The automation decision and the integration decision have to work together. Turning automation back on isn’t enough: know what it will do when it wakes up. For Steve Trucking, the status flows and the Change Data Capture subscriber should see only the changes made after cutover, never the weekend’s load. ⟲

L’IA rend la conception des contournements plus importante

Section intitulée « L’IA rend la conception des contournements plus importante »

Ajoutez maintenant des agents qui réagissent à une nouvelle requête client, à un compte modifié, à un événement publié ou à une tâche dans une file d’attente. Une migration crée des schémas de données à l’échelle des machines ; voulons-nous que des agents réagissent à chaque enregistrement migré ? Probablement pas par accident. Les processus déclenchés par des agents ont leur place dans le même inventaire que les flows, les triggers, les notifications, les intégrations et les événements, et si le contexte de migration doit les neutraliser, concevez-le délibérément.

Au-delà de l’examen : ce que l’IA change. Les agents sont un autre type d’effet de bord, qui peut réagir de façon autonome aux données migrées. Traitez les actions déclenchées par des agents comme n’importe quelle autre automatisation : décidez de les exécuter, de les simuler, de les différer ou de les neutraliser, et testez la décision lors de la répétition.

  • Quelles automatisations s’exécutent, ne sont pas nécessaires, sont simulées ou sont différées pour chaque catégorie de données migrées, en sachant que désactiver l’une d’elles veut dire répondre de sa logique métier.
  • Quelles règles de validation représentent une vérité durable des données, et lesquelles sont des règles du processus actuel qui demandent un traitement propre à la migration.
  • How scoped bypasses are designed into every automation from the start, tested on and off, and deployed long before they’re needed, without an unrestricted “skip everything” path. ⟲
  • Comment les données dérivées, le recalcul du partage et la logique lente de la plateforme sont traités : après le chargement, en différé, ou par un objet de transit.
  • Quels effets de bord externes et quelles intégrations sont neutralisés ou rattrapés délibérément, et comment la répétition et la bascule prouvent que l’automatisation normale a été rétablie en sécurité.

La migration ne réussit pas parce que chaque flow s’est exécuté, que chaque trigger s’est déclenché et que chaque règle de validation a été évaluée. C’est le comportement transactionnel normal, et la migration a un autre travail : déplacer les données dans la nouvelle architecture, préserver les vérités qui comptent, créer les valeurs dérivées dont nous avons besoin, éviter les faux effets de bord, garder le système maîtrisable, puis le remettre en fonctionnement normal. Pour chaque automatisation : pas besoin, la simuler, la différer, ou la laisser délibérément s’exécuter. Mais faites-en une décision. Ne laissez pas cinq millions d’enregistrements la prendre pour vous.