Patterns
Rollout sandbox → production avec feature flag
Dual-write transitionnel et bascule progressive
Bascule de l'environnement sandbox vers production en limitant le risque de double-facturation ou de divergence comptable. Pattern : (1) en phase de test interne, l'app appelle uniquement `sk_test_*` ; (2) en pré-rollout, activer un feature flag `scell.dual_write=true` qui envoie chaque facture aux DEUX environnements et compare les réponses (même numéro, même montants, même statut). Tout écart est journalisé, pas bloquant ; (3) après 1-2 semaines de dual-write sans divergence, basculer le flag vers `scell.target=prod` et désactiver les écritures sandbox sur les flux comptables. Côté code, encapsuler dans un `ScellClient` qui prend la config en runtime (LaunchDarkly, Unleash, table feature_flags PG). Ne jamais basculer en production sans avoir un kill-switch (flag inverse) testé. Ce pattern est aussi celui imposé par la DGFiP pour la transition LF 2026 : émetteurs en dual-write avec PPF avant bascule définitive sur PDP.
À retenir
- Phase 1 : sandbox uniquement (sk_test_*)
- Phase 2 : dual-write 1-2 semaines avec comparaison automatique
- Phase 3 : bascule prod (sk_live_*) avec kill-switch testé
- Feature flag runtime : LaunchDarkly, Unleash ou table PG
- Pattern aligné avec la transition LF 2026 PPF → PDP
Exemple de code
class ScellClient {
constructor(private flags: FeatureFlags) {}
async createInvoice(payload: InvoiceCreate): Promise<Invoice> {
const target = this.flags.get('scell.target', 'sandbox');
if (this.flags.get('scell.dual_write', false)) {
const [prod, sandbox] = await Promise.allSettled([
this.call('live', payload),
this.call('test', payload),
]);
this.compareAndLog(prod, sandbox);
return target === 'prod' ? unwrap(prod) : unwrap(sandbox);
}
return this.call(target === 'prod' ? 'live' : 'test', payload);
}
}