Réalisations
Captures et démonstrations issues des projets réels.

Validation de migration vers Odoo 17
Étape intermédiaire de la migration Odoo.sh, utilisée pour isoler les incompatibilités avant la montée finale.

Validation de migration vers Odoo 18
Passage de validation avant la branche v19, avec correction progressive des modules personnalisés et tiers.

Migration Odoo 19 réussie
Validation de la branche cible Odoo 19 avant merge staging → production.
01
Chez 1UP Distribution, Odoo est l'ERP de l'entreprise. Un ERP, ou progiciel de gestion intégré, est un logiciel qui centralise dans un même système les données et les processus nécessaires au fonctionnement de plusieurs services. Odoo occupe ainsi une place centrale dans le système d'information, c'est-à-dire l'ensemble des logiciels, des données et des échanges numériques utilisés par l'entreprise. Environ trois quarts des employés l'utilisent quotidiennement pour la comptabilité, le suivi de la relation client, les ventes, les achats, l'inventaire et l'administration des ventes, qui couvre le traitement des commandes depuis leur réception jusqu'à leur facturation. L'ERP compte 20 utilisateurs internes ainsi qu'une dizaine d'agents commerciaux externes disposant d'accès plus restreints, adaptés à leur rôle.
Le reste du système d'information est connecté à Odoo à différents degrés. Le site B2B — un portail de vente réservé aux clients professionnels — dépend directement des données de l'ERP. Il les consulte et les met à jour par API, une interface technique permettant à deux applications d'échanger automatiquement des informations, pour gérer notamment les clients, les produits, les commandes et les stocks. Un hub d'intégration, c'est-à-dire un programme intermédiaire chargé d'orchestrer les échanges entre plusieurs outils, relie également Odoo, différentes marketplaces et ShippingBo. Une marketplace est une plateforme de vente externe sur laquelle plusieurs vendeurs proposent leurs produits. ShippingBo est une suite logistique qui centralise les commandes issues de ces différents canaux, organise leur préparation en entrepôt et pilote leur expédition. Des outils de business intelligence transforment enfin les données d'Odoo en indicateurs et en tableaux de bord destinés au pilotage opérationnel.
À l'été 2025, l'entreprise utilisait encore Odoo 16, une version majeure publiée en 2022 dont le support standard arrivait à son terme. Le support standard correspond à la période pendant laquelle l'éditeur fournit normalement ses corrections de bugs et ses mises à jour de sécurité. Les données étaient enregistrées dans PostgreSQL, un système de gestion de base de données chargé de stocker et d'organiser durablement les informations de l'ERP. Cette base comportait 16 modules développés sur mesure, un module étant une extension logicielle qui ajoute ou modifie une fonctionnalité d'Odoo. Elle intégrait aussi une dizaine de modules tiers, donc créés par des éditeurs ou développeurs extérieurs, ainsi que plusieurs centaines de personnalisations réalisées avec Odoo Studio.
Odoo Studio est un outil visuel qui permet de créer des champs de données, de modifier les écrans de l'ERP — appelés vues — ou d'ajouter des actions automatisées sans développer un module complet. Ces personnalisations sont utiles pour répondre rapidement à un besoin, mais elles sont principalement enregistrées dans la base de données plutôt que dans le dépôt de code. Un dépôt de code est un espace versionné qui conserve les fichiers du logiciel et l'historique de leurs modifications. Lorsque les personnalisations Studio deviennent nombreuses, il est donc plus difficile pour un développeur de les inventorier, de suivre leur évolution et de les adapter lors d'une migration.
L'ERP était hébergé sur Odoo.sh, la plateforme d'hébergement gérée par Odoo selon le modèle PaaS, ou Platform as a Service. Dans ce modèle, l'éditeur fournit l'infrastructure et les outils nécessaires pour construire, tester et exploiter l'application sans que l'entreprise administre elle-même les serveurs. Odoo.sh est relié au dépôt GitHub du projet, GitHub étant le service utilisé pour stocker, versionner et partager le code source. La plateforme fournit un environnement de développement pour expérimenter, un environnement de préproduction pour vérifier les changements sur une copie réaliste et un environnement de production utilisé quotidiennement par les utilisateurs. Elle automatise également les sauvegardes, les tests techniques et le déploiement, c'est-à-dire la publication d'une nouvelle version de l'application. Pour continuer à bénéficier normalement de cet hébergement, des mises à jour de sécurité et du support de l'éditeur, l'entreprise devait quitter Odoo 16. Le projet a commencé à l'été 2025 avec l'objectif initial d'achever la migration au plus tard en janvier 2026.
J'étais responsable de l'intégralité du volet technique. Un prestataire externe devait initialement m'assister et effectuer une vérification finale, mais son intervention n'a pas eu lieu. J'ai finalement pris en charge seul la préparation, les migrations successives, les tests, la mise en production et les corrections après la bascule. Mon principal appui fonctionnel était l'assistante de direction, dont la connaissance transversale de l'ERP et des processus métier permettait de vérifier les comportements attendus du point de vue des utilisateurs.
La complexité venait autant du volume de personnalisations que de l'écart entre les versions. Le passage de la version 16 à la version 19 imposait de traiter successivement les migrations 16 vers 17, 17 vers 18, puis 18 vers 19. Les modules sur mesure étaient principalement écrits en Python, un langage de programmation utilisé pour définir la logique métier d'Odoo. Pour chaque vue personnalisée avec Studio, il fallait également comprendre les expressions XPath générées. Un XPath est un chemin de sélection qui indique quel élément d'un document XML doit être ciblé ; XML est le langage de balisage utilisé par Odoo pour décrire la structure de ses écrans. Il fallait ensuite vérifier que l'élément ciblé existait toujours dans le nouveau code source, c'est-à-dire dans les fichiers qui définissent le fonctionnement de la nouvelle version d'Odoo. En parallèle, il fallait récupérer les nouvelles versions des modules tiers, migrer manuellement ceux qui n'étaient plus maintenus et corriger ceux qui restaient défectueux malgré une mise à jour officielle.
02
Le premier critère de réussite était de faire passer l'ensemble de l'ERP sur Odoo 19 sans perdre les données nécessaires à l'activité, et en particulier sans perdre de données comptables ni de pièces justificatives. Il ne suffisait donc pas d'obtenir une application capable de démarrer sur la nouvelle version : il fallait repérer avant la bascule chaque zone dans laquelle la migration pouvait omettre, altérer ou rendre inaccessible une information, puis contrôler le résultat obtenu. Le deuxième objectif était de conserver les fonctionnalités qui répondaient encore à un besoin métier réel. Une régression fonctionnelle est la disparition ou le mauvais fonctionnement, après une modification du logiciel, d'un comportement qui fonctionnait auparavant. La migration devait réduire ces régressions au minimum afin que la nouvelle version reste réellement exploitable par les différents services.
La comptabilité constituait le périmètre le plus sensible. L'ERP enregistre notamment les factures reçues des fournisseurs pour justifier les achats de l'entreprise. Dans Odoo, toutes les informations ne se trouvent pas uniquement dans la base PostgreSQL : les fichiers associés aux enregistrements sont conservés dans un espace distinct appelé filestore. Ce répertoire de stockage contient les pièces jointes et d'autres données binaires, c'est-à-dire des fichiers tels que des factures au format PDF, des images ou des documents importés. Une migration pouvait donc laisser visible l'écriture correspondant à un achat tout en rendant sa facture jointe indisponible si le filestore était incomplet ou mal rattaché à la base migrée. Une telle perte aurait diminué la traçabilité comptable et compliqué la justification de l'opération lors d'un contrôle comptable ou fiscal. Cet enjeu était d'autant plus important que les factures clients et fournisseurs sont des pièces justificatives que l'entreprise doit conserver pendant dix ans à compter de la clôture de l'exercice concerné.
La continuité fonctionnelle devait également limiter la friction créée par le changement de version. L'objectif n'était pas de reproduire aveuglément chaque ancien comportement, mais de préserver tout ce qui restait nécessaire aux processus de comptabilité, de vente, d'achat, d'inventaire et d'administration des ventes. Les écarts d'interface ou de fonctionnement devaient être identifiés, expliqués et, lorsque cela était nécessaire, accompagnés par une formation. Pour les utilisateurs, qu'ils soient techniques ou non, la migration devait être aussi transparente que possible : ils devaient retrouver leurs données, comprendre les évolutions utiles et pouvoir reprendre leur travail sans devoir réapprendre l'ensemble de l'ERP.
La disponibilité de l'outil représentait un autre objectif majeur. Comme l'ERP soutient le travail quotidien de la majorité des employés, une interruption de plusieurs jours n'était pas acceptable. Les migrations et les corrections devaient donc être testées à l'avance dans les environnements Odoo.sh afin que la mise en production se concentre sur l'application d'un processus déjà vérifié. Lors de la bascule, Odoo.sh devait reconstruire l'environnement de production, c'est-à-dire recréer l'application à partir de la base migrée et de la version validée du code, puis la remettre à disposition des utilisateurs avec une interruption aussi courte que possible. Une indisponibilité temporaire du site B2B pouvait être tolérée, car son propre code devait lui aussi être adapté à la nouvelle version de l'ERP. La priorité restait toutefois le redémarrage rapide d'Odoo, dont dépendaient davantage de processus internes.
Enfin, la migration devait apporter une valeur fonctionnelle et ne pas se limiter à une obligation de maintenance. Les utilisateurs attendaient notamment un rapprochement bancaire plus simple : cette opération consiste à associer les mouvements observés sur un compte bancaire aux factures, paiements et écritures comptables correspondants afin de vérifier et de justifier les flux d'argent. Ils attendaient également une gestion de l'inventaire plus accessible ainsi que les nouvelles possibilités liées à l'intelligence artificielle, notamment l'interrogation des données de l'ERP en langage naturel et leur utilisation pour faciliter certaines analyses. La fenêtre de mise en production était contrainte par le calendrier de l'entreprise, particulièrement active en octobre, novembre et décembre. Il était trop risqué d'introduire une évolution aussi structurante pendant cette période. Le projet devait donc être préparé et testé en amont, avec une bascule visée au début de l'année 2026, dès la fin du pic d'activité.
03
Le premier risque était que la production ne redémarre pas correctement après la migration. Odoo n'est pas un outil isolé : il constitue le point central autour duquel s'organisent la comptabilité, les ventes, les achats, l'inventaire et l'administration des ventes. Une erreur bloquante dans le code, dans le chargement d'un module ou dans la base migrée aurait donc pu rendre l'application inutilisable. Pour réduire ce risque, la migration devait être répétée dans les environnements de préproduction d'Odoo.sh jusqu'à obtenir un processus reproductible, au lieu de découvrir les erreurs directement sur le système utilisé par l'entreprise.
Une indisponibilité d'Odoo aurait empêché tous les services utilisant l'ERP d'accéder à leurs informations ou d'enregistrer de nouvelles opérations. La comptabilité n'aurait plus pu consulter les factures ni poursuivre ses traitements ; les équipes commerciales et l'administration des ventes n'auraient plus pu suivre les clients et les commandes ; les achats et la logistique auraient perdu leur vision actualisée des approvisionnements et des stocks. L'impact ne se limitait donc pas à une gêne informatique : au-delà d'une courte interruption planifiée, une grande partie de l'activité quotidienne aurait été immobilisée.
Le site B2B et les marketplaces dépendent des données d'Odoo et doivent pouvoir lui transmettre les commandes reçues. Si l'ERP était indisponible, ces plateformes auraient continué à présenter des informations devenues obsolètes ou auraient dû suspendre leurs échanges. Elles n'auraient plus pu pousser une commande, c'est-à-dire créer automatiquement dans Odoo la commande passée sur un canal externe. Le risque était alors d'accumuler des commandes en attente, d'afficher des stocks qui n'étaient plus à jour ou de créer des écarts entre ce que le client voyait et ce que l'entreprise pouvait réellement traiter. Les parcours complets de synchronisation devaient donc être vérifiés en plus du fonctionnement interne d'Odoo.
L'entreprise réalise une part de son activité au moyen de processus qui convergent vers l'ERP. Chaque heure pendant laquelle une commande ne pouvait plus être reçue, validée, préparée ou facturée avait donc un coût. Cet impact n'a pas été chiffré précisément dans le cadre du projet, mais il était direct : ralentissement ou arrêt des ventes, retard de traitement, travail de rattrapage et risque de dégradation du service rendu aux clients. Cette contrainte justifiait une préparation longue, une bascule hors du pic d'activité de fin d'année et une priorité donnée au rétablissement d'Odoo avant celui des systèmes moins critiques.
Une migration de base ne doit pas seulement conserver le nombre global d'enregistrements. Elle doit aussi préserver leurs valeurs, leurs relations et leur historique. Une facture encore présente mais rattachée au mauvais fournisseur, une commande dont certaines lignes auraient disparu ou un paiement ayant perdu son lien comptable auraient constitué des pertes fonctionnelles, même si la base démarrait correctement. La mesure de maîtrise consistait à travailler sur des copies réalistes de la production, à examiner les erreurs produites à chaque changement de version et à contrôler en priorité les objets indispensables : clients, produits, commandes, factures, paiements, achats et mouvements de stock.
Le filestore est l'espace dans lequel Odoo conserve notamment les pièces jointes et les champs binaires associés aux enregistrements. Une base PostgreSQL restaurée sans le filestore correspondant peut afficher les références des documents sans être capable d'ouvrir les fichiers réels. Ce risque était particulièrement grave pour les factures fournisseurs et les autres justificatifs comptables. La sauvegarde utilisée pour la migration et pour un éventuel retour arrière devait donc être complète : la base et son filestore devaient provenir du même état de la production. Des contrôles ciblés sur l'ouverture de documents permettaient de vérifier autre chose que la seule présence des écritures comptables.
Si Odoo était devenu indisponible ou si une anomalie critique avait empêché la reprise de l'activité, le scénario de secours était un retour arrière. Cette opération, parfois appelée rollback, consiste à abandonner la version nouvellement déployée et à restaurer le dernier état stable connu. Dans ce projet, le point de reprise était la sauvegarde complète réalisée juste avant la migration de la production. Le retour à cet état aurait limité la perte de données, car la période située entre la sauvegarde et la tentative de bascule devait rester aussi courte que possible. Les commandes éventuellement restées en attente sur les canaux externes auraient ensuite dû être contrôlées et resynchronisées afin d'éviter les doublons ou les oublis.
Une migration peut réussir techniquement tout en dégradant une action quotidienne. Un bouton peut disparaître, un calcul peut produire un autre résultat, une automatisation peut ne plus se déclencher ou une étape peut devenir inaccessible à certains utilisateurs. Ces régressions étaient difficiles à détecter uniquement avec des tests techniques, car leur importance dépend du fonctionnement réel de l'entreprise. La maîtrise du risque reposait donc sur des essais fonctionnels couvrant les principaux parcours métier et sur la validation d'une personne disposant d'une connaissance transversale de l'ERP. Les problèmes apparus après la bascule, notamment autour des numéros mobiles et des marges de factures, ont confirmé qu'une période de stabilisation restait nécessaire même après une migration réussie.
Les 16 modules internes modifiaient le comportement standard d'Odoo pour l'adapter aux besoins de l'entreprise. Entre les versions 16 et 19, des méthodes Python, des modèles de données, des champs ou des vues pouvaient être renommés, déplacés ou supprimés. Un module incompatible pouvait empêcher le démarrage de toute la base ou produire une erreur seulement lorsqu'un utilisateur exécutait une action précise. Chaque module devait donc être relu, adapté et installé sur les versions intermédiaires 17, 18 puis 19. Cette progression permettait d'isoler l'origine d'une erreur au lieu de cumuler trois changements majeurs en une seule étape impossible à diagnostiquer.
Une dizaine d'extensions provenaient de développeurs ou d'éditeurs externes. Leur compatibilité ne dépendait donc pas entièrement de moi : certaines disposaient d'une nouvelle version, d'autres n'étaient plus maintenues et certaines mises à jour officielles restaient incomplètes. Le risque était de devoir retarder la migration à cause d'un composant dont l'entreprise ne maîtrisait pas le calendrier. Pour chaque module, il fallait déterminer si une version compatible existait, si elle devait être corrigée localement, si la fonctionnalité pouvait être remplacée ou si une migration manuelle était nécessaire. Cette analyse évitait de considérer la présence d'une nouvelle version comme une preuve suffisante de fiabilité.
Les centaines de modifications réalisées avec Studio étaient principalement enregistrées dans la base plutôt que documentées dans le dépôt de code. Elles pouvaient cibler un champ ou un élément d'écran ayant changé dans Odoo 19. Une expression XPath devenue invalide pouvait empêcher l'affichage d'une vue complète, tandis qu'une action automatisée pouvait continuer à exister sans produire le résultat attendu. Le volume et la faible visibilité de ces personnalisations augmentaient le risque d'oubli. Leur maîtrise nécessitait un inventaire, l'analyse des messages d'erreur pendant les migrations successives et la recherche de l'élément équivalent dans le nouveau code source avant de corriger ou de supprimer la personnalisation devenue obsolète.
Le passage à Odoo 19 pouvait modifier les champs disponibles, les valeurs attendues ou le comportement des API utilisées par le site B2B, le hub d'intégration, les marketplaces, ShippingBo et les outils d'analyse. Une intégration peut sembler active tout en échangeant des informations incomplètes : commande créée sans ligne, client non reconnu, stock non actualisé ou statut logistique qui ne revient plus dans l'ERP. Il fallait donc vérifier les échanges dans les deux sens et pas seulement la disponibilité de chaque application. Le code du site B2B devait lui aussi évoluer afin que les deux systèmes partagent à nouveau le même contrat d'échange, c'est-à-dire la même définition des données transmises et de leur format.
Migrer le code ne devait ni accorder des droits supplémentaires ni bloquer les utilisateurs légitimes. La sécurité d'Odoo repose sur plusieurs couches. Les ACL, ou listes de contrôle d'accès, autorisent un groupe à lire, créer, modifier ou supprimer tous les objets d'un modèle, un modèle représentant une catégorie de données comme les commandes ou les factures. Les groupes rassemblent les utilisateurs selon leur rôle et peuvent hériter des autorisations d'autres groupes ; les privilèges d'un utilisateur correspondent à l'ensemble des droits ainsi obtenus. Les record rules, ou règles d'enregistrement, appliquent ensuite des filtres pour limiter les enregistrements individuels accessibles, par exemple aux seules commandes d'une équipe. Des restrictions peuvent aussi protéger certains champs sensibles. À l'inverse, masquer un menu ou une vue ne suffit pas à sécuriser les données. Une modification de modèle, de groupe ou de règle pendant la migration pouvait donc ouvrir un accès trop large. Les droits devaient être contrôlés avec des comptes représentatifs et selon le principe du moindre privilège, qui consiste à n'accorder que les autorisations nécessaires au travail de chacun.
Le changement de version pouvait désorienter les utilisateurs si les écrans ou les parcours évoluaient sans explication. La formation et l'accompagnement visaient à réduire cette friction, mais l'enjeu n'était pas de reconstruire artificiellement leur confiance envers l'ERP. Il s'agissait surtout de rendre visibles les raisons de la migration : maintien du support, gains de performance et accès à de nouvelles fonctionnalités. En tant que responsable de l'ensemble du volet technique et seul développeur interne, je devais aussi démontrer ma capacité à préparer une opération critique, à arbitrer entre continuité et évolution, puis à réagir aux incidents sans provoquer de blocage durable. Une migration maîtrisée devait montrer à l'entreprise qu'elle pouvait compter sur moi pour conduire un changement structurant et en assumer les conséquences.
04
J'ai commencé par relever la version de chacun des modules installés afin de décider de son traitement. Les extensions dont la dernière version disponible était antérieure à Odoo 16 étaient considérées comme des modules legacy, c'est-à-dire du code ancien qui n'était plus maintenu pour les versions récentes de l'ERP. Leur migration ne consistait pas à les conserver à tout prix : il fallait préparer leur suppression propre, donc retirer leur code et leurs dépendances sans laisser de références incohérentes dans la base ni casser les données encore utiles. Pour les autres modules tiers, j'ai recherché une version compatible avec les versions d'Odoo suivantes. J'ai téléchargé les extensions gratuites et acheté les nouvelles versions des extensions payantes, puis je les ai intégrées une par une aux essais de migration. La présence d'une version récente ne garantissait pas son fonctionnement : certains modules comportaient encore des erreurs que j'ai dû corriger. Dans d'autres cas, le nouveau code fonctionnait mais ne contenait plus les personnalisations ajoutées au-dessus de la version précédente ; j'ai alors réintégré ces adaptations métier dans la nouvelle base de code.
Pour chaque palier, je déposais le code adapté dans le dépôt GitHub du projet. Un push est l'envoi vers le dépôt distant des commits réalisés localement, un commit étant un état identifié et historisé du code. Ce push déclenchait sur Odoo.sh un build, c'est-à-dire l'exécution d'une révision précise du projet avec un serveur Odoo et une base de données. Lorsqu'il s'agissait d'une branche de préproduction, le rebuild recréait ce build à partir d'une copie récente de la production afin de recommencer l'essai dans des conditions réalistes. La plateforme exécutait également la mise à niveau vers la version majeure suivante et les scripts nécessaires à la transformation de la base. Un script de migration est un programme qui adapte la structure ou le contenu des données à ce qu'attend la nouvelle version. Le travail avançait ensuite par itérations : lancer le build, observer l'échec, corriger le code ou les données responsables, pousser une nouvelle révision et recommencer jusqu'à obtenir un passage complet. Je n'abordais le palier suivant qu'après avoir stabilisé le précédent, ce qui évitait de mélanger les ruptures introduites par trois versions différentes.
Chaque build et chaque opération de migration généraient des logs, c'est-à-dire un journal chronologique des événements exécutés par la plateforme et par l'application. Les messages étaient classés selon plusieurs niveaux. Une information, ou niveau info, décrit le déroulement normal d'une opération ; un warning signale une situation inhabituelle qui mérite une vérification sans nécessairement empêcher le démarrage ; une error correspond à une défaillance susceptible de faire échouer le build ou une fonctionnalité. Lorsqu'une erreur Python se produisait, le log contenait généralement un traceback. Ce relevé présente la chaîne des appels de fonctions traversés avant l'erreur, avec les fichiers, les méthodes et les numéros de ligne concernés. Il constituait mon premier point d'entrée pour remonter du symptôme visible jusqu'à la portion de code qui l'avait provoqué.
La plupart des tracebacks indiquaient suffisamment clairement le module, le fichier ou la méthode à examiner. Lorsqu'ils n'étaient pas explicites, je devais reconstruire les conditions exactes de déclenchement. J'analysais alors conjointement quatre éléments : le code qui exécutait l'opération, les données particulières présentes dans la base, les changements introduits par le nouveau code d'Odoo et les transformations effectuées par le script de migration. Cette mise en relation était nécessaire, car une erreur apparemment située dans le code standard pouvait être déclenchée uniquement par une ancienne donnée, par une personnalisation ou par un champ qui n'avait pas été transformé comme prévu. Je cherchais donc la cause racine, c'est-à-dire le premier défaut expliquant réellement la chaîne d'erreurs, plutôt que de corriger uniquement le dernier message affiché. Cette méthode évitait les correctifs superficiels qui auraient seulement déplacé le problème vers le rebuild suivant.
Lorsque la documentation ne suffisait pas, je retraçais directement le fonctionnement de la partie défaillante dans le code source. Une méthode est un bloc de code associé à un modèle et chargé d'exécuter une opération ; un modèle représente une catégorie d'objets métier, comme les clients, les commandes ou les factures. Odoo permet à un module d'hériter d'un modèle existant pour compléter ou remplacer certaines de ses méthodes sans recopier tout le programme. Cette architecture rend l'ERP extensible, mais elle complique le diagnostic : une même méthode peut être successivement modifiée par le socle standard d'Odoo, les applications officielles, plusieurs modules tiers et les modules internes. Je devais donc suivre l'ensemble de cette chaîne d'héritage, parfois répartie sur des dizaines de modules, pour comprendre dans quel ordre les versions d'une méthode étaient appelées et laquelle introduisait le comportement incorrect. Cette lecture me permettait aussi d'identifier les nouveaux mécanismes prévus par Odoo 19 au lieu de reproduire une solution devenue obsolète.
Une fois un build capable de démarrer, la validation ne s'arrêtait pas à l'absence d'erreur dans les logs. J'ai effectué une recette, c'est-à-dire une série de vérifications destinées à comparer le comportement obtenu avec le fonctionnement attendu par l'entreprise. Elle couvrait les parcours de vente, d'achat, de comptabilité, d'inventaire et d'administration des ventes, ainsi que les échanges avec le site B2B et les autres systèmes connectés. J'ai également parcouru les vues recensées, une vue étant un écran de consultation ou de saisie dans Odoo, les automatisations, les actions planifiées et les paramètres de configuration. Il fallait vérifier à la fois qu'un écran s'affichait, que les données présentées étaient correctes et que l'action réalisée produisait le bon résultat. Les essais avec différents profils permettaient enfin de repérer une fonctionnalité disponible pour un administrateur mais inaccessible à l'utilisateur qui devait réellement l'employer.
Lorsque les migrations successives et la recette nous ont donné suffisamment de confiance, nous avons créé plusieurs sauvegardes de la production avant de lancer l'opération définitive sur Odoo.sh. Ces sauvegardes constituaient les points de retour disponibles si la nouvelle version empêchait la reprise de l'activité. La plateforme a ensuite exécuté la migration et reconstruit l'environnement de production avec le code compatible Odoo 19. L'opération a duré plusieurs heures, pendant lesquelles l'ERP est resté indisponible. Dès son redémarrage, nous avons effectué une nouvelle série de tests sur les processus les plus critiques afin de prendre une décision de go/no-go : conserver la nouvelle version si elle permettait de travailler sans anomalie critique, ou déclencher le rollback vers la sauvegarde si un problème suffisamment grave menaçait les données ou bloquait l'activité. Aucune anomalie détectée à ce stade n'a imposé ce retour arrière ; la production a donc été maintenue sur Odoo 19 et la phase de stabilisation a commencé.
Pendant environ un mois après la bascule, nous avons demandé aux utilisateurs d'ouvrir un ticket pour chaque problème rencontré. Un ticket est une fiche de suivi qui décrit une anomalie, centralise les échanges et permet d'en suivre le traitement jusqu'à sa résolution. Pour rendre les signalements exploitables, les utilisateurs pouvaient joindre des captures d'écran, de courts enregistrements vidéo, des tracebacks ou des messages d'erreur. Ils indiquaient aussi les étapes de reproduction, c'est-à-dire la succession exacte d'actions permettant de faire réapparaître le problème, puis distinguaient le comportement observé du comportement attendu. J'ai trié ces tickets par degré d'urgence : les blocages empêchant de travailler et les risques portant sur les données ou la comptabilité passaient avant les défauts non bloquants. Cette organisation m'a permis de reproduire plus rapidement les anomalies, d'en rechercher la cause dans le code ou les données, de livrer les corrections prioritaires et de conserver une trace des décisions prises pendant la stabilisation. C'est notamment dans cette phase que j'ai traité la récupération des numéros mobiles et la fiabilisation des marges de factures.
05
J'ai été à l'origine de l'alerte en informant le directeur général, également désigné par le sigle CEO pour Chief Executive Officer, qu'Odoo 16 ne serait plus maintenu normalement que pendant quelques mois. Mon rôle était de traduire cette échéance technique en conséquence opérationnelle : rester sur cette version aurait progressivement privé l'entreprise des conditions normales de support, des correctifs et des évolutions de l'éditeur. À partir de cette information, le directeur général a pris la décision de démarrer la migration. Le projet associait donc une initiative technique de ma part à un arbitrage de direction, nécessaire pour engager du temps, accepter une période de changement et donner une priorité suffisante à l'opération.
J'ai pris en charge seul l'ensemble du volet technique : analyse du code, adaptation des modules, migrations successives, diagnostic des erreurs, préparation de la production et corrections après la bascule. L'assistante de direction constituait ma principale interlocutrice fonctionnelle. Une responsabilité fonctionnelle consiste à vérifier qu'un logiciel répond bien aux pratiques et aux règles de l'entreprise, indépendamment de la manière dont il est programmé. Sa connaissance transversale lui permettait de valider les processus métier, de confirmer quelles personnalisations restaient nécessaires et de décider lesquelles pouvaient être supprimées parce qu'elles ne correspondaient plus à un usage utile.
L'assistante de direction gérait également l'achat des nouvelles versions payantes des modules tiers. Cette répartition distinguait la décision d'achat et la relation administrative avec l'éditeur de mon travail d'évaluation et d'intégration technique. Elle assurait en parallèle la coordination avec les équipes : diffusion des demandes de test, mobilisation des personnes concernées et remontée des besoins métier. Notre collaboration formait ainsi un binôme complémentaire. Je pouvais expliquer les incompatibilités, les contraintes et les solutions possibles ; elle pouvait évaluer leur importance pour l'activité, obtenir les validations nécessaires et organiser la participation des services.
Tous les services utilisant Odoo ont participé à la validation. Ils disposaient d'un accès à une base de données de préproduction, également appelée environnement de staging, sur laquelle la migration avait été appliquée. Cette base reproduisait les données et les principaux comportements de la production sans modifier le système réellement utilisé pour l'activité quotidienne. Les utilisateurs pouvaient donc consulter leurs dossiers, ouvrir leurs écrans habituels et exécuter leurs opérations dans un cadre sans conséquence sur les données de travail. Cette participation élargie était indispensable : aucun développeur ne peut connaître avec le même niveau de précision les habitudes de la comptabilité, des ventes, des achats, de la logistique ou de l'administration des ventes.
Je n'ai pas demandé aux équipes de se limiter à vérifier si l'application s'ouvrait. Je leur ai demandé de reproduire tout ce qu'elles effectuaient au quotidien puis de me signaler les différences, les blocages et les comportements inattendus. Cette démarche correspond à un test exploratoire métier : l'utilisateur s'appuie sur sa connaissance du travail réel pour parcourir les situations qu'il juge importantes, plutôt que de suivre uniquement un scénario technique écrit par le développeur. Les utilisateurs connaissaient mieux que quiconque leurs propres processus et pouvaient repérer des détails invisibles pour moi, par exemple un champ manquant, une étape devenue plus longue, un calcul différent ou une information qui n'apparaissait plus au bon endroit.
La migration définitive a été réalisée par l'assistante de direction et moi-même après la fin de la journée de travail. Ce choix réduisait le nombre de personnes exposées à l'interruption et garantissait qu'aucun utilisateur ne continuait à créer ou modifier des données dans Odoo pendant la sauvegarde et la transformation de la base. J'assurais l'exécution et le contrôle techniques tandis qu'elle pouvait valider les comportements métier les plus importants et représenter les besoins opérationnels. Nous formions aussi le premier niveau de décision face au résultat : poursuivre sur Odoo 19 lorsque les fonctions essentielles étaient disponibles, ou revenir à la sauvegarde si une anomalie critique rendait la reprise de l'activité trop risquée.
Nous sollicitions le support officiel d'Odoo ou les éditeurs de modules tiers lorsque l'origine du problème se trouvait dans un composant sur lequel nous ne pouvions pas intervenir. Cette distinction évitait d'attendre une réponse externe pour une erreur que je pouvais corriger dans notre propre code, tout en reconnaissant les limites de notre périmètre. À plusieurs reprises, le script de migration exécuté par la plateforme Odoo.sh s'est interrompu alors que nous n'avions aucun accès permettant de le modifier. J'ai alors rassemblé les éléments de diagnostic disponibles et transmis le problème au support Odoo. Pour une extension externe, la même logique consistait à contacter son éditeur lorsque le défaut relevait de son produit, tout en vérifiant de notre côté que l'erreur ne provenait pas d'une personnalisation locale.
Je présentais régulièrement l'avancement, les difficultés et les prochaines décisions à ma responsable directe — mon N+1, l'assistante de direction — ainsi qu'au niveau hiérarchique suivant — mon N+2, le directeur général. Ces points permettaient de rendre visibles les progrès, les blocages externes et le niveau de risque restant avant la production. Dans les échanges avec les utilisateurs, mon rôle était différent : je partais de leur description métier pour retrouver dans Odoo la source technique probable du problème. Je reformulais ensuite mon hypothèse en termes compréhensibles par une personne non technique, puis je lui demandais de confirmer que cette explication correspondait bien à la situation observée. Ce n'est qu'après cet alignement que j'appliquais la correction. Cette boucle évitait de résoudre un symptôme mal compris et faisait de moi l'interface entre l'expérience des utilisateurs, les règles de l'entreprise et le fonctionnement interne du logiciel.
06
Le résultat le plus important est que la migration n'a provoqué aucune perte définitive dans les données de l'entreprise. Les difficultés rencontrées concernaient principalement l'affichage et le fonctionnement du code. Certaines vues ne s'ouvraient plus parce que leurs héritages XML, souvent créés ou modifiés avec Studio, ciblaient des éléments qui avaient changé dans Odoo 19. Un héritage XML permet à une personnalisation de modifier une partie précise d'un écran standard ; si cette partie est renommée ou déplacée, la personnalisation ne retrouve plus son point d'insertion et la vue peut devenir inutilisable. Plusieurs modules tiers ont aussi présenté des erreurs alors même que leurs éditeurs les diffusaient comme des versions compatibles avec Odoo 19. J'ai corrigé ces défauts sans devoir restaurer une ancienne version de la base et sans sacrifier les informations métier.
La bascule définitive a rendu l'ERP indisponible pendant environ trois heures. Cette durée incluait la transformation de la base, le rebuild de l'environnement Odoo.sh et les premières vérifications sur la production. Comme l'opération avait été lancée après la journée de travail, l'interruption n'a pas immobilisé les utilisateurs au milieu de leurs tâches et aucun enregistrement n'était créé en parallèle dans l'ancienne version. Le résultat respecte donc la contrainte de continuité fixée au départ : l'entreprise n'a pas subi plusieurs jours d'arrêt et il n'a pas été nécessaire d'utiliser le scénario de retour arrière préparé avant la migration.
Les 16 modules développés en interne ont tous été conservés et adaptés à Odoo 19 parce qu'ils répondaient encore à des besoins propres à l'entreprise. Quatre modules tiers devenus inutiles ont été retirés au lieu d'être migrés sans justification ; les autres extensions nécessaires ont été mises à jour et corrigées. Environ 15 % des personnalisations Studio ont été conservées, notamment les filtres associés aux vues de recherche. Une vue de recherche définit les critères permettant aux utilisateurs de filtrer, regrouper et retrouver les enregistrements utiles dans une liste. Les autres personnalisations n'ont pas été reportées parce qu'elles ne correspondaient plus à une fonctionnalité nécessaire. Aucune fonctionnalité manquante ne reste donc à réintroduire : cette sélection a réduit le volume de comportements cachés dans la base sans diminuer le périmètre métier attendu.
Le cœur de l'ERP a été rétabli lors de la bascule, puis les services externes ont été remis à niveau progressivement dans les quelques jours suivants. Le site B2B, les marketplaces et les autres outils connectés ont notamment dû adapter leurs appels à la nouvelle API externe d'Odoo 19. L'ancienne intégration utilisait l'interface JSON-RPC sur le chemin /jsonrpc. JSON-RPC est un protocole qui permet à une application distante de demander l'exécution d'une méthode en transmettant notamment la base, l'identifiant numérique de l'utilisateur — appelé uid — et son mot de passe. La nouvelle API JSON-2 expose ses opérations sous le chemin /json/2 et remplace cette authentification par une clé d'API envoyée comme jeton Bearer dans l'en-tête d'autorisation de la requête HTTP. Un jeton Bearer est un secret présenté par l'application appelante pour prouver qu'elle est autorisée. Cette adaptation a rétabli les synchronisations tout en alignant les intégrations sur le mécanisme introduit par Odoo 19.
Le gain de performance le plus visible concerne le chargement du rapprochement bancaire utilisé par la comptabilité. Les écrans de lettrage s'affichent plus rapidement qu'avec Odoo 16, ce qui réduit l'attente pendant l'association des mouvements bancaires avec les factures et les paiements correspondants. Ce résultat reste qualitatif, car aucun chronométrage systématique avant et après la migration n'a été réalisé. Il doit aussi être nuancé : le chargement demeure plus long que celui de la plupart des autres vues de l'ERP. La migration a donc apporté une amélioration perceptible sans supprimer entièrement la limite de performance de ce processus.
Les fonctionnalités d'intelligence artificielle faisaient partie des possibilités étudiées avec Odoo 19, mais elles n'ont pas été activées dans l'ERP de production. Dans les usages envisagés, le module d'Odoo consommait trop de tokens par rapport à la valeur attendue. Un token est une petite unité de texte traitée par un modèle d'intelligence artificielle ; le volume de tokens influence directement la consommation technique et, selon le fournisseur, le coût des requêtes. Déployer une fonctionnalité uniquement parce qu'elle était nouvelle aurait donc créé une dépense difficile à justifier. Le choix de ne pas l'intégrer pour le moment constitue une décision de maîtrise des coûts et de l'architecture, avec la possibilité de réévaluer la solution lorsque son efficacité ou les besoins de l'entreprise auront évolué.
Les retours reçus après la stabilisation ont été globalement positifs. Les utilisateurs ont retrouvé leurs données et leurs processus sur la nouvelle version, puis ont demandé à être davantage guidés dans la découverte des changements et des nouvelles fonctionnalités. Ce retour montre que la réussite ne se limitait plus à corriger des erreurs : une fois l'outil stabilisé, l'enjeu devenait de transformer la mise à niveau technique en usages concrets. L'accompagnement devait présenter les nouveaux écrans, expliquer les différences utiles et aider chaque service à identifier les gains applicables à son travail, sans imposer des fonctions sans rapport avec ses besoins.
L'entreprise utilise désormais une version récente et maintenue d'Odoo, ce qui rétablit l'accès normal aux correctifs et aux évolutions de l'éditeur. Cette situation ne signifie pas qu'un logiciel devient automatiquement exempt de vulnérabilités, mais elle réduit l'exposition créée par le maintien d'une version vieillissante et facilite l'application des corrections de sécurité. La suppression de quatre modules tiers inutiles et d'une grande partie des personnalisations Studio a aussi diminué la dette technique. La dette technique désigne le coût et le risque accumulés lorsque du code ancien, des dépendances non maintenues ou des solutions rapides rendent les futures évolutions plus difficiles. Le périmètre à maintenir est désormais mieux aligné avec les besoins réels de l'entreprise.
Ce projet m'a permis de démontrer mon autonomie sur une transformation critique menée sans autre développeur interne. Les migrations répétées, la lecture des tracebacks et l'analyse des héritages m'ont donné une compréhension beaucoup plus large du fonctionnement d'Odoo, depuis la base de données jusqu'aux vues, aux modules et aux intégrations externes. Cette expérience m'a fait franchir un cap : je ne me contentais plus de développer une fonctionnalité isolée, je devais comprendre les conséquences d'un changement à l'échelle de tout le système d'information. Les échanges avec chaque service ont aussi renforcé ma capacité à identifier des enjeux différents, à expliquer une contrainte technique et à construire une solution compréhensible par des interlocuteurs non techniques.
Plusieurs indicateurs permettent aujourd'hui de considérer la migration comme réussie : aucune perte de données n'a été constatée, aucun incident bloquant lié à la migration ne reste identifié en production, les processus métier essentiels fonctionnent et tous les utilisateurs ont effectué la transition vers Odoo 19. Les intégrations externes ont également été rétablies après leur adaptation à la nouvelle API. La production n'a pas nécessité de rollback et l'ERP a atteint un état stable après environ un mois de corrections prioritaires. Ces résultats répondent aux critères définis au début du projet : préserver les données, maintenir l'activité, conserver les fonctions nécessaires et rendre la nouvelle version utilisable par l'ensemble de l'entreprise.
07
À la fin du mois principal de stabilisation, le travail ne s'est pas arrêté brutalement. Il restait des anomalies non urgentes découvertes après la migration, mais aussi des demandes qui existaient déjà avant le projet et qui avaient été différées pour donner la priorité au passage vers Odoo 19. Un backlog est la liste ordonnée des corrections et évolutions qui restent à traiter. Distinguer les tickets réellement provoqués par la migration des problèmes antérieurs évitait d'attribuer à la nouvelle version toute difficulté observée après la bascule. Les incidents critiques ont été résolus en premier ; les autres sujets ont rejoint le cycle normal de maintenance et d'amélioration de l'ERP.
La réduction importante du nombre de personnalisations Studio ne laisse pas de trou fonctionnel connu. Les quelque 15 % conservés correspondent aux éléments encore utiles, notamment certains filtres de recherche. Les autres personnalisations ont été abandonnées parce qu'elles étaient devenues obsolètes, redondantes avec le fonctionnement standard ou sans valeur suffisante pour justifier leur maintenance. Il n'existe donc pas de chantier différé destiné à reconstruire mécaniquement les 85 % supprimés. Une nouvelle personnalisation ne sera ajoutée que si un besoin métier actuel est confirmé, ce qui évite de recréer immédiatement la dette technique supprimée pendant la migration.
La majorité des services externes a été adaptée à l'API JSON-2, mais une intégration utilise encore l'ancien mécanisme. Je ne dispose pas de la maîtrise de son code : sa migration dépend du prestataire qui développe ou exploite ce service. Cette situation constitue une dépendance externe, c'est-à-dire qu'une évolution nécessaire ne peut pas être réalisée uniquement avec les ressources internes. Mon rôle consiste à rendre le besoin explicite, à fournir les informations techniques utiles et à vérifier le résultat lorsque le prestataire livre son adaptation. Tant que ce travail n'est pas achevé, cette intégration reste un point particulier à surveiller dans une architecture par ailleurs modernisée.
Aujourd'hui, la stabilité d'Odoo 19 est entretenue par plusieurs activités complémentaires. Je surveille les erreurs afin d'identifier les anomalies avant qu'elles ne deviennent bloquantes, je mets à jour les modules lorsque des corrections ou des compatibilités sont nécessaires, je traite les tickets transmis par les utilisateurs et je contrôle la disponibilité des sauvegardes. Une sauvegarde n'est utile que si elle correspond à un état cohérent et peut servir de point de restauration en cas d'incident. Cette maintenance préventive et corrective permet de ne pas attendre la prochaine migration majeure pour traiter l'accumulation de problèmes. L'ERP est ainsi considéré comme un produit vivant, dont la fiabilité dépend d'un suivi régulier après sa mise en production.
Le bénéfice le plus certain à court terme est que les différentes applications de l'ERP peuvent désormais utiliser les fonctionnalités de la version 19 et recevoir les corrections correspondant à cette génération du logiciel. Toutes ces possibilités ne sont pas nécessairement activées : chaque service doit encore déterminer lesquelles répondent réellement à ses besoins. La migration a néanmoins supprimé la barrière technique qui empêchait de les étudier. L'entreprise dispose donc d'une base récente sur laquelle elle peut faire évoluer la comptabilité, les ventes, les achats, l'inventaire et les autres applications sans commencer par rattraper plusieurs versions de retard.
Le rapprochement bancaire est plus rapide qu'avant, mais il reste un processus coûteux par rapport aux autres vues. Un travail d'analyse et d'optimisation demeure donc pertinent. La contrainte est de ne pas casser le moteur interne d'Odoo, c'est-à-dire le code standard qui orchestre les modèles, les calculs et les règles communes de l'ERP. Modifier directement ce socle pourrait produire un gain immédiat tout en rendant les correctifs officiels et les prochaines migrations beaucoup plus difficiles. Les améliorations doivent privilégier la configuration, les modules d'extension, les requêtes maîtrisées et la mesure des temps de traitement avant d'envisager une modification profonde du fonctionnement standard.
Lors d'une future montée de version, je commencerais par mieux répertorier les processus de chaque service. Cet inventaire ne se limiterait pas au nom d'une fonctionnalité : il décrirait les acteurs, les données utilisées, les étapes importantes, le résultat attendu et les dépendances avec d'autres outils. Chaque processus pourrait ensuite devenir un scénario de recette réutilisable. Les utilisateurs seraient associés plus régulièrement aux versions intermédiaires au lieu d'intervenir principalement lorsque la migration semble déjà techniquement avancée. Cette fréquence permettrait de détecter plus tôt une régression et de réduire le coût des corrections tardives.
Certains besoins ne sont pas perçus de la même manière par tous les utilisateurs. Une fonctionnalité peut faire gagner du temps à un service tout en ajoutant une contrainte à un autre. Pour éviter de développer, supprimer puis reconstruire une solution, je souhaite mieux croiser ces attentes avant de décider. L'arbitrage consiste à confronter les avantages, les contraintes et la priorité de plusieurs demandes afin de choisir une solution commune ou d'assumer explicitement une différence de fonctionnement. Des validations plus fréquentes avec les personnes concernées réduiraient les incompréhensions et les pertes de temps liées à une décision prise à partir d'un seul point de vue.
À moyen terme, je souhaite continuer à limiter les personnalisations Studio et les modules tiers lorsque leur usage rend le comportement difficile à suivre ou dépend d'un éditeur peu réactif. L'objectif n'est pas de tout redévelopper en interne : une extension externe maintenue et bien documentée peut rester le meilleur choix. En revanche, les adaptations propres à l'entreprise gagnent à être placées dans des modules internes versionnés. Leur code et l'historique de leurs changements sont alors visibles dans le dépôt GitHub, testables en préproduction et plus faciles à relire lors d'une future migration. Cette orientation augmente la maîtrise du système sans renoncer aux composants externes réellement utiles.
L'intelligence artificielle pourrait être reconsidérée si le code fourni par Odoo devient plus efficace dans sa consommation de tokens ou si je développe une intégration sur mesure, limitée aux données et aux tâches réellement utiles. Une intégration sur mesure permettrait de contrôler le contexte transmis au modèle, le volume traité, les droits d'accès et le coût de chaque usage. Mon projet personnel d'outil de business intelligence connecté à Odoo pourrait également profiter de la nouvelle API, mais il reste pour l'instant extérieur au périmètre de l'entreprise. Il ne deviendra un lendemain direct de la migration que si l'entreprise choisit de l'expérimenter puis de l'adopter. Dans l'immédiat, le résultat concret reste l'accès aux nouvelles fonctionnalités des applications Odoo et l'existence d'une base plus saine pour décider des prochains projets.
08
Ma principale erreur a été de ne pas mettre en place dès le début une gestion de projet dédiée à la migration. J'avais engagé le travail technique, mais le suivi structuré de chaque périmètre, de son état et de ses blocages est arrivé trop tard. J'ai donc perdu du temps à reconstituer plusieurs fois ce qui avait déjà été analysé, ce qui restait à corriger et ce qui pouvait être considéré comme validé. Un tableau de pilotage créé dès la phase d'inventaire aurait dû associer à chaque module, personnalisation, processus et intégration un responsable, une version cible, un statut, une preuve de test et une décision. Cette traçabilité n'aurait pas supprimé la complexité, mais elle aurait réduit le travail de mémoire et facilité la reprise après chaque série de corrections.
Au début du projet, je me suis surtout concentré sur les vues, donc sur les écrans modifiés par Studio. Cette approche était trop étroite. Studio peut également créer des filtres de recherche, des actions automatisées déclenchées lorsqu'un enregistrement remplit certaines conditions, des actions planifiées exécutées périodiquement, des rapports PDF produits avec QWeb et des modifications de droits utilisateurs. QWeb est le moteur de modèles utilisé par Odoo pour transformer une structure XML et des données en document, notamment en facture ou autre rapport PDF. Une migration peut donc afficher correctement les écrans tout en conservant une automatisation défaillante, un rapport incomplet ou une autorisation inadaptée. J'aurais dû considérer Studio comme un ensemble de comportements transversaux et pas seulement comme un outil de personnalisation visuelle.
La partie de ma démarche que je conserverais absolument est l'analyse complète des personnalisations puis le suivi d'un état de migration pour chacune d'elles. Ce suivi permettait de distinguer les éléments à conserver, adapter, remplacer ou supprimer, puis d'indiquer ceux qui étaient seulement corrigés techniquement et ceux qui avaient réellement été validés par le métier. Il apportait aussi une mémoire du projet : lorsqu'une erreur réapparaissait sur la version suivante, je pouvais retrouver la décision précédente et comprendre si le correctif devait être rejoué ou repensé. Mon erreur n'a donc pas été de choisir cette méthode, mais de ne pas l'avoir appliquée de manière exhaustive suffisamment tôt.
Réaliser seul la partie technique était exigeant, mais le délai de six mois et le résultat final montrent que cette responsabilité restait soutenable. En revanche, un accompagnement supplémentaire sur la préparation et la formation des utilisateurs aurait été pertinent. Expliquer les nouveaux écrans, organiser les démonstrations, recueillir les questions et produire des supports représente un projet à part entière. En cumulant ce travail avec le diagnostic du code, les migrations et les corrections, je devais répartir mon attention entre deux charges importantes. Une personne chargée de l'accompagnement au changement m'aurait permis de rester davantage concentré sur les risques techniques tout en offrant aux utilisateurs une présentation plus régulière et mieux structurée des évolutions.
Certaines petites anomalies apparues après la bascule concernaient des actions automatisées. Elles n'étaient pas nécessairement visibles en ouvrant une vue ou en exécutant une seule fois un parcours métier. Une automatisation doit être testée avec son événement déclencheur, ses conditions d'entrée, les données qu'elle modifie et les effets qu'elle ne doit pas produire. Ma recette couvrait un grand nombre d'usages, mais elle ne formalisait pas systématiquement toutes ces dimensions pour chaque action. Une matrice de tests associant à chaque automatisation un cas nominal, un cas où elle ne doit pas se déclencher et un contrôle du résultat aurait permis de détecter davantage de ces erreurs avant la mise en production.
Lors d'une prochaine migration, je voudrais automatiser en priorité les vérifications portant sur ces deux catégories. Une action automatisée réagit à un événement, par exemple la création ou la modification d'une facture. Une action planifiée, aussi appelée tâche cron, s'exécute à une fréquence définie sans intervention humaine, par exemple chaque nuit. Les tests pourraient préparer des données représentatives, déclencher explicitement l'action, puis vérifier l'état final attendu et l'absence de doublon. Cette automatisation ne remplacerait pas la recette des utilisateurs, car un test technique ne juge pas la pertinence métier d'un résultat. Elle fournirait cependant une première barrière reproductible à chaque rebuild et réduirait le risque qu'une correction sur un module casse silencieusement une autre règle.
Avec le recul, la durée de préparation n'était pas excessive compte tenu du périmètre, du passage par trois versions majeures, du nombre de personnalisations et du fait qu'il s'agissait de ma première migration menée seul techniquement. Une partie du temps a été consommée par les cycles successifs de rebuild, par l'analyse du code source, par les corrections de modules tiers et par l'attente de réponses sur des composants externes. Une meilleure méthode aurait réduit certaines répétitions, mais chercher à comprimer fortement le calendrier aurait déplacé le risque vers la production. Mon autocritique porte donc davantage sur l'organisation du travail à l'intérieur de ces six mois que sur la durée globale accordée au projet.
L'environnement de préproduction Odoo.sh se rapproche de la production, mais il la neutralise volontairement sur plusieurs points afin d'éviter des effets réels. Certaines actions planifiées sont désactivées, les courriels sortants sont interceptés et plusieurs connecteurs externes fonctionnent en mode de test. Il était donc impossible de reproduire fidèlement chaque usage quotidien. La difficulté était encore plus forte pour les services externes qui devaient eux-mêmes être modifiés pour devenir compatibles avec Odoo 19 : tant que les deux côtés n'étaient pas prêts, un essai complet de bout en bout restait partiel. Cette limite n'excuse pas les erreurs évitables, mais elle explique pourquoi une migration de cette taille conserve nécessairement une phase de surveillance et de stabilisation après la bascule.
À un développeur chargé seul d'une migration comparable, je conseillerais de dresser avant toute correction une liste aussi complète que possible de ce qui constitue réellement l'ERP. Cette liste doit couvrir les modules internes et tiers, les données, les vues, les champs Studio, les filtres, les rapports QWeb, les actions automatisées, les tâches planifiées, les droits d'accès, les intégrations et les processus de chaque service. Il faut ensuite rattacher à chaque élément une méthode de vérification et une personne capable de confirmer le résultat. L'objectif n'est pas de prétendre qu'aucun oubli n'est possible, mais de rendre les angles morts visibles et de réduire au minimum le nombre d'éléments découverts seulement après la production.
J'évalue ma gestion globale du projet à 7 sur 10. Les points positifs sont importants : la migration a abouti, aucune donnée n'a été perdue, l'interruption a été limitée, les modules internes ont été conservés et tous les utilisateurs ont rejoint la nouvelle version. Je retire toutefois trois points pour le manque de méthode initial dans le suivi, pour une recette des processus métier qui aurait dû être plus structurée et pour un accompagnement insuffisant des utilisateurs face aux changements de l'ERP. Atteindre 10 ne signifierait pas garantir une migration sans aucune anomalie, ce qui serait irréaliste. Cela signifierait disposer dès le départ d'un inventaire exhaustif, de tests reproductibles, de validations métier régulières et d'un véritable plan de formation mené en parallèle du chantier technique.