# Backlog

> Liste exhaustive des tâches issues de l'audit, classées par priorité. Statut : `[ ]` à faire ·
> `[~]` en cours · `[x]` fait.
> **Étape 1 (fondations) réalisée le 2026-06-13** : structure à la racine, config non versionnée,
> micro-noyau (routeur, PDO, sessions, CSRF, vues), `.htaccess` durci, schéma + seed importés en local,
> rendu public minimal vérifié (accueil 200 lisant la base, 404). Voir `migration.md`.
> **Auth admin réalisée le 2026-06-13** : login `password_hash`/CSRF, garde de session, déconnexion,
> throttle anti-bruteforce, script CLI `bin/create-admin.php` (flux vérifié de bout en bout).
> **Front public iso-design réalisé le 2026-06-13** : Bootstrap 5 + GLightbox (vendored), en-tête +
> **menu off-canvas**, accueil (tuiles), page galerie (grille 4/2/1 + lightbox + lazy-load), pied de page
> 2 colonnes, thème par variables CSS ; galeries de démo + **flux vérifié** (accueil/galerie/404/média).
> **CRUD galeries réalisé le 2026-06-13** : liste, création (slug auto), édition (intro **TinyMCE** +
> **sanitization serveur** vérifiée anti-XSS), statut, **ordre manuel**, couverture, SEO, suppression.
> **CRUD images + ImageService réalisés le 2026-06-13** : upload multiple, GD (4 profils, crop/orientation,
> **JPEG+WebP**), original conservé, nom obligatoire, ordre manuel, suppression (purge dérivés) — **flux vérifié**.
> **Pages éditables réalisées le 2026-06-13** : accueil (texte **TinyMCE** + SEO) et mentions légales
> (activable, lien pied de page, 404 si masquée, noindex) ; SEO par page (title/meta/H1/lang) — **flux vérifié**.
> **Paramètres + thème couleurs réalisés le 2026-06-13** : titre/accroche/langue/auteur, menu, galeries
> (lazy/lot), contact (activable), **6 couleurs** (validation hex anti-injection + reset) — **flux vérifié**.
> **Formulaire de contact réalisé le 2026-06-13** : activable, validation + CSRF, **honeypot + horodatage +
> throttle**, **PHPMailer** (vendored), reCAPTCHA (si clés), stockage des messages — **flux vérifié**.
> **SEO global réalisé le 2026-06-13** : `sitemap.xml` + `robots.txt` dynamiques, **Open Graph**,
> **redirections** admin (301/302/410) appliquées au routeur — **flux vérifié**.
> Référence : `migration.md` (étapes/risques), `cms.md` (conception), `decisions.md` (choix).

## P0 — Fondations & sécurité (bloquant)

