# 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.
