# #14 — Créer et rattacher les formulaires 2027 par migration

> Statut : 🟡 **Lot 1 — partiellement fait** · rattachements ✅ faits et testés en local (migration `0.5`) · reste la création des formulaires en production

**Formulaires :** les 10 formulaires de l'édition 2027 · **Charge :** M
**Prérequis :** aucun — c'est la migration qui doit passer en premier en production

## Objectif

Reproduire en production, de façon programmatique et rejouable, ce qui a été fait manuellement en
local : créer les formulaires de l'édition 2027 à partir de ceux de 2026.

C'est le premier usage réel du mécanisme de migration décrit dans [CLAUDE.md](../CLAUDE.md), et un
bon banc d'essai : l'opération est autonome, vérifiable, et sans effet sur les données existantes.

## ⚠️ La duplication manuelle est incomplète

**Aucun des 10 formulaires 2027 n'est rattaché à une rubrique ni à un article**, alors que tous
leurs équivalents 2026 le sont. `action/dupliquer_formulaire.php` ne copie que les colonnes de
`spip_formulaires` — il ignore complètement la table `spip_formulaires_liens`.

Ce n'est pas un détail cosmétique. [set_dossier_step.html:3-8](../squelettes/inclure/set_dossier_step.html#L3-L8)
détermine l'étape courante du dossier ainsi :

```
<BOUCLE_dossier_rubriques_statuts(RUBRIQUES) {id_parent=12}{0,6}{par num titre}>
  <BOUCLE_dossier_rubriques_statuts_formulaire(FORMULAIRES) {id_rubrique}>
    <BOUCLE_..._reponse(FORMULAIRES_REPONSES formulaires) {id_formulaire}{id_auteur=…}>
      #SET{#IDENTIFIANT, oui}
```

Le fichier teste ensuite `#GET{catalogue_visiteurs_2027}`, `#GET{offres_stands_exposants_2027}`,
etc. Comme les rubriques ne portent que les formulaires **2026**, ces variables ne passeront jamais
à `oui` : **le dossier ne pourra jamais être marqué comme complet**, et l'exposant restera bloqué à
l'étape 1.

Deux modes d'accès coexistent dans le site, ce qui explique que le défaut soit passé inaperçu :

- **par identifiant** — `#FORMULAIRE_FORMIDABLE{demande_acces_2027}`, boucles `{identifiant=…}` :
  fonctionne sans rattachement ;
- **par rubrique** — la boucle ci-dessus, et l'affichage des formulaires dans les rubriques du
  dossier : exige le rattachement.

## Faisabilité : oui

Les définitions représentent **91 Ko au total** pour les 10 formulaires (`saisies` +
`traitements`). Deux approches possibles.

### Option A — Rejouer la duplication depuis les formulaires 2026 de production

La migration lit les formulaires 2026 **en production** et les duplique.

- ✅ Peu de code, aucun gros artefact dans le dépôt.
- ❌ Le résultat dépend de l'état de la production au moment de l'exécution. Si les formulaires 2026
  y ont été retouchés depuis le dernier dump, les 2027 obtenus ne seront **pas** ceux testés en
  local.

### Option B — Embarquer les définitions 2027 dans le plugin (recommandée)

Exporter les 10 définitions locales en fichiers YAML versionnés dans
`plugins/reuseeconomyexpo/migrations/2027/`, et les importer depuis la migration.

- ✅ Déterministe : la production reçoit exactement ce qui a été testé en local.
- ✅ Les définitions sont dans Git, donc relisibles et comparables d'une édition à l'autre.
- ✅ Cohérent avec le principe posé dans CLAUDE.md : « ce qui a été testé en local est ce qui tourne
  en production ».
- ❌ 91 Ko d'artefacts dans le dépôt — négligeable.

**Recommandation : option B**, avec un contrôle préalable qui compare les formulaires 2026 de
production à ceux dont les copies 2027 sont issues, et **interrompt la migration en cas d'écart**
plutôt que de produire silencieusement un état divergent.

⚠️ Ne pas utiliser l'import YAML natif de Formidable : il crée systématiquement un nouveau
formulaire et suffixe l'identifiant s'il existe déjà (voir CLAUDE.md). Écrire l'insertion dans la
migration.

## Rattachement aux rubriques — ✅ fait

Les rubriques ne sont **pas millésimées** : ce sont des rubriques de structure, permanentes d'une
édition à l'autre. Seul le formulaire qui y est rattaché change. La migration doit donc, pour
chaque formulaire, **rattacher le 2027 puis détacher le 2026**.

**Réalisé** par la migration `0.5` (`reex_maj_0_5_rattacher_formulaires_2027()`), appuyée sur le
helper `reex_formulaire_transferer_liens()`. Exécutée en local le 12/08/2026 :
**22 rattachements transférés**, rejeu vérifié sans effet. Elle partira en production avec le reste
du plugin.

