Évolution de schéma sûre lors de la régénération pour des migrations prévisibles
L'évolution de schéma sûre lors de la régénération garde les données de production valides quand le code backend est régénéré. Apprenez une méthode pratique pour planifier les modifications de schéma et les migrations.

Pourquoi les changements de schéma paraissent risqués quand le backend est régénéré
Quand votre backend est régénéré à partir d'un modèle visuel, une modification de la base de données peut ressembler à tirer un fil sur un pull. Vous modifiez un champ dans le Data Designer, cliquez sur régénérer, et soudain vous ne changez pas seulement une table. Vous changez aussi l'API générée, les règles de validation et les requêtes que votre application utilise pour lire et écrire des données.
Ce qui foire le plus souvent, ce n'est pas que le nouveau code n'arrive pas à se compiler. Beaucoup de plateformes no-code (y compris AppMaster, qui génère du code Go réel pour les backends) génèrent volontiers un projet propre à chaque fois. Le vrai risque, c'est que des données de production existent déjà et ne se remodèlent pas automatiquement pour correspondre à vos nouvelles idées.
Les deux premiers échecs que les gens remarquent sont simples :
- Lectures cassées : l'application ne peut plus charger des enregistrements parce qu'une colonne a été déplacée, un type a changé, ou une requête attend quelque chose qui n'existe plus.
- Écritures cassées : les nouveaux enregistrements ou les mises à jour échouent parce que des contraintes, des champs obligatoires ou des formats ont changé, alors que les clients existants envoient encore l'ancien format.
Ces deux échecs sont douloureux car ils peuvent rester invisibles jusqu'à ce que de vrais utilisateurs les rencontrent. Une base de staging peut être vide ou fraîchement initialisée, donc tout a l'air correct. La production a des cas limites : des NULL là où vous pensiez avoir des valeurs, d'anciens libellés d'enum, ou des lignes créées avant l'apparition d'une nouvelle règle.
C'est pourquoi l'évolution de schéma sûre lors de la régénération est importante. L'objectif est de rendre chaque changement sûr même quand le code backend est entièrement régénéré, afin que les anciens enregistrements restent valides et que les nouveaux puissent toujours être créés.
« Migrations prévisibles » signifie simplement que vous pouvez répondre à quatre questions avant de déployer : qu'est-ce qui va changer dans la base de données, que va-t-il arriver aux lignes existantes, quelle version de l'application peut fonctionner pendant le déploiement, et comment revenir en arrière si quelque chose d'inattendu survient.
Un modèle simple : schéma, migrations et code régénéré
Quand votre plateforme peut régénérer le backend, il est utile de séparer mentalement trois choses : le schéma de la base de données, les étapes de migration qui le modifient, et les données en production. Confondre ces éléments est la raison pour laquelle les changements semblent imprévisibles.
Pensez à la régénération comme à « reconstruire le code de l'application à partir du modèle le plus récent ». Dans un outil comme AppMaster, cette reconstruction peut se produire souvent pendant le travail normal : vous ajustez un champ, modifiez la logique métier, ajoutez un endpoint, régénérez, testez, répétez. La régénération est fréquente. Votre base de production ne devrait pas l'être.
Voici le modèle simple.
- Schéma : la structure des tables, colonnes, index et contraintes. C'est ce que la base de données attend.
- Migrations : les étapes ordonnées et reproductibles qui font évoluer le schéma d'une version à la suivante (et parfois transforment aussi les données). C'est ce que vous exécutez sur chaque environnement.
- Données d'exécution : les enregistrements réels créés par les utilisateurs et les processus. Ils doivent rester valides avant, pendant et après le changement.
Le code régénéré doit être traité comme « l'application actuelle qui parle au schéma actuel ». Les migrations sont le pont qui maintient le schéma et les données d'exécution alignés au fur et à mesure que le code évolue.
Pourquoi la régénération change la donne
Si vous régénérez souvent, vous ferez naturellement beaucoup de petites modifications de schéma. C'est normal. Le risque apparaît quand ces modifications impliquent un changement de base de données non rétrocompatible, ou quand votre migration n'est pas déterministe.
Une façon pratique de gérer cela est de planifier une évolution de schéma sûre lors de la régénération comme une série de petites étapes réversibles. Plutôt que d'effectuer un grand basculement, réalisez des mouvements contrôlés qui maintiennent les anciens et nouveaux chemins de code fonctionnels pendant un court laps de temps.
Par exemple, si vous voulez renommer une colonne utilisée par une API en production, ne la renommez pas immédiatement. Ajoutez d'abord la nouvelle colonne, écrivez dans les deux, rétro-remplissez les lignes existantes, puis basculez les lectures vers la nouvelle colonne. Ce n'est qu'après cela que vous supprimez l'ancienne colonne. Chaque étape est facile à tester, et si quelque chose tourne mal, vous pouvez faire une pause sans corrompre les données.
Ce modèle mental rend les migrations prévisibles, même quand la régénération du code a lieu quotidiennement.
Types de changements de schéma et ceux qui cassent la production
Quand votre backend est régénéré à partir du schéma le plus récent, le code suppose généralement que la base de données correspond à ce schéma maintenant. C'est pourquoi l'évolution sûre du schéma concerne moins la question « Peut-on changer la base ? » que « Les anciennes données et les anciennes requêtes survivront-elles pendant le déploiement ? »
Certains changements sont naturellement sûrs parce qu'ils n'invalident pas les lignes ou requêtes existantes. D'autres modifient le sens des données ou suppriment quelque chose que l'application en cours attend encore, et c'est là que les incidents de production surviennent.
Faible risque, généralement sûr (ajout)
Les modifications additives sont les plus faciles à déployer car elles peuvent coexister avec d'anciennes données.
- Nouvelle table dont rien ne dépend encore.
- Nouvelle colonne nullable sans exigence de valeur par défaut.
- Nouveau champ d'API optionnel de bout en bout.
Exemple : ajouter une colonne nullable middle_name à la table users est typiquement sûr. Les lignes existantes restent valides, le code régénéré peut la lire quand elle est présente, et les anciennes lignes auront simplement NULL.
Risque moyen (changement de sens)
Ces changements fonctionnent souvent techniquement mais altèrent le comportement. Ils demandent une coordination soignée car la régénération met à jour les validations, les modèles générés et les hypothèses de la logique métier.
Les renommages sont le piège classique : renommer phone en mobile_phone peut régénérer du code qui ne lit plus phone, alors que la production contient encore les données là-bas. De même, changer d'unité (prix en dollars vs en cents) peut corrompre silencieusement les calculs si vous mettez à jour le code avant les données, ou les données avant le code.
Les enums sont une autre zone dangereuse. Resserer un enum (supprimer des valeurs) peut rendre des lignes existantes invalides. Étendre un enum (ajouter des valeurs) est généralement sûr, mais seulement si tous les chemins de code peuvent gérer la nouvelle valeur.
Une approche pratique est de traiter les changements de sens comme « ajouter, rétro-remplir, basculer, puis supprimer plus tard ».
Haut risque (destructif)
Les changements destructifs sont ceux qui cassent le plus souvent la production immédiatement, surtout quand la plateforme régénère du code qui cesse d'attendre l'ancienne forme.
Supprimer une colonne, une table, ou passer une colonne de nullable à not-null peut faire échouer les écritures dès qu'une requête tente d'insérer une ligne sans cette valeur. Même si vous pensez « toutes les lignes l'ont déjà », le prochain cas limite ou job en arrière-plan peut prouver le contraire.
Si vous devez faire un changement not-null, procédez par phases : ajoutez d'abord la colonne nullable, rétro-remplissez, mettez la logique applicative à jour pour toujours la renseigner, puis imposez not-null.
Performances et sécurité (peuvent bloquer les écritures)
Les index et contraintes ne sont pas des changements de forme de données, mais ils peuvent tout de même causer des indisponibilités. Créer un index sur une grande table ou ajouter une contrainte UNIQUE peut verrouiller les écritures assez longtemps pour provoquer des timeouts. Dans PostgreSQL, certaines opérations sont plus sûres lorsqu'elles sont réalisées avec des méthodes compatibles online, mais le point clé est le timing : effectuez les opérations lourdes en période de faible trafic et mesurez leur durée sur une copie de staging.
Quand les changements demandent plus de soin en production, prévoyez :
- Un déploiement en deux étapes (d'abord le schéma, puis le code, ou l'inverse) qui reste compatible.
- Des backfills qui s'exécutent par lots.
- Un plan de rollback clair (que se passe-t-il si le backend régénéré est mis en ligne trop tôt).
- Des requêtes de vérification qui prouvent que les données correspondent aux nouvelles règles.
- Un ticket « supprimer l'ancien champ plus tard » pour que le nettoyage n'ait pas lieu dans le même déploiement.
Si vous utilisez une plateforme comme AppMaster qui régénère le code backend à partir du Data Designer, l'état d'esprit le plus sûr est : déployez d'abord des changements que les anciennes données peuvent supporter aujourd'hui, puis durcissez les règles seulement après que le système se soit adapté.
Principes pour des changements sûrs lors de la régénération
Les backends régénérés sont formidables jusqu'à ce qu'un changement de schéma arrive en production et que les anciennes lignes ne correspondent plus à la nouvelle forme. L'objectif de l'évolution de schéma sûre est simple : garder votre application fonctionnelle pendant que la base de données et le code régénéré se rattrapent l'un l'autre par petites étapes prévisibles.
Par défaut : « étendre, migrer, contracter »
Traitez chaque changement significatif comme trois mouvements. D'abord, étendez le schéma pour que l'ancien et le nouveau code puissent fonctionner. Ensuite, migrez les données. Enfin, contractez en supprimant les anciennes colonnes, valeurs par défaut ou contraintes.
Règle pratique : ne combinez jamais « nouvelle structure » et « nettoyage destructif » dans le même déploiement.
Supportez l'ancien et le nouveau format pendant un moment
Supposez qu'il y aura une période où :
- certaines lignes ont les nouveaux champs, d'autres non
- certaines instances d'app exécutent l'ancien code, d'autres le code régénéré
- des jobs en arrière-plan, des imports ou des clients mobiles peuvent être à la traîne
Concevez votre base pour que les deux formes soient valides pendant ce chevauchement. Cela compte d'autant plus quand une plateforme régénère votre backend depuis le modèle le plus récent (par exemple, dans AppMaster quand vous mettez à jour le Data Designer et régénérez le backend Go).
Rendre les lectures compatibles avant les écritures
Commencez par faire en sorte que le nouveau code puisse lire les anciennes données en toute sécurité. Ce n'est qu'ensuite que vous devez basculer les chemins d'écriture pour produire la nouvelle forme de données.
Par exemple, si vous scindez un champ « status » en « status » + « status_reason », déployez du code qui gère d'abord l'absence de « status_reason ». Ensuite, commencez à écrire « status_reason » pour les nouvelles mises à jour.
Décidez du traitement des données partielles et inconnues
Quand vous ajoutez des enums, des colonnes non-null ou des contraintes plus strictes, décidez à l'avance ce qu'il faut faire si les valeurs sont manquantes ou inattendues :
- autoriser les NULL temporairement, puis rétro-remplir
- définir une valeur par défaut sûre qui ne change pas le sens
- garder une valeur « inconnu » pour éviter d'échouer les lectures
Cela évite la corruption silencieuse (mauvaises valeurs par défaut) et les échecs brutaux (nouvelles contraintes rejetant les anciennes lignes).
Avoir une stratégie de rollback pour chaque étape
Le rollback est le plus simple durant la phase d'expansion. Si vous devez revenir en arrière, l'ancien code doit encore fonctionner contre le schéma étendu. Écrivez ce que vous feriez pour revenir en arrière (code uniquement, ou code plus migration), et évitez les changements destructifs jusqu'à ce que vous soyez sûr de ne pas avoir besoin d'annuler.
Pas à pas : planifier un changement qui survit à la régénération
Les backends régénérés sont impitoyables : si le schéma et le code généré divergent, la production le découvre généralement la première. L'approche la plus sûre est de traiter chaque changement comme un petit déploiement réversible, même si vous construisez avec des outils no-code.
Commencez par écrire l'intention en langage simple et ce à quoi ressemblent vos données aujourd'hui. Choisissez 3 à 5 vraies lignes de production (ou un dump récent) et notez les éléments problématiques : valeurs vides, anciens formats, valeurs par défaut surprenantes. Cela vous empêche de concevoir un champ idéal que les données réelles ne peuvent pas satisfaire.
Voici une séquence pratique qui fonctionne bien quand votre plateforme régénère le code backend (par exemple, quand AppMaster régénère des services backend Go depuis le modèle Data Designer) :
-
Étendre d'abord, ne pas remplacer. Ajoutez de nouvelles colonnes ou tables de manière additive. Rendez d'abord les nouveaux champs nullable, ou donnez-leur des valeurs par défaut sûres. Si vous introduisez une nouvelle relation, autorisez la clé étrangère à être vide jusqu'à ce que vous l'ayez remplie.
-
Déployez le schéma étendu sans rien supprimer. Appliquez le changement de base pendant que l'ancien code fonctionne encore. Le but : l'ancien code peut continuer à écrire dans les anciennes colonnes et la base accepte ces écritures.
-
Rétro-remplissez avec un job contrôlé. Remplissez les nouveaux champs via un processus par lots que vous pouvez surveiller et relancer. Gardez-le idempotent (l'exécuter deux fois ne doit pas corrompre les données). Faites-le progressivement si la table est grande et loggez le nombre de lignes mises à jour.
-
Basculez les lectures d'abord, avec repli. Mettez à jour la logique régénérée pour préférer les nouveaux champs, mais retombez sur les anciens quand les nouveaux sont manquants. Ce n'est qu'après que les lectures sont stables que vous passez les écritures aux nouveaux champs.
-
Nettoyez en dernier. Quand vous avez confiance (et un plan de rollback), supprimez les anciens champs et durcissez les contraintes : ajoutez NOT NULL, contraintes d'unicité, et clés étrangères.
Exemple concret : vous voulez remplacer un status en texte libre par un status_id pointant vers une table statuses. Ajoutez status_id nullable, rétro-remplissez depuis les valeurs textuelles, mettez l'app à lire status_id en tombant sur status si nécessaire, puis supprimez status et rendez status_id obligatoire. Cela rend chaque étape sûre parce que la base reste compatible à tout moment.
Schémas pratiques réutilisables
Quand votre backend est régénéré, de petits ajustements de schéma peuvent se répercuter sur les API, les validations et les formulaires UI. L'objectif est de modifier de façon que les anciennes données restent valides pendant que le nouveau code est déployé.
Schéma 1 : renommage non destructif
Renommer directement est risqué car les anciennes lignes et l'ancien code attendent souvent le nom original. Une approche plus sûre est de considérer le renommage comme une période de migration courte.
- Ajoutez la nouvelle colonne (par exemple
customer_phone) et conservez l'ancienne (phone). - Mettez la logique en écriture double : quand vous enregistrez, écrivez dans les deux champs.
- Rétro-remplissez les lignes existantes pour que
customer_phonesoit renseignée. - Basculez les lectures vers la nouvelle colonne une fois la couverture élevée.
- Supprimez l'ancienne colonne dans une version ultérieure.
Cela fonctionne bien dans des outils comme AppMaster où la régénération reconstruit les modèles de données et les endpoints depuis le schéma courant. L'écriture double maintient les deux générations de code compatibles pendant la transition.
Schéma 2 : scinder un champ en deux
Diviser full_name en first_name et last_name est similaire, mais le rétro-remplissage est plus délicat. Conservez full_name jusqu'à ce que la scission soit complète.
Règle pratique : ne supprimez pas le champ original tant que chaque enregistrement n'est pas soit rétro-rempli soit doté d'un repli clair. Si le parsing échoue, stockez la chaîne entière dans last_name et marquez l'enregistrement pour revue.
Schéma 3 : rendre un champ obligatoire
Passer un champ nullable à obligatoire casse souvent la production. L'ordre sûr est : rétro-remplir d'abord, puis imposer.
Le rétro-remplissage peut être mécanique (fixer une valeur par défaut) ou piloté par métier (demander aux utilisateurs de compléter les données manquantes). Ce n'est qu'après que les données sont complètes que vous ajoutez NOT NULL et mettez à jour les validations. Si votre backend régénéré ajoute automatiquement des validations plus strictes, cette séquence évite les échecs surprises.
Schéma 4 : changer un enum en sécurité
Les enums cassent quand l'ancien code envoie d'anciennes valeurs. Pendant la transition, acceptez les deux. Si vous remplacez "pending" par "queued", gardez temporairement les deux valeurs valides et mappez-les dans votre logique. Quand vous êtes sûr qu'aucun client n'envoie l'ancienne valeur, supprimez-la.
Si le changement doit être livré en une seule release, réduisez le risque en limitant le périmètre :
- Ajoutez de nouveaux champs mais conservez les anciens, même inutilisés.
- Utilisez une valeur par défaut en base pour que les insertions continuent de fonctionner.
- Rendez le code tolérant : lisez le nouveau champ, retombez sur l'ancien.
- Ajoutez une couche de mapping temporaire (ancienne valeur en entrée, nouvelle valeur stockée).
Ces schémas gardent les migrations prévisibles même quand le code régénéré change rapidement de comportement.
Erreurs courantes qui causent des surprises
Les plus grosses surprises arrivent quand on traite la régénération du code comme un bouton magique de remise à zéro. Les backends régénérés peuvent garder votre code propre, mais votre base de production contient toujours les données d'hier, avec la forme d'hier. L'évolution sûre du schéma signifie planifier pour les deux : le nouveau code généré et les anciens enregistrements encore présents.
Un piège fréquent est de supposer que la plateforme « s'occupe des migrations ». Par exemple, dans AppMaster vous pouvez régénérer un backend Go depuis le Data Designer mis à jour, mais la plateforme ne peut pas deviner comment vous voulez transformer les données réelles des clients. Si vous ajoutez un champ obligatoire, vous devez toujours avoir un plan clair pour attribuer une valeur aux lignes existantes.
Une autre surprise est de supprimer ou renommer des champs trop tôt. Un champ peut sembler inutilisé dans l'UI principale, mais être lu par un rapport, une exportation planifiée, un webhook ou un écran admin que quelqu'un ouvre rarement. Le changement semble sûr en test, puis échoue en production parce qu'un chemin d'accès oublié s'attend encore à l'ancien nom de colonne.
Voici cinq erreurs qui mènent souvent à des rollbacks nocturnes :
- Changer le schéma et régénérer le code sans écrire ni vérifier la migration de données qui rendrait les anciennes lignes valides.
- Renommer ou supprimer une colonne avant que tous les lecteurs et écrivains aient été mis à jour et déployés.
- Rétro-remplir une grosse table sans vérifier la durée et si cela bloquera d'autres écritures.
- Ajouter d'abord une contrainte (NOT NULL, UNIQUE, clé étrangère), puis découvrir des données legacy qui la violent.
- Oublier les jobs en arrière-plan, exports et rapports qui lisent encore les anciens champs.
Scénario simple : vous renommez phone en mobile_number, ajoutez une contrainte NOT NULL et régénérez. Les écrans de l'app peuvent fonctionner, mais une ancienne exportation CSV sélectionne encore phone, et des milliers d'enregistrements ont mobile_number NULL. La solution est généralement un changement en phases : ajoutez la nouvelle colonne, écrivez dans les deux pendant un temps, rétro-remplissez en sécurité, puis resserrez les contraintes et supprimez l'ancien champ une fois que vous avez la preuve qu'il n'est plus utilisé.
Checklist pré-déploiement rapide pour des migrations plus sûres
Quand votre backend est régénéré, le code peut changer vite, mais vos données de production ne pardonnent pas les surprises. Avant de livrer un changement de schéma, faites un contrôle rapide « est-ce que ça peut échouer en sécurité ? ». Cela rend l'évolution sûre du schéma ennuyeuse (et c'est ce que vous voulez).
Les 5 vérifications qui détectent la plupart des problèmes
- Taille et vitesse du backfill : estimez combien de lignes existantes doivent être mises à jour et combien de temps cela prendra en production. Un backfill acceptable sur une petite base peut prendre des heures sur de vraies données et ralentir l'app.
- Verrous et risque d'indisponibilité : identifiez si le changement peut bloquer les écritures. Certaines opérations (modifier de grandes tables ou changer de type) peuvent tenir des verrous assez longtemps pour provoquer des timeouts. Si le risque existe, prévoyez un déploiement plus sûr (ajouter d'abord la colonne, rétro-remplir plus tard, basculer le code en dernier).
- Compatibilité ancien code vs nouveau schéma : supposez que l'ancien backend puisse s'exécuter un court instant contre le nouveau schéma pendant le déploiement ou le rollback. Demandez-vous : la version précédente lira et écrira-t-elle sans planter ? Sinon, vous avez besoin d'une release en deux étapes.
- Comportement des valeurs par défaut et NULL : pour les nouvelles colonnes, décidez du comportement pour les enregistrements existants. Seront-ils NULL, ou avez-vous besoin d'une valeur par défaut ? Assurez-vous que votre logique traite l'absence de valeur comme normale, surtout pour les flags, statuts et timestamps.
- Signaux de monitoring à surveiller : choisissez les alarmes exactes que vous surveillerez après le déploiement : taux d'erreur (échecs API), requêtes lentes en base, échecs de queues/jobs, et toute action utilisateur clé (checkout, login, soumission de formulaire). Surveillez aussi les bugs silencieux comme une montée des erreurs de validation.
Un exemple rapide
Si vous ajoutez un nouveau champ obligatoire status à une table orders, ne le poussez pas d'un coup en « NOT NULL, sans valeur par défaut ». Ajoutez-le d'abord en nullable avec une valeur par défaut pour les nouvelles lignes, déployez un code régénéré qui gère l'absence de status, retro-remplissez les anciennes lignes, puis resserrez la contrainte.
Dans AppMaster, cet état d'esprit est particulièrement utile car le backend peut être régénéré souvent. Traitez chaque changement de schéma comme un petit release avec un rollback simple, et vos migrations resteront prévisibles.
Exemple : faire évoluer une application active sans casser les enregistrements existants
Imaginez un outil interne de support où les agents taguent des tickets avec un champ texte libre priority (exemples : "high", "urgent", "HIGH", "p1"). Vous voulez passer à un enum strict pour que les rapports et règles de routage cessent de deviner.
L'approche sûre est un changement en deux releases qui garde les anciennes données valides pendant que votre backend est régénéré.
Release 1 : étendre, écrire dans les deux et rétro-remplir
Commencez par étendre le schéma sans rien supprimer. Ajoutez un nouveau champ enum, par exemple priority_enum avec des valeurs low, medium, high, urgent. Gardez l'ancien champ priority_text.
Ensuite, mettez la logique à jour pour que les nouveaux tickets et les tickets modifiés écrivent dans les deux champs. Dans un outil no-code comme AppMaster, cela signifie typiquement ajuster le modèle Data Designer et mettre à jour le Business Process pour mapper l'entrée vers l'enum tout en conservant le texte original.
Puis rétro-remplissez les tickets existants par petits lots. Mappez les valeurs textes communes vers l'enum ("p1" et "urgent" -> urgent, "HIGH" -> high). Tout ce qui est inconnu peut temporairement être mappé sur medium pendant que vous révisez.
Ce que voient les utilisateurs : idéalement rien ne change encore. L'UI peut garder le même contrôle de priorité, mais en coulisse vous remplissez le nouvel enum. Les rapports peuvent commencer à utiliser l'enum dès que le rétro-remplissage est en cours.
Release 2 : contracter et supprimer l'ancien chemin
Quand vous êtes confiant, basculez les lectures pour n'utiliser que priority_enum, mettez à jour les filtres et tableaux de bord, puis supprimez priority_text lors d'une migration ultérieure.
Avant la Release 2, validez avec un petit échantillon pour détecter les cas limites :
- Choisissez 20 à 50 tickets répartis par équipes et âges.
- Comparez la priorité affichée avec la valeur enum stockée.
- Vérifiez les comptes par valeur enum pour repérer des pics suspects (par exemple trop de
medium).
Si des problèmes apparaissent, le rollback est simple car la Release 1 a conservé l'ancien champ : redéployez la logique de Release 1 et faites lire l'UI depuis priority_text pendant que vous corrigez le mapping et relancez le rétro-remplissage.
Prochaines étapes : faire de l'évolution du schéma une habitude reproductible
Si vous voulez des migrations prévisibles, traitez les changements de schéma comme un petit projet, pas une modification rapide. L'objectif est simple : chaque changement doit être facile à expliquer, à répéter et difficile à casser accidentellement.
Un modèle de données visuel aide car il rend l'impact visible avant le déploiement. Quand vous pouvez voir tables, relations et types en un seul endroit, vous remarquez des choses faciles à manquer dans un script, comme un champ obligatoire sans valeur sûre, ou une relation qui orpheline des enregistrements anciens. Faites rapidement un "qui dépend de ça ?" : API, écrans, rapports et jobs en arrière-plan.
Quand vous devez changer un champ déjà en usage, préférez une courte période de transition avec des champs dupliqués. Par exemple, ajoutez phone_e164 tout en conservant phone_raw pendant une ou deux releases. Mettez la logique métier pour lire d'abord le nouveau champ et retomber sur l'ancien s'il est absent. Écrivez dans les deux champs pendant la transition, puis supprimez l'ancien seulement après vérification complète du rétro-remplissage.
La discipline des environnements transforme les bonnes intentions en releases sûres. Gardez dev, staging et production alignés, mais ne les considérez pas comme identiques.
- Dev : vérifiez que le backend régénéré démarre proprement et que les flux basiques fonctionnent après régénération.
- Staging : exécutez le plan de migration complet sur des données proches de la production et validez les requêtes et rapports clés.
- Production : déployez quand vous avez un plan de rollback, un monitoring clair et un petit ensemble de contrôles obligatoires.
Rendez votre plan de migration concret, même s'il est court. Incluez : ce qui change, l'ordre, comment rétro-remplir, comment vérifier et comment revenir en arrière. Puis exécutez-le de bout en bout dans un environnement de test avant d'aller en production.
Si vous utilisez AppMaster, appuyez-vous sur le Data Designer pour raisonner visuellement sur le modèle, et laissez la régénération maintenir le code backend cohérent avec le schéma mis à jour. L'habitude qui rend tout prévisible est de rendre les migrations explicites : vous pouvez itérer vite, mais chaque changement a quand même un chemin planifié pour les données de production existantes.


