Logique du système de mise à jour¶
Présentation générale¶
Le système de mise à jour de Maarch Courrier repose sur un mécanisme de migrations versionnées qui permet de faire évoluer l'application de manière contrôlée et sécurisée. Ce système orchestre l'application séquentielle de modifications de base de données et de transformations métier tout en garantissant la possibilité de revenir en arrière en cas de problème.
Le script UpdateLauncherScript.php, situé dans [MaarchCourrierDirectory]/src/backend/Core/Infrastructure/Update/, sert d'orchestrateur du système.
Il est exécuté uniquement lors du démarrage des conteneurs Docker (docker up), via le script d’entrée [MaarchCourrierDirectory]/container/entrypoint.sh.
Le concept de version et de migration¶
Structure organisationnelle¶
Les migrations sont organisées dans une arborescence basée sur des tags de version. Chaque version correspond à un dossier situé dans [MaarchCourrierDirectory]/migration/. Par exemple, pour la version 2301.2.0, un dossier migration/2301.2.0/ contient l'ensemble des scripts nécessaires à cette évolution.
Cette organisation permet de :
- Tracer précisément les modifications appliquées
- Isoler les changements par version
- Faciliter les tests et le débogage
Types de migrations¶
Le système supporte deux types de migrations complémentaires :
Migrations SQL : Un fichier unique par version (ex : 2301.2.0.sql) contenant les modifications structurelles de la base de données. Ce fichier peut inclure des directives spéciales comme --DATABASE_BACKUP|tableName pour sauvegarder des tables avant modification.
Migrations PHP : Des scripts personnalisés permettant des transformations complexes nécessitant la logique métier de l'application. Ces scripts offrent un accès complet aux services et peuvent effectuer des opérations impossibles en SQL pur.
Le cycle de vie d'une migration PHP¶
Le contrat d'interface¶
Chaque migration PHP doit implémenter l'interface CustomMigrationUpdateInterface, qui définit un contrat strict en trois méthodes. Ce contrat garantit que toutes les migrations suivent le même protocole de sécurité.
Les trois phases obligatoires¶
1. La sauvegarde (backup())
Avant toute modification, cette méthode crée une copie de sécurité des données concernées. C'est le filet de sécurité qui permettra la restauration en cas de problème.
2. La mise à jour (update())
Cette méthode contient la logique effective de la migration. Elle modifie les données, restructure les informations, ou effectue toute transformation nécessaire à l'évolution de l'application.
3. Le retour arrière (rollback())
En cas d'échec de la mise à jour, cette méthode restaure l'état initial en utilisant les sauvegardes créées lors du backup(). Elle annule tous les changements effectués.
Convention de nommage et ordre d'exécution¶
Les fichiers PHP suivent une convention stricte : [index]-[NomDeLaClasse].php. L'index numérique (01, 02, 03...) détermine l'ordre d'exécution. Cette approche garantit que les migrations interdépendantes s'exécutent dans le bon ordre.
Le nom de classe après le tiret doit correspondre exactement au nom de la classe définie dans le fichier, permettant au système de charger correctement la migration.
La gestion des erreurs et la résilience¶
Principe de l'atomicité¶
Lorsqu'une migration échoue, le système applique un principe d'atomicité : soit toutes les migrations d'une version s'exécutent avec succès, soit aucune ne reste appliquée. Il n'existe pas d'état intermédiaire.
Stratégie de rollback en cascade¶
Si la migration 03-TransformData.php échoue, le système :
- Exécute immédiatement son propre
rollback() - Annule ensuite
02-MigrateUsers.php(ordre inverse) - Puis annule
01-UpdateSchema.php(LIFO)
Cette cascade inversée garantit que les dépendances entre migrations sont respectées lors du retour arrière.
Distinction des problèmes¶
Le système classe les erreurs en trois catégories :
- Erreur de backup : La migration s'arrête immédiatement avant toute modification (
CouldNotRunTheBackupFromTheMigrationProblem) - Erreur d'update avec rollback réussi : Les modifications sont annulées proprement (
CouldNotRunTheUpdateFromTheMigrationButRollbackSuccessfullyProblem) - Erreur d'update ET de rollback : Situation critique nécessitant une intervention manuelle (
CouldNotRunTheUpdateAndRollbackFromTheMigrationProblem)
Le support multi-configuration¶
Applications socle et customs¶
Maarch Courrier distingue deux contextes d'exécution :
L'application socle : C'est le cœur du système, sans personnalisation. Les migrations s'appliquent directement avec la configuration par défaut.
Les applications customs : Chaque configuration personnalisée (identifiée par un customId) peut avoir ses propres migrations indépendantes. Le système détecte automatiquement les customs disponibles et applique leurs migrations séquentiellement.
Isolation et configuration¶
Pour chaque custom, le système :
- Réinitialise le lanceur avec la configuration spécifique
- Charge la connexion à la base de données appropriée
- Applique uniquement les migrations du custom concerné
- Enregistre les logs dans un espace dédié
Cette isolation garantit qu'un problème sur un custom n'affecte pas les autres configurations.
La traçabilité et le débogage¶
Journalisation structurée¶
Tous les événements sont enregistrés via un système de logs hiérarchisé :
- Logs SQL : Stockés dans le docserver de migration (
/opt/maarch/docservers/[custom_ID]/migration/[tag_version]/) - Logs applicatifs : Enregistrés dans
technique.logpour le suivi des actions PHP
Niveaux d'information¶
Le système journalise différents niveaux d'événements :
- Fichiers traités avec succès
- Fichiers ignorés (syntaxe invalide, interface manquante)
- Avertissements lors des rollbacks
- Erreurs critiques avec traces complètes
L'orchestration technique¶
Le rôle du lanceur (UpdateLauncherScript)¶
Le lanceur est le chef d'orchestre du processus. Il :
- Initialise l'environnement (autoloader, logger, services)
- Découvre les configurations disponibles (socle/customs)
- Délègue l'exécution à
UpdateExecution - Gère le cycle de vie global de la mise à jour
Validation et sécurité¶
Avant d'exécuter une migration PHP, le système effectue plusieurs vérifications :
- Syntaxe PHP valide : Analyse lexicale via
token_get_all() - Interface correcte : Vérification que la classe implémente
CustomMigrationUpdateInterface - Namespace conforme : Le namespace doit suivre le pattern
Migration\_[version](ex :Migration\_2301_2_0)
Si l'une de ces conditions échoue, le fichier est ignoré avec un avertissement dans les logs.
Pourquoi cette architecture¶
Robustesse opérationnelle¶
L'approche backup-update-rollback garantit qu'une mise à jour ne peut jamais corrompre définitivement l'application. En cas de problème, l'état antérieur est restauré automatiquement.
Évolutivité maîtrisée¶
La séparation SQL/PHP permet d'adapter le niveau de complexité aux besoins. Les modifications simples restent en SQL pour leur simplicité, tandis que les transformations métier complexes bénéficient de la puissance de PHP.
Maintenance facilitée¶
L'organisation par version et la traçabilité complète permettent de comprendre rapidement l'historique des modifications et de diagnostiquer les problèmes en production.