- [ ] **SEC-01** Faire **roter le mot de passe DB** exposé dans l'ancien `libs/function.php` (action côté hébergeur/propriétaire).
- [x] **SEC-02** Ne reprendre **aucun secret** de l'ancien code ; définir `config/local.php` (non versionné) + `config/config.php` (versionné, sans secret).
- [ ] **DEC-00** Trancher les questions ouvertes de `decisions.md` (webroot, éditeur HTML, lightbox, upload, email, sanitization).
- [x] **DB-01** Figer le schéma neuf dans `database/schema.sql` (8 tables, utf8mb4, MySQL 8 / MariaDB 10.11) — importé en local.
- [x] **DB-02** `database/seed.sql` (settings + profils d'image + pages) + script `bin/create-admin.php` (`password_hash`) pour le 1ᵉʳ compte.
- [x] **CORE-01** Micro-noyau : routeur + front controller public (`index.php`, autoloader PSR-4).
- [x] **CORE-02** Couche base de données PDO (utf8mb4, requêtes préparées, fallback propre si DB absente).
- [x] **CORE-03** Sessions sécurisées + jeton CSRF réutilisable.
- [x] **CORE-04** Gestion des erreurs (404 propre, `display_errors` piloté par `app.debug`) — *500 stylée à venir*.
- [~] **CORE-05** `.htaccess` racine : front controller, HTTPS (hors local), cache, **blocage** `config/`/`src/`/`storage/`/`database/`/`templates/` — *non-www→www à ajouter au déploiement*.

## P1 — Front public (iso-design) & CMS cœur

### Front public
- [x] **PUB-01** Gabarit de base : en-tête, conteneur, pied de page + **thème par variables CSS**.
- [x] **PUB-02** Page d'accueil : intro éditoriale (page `home`) + tuiles des galeries publiées.
- [x] **PUB-03** Page galerie : grille responsive **4/2/1 colonnes** (CSS grid, ≤1000px → 2, ≤560px → 1).
- [x] **PUB-04** Lightbox sur les images (GLightbox), titre = nom de l'image.
- [x] **PUB-05** Fil d'Ariane (Accueil › Galerie).
- [-] **PUB-06** Tuiles de sous-galeries — **sans objet** (galeries plates, D-23).
- [x] **PUB-07** Lazy-load des images **au défilement**, **paramétrable** (voir LAZY-*).
- [x] **PUB-08** 404 réelle (l'ancien site redirigeait tout inconnu vers l'accueil).
- [x] **PUB-09** CSS reproduisant le rendu (fond gris, hover zoom, fil d'Ariane, tuiles) — *reprise fine au pixel à affiner*.
- [x] **PUB-10** **Bootstrap 5** vendored (`assets/vendor/bootstrap`, sans build, **sans jQuery**) (D-11).
- [x] **PUB-11** Lightbox **GLightbox** vendored (`assets/vendor/glightbox`) (D-15).
- [x] **PUB-12** Pied de page **2 colonnes** (« réf » + « galeries ») — *contenu détaillé à préciser (Q-13)*.

### Navigation — menu hamburger responsive *(exigence client, D-12)*
- [x] **NAV-01** En-tête avec marque + bouton de menu.
- [x] **NAV-02** Hamburger ouvrant un **panneau off-canvas** Bootstrap 5 (hamburger permanent — nav horizontale desktop différée, Q-17).
- [x] **NAV-03** Contenu dynamique : Accueil + galeries publiées (triées) + Contact (si activé).
- [x] **NAV-04** Accessibilité de base (`aria-controls`/`aria-label`, focus géré par l'off-canvas BS5).
- [x] **NAV-05** `menu_mode` + `menu_show_contact` **éditables dans l'admin** ; `menu_breakpoint` non exposé (hamburger permanent).

### Thème — gestion simple des couleurs *(exigence client, D-13)*
- [x] **THEME-01** Écran admin avec **6 sélecteurs de couleur** (fond, texte, accent/liens, en-tête, pied de page, survol) + **reset**.
- [x] **THEME-02** Stockage `settings` (`theme_color_*`) + **validation hexadécimale** (anti-injection CSS) — **vérifié**.
- [x] **THEME-03** Injection des couleurs en **variables CSS** dans le `<head>` public.
- [x] **THEME-04** Le CSS du site **référence les variables** ; défauts = couleurs de production.

### Lazy-load paramétrable *(exigence client, D-14)*
- [x] **LAZY-01** Réglages (`settings`) : `gallery_lazyload_enabled` + `gallery_batch_size` (lus par `GalleryController`).
- [x] **LAZY-02** Chargement au défilement en JS (IntersectionObserver, `assets/js/public.js`) + `loading="lazy"`.
- [x] **LAZY-03** Repli si désactivé (tout rendu d'emblée) + dimensions d'image (`width`/`height`, anti-CLS).

### Authentification admin
- [x] **ADM-01** Connexion admin (`password_hash`/`password_verify`), formulaire protégé CSRF.
- [x] **ADM-02** Garde de session sur les routes `/admin`, déconnexion (POST + CSRF).
- [x] **ADM-03** Anti-bruteforce simple (`LoginThrottle` : 5 essais puis temporisation).

### CMS — galeries
- [x] **GAL-01** Liste des galeries (statut, nb images, ordre) avec actions.
- [x] **GAL-02** Création (titre obligatoire → slug auto unique, statut brouillon par défaut).
- [x] **GAL-03** Édition : intro HTML (**TinyMCE**), couverture, statut, champs SEO.
- [x] **GAL-04** Réordonnancement manuel (boutons monter/descendre, échange de `sort_order`).
- [x] **GAL-05** Publication / dépublication (statut dans le formulaire).
- [x] **GAL-06** **Désactivation** (statut brouillon) **et** suppression définitive (confirmation + purge des médias) (D-24).

### CMS — images
- [x] **IMG-01** Upload **multiple** (multipart) dans une galerie.
- [x] **IMG-02** **Nom obligatoire** (auto depuis le fichier à l'upload, rejet si vidé à l'édition) + `alt`.
- [x] **IMG-03** `ImageService` (GD) : 4 profils (vignette, normal, plein écran, couverture) — crop/ajustement orientation-aware + **WebP** ; **original conservé** (`storage/uploads`).
- [x] **IMG-04** Correction d'orientation via EXIF.
- [x] **IMG-05** Réordonnancement manuel (boutons monter/descendre → `sort_order`).
- [x] **IMG-06** Statut publié/masqué + suppression unitaire (purge des dérivés).
- [x] **IMG-07** Définir une image comme couverture (sélecteur dans l'édition de galerie).
- [x] **IMG-08** Validation d'upload (`finfo`, taille 30 Mo, renommage normalisé, original en dossier privé).
- [x] **IMG-09** `.user.ini` (30 Mo) ajouté — *appliqué par Apache ; à confirmer côté hébergeur*.
- [~] **IMG-10** EXIF : **orientation corrigée** ; **conservation EXIF + écriture auteur** (`image_author`) restent à faire (GD ré-encode sans EXIF) (D-22).
- [ ] **IMG-11** Écran admin **profils d'image** (les 4 profils sont en base et appliqués ; **UI d'édition à faire**) (D-26).
- [x] **IMG-12** **WebP** généré par profil + `<picture>` (repli JPEG) côté public — vérifié (D-26).

### CMS — page d'accueil & paramètres
- [x] **HOME-01** Édition de la page d'accueil (texte HTML **TinyMCE** + SEO) via le module Pages générique.
- [x] **SET-01** Paramètres du site (`site_title`, `tagline`, `default_lang`, `image_author`, contact, menu, galeries) — *upload du logo à venir*.
- [x] **SET-02** Paramètre **langue par défaut** `default_lang` (fr/en) éditable (D-25).
- [~] **I18N-01** `lang` piloté par `default_lang` (éditable) ✓ ; **extraction des chaînes d'UI** (traduisibles) restant à faire (D-25).

### CMS — page Mentions légales *(exigence client, D-16)*
- [x] **LEGAL-01** Page **Mentions légales** (`pages`, slug `mentions-legales`) : champ HTML éditable (TinyMCE).
- [x] **LEGAL-02** Activation via statut publié/masqué + **lien en pied de page** si publiée ; **404** sinon — vérifié.
- [x] **LEGAL-03** `noindex` par défaut (modifiable) ; balise `<meta robots>` émise.

### Éditeur de contenu riche *(TinyMCE, D-18)*
- [x] **EDIT-01** **TinyMCE** intégré — barre minimale : styles (Normal, H1–H3), **gras**, *italique*, exposant, listes, lien. *(servi via jsDelivr ; à auto-héberger au déploiement, D-18)*
- [x] **EDIT-02** **Sanitization serveur** (`App\Core\Html`, liste blanche + drop des balises dangereuses) — anti-XSS **vérifié** (Q-03).

## P2 — Contact, SEO, migration de contenu (avant prod)

### Contact
- [x] **CON-01** Bascule activable/désactivable (`settings.contact_enabled`) — page 404 si désactivé.
- [x] **CON-02** Formulaire public (nom, email, message) + validation serveur + CSRF.
- [x] **CON-03** Anti-abus : honeypot + horodatage + limitation de fréquence ; **reCAPTCHA** actif si clés présentes (D-21).
- [x] **CON-04** Envoi via **PHPMailer** (vendored, SMTP depuis `config/local.php`) — *clés SMTP à renseigner en prod* (D-20).
- [x] **CON-05** Journalisation des messages en base (`contact_messages`) — vérifié.

### SEO
- [x] **SEO-01** Champs SEO par galerie et par page (`seo_title`, `seo_description`, `noindex`) éditables.
- [x] **SEO-02** `<title>`/`<meta>`/H1 + `<meta robots>` **uniques par page** (galeries, pages, accueil).
- [x] **SEO-03** Attribut `lang` piloté par `default_lang` (l'ancien était `lang="en"` en dur) (D-25).
- [x] **SEO-04** `sitemap.xml` dynamique (accueil + galeries/pages publiés non `noindex`) — vérifié.
- [x] **SEO-05** `robots.txt` dynamique (`Disallow: /admin` + `Sitemap:`) — vérifié.
- [~] **SEO-06** Slugs **contrôlés par l'admin** (galeries/pages) ; reprise des slugs *legacy* à la migration de contenu.
- [x] **SEO-07** **Redirections** admin (301/302/410) appliquées par le routeur — vérifié ; ajouter `/info.php`, `/update.php` au déploiement.
- [x] **SEO-08** Balises **Open Graph** de base (type, site_name, title, url, description).

### Migration de contenu (script dédié)
- [ ] **MIG-01** Script de migration : dossiers `image_in/` → galeries, fichiers → images.
- [ ] **MIG-02** Dériver le nom depuis `goodname` (après `##`) ; **nettoyer** noms vides, simple `#`, doublons de préfixe.
- [ ] **MIG-03** Réimporter les **originaux** `image_in/` (qualité) plutôt que les dérivés `img/`.
- [ ] **MIG-04** Reprendre `image_in/text.txt` → page d'accueil (bio FR/EN + contact).
- [ ] **MIG-05** Filtrer le bruit (`Thumbs.db`, `.ftpquota`).
- [ ] **MIG-06** Vérification manuelle de l'ordre et des couvertures par galerie.

## P3 — Performance & améliorations

- [x] **PERF-01** Sortie **WebP** par profil (D-26) + `loading="lazy"` + `<picture>` (repli JPEG) — réalisé.
- [ ] **PERF-02** En-têtes de cache (`mod_expires`) repris/adaptés.
- [ ] **PERF-03** Modernisation front : alléger/retirer jQuery, lightbox moderne (sans casser le rendu).
- [ ] **PERF-04** Optimisation des images à l'upload (qualité/dimensions raisonnables).
- [ ] **A11Y-01** Accessibilité de base (contrastes, `alt`, focus visibles, navigation clavier).
- [ ] **OPS-01** (Option) Journal d'activité admin.
- [ ] **OPS-02** (Option) Sauvegarde/export simple du contenu.
- [ ] **TAG-01** (**En attente / stand-by**, D-23) Tags de galeries (`tags` + `gallery_tags`) — uniquement si un regroupement devient nécessaire.
- [ ] **TAG-02** (**En attente**) Filtrage/affichage public des galeries par tag.

## Recette finale (avant mise en production)
- [ ] **QA-01** Tests desktop + mobile (menus, galeries, lightbox, contact).
- [ ] **QA-02** Revue sécurité (uploads, CSRF, sessions, secrets hors dépôt, suppression endpoints debug).
- [ ] **QA-03** Tests sur MySQL 8 **et** MariaDB 10.11.
- [ ] **QA-04** Vérification SEO (titres, sitemap, robots, redirections, HTTPS, non-www→www).
- [ ] **QA-05** Validation fidélité visuelle vs production.
