# Migration des données legacy (MyFARAH_Web → newfarahgroupe)

## Statut réel, par table

Les deux exports disponibles localement (`my_farah.sql`, `my_farah (1).sql`)
sont **tous les deux tronqués** par une erreur 500 du serveur d'export OVH,
en plein milieu d'une instruction `INSERT` (voir `docs.txt`). phpMyAdmin
dumpe les tables par ordre alphabétique : tout ce qui vient, dans l'ordre
alphabétique, **avant** le point de troncature est complet ; tout ce qui vient
après est **totalement absent** (pas de ligne tronquée à corriger : la table
n'apparaît simplement jamais dans le fichier).

| Donnée legacy | Table source | Disponible ? | Migrateur |
|---|---|---|---|
| Étages | `app_my_farah_etage` | ✅ complète (4 lignes) | `LegacyHospitalisationInfrastructureMigrator` |
| Chambres | `app_my_farah_chambre` | ✅ complète (132 lignes) | `LegacyHospitalisationInfrastructureMigrator` |
| Assurances | `app_my_farah_assurance` | ✅ complète (146 lignes) | `LegacyAssuranceMigrator` |
| Catégories d'actualités | `app_my_farah_categorie_actualites` | ✅ complète (6 lignes) | `LegacyCmsMigrator` |
| Actualités | `app_my_farah_actualites` | ✅ complète (5 lignes) | `LegacyCmsMigrator` |
| FAQ | `app_my_farah_faq` | ✅ structure présente, 0 ligne | `LegacyCmsMigrator` |
| Rôles | `app_my_farah_level` | ❌ absente des deux dumps | `LegacyRoleAndUserMigrator` (prêt, non vérifié sur données réelles) |
| Utilisateurs | `app_my_farah_user` | ❌ absente des deux dumps | `LegacyRoleAndUserMigrator` (prêt, non vérifié sur données réelles) |
| Patients | `app_my_farah_patient` | ❌ absente des deux dumps | `LegacyPatientMigrator` (prêt, non vérifié sur données réelles) |
| Médecins | `app_my_farah_medecin` | ❌ absente des deux dumps | non écrit (colonnes confirmées par lecture du code, voir ci-dessous) |
| Spécialités | `app_my_farah_specialite` | ❌ absente des deux dumps | non écrit |
| Rendez-vous | (table exacte non identifiée) | ❌ absente | non écrit |
| Factures patient | `app_my_farah_facture` | ⚠️ présente mais hors périmètre (voir note) | non écrit |

**Note sur `app_my_farah_facture`** : cette table contient bien des données
réelles et complètes, mais ce sont des enregistrements de transaction Orange
Money (token de paiement, URL de paiement, statut de notification) liés à un
`id_rendezvous`/`id_patient` — pas des factures patient au sens de notre
module Facturation. Comme les patients et rendez-vous ne sont pas disponibles,
ces lignes n'ont pas de cible significative et n'ont pas été migrées.

## Pourquoi ne pas se connecter directement à la base de production ?

`MyFARAH_Web/inc/config.php` contient des identifiants de connexion à la base
de production OVH (`polyclinaifaradb.mysql.db`). Une connexion directe
permettrait en théorie de contourner le bug d'export phpMyAdmin et de
récupérer un dump complet — mais cette base contient des données patients
réelles (PHI). Cette action n'a pas été effectuée : elle nécessite une
décision et une autorisation explicites du responsable du projet, pas une
initiative automatisée. Voir la section « Procédure recommandée » ci-dessous.

## Ce qui a été fait dans ce dépôt

- `src/Migration/LegacyHospitalisationInfrastructureMigrator.php`,
  `LegacyAssuranceMigrator.php`, `LegacyCmsMigrator.php` : trois migrateurs
  pour les données réellement disponibles, **exécutés avec succès sur les
  données réelles extraites de `my_farah.sql`** (voir « Exécution réelle »
  ci-dessous).
- `src/Migration/LegacyPatientMigrator.php`, `LegacyRoleAndUserMigrator.php`
  (préexistants) : prêts, mais leur mapping de colonnes n'a pu être vérifié
  que par lecture du code source legacy, jamais sur un échantillon réel —
  **à valider sur un vrai dump avant toute migration de production**.
- `database/migrate-legacy/extract-available-legacy-tables.php` : script
  réutilisable qui extrait, depuis n'importe quel dump `my_farah.sql` futur
  (par ex. un export plus complet), les tables disponibles avant le point de
  troncature.
- `database/migrate-legacy/legacy-available-subset.sql` : le résultat de ce
  script appliqué à `my_farah.sql` — sous-ensemble réel et réimportable
  (étages, chambres, assurances, catégories, actualités, FAQ). Ne contient
  aucune donnée patient (PHI) : uniquement de l'infrastructure hospitalière,
  des partenaires assurance, et du contenu éditorial public.
- `bin/migrate-legacy.php` : orchestrateur qui exécute les 5 migrateurs dans
  l'ordre, idempotent (relancer ne duplique rien), et résilient — si une table
  source manque (dump partiel), il le signale et continue plutôt que de
  planter.
- `tests/Feature/LegacyMigrationTest.php` : 7 tests d'intégration réels
  (contre MySQL, pas de mocks) couvrant les 5 migrateurs, y compris les cas
  limites trouvés en travaillant sur les vraies données (doublons de
  `libelle_chambre`, ex. plusieurs chambres nommées juste « CH »).

## Exécution réelle effectuée

Le 2026-06-25, `bin/migrate-legacy.php` a été exécuté avec
`database/migrate-legacy/legacy-available-subset.sql` comme source, vers une
base tenant fraîchement provisionnée (schéma `tenant_template` à jour) :

```
Étages     : 4 migrés
Chambres   : 132 migrées
Assurances : 146 migrées
Catégories : 6 migrées
Actualités : 5 migrées
```

Une seconde exécution a confirmé l'idempotence (tout est passé à "ignoré",
aucun doublon créé). La base de démonstration a ensuite été supprimée — ce
n'était qu'une vérification, pas l'établissement réel.

