# Migration

> Suivi de la migration de l'ancien site (`daniel-old`, lecture seule) vers le nouveau CMS maison
> (`W:\daniel`). Ce document est le résultat de la **phase d'audit** : plan, étapes, risques, priorités.
> Aucun code n'est produit à ce stade.

## 1. Stratégie générale

- **Reconstruction**, pas portage : le code de l'ancien site n'est pas réutilisé. On en conserve la
  **logique métier** (galeries, tri, tailles d'images, design) et le **contenu** (images, textes, slugs).
- **Base neuve** : jamais d'import des tables `folders`/`files`. Le contenu est ré-injecté via un
  script de migration **à écrire ultérieurement** (pas dans cette phase).
- **Iso-design** côté public : rendu proche de la production (référence visuelle).
- **Iso-URL** autant que possible : conserver les 8 slugs existants pour préserver le SEO.
- **Bascule unique** en fin de parcours (pas de cohabitation longue des deux systèmes).

## 2. Plan de migration détaillé (étapes)

### Étape 0 — Audit & documentation (EN COURS / cette phase)
- Lecture intégrale de `daniel-old` et analyse de la production.
- Production des 5 documents (`architecture`, `migration`, `backlog`, `cms`, `decisions`).
- **Livrable** : compréhension complète + propositions. **Aucun code.**

### Étape 1 — Décisions & fondations (sur validation)
- Trancher les questions ouvertes (`decisions.md`) : structure webroot, éditeur HTML, lib lightbox,
  stratégie d'upload, envoi d'email, sanitization HTML.
- Définir la configuration : `config/config.php` (versionné) + `config/local.php` (secrets, non versionné).
- Figer le **schéma** (`database/schema.sql`) à partir de la proposition de `cms.md`.
> ✅ **Réalisé (2026-06-13)** : questions Q-01→Q-17 tranchées ; `config/config.php` + `config/local.php`
> (non versionné) en place ; schéma (8 tables) + seed importés en local (base `daniel`).

### Étape 2 — Noyau technique
- Micro-noyau : routeur, couche PDO, vues, gestion des erreurs (sans fuite d'info), sessions, CSRF.
- `.htaccess` (front controller, HTTPS, non-www→www, cache, protection des dossiers sensibles).
> ✅ **Réalisé (2026-06-13)** : micro-noyau (Router, Database PDO, Settings, Session, Csrf, Request,
> Response, View) + `.htaccess` durci ; rendu public minimal vérifié (accueil 200 lisant la base, 404).
> Restent : redirection non-www→www (au déploiement) et page 500 stylée.

### Étape 3 — Front public (iso-design)
- Reproduction du gabarit production : en-tête/logo, grille 4 colonnes responsive (4/2/1),
  lightbox, fil d'Ariane, tuiles de galeries, pied de page.
- Lazy-load des images au-delà des 12 premières (comportement actuel).
- 404 réelle.
> ✅ **Réalisé (2026-06-13)** : Bootstrap 5 + GLightbox vendored ; en-tête + **menu off-canvas** ;
> accueil (tuiles) ; page galerie (grille 4/2/1 + lightbox + lazy-load paramétrable) ; pied de page
> 2 colonnes ; thème par variables CSS. Démo seedée (`bin/seed-demo.php`), flux vérifié
> (accueil/galerie/404/média). Reste : reprise fine du rendu production au pixel.

### Étape 4 — CMS (back-office)
- Authentification admin (`password_hash`, sessions, CSRF, anti-bruteforce simple).
- CRUD galeries (nom, slug, ordre, statut, intro HTML, couverture, SEO).
- CRUD images (nom obligatoire, alt, ordre manuel, statut) + `ImageService` (GD) pour les dérivés.
- Page d'accueil éditable + paramètres du site.
- Formulaire de contact activable/désactivable + envoi email (destination en config locale).
- Champs SEO + génération `sitemap.xml` / `robots.txt`.
> ✅ **Auth + CRUD galeries/images/pages + paramètres + contact réalisés (2026-06-13)** : auth (`password_hash` + CSRF,
> `LoginThrottle`, `bin/create-admin.php`) ; **CRUD galeries** (slug auto, **TinyMCE** + **sanitization
> serveur**, ordre, couverture, SEO) ; **CRUD images** (`ImageService` GD : 4 profils + **WebP** + original) ;
> **pages éditables** (accueil + mentions légales, TinyMCE + SEO par page : title/meta/H1/`lang`/noindex) ;
> **paramètres + thème couleurs** (titre/langue/menu/galeries/contact, **6 couleurs** validées + reset) ;
> **formulaire de contact** (activable, validation/CSRF, honeypot + throttle, **PHPMailer**, reCAPTCHA si clés, messages stockés).
> **SEO global** (sitemap.xml + robots.txt dynamiques, Open Graph, redirections 301/302/410).
> Restent : **finitions** (logo éditable, EXIF auteur, écran profils d'image, TinyMCE auto-hébergé, non-www→www).

### Étape 5 — Migration de contenu (script dédié, ultérieur)
- Mapper les 8 dossiers `image_in/` → galeries ; 1 fichier → 1 image.
- Dériver le **nom** depuis le `goodname` (partie après `##`), **nettoyer** les cas dégradés
  (noms vides, simple `#`, préfixes en doublon).
- Reprendre `image_in/text.txt` → page d'accueil ; appliquer les slugs existants.
- Réimporter de préférence les **originaux** de `image_in/` (meilleure qualité que les dérivés de `img/`).
- Vérification manuelle de l'ordre (l'ancien ordre par préfixe/EXIF est ambigu — voir risques).

### Étape 6 — SEO & redirections
- Conserver les slugs ; ajouter redirections 301 utiles ; 410 pour `/info.php`, `/update.php`.
- `sitemap.xml`, `robots.txt`, balises par page, Open Graph.
> ✅ **Réalisé (2026-06-13)** : `sitemap.xml` + `robots.txt` dynamiques, **Open Graph** par page,
> **redirections** admin (301/302/410) appliquées au routeur. À ajouter au déploiement : redirections
> `/info.php`, `/update.php` et reprise des slugs *legacy* lors de la migration de contenu.

### Étape 7 — Recette, sécurité, performance
- Tests fonctionnels (desktop/mobile, galeries, contact), revue sécurité (uploads, CSRF, sessions),
  performance (poids images, cache, WebP éventuel).

### Étape 8 — Mise en production
- Déploiement sur l'hébergement mutualisé, configuration `config/local.php` côté serveur,
  **rotation des identifiants** de base, bascule DNS/vhost, vérification HTTPS et redirections.

## 3. Risques de migration

### 3.1 Risques de sécurité (hérités de l'ancien site)
| # | Risque | Gravité | Mitigation |
|---|--------|---------|-----------|
| S1 | **Identifiants de base de production en clair** dans le code source `libs/function.php` (`DB_USER`/`DB_PASSWORD`) | **Critique** | Ne jamais reprendre ; **rotation immédiate** du mot de passe DB ; secrets en `config/local.php` non versionné |
| S2 | `info.php` (`phpinfo()`) **exposé publiquement** | Élevé | Ne pas reproduire ; supprimer tout endpoint de debug |
| S3 | « Admin » = HTTP Basic Auth sur `/libs/`, scripts destructifs déclenchés en **GET**, sans CSRF | Élevé | Vraie auth applicative + CSRF + actions en POST |
| S4 | Email dev `contact@mixer.fr` codé en dur (≠ contact réel `daniel.tiziani@dbmail.com`) | Moyen | Email de destination en config locale, vérifié |
| S5 | Connexion DB en `SET NAMES 'utf8'` (3 octets) | Moyen | **utf8mb4** partout (caractères accentués, `&`, etc.) |
| S6 | PHP 7.3 en fin de vie | Moyen | Cible PHP 8.3/8.4, code compatible |

### 3.2 Risques liés au contenu (qualité des données sources)
| # | Risque | Détail constaté | Mitigation |
|---|--------|-----------------|-----------|
| C1 | **Noms d'images vides** | `Bouches à clef/010##.JPG` → `goodname` vide | Le CMS impose un nom ; à compléter manuellement à la migration |
| C2 | **Préfixes de tri en doublon** | `009##…(50×33)` et `009##…(56×38)` ; deux `010##` (GRAVURES NOIRES) ; deux `011##` | Ordre ambigu → **ordre manuel** à valider par galerie |
| C3 | **Typo de séparateur** | `Gravures Pliages/0012#…` (un seul `#`) → nom mal découpé | Nettoyage au cas par cas |
| C4 | Bruit de fichiers | `Thumbs.db`, `.ftpquota` dans les sources | Filtrage à l'import (types image uniquement) |
| C5 | Caractères spéciaux/accents | `&`, accents, dimensions décimales `47.5 x 63.5 cm` | utf8mb4 + slugs normalisés ; vérifier le rendu |
| C6 | Doublon de source possible | Deux fichiers `009##` distincts dans Anfractuosité | Dédoublonnage à l'import |
| C7 | Qualité des images | Les `img/` sont déjà re-compressés (perte) ; les `image_in/` sont les originaux | Réimporter les **originaux** quand ils existent |

### 3.3 Risques fonctionnels / techniques
| # | Risque | Détail | Mitigation |
|---|--------|--------|-----------|
| F1 | Pipeline ancien **fragile** | Boucle de redirections JS `do_image.php?id=N` ; `do_first_image.php` paraît **cassé/mort** ; `max_execution_time=30` → timeouts possibles | Nouveau traitement unitaire à l'upload, transactionnel |
| F2 | **Perte d'ordre** | L'ancien ordre dépend de la date EXIF / préfixes ambigus | Figer un ordre explicite en base à la migration |
| F3 | **Upload limité à 2 Mo** en prod | `upload_max_filesize=2M` | Augmenter via `.user.ini` ou redimensionnement client (à valider hébergeur) |
| F4 | **Fidélité visuelle** | CSS ancien contient des commentaires `//` invalides en CSS (probable SCSS servi brut) | Recréer un CSS propre iso-rendu, vérifier au pixel |
| F5 | Dépendances datées | Bootstrap 3 + jQuery + Fancybox 2.1.5 (2013) | Moderniser sans casser le rendu (décision ouverte) |
| F6 | **SEO** | Slugs à préserver, sinon redirections | Iso-slugs + 301 ciblés + sitemap |
| F7 | Environnement | MySQL 8 (local) vs MariaDB 10.11 (prod) | Éviter le SQL non portable ; tester sur les deux |

### 3.4 Risques de périmètre / process
| # | Risque | Mitigation |
|---|--------|-----------|
| P1 | Écriture accidentelle hors `W:\daniel` (notamment `daniel-old`) | Vérifier le chemin cible **avant chaque écriture** ; `daniel-old` strictement en lecture |
| P2 | Sur-ingénierie (« usine à gaz ») | CMS minimal, sans framework lourd (exigence AGENTS.md) |
| P3 | Fuite de secret dans Git | `config/local.php` non versionné ; pas de push sans validation |

## 4. Priorités

**P0 — Bloquant / sécurité**
- Rotation des identifiants DB exposés (S1). Ne pas reproduire S1–S3.
- Fondations : config non versionnée, noyau PDO/CSRF/sessions, schéma figé.

**P1 — Cœur de valeur**
- Front public iso-design + 404.
- CMS galeries + images (nom obligatoire, ordre manuel).
- Page d'accueil éditable.

**P2 — Indispensable avant prod**
- Formulaire de contact (activable) + email en config locale.
- SEO par page + sitemap + robots + iso-slugs + redirections.
- Migration de contenu (script + nettoyage qualité données).

**P3 — Améliorations**
- Performance (WebP, cache, lazy-load), modernisation front, journal d'activité, multilingue éventuel.

> Détail des tâches : `backlog.md`. Conception CMS : `cms.md`. Choix techniques : `decisions.md`.