Mapping relevé sur l'édition 2026 et reproduit à l'identique :

| Formulaire | Rattachements (objet / id / intitulé) |
| --- | --- |
| `catalogue_visiteurs` | rubrique 8 *(2. Informations pour les visiteurs)* · rubrique 61 *(Catalogue visiteurs)* · rubrique 133 *(Visitor catalog)* · rubrique 142 *(2. Visitors catalog informations)* · article 85 · article 201 |
| `offres_stands_exposants` | rubrique 4 *(3. Sélectionnez votre stand…)* · rubrique 140 *(3. Stand and equipments)* |
| `offres_stands_coexposants` | rubrique 163 *(3. …stand en co-exposition)* |
| `offres_complementaires` | rubrique 5 *(4. Offres complémentaires)* · rubrique 141 *(4. Complementary offers)* |
| `demande_inscription` | rubrique 7 *(2. Envoi du dossier)* |
| `validation_contrat` | rubrique 9 *(4. Validation du contrat et des CGV)* |
| `coexposition` | rubrique 6 *(Co-exposants)* |
| `informations_logistiques` | rubrique 23 *(Informations logistiques)* · rubrique 132 *(Logistic informations)* · article 199 |
| `attestation_responsabilite_civile` | rubrique 22 · rubrique 131 *(Certificate of civil liability)* · articles 22, 26, 196 |
| `demande_acces` | **aucun** — accédé par identifiant uniquement |

`inscription_trophees_vrac` est **hors périmètre** de ce ticket.

## ⚠️ Décision à prendre : le parcours anglais du contrat

Le relevé fait apparaître une anomalie qui n'a rien à voir avec la duplication, mais qu'il faut
trancher avant d'écrire le mapping :

| Formulaire 2026 | Rubriques rattachées |
| --- | --- |
| `validation_contrat_2026` *(celui que le code utilise)* | 9 — *4. Validation du contrat et des CGV* **(FR)** |
| `validation_contract_2026` *(le doublon avec la coquille)* | 14 — *5. Paiement* **(FR)** · 137 — *4. Terms validation* **(EN)** · 144 — *5. Payment* **(EN)** |

Autrement dit, **le parcours anglais et la page de paiement française sont servis par le formulaire
à la coquille**, alors que les squelettes référencent `validation_contrat_<N>`. Les deux
formulaires cohabitent depuis au moins l'édition 2026.

Pour 2027, il n'existe qu'un seul formulaire (`validation_contrat_2027`, celui créé après
correction). Trois questions :

1. Rattache-t-on `validation_contrat_2027` aux **quatre** rubriques (9, 14, 137, 144), unifiant les
   parcours FR et EN ? C'est l'option cohérente, mais elle change le comportement du parcours
   anglais.
2. Les rubriques 14 et 144 sont des pages de **paiement** — un formulaire de validation de contrat
   y a-t-il sa place, ou s'agit-il d'un reliquat ?
3. Confirmer que les deux formulaires 2026 étaient bien redondants, et non deux étapes distinctes.

## Exigences de la migration

- **Idempotente** : si un formulaire 2027 existe déjà, ne rien faire — ni doublon, ni écrasement.
  Même chose pour les liens.
- **Ne pas répliquer les orphelins** : `validation_contract_2027` (statut `poubelle`),
  `catalogue_visiteurs_1766569284`, `informations_logistiques_2026_1766568797`,
  `attestation_responsabilite_civile_2026_1766567885` ne doivent pas partir en production.
- **Statuts** : les 2027 en `publie`, les 2026 basculés en `refuse` — c'est la convention
  d'archivage du site (les réponses restent consultables). À faire dans la même migration que le
  détachement, pour éviter un état intermédiaire où les deux éditions sont actives.
- **`inscription_trophees_vrac_2027` est hors périmètre.** Il y aura bien des Trophées en 2027, mais
  le sujet est traité séparément — voir la note de dette dans [CLAUDE.md](../CLAUDE.md).
- Journaliser chaque création et chaque rattachement dans `tmp/log/reex.log`.

## Critères d'acceptation

- Les 10 formulaires 2027 existent en production, en `publie`, avec des définitions identiques à
  celles validées en local.
- Chaque rubrique et chaque article du tableau ci-dessus pointe vers le formulaire 2027, et plus
  vers le 2026.
- Les formulaires 2026 sont en `refuse` et leurs réponses restent consultables.
- `set_dossier_step.html` calcule correctement l'étape d'un dossier 2027 — vérification par un
  parcours complet en local avant déploiement.
- Rejouer la migration ne produit aucun changement.