## Décisions de mapping documentées

- **Numéros de chambre** : `chambres.numero` est UNIQUE dans le nouveau
  schéma, mais de vrais doublons existent dans les données legacy (plusieurs
  chambres nommées juste « CH »). Le numéro migré est donc
  `"{libellé} (legacy #{id})"` pour garantir l'unicité et l'idempotence.
  À renommer proprement depuis l'écran Hospitalisation après migration.
- **Type de chambre** (`type_chambre` : codes `1`..`7` sans légende
  retrouvée) : non mappé, toutes les chambres migrées sont `standard` par
  défaut — à reclasser manuellement.
- **Statut de chambre** (`libre`/`occupee`/`maintenance`) : `etat_chambre` et
  `id_hospitalisation` ne permettent pas de déduire l'occupation réelle au
  moment de l'export de façon fiable ; toutes les chambres migrées sont
  `libre` par défaut.
- **Statut d'actualité** (`brouillon`/`publie`) : `etat_actualites` vaut `0`
  pour les 5 lignes disponibles (aucune variation observée, polarité non
  déductible). Toutes les actualités migrées sont créées en `brouillon` — la
  date de publication legacy est conservée dans `publie_at` à titre
  informatif, à valider avant publication réelle.
- **Images** (actualités, etc.) : seuls les noms de fichiers sont migrés
  (`image_path`). Les fichiers eux-mêmes (dossier `uploads/` côté legacy) ne
  sont pas présents dans ce dépôt et doivent être transférés séparément
  (ex. `rsync`) vers `storage/uploads/{db_name}/...` avant que ces images
  s'affichent réellement.

## Procédure recommandée pour débloquer Médecins / Utilisateurs / Patients / Rendez-vous

1. Demander un accès SSH ou un export `mysqldump --single-transaction
   --quick --no-tablespaces` direct sur le serveur OVH (contourne le bug
   d'export phpMyAdmin qui tronque systématiquement avant ces tables).
2. Restaurer ce dump en staging isolé (jamais en production directement).
3. Lancer `php database/migrate-legacy/extract-available-legacy-tables.php`
   sur ce nouveau dump pour voir si la couverture s'est étendue.
4. Avant toute migration réelle de patients/utilisateurs, valider sur un
   échantillon que les noms de colonnes utilisés par `LegacyPatientMigrator`
   et `LegacyRoleAndUserMigrator` (déduits du code source, jamais vérifiés
   sur données réelles) correspondent bien à la structure réelle des tables
   `app_my_farah_patient` / `app_my_farah_user` / `app_my_farah_level` —
   ajuster les migrateurs si besoin avant de lancer sur l'intégralité.
5. Pour Médecins/Spécialités/Rendez-vous, aucun migrateur n'existe encore :
   les noms de colonnes ci-dessous ont été confirmés par lecture directe de
   `MyFARAH_Web/_req/global/app_my_farah_medecin.php` et
   `app_my_farah_specialite.php`, mais aucun migrateur n'a été écrit tant que
   les données réelles ne sont pas disponibles pour le vérifier :
   - `app_my_farah_medecin` : `id_specialite, nom_medecin, prenom_medecin,
     tel_medecin, email_medecin, titre_medecin, etat_medecin, montant_medecin`
   - `app_my_farah_specialite` : `libelle_specialite, etat_specialite`
6. Exécuter `php bin/migrate-legacy.php --legacy-host=... --legacy-database=...
   --tenant-host=... --tenant-database=...` (idempotent, peut être relancé).

## Commandes utiles

```bash
# Régénérer le sous-ensemble réel à partir d'un dump my_farah.sql
php database/migrate-legacy/extract-available-legacy-tables.php /chemin/vers/my_farah.sql > database/migrate-legacy/legacy-available-subset.sql

# Importer ce sous-ensemble dans une base de travail
mysql --default-character-set=utf8mb4 -u root nom_base < database/migrate-legacy/legacy-available-subset.sql

# Lancer la migration vers un établissement déjà provisionné
php bin/migrate-legacy.php \
  --legacy-host=127.0.0.1 --legacy-database=nom_base --legacy-username=root \
  --tenant-host=127.0.0.1 --tenant-database=newfarah_tenant_xxx --tenant-username=root
```
