# Migration v2 - Architecture modulaire ## Vue d'ensemble Cette nouvelle architecture simplifie la migration en utilisant : - **Source fixe** : `geosector` (synchronisée 2x/jour par PM7 depuis nx4) - **Multi-environnement** : `--env=dva` (développement), `--env=rca` (recette) ou `--env=pra` (production) - **Auto-détection** : L'environnement est détecté automatiquement selon le serveur - **Classes réutilisables** : Configuration, Logger, Connexion ## Structure modulaire ``` migration2/ ├── README.md # Ce fichier ├── logs/ # Logs de migration (auto-créé) │ └── .gitignore ├── php/ │ ├── migrate_from_backup.php # Script principal orchestrateur │ └── lib/ │ ├── DatabaseConfig.php # Configuration multi-env │ ├── MigrationLogger.php # Gestion des logs │ ├── DatabaseConnection.php # Connexions PDO │ ├── OperationMigrator.php # Migration des opérations │ ├── UserMigrator.php # Migration des ope_users │ ├── SectorMigrator.php # Migration des secteurs │ └── PassageMigrator.php # Migration des passages ``` **Architecture modulaire** : Chaque type de données a son propre migrator spécialisé, orchestré par le script principal. ## ⚠️ AVERTISSEMENT IMPORTANT **Par défaut, le script SUPPRIME toutes les données de l'entité dans la base cible avant la migration.** Cela inclut : - ✅ Toutes les opérations de l'entité - ✅ Tous les utilisateurs de l'entité - ✅ Tous les secteurs et passages - ✅ Tous les médias associés - ℹ️ L'entité elle-même est conservée (seules les données liées sont supprimées) Pour **désactiver** la suppression et conserver les données existantes : ```bash php php/migrate_from_backup.php --mode=entity --entity-id=45 --delete-before=false ``` ⚠️ **Attention** : Sans suppression préalable, risque de doublons si les données existent déjà. --- ## Utilisation ### Migration d'une entité spécifique #### Sur dva-geo (IN3) ```bash # Auto-détection de l'environnement (recommandé) php php/migrate_from_backup.php --mode=entity --entity-id=45 # Ou avec environnement explicite php php/migrate_from_backup.php --env=dva --mode=entity --entity-id=45 ``` #### Sur rca-geo (IN3) ```bash # Auto-détection de l'environnement (recommandé) php php/migrate_from_backup.php --mode=entity --entity-id=45 # Ou avec environnement explicite php php/migrate_from_backup.php --env=rca --mode=entity --entity-id=45 ``` #### Sur pra-geo (IN4) ```bash # Auto-détection de l'environnement (recommandé) php php/migrate_from_backup.php --mode=entity --entity-id=45 # Ou avec environnement explicite php php/migrate_from_backup.php --env=pra --mode=entity --entity-id=45 ``` ### Migration globale (toutes les entités) ```bash # Sur dva-geo, rca-geo ou pra-geo php php/migrate_from_backup.php --mode=global ``` ### Options disponibles ```bash --env=ENV # 'dva' (développement), 'rca' (recette) ou 'pra' (production) # Par défaut : auto-détection selon le hostname --mode=MODE # 'global' ou 'entity' (défaut: global) --entity-id=ID # ID de l'entité à migrer (requis si mode=entity) --log=PATH # Fichier de log personnalisé # Par défaut : logs/migration_YYYYMMDD_HHMMSS.log --delete-before # Supprimer les données existantes avant migration (défaut: true) --help # Afficher l'aide complète ``` ### Exemples d'utilisation ```bash # Migration STANDARD (avec suppression des données existantes - recommandé) php php/migrate_from_backup.php --mode=entity --entity-id=45 # Migration SANS suppression (pour ajout/mise à jour uniquement - risque de doublons) php php/migrate_from_backup.php --mode=entity --entity-id=45 --delete-before=false # Migration avec log personnalisé php php/migrate_from_backup.php --mode=entity --entity-id=45 --log=/custom/path/entity_45.log # Afficher l'aide complète php php/migrate_from_backup.php --help ``` ## Différences avec l'ancienne version | Aspect | Ancien | Nouveau | |--------|--------|---------| | **Source** | `--source-db=geosector_YYYYMMDD_HH` | Toujours `geosector` (fixe) | | **Cible** | `--target-db=pra_geo` | Déduite de `--env` ou auto-détectée (dva_geo, rca_geo, pra_geo) | | **Config** | Constantes hardcodées | Classes configurables | | **Environnement** | Manuel | Auto-détection par hostname (dva-geo, rca-geo, pra-geo) | | **Arguments** | 2 arguments DB requis | 1 seul `--env` (optionnel) | ## Avantages ✅ **Plus simple** : Plus besoin de spécifier les noms de bases ✅ **Plus sûr** : Moins de risques d'erreurs de saisie ✅ **Plus flexible** : Fonctionne sur dva-geo, rca-geo et pra-geo sans modification ✅ **Plus maintenable** : Configuration centralisée dans DatabaseConfig ✅ **Meilleurs logs** : Séparateurs, niveaux (info/warning/error/success) ## Déploiement ### Copier vers dva-geo (IN3) ```bash scp -r migration2 root@195.154.80.116:/tmp/ ssh root@195.154.80.116 "incus file push -r /tmp/migration2 dva-geo/var/www/geosector/api/scripts/" ``` ### Copier vers rca-geo (IN3) ```bash scp -r migration2 root@195.154.80.116:/tmp/ ssh root@195.154.80.116 "incus file push -r /tmp/migration2 rca-geo/var/www/geosector/api/scripts/" ``` ### Copier vers pra-geo (IN4) ```bash scp -r migration2 root@51.159.7.190:/tmp/ ssh root@51.159.7.190 "incus file push -r /tmp/migration2 pra-geo/var/www/geosector/api/scripts/" ``` ### Test après déploiement ```bash # Se connecter au container incus exec dva-geo -- bash # ou rca-geo, ou pra-geo # Tester avec une entité cd /var/www/geosector/api/scripts/migration2 php php/migrate_from_backup.php --mode=entity --entity-id=45 ``` ## Logs Les logs sont enregistrés par défaut dans : ``` scripts/migration2/logs/migration_[MODE]_YYYYMMDD_HHMMSS.log ``` **Nommage automatique selon le mode :** - Migration globale : `migration_global_20251021_143045.log` - Migration d'une entité : `migration_entite_45_20251021_143045.log` Format des logs : - `[INFO]` : Informations générales - `[SUCCESS]` : Opérations réussies - `[WARNING]` : Avertissements - `[ERROR]` : Erreurs Le dossier `logs/` est créé automatiquement si nécessaire. **Note :** Vous pouvez toujours spécifier un fichier de log personnalisé avec l'option `--log=PATH`. ## Récapitulatif de migration À la fin de chaque migration, un **récapitulatif détaillé** est automatiquement affiché et enregistré dans le fichier de log. ### Format du récapitulatif ``` ======================================== 📊 RÉCAPITULATIF DE LA MIGRATION ======================================== Entité: Nom de l'entité (ID: XX) Date: YYYY-MM-DD HH:MM:SS Opérations migrées: 3 Opération #1: "Adhésions 2024" (ID: 850) ├─ Utilisateurs: 12 ├─ Secteurs: 5 ├─ Passages totaux: 245 └─ Détail par secteur: ├─ Centre-ville (ID: 5400) │ ├─ Utilisateurs affectés: 3 │ └─ Passages: 67 ├─ Quartier Est (ID: 5401) │ ├─ Utilisateurs affectés: 5 │ └─ Passages: 98 └─ Nord (ID: 5402) ├─ Utilisateurs affectés: 4 └─ Passages: 80 Opération #2: "Collecte Printemps" (ID: 851) ├─ Utilisateurs: 8 ├─ Secteurs: 3 ├─ Passages totaux: 156 └─ Détail par secteur: [...] ======================================== ``` ### Informations fournies Le récapitulatif inclut pour chaque migration : **Au niveau de l'entité :** - Nom et ID de l'entité - Date et heure de la migration - Nombre total d'opérations migrées **Pour chaque opération :** - Nom et nouvel ID - Nombre d'utilisateurs migrés - Nombre de secteurs migrés - Nombre total de passages migrés **Pour chaque secteur :** - Nom et nouvel ID - Nombre d'utilisateurs affectés au secteur - Nombre de passages effectués dans le secteur ### Utilisation du récapitulatif Ce récapitulatif permet de : - ✅ Vérifier rapidement que toutes les données ont été migrées - ✅ Comparer avec les données source pour validation - ✅ Identifier d'éventuelles anomalies (secteurs vides, passages manquants) - ✅ Documenter précisément ce qui a été migré - ✅ Tracer les migrations pour audit Le récapitulatif est présent à la fois : - **À l'écran** (stdout) en temps réel - **Dans le fichier de log** pour conservation ## Dépannage ### Erreur "env doit être 'dva', 'rca' ou 'pra'" L'auto-détection a échoué. Spécifiez manuellement : ```bash php php/migrate_from_backup.php --env=dva --mode=entity --entity-id=45 ``` ### Erreur de connexion Vérifiez que vous êtes bien dans le bon container (dva-geo, rca-geo ou pra-geo). ### Données dupliquées après migration Si vous avez des doublons, c'est que vous avez utilisé `--delete-before=false` sur des données existantes. **Solution** : Refaire la migration avec suppression (défaut) : ```bash php php/migrate_from_backup.php --mode=entity --entity-id=45 ``` ### Vérifier ce qui sera supprimé avant migration Consultez la section "Ordre de suppression" ci-dessous pour voir exactement quelles tables seront affectées. ### Logs non créés Vérifiez les permissions du dossier `logs/` : ```bash ls -la scripts/migration2/logs/ ``` ## Détails techniques ### Architecture hiérarchique de migration La migration fonctionne par **opération** avec une hiérarchie complète : ``` Pour chaque opération de l'entité: migrateOperation($oldOperationId) ├── Créer operation ├── Migrer ope_users (DISTINCT depuis ope_users_sectors) │ └── Mapper oldUserId → newOpeUserId ├── Pour chaque secteur DISTINCT de l'opération: │ └── migrateSector($oldOperationId, $newOperationId, $oldSectorId) │ ├── Créer ope_sectors │ ├── Mapper "opId_sectId" → newOpeSectorId │ ├── Migrer sectors_adresses (fk_sector = newOpeSectorId) │ ├── Migrer ope_users_sectors (avec mappings users + sector) │ ├── Migrer ope_pass (avec mappings users + sector) │ │ └── Pour chaque passage: │ │ └── migratePassageHisto($oldPassId, $newPassId) │ └── Migrer médias des passages └── Migrer médias de l'opération ``` ### Changement d'organisation des données : Exemple concret #### Contexte : Opération de collecte des adhésions 2024 **Ancienne organisation** (base geosector - partagée) : - 1 opération "Adhésions 2024" avec ID 450 - 3 utilisateurs affectés : Jean (ID 100), Marie (ID 101), Paul (ID 102) - 2 secteurs utilisés : Centre-ville (ID 1004) et Quartier Est (ID 1005) - Jean travaille sur Centre-ville, Marie et Paul sur Quartier Est Dans l'ancienne base : - Les 3 users existent UNE SEULE FOIS dans la table centrale `users` - Les 2 secteurs existent UNE SEULE FOIS dans la table centrale `sectors` - Les liens entre users et secteurs sont dans `ope_users_sectors` - Les passages font référence directement aux users (ID 100, 101, 102) **Nouvelle organisation** (base rca_geo/pra_geo - isolée par opération) : Après migration, **CHAQUE opération devient autonome** : - L'opération "Adhésions 2024" reçoit un nouvel ID (exemple : 850) - Les 3 utilisateurs sont **dupliqués** dans `ope_users` avec de nouveaux IDs : - Jean → ope_users.id = 2500 (avec fk_user = 100 et fk_operation = 850) - Marie → ope_users.id = 2501 (avec fk_user = 101 et fk_operation = 850) - Paul → ope_users.id = 2502 (avec fk_user = 102 et fk_operation = 850) - Les 2 secteurs sont **dupliqués** dans `ope_sectors` : - Centre-ville → ope_sectors.id = 5400 (avec fk_operation = 850) - Quartier Est → ope_sectors.id = 5401 (avec fk_operation = 850) - Tous les passages sont mis à jour pour référencer les NOUVEAUX IDs (2500, 2501, 2502) **Pourquoi cette duplication ?** ✅ **Isolation complète** : Si l'opération est supprimée, tout part avec (secteurs, users, passages) ✅ **Performance** : Pas de jointures complexes entre opérations ✅ **Historique** : Les données de l'opération restent figées dans le temps ✅ **Simplicité** : Chaque opération est indépendante **Impact pour un utilisateur qui travaille sur 3 opérations différentes** : - Il existera 1 seule fois dans la table centrale `users` (ID 100) - Il existera 3 fois dans `ope_users` (1 enregistrement par opération) - Chaque enregistrement `ope_users` garde la référence vers `users.id = 100` Cette architecture permet de **fermer** une opération complètement sans impacter les autres. ### Sélection des opérations à migrer Pour chaque entité, **maximum 3 opérations** sont migrées : 1. **1 opération active** (`active = 1`) 2. **2 dernières opérations inactives** (`active = 0`) ayant au moins **10 passages effectués** (`fk_type = 1`) ### Ordre de suppression (si --delete-before=true) Les données sont supprimées dans cet ordre pour respecter les contraintes de clés étrangères : 1. `medias` - Médias associés à l'entité ou aux opérations 2. `ope_pass_histo` - Historique des passages 3. `ope_pass` - Passages 4. `ope_users_sectors` - Associations utilisateurs/secteurs 5. `ope_users` - Utilisateurs d'opérations 6. `sectors_adresses` - Adresses de secteurs 7. `ope_sectors` - Secteurs d'opérations 8. `operations` - Opérations 9. `users` - Utilisateurs de l'entité ⚠️ **L'entité elle-même** (`entites`) **n'est jamais supprimée**. ### Tables de référence non migrées Les tables suivantes ne sont **pas** migrées car déjà remplies dans la cible : - `x_*` - Tables de référence (secteurs, adresses, etc.) ## Notes importantes 1. **Configuration centralisée** : Les paramètres de connexion DB sont récupérés depuis `AppConfig.php` - pas de duplication 2. **Chiffrement** : ApiService est toujours utilisé pour les mots de passe 3. **Logique métier** : Inchangée (migrateEntites, migrateUsers, etc.) 4. **Mappings** : Secteurs et adresses sont toujours mappés automatiquement 5. **Backup** : Un backup de l'ancien script est disponible dans `migrate_from_backup.php.backup` 6. **Suppression par défaut** : Activée pour éviter les doublons et garantir une migration propre ## Statut **Architecture modulaire v2** : - ✅ DatabaseConfig.php - Configuration multi-environnement - ✅ MigrationLogger.php - Gestion des logs - ✅ DatabaseConnection.php - Connexions PDO - ✅ OperationMigrator.php - Migration hiérarchique des opérations - ✅ UserMigrator.php - Migration des utilisateurs par opération - ✅ SectorMigrator.php - Migration des secteurs par opération - ✅ PassageMigrator.php - Migration des passages et historiques - ✅ migrate_from_backup.php - Script principal orchestrateur - ⏳ Tests sur rca-geo - ⏳ Tests sur pra-geo ## Support En cas de problème, consulter les logs détaillés ou contacter l'équipe technique.