# ⚠️ NOTE PÉRIMÉE — ne pas suivre les recommandations ci-dessous

Une session Claude Code parallèle (commits `9123ca8`, `c6ad62f`, `525d0a6`, entre 20:56 et
21:48 le même jour) a déjà branché tout ce que cette note recommandait de faire différemment
— en mieux, et sans les erreurs ci-dessous. État réel actuel, vérifié dans le code :

- **`checklist_json` EST le mécanisme retenu et lu** (`api/cards.php` l.234), pas abandonné.
  `renseignements.fields` reste un **repli legacy** pour les cartes pas encore migrées
  (`action-detail.js` l.190-202) — donc **ne pas supprimer `checklist_json`**, ordre inverse
  de ce que je recommandais plus bas.
- **`mesure.questions` a sa propre table dédiée** : `card_guide_mesure_questions` (migration
  `2026_07_06_029`), pas une extension de `card_guide_indicateurs` (celle-ci est gardée telle
  quelle pour compat ascendante, non touchée).
- **`action_impact_schedule` existe**, `action-impact.js` lit dynamiquement les métriques par
  carte (plus de `METRIC = 'contacts'` en dur) — `actions.impact_next_at` a même été
  supprimée proprement (plus lue nulle part).
- **`objectif_label` / `objectif_metric_principale`** ajoutés sur `card_guide`.

Donc : `PROMPT_redaction_cartes.md` peut être utilisé tel quel pour la rédaction en masse. Le
seul point à corriger dedans : C-003 n'a **pas** été migré vers `checklist` — il tourne encore
sur le repli `renseignements.fields`, contrairement à ce que le prompt affirme.

Je laisse le reste de cette note ci-dessous pour trace, mais aucune de ses actions proposées
ne doit être exécutée.

---



## Pourquoi cette note
`PROMPT_redaction_cartes.md` (prompt de rédaction de contenu) décrit un schéma cible
(`checklist`, `objectif`, `mesure.questions`) cohérent avec ce qui a été discuté avec Mr
Fauquant, mais **deux vérifications dans le code réel montrent que rien de tout ça n'est
branché**, et qu'une partie a même divergé (une session du 6 juillet a ajouté du contenu
directement dans `data/card_guides/*.json`, à l'encontre de la consigne "tout en BDD").

Avant de rédiger les 122 cartes restantes avec ce prompt, il faut trancher et coder ce qui
suit — sinon le contenu produit ne s'affichera nulle part.

## 1. Checklist : ne pas créer un mécanisme parallèle — étendre l'existant

**Constat** : `action-detail.js` (ligne 189) lit `card.guide.renseignements.fields`, pas un
champ `checklist`. Le `checklist_json` que j'ai ajouté par migration (`sql/2026_07_06_030`)
n'est lu par aucun code. C-003 a déjà 4 items (booléens) dans `renseignements.fields` — donc
un mécanisme fonctionne déjà, juste pas celui qu'on a nommé "checklist" dans nos échanges.

**Décision proposée** : ne pas maintenir deux colonnes JSON qui font la même chose
(`renseignements_json` et `checklist_json` sont toutes les deux du TEXT libre sur
`card_guide` — redondant). On garde **une seule colonne, `renseignements_json`**, et on
enrichit le schéma de chaque item avec des clés optionnelles :

```json
{
  "id": "chk2",
  "type": "boolean",
  "label": "Observer et noter ce qui se passe",
  "detail": "texte long optionnel, affiché via un « en savoir plus »",
  "requires_proof": false,
  "printable_worksheet": true,
  "worksheet_section": "observation"
}
```

Aucune migration de schéma nécessaire pour ça (`renseignements_json` est déjà du TEXT libre).
Ce qui manque, c'est le **code front** pour exploiter ces nouvelles clés :
- `detail` : actuellement invisible. Ajouter un toggle "En savoir plus" sous le label.
- `requires_proof` : actuellement, l'upload photo/document est proposé pour **tous** les
  items sans distinction (`action-detail.js` ligne 216). Décision à prendre : garder ce
  comportement (simple, déjà en prod) et traiter `requires_proof` comme un signal visuel
  seulement (item mis en avant), ou vraiment conditionner l'affichage de l'upload à ce flag.
  Je recommande la première option — moins de risque de régression sur ce qui marche déjà.
- `printable_worksheet` + `worksheet_section` : ajouter un bouton "Imprimer la fiche" vers
  `GET /api/cards/{id}/worksheet.pdf` (cf. `NOTE_generation_dynamique_worksheet.md`).

**Action requise** :
1. Migration : `ALTER TABLE card_guide DROP COLUMN checklist_json;` (colonne créée le 6
   juillet, jamais lue, aucune donnée réelle dessus — sans risque de la supprimer).
2. SQL de contenu : réécrire l'UPDATE de C-006 pour écrire dans `renseignements_json` au lieu
   de `checklist_json` (fourni ci-dessous, prêt à l'emploi).
3. Corriger `PROMPT_redaction_cartes.md` : remplacer partout "`checklist`" par
   "`renseignements.fields` (item enrichi)" et supprimer la mention "C-003 a déjà été migré"
   (c'est faux — ses 4 items sont dans `renseignements.fields` depuis le début, jamais dans
   un champ séparé).

## 2. Mesure : étendre `card_guide_indicateurs`, pas un nouveau blob JSON

**Constat** : le mécanisme de mesure existant est déjà une **table dédiée**
(`card_guide_indicateurs` : `card_id`, `indicateur_ref`, `label`, `objectif`,
`comment_mesurer`), pas un blob JSON. C'est le bon pattern (cohérent avec la table
`action_impact_schedule` déjà actée) — on l'étend plutôt que d'introduire
`mesure.questions` comme structure JSON séparée.

**Constat additionnel, plus bloquant** : `action-impact.js` ligne 14 a la métrique **codée en
dur** :
```js
const METRIC = 'contacts'; // clé de mesure par défaut (adaptable par carte)
```
Aucune carte ne peut avoir une métrique différente de `'contacts'` aujourd'hui, quelle que
soit la donnée en base. C'est le vrai bloquant avant toute rédaction de contenu `mesure` —
écrire du contenu pour des métriques que le front ignore ne sert à rien.

**Migration proposée** (étend la table existante) :

```sql
-- #migration 2026_07_06_032
ALTER TABLE card_guide_indicateurs
  MODIFY COLUMN indicateur_ref VARCHAR(40) NOT NULL, -- était VARCHAR(10) ("M1"), trop court
                                                        -- pour des clés type "contacts_email"
  ADD COLUMN type              VARCHAR(20) NOT NULL DEFAULT 'number', -- number | boolean | select
  ADD COLUMN options_json      TEXT        NULL,       -- si type = select
  ADD COLUMN unit              VARCHAR(20) NULL,
  ADD COLUMN cadence_jours     INT         NOT NULL DEFAULT 7,
  ADD COLUMN depends_on_metric VARCHAR(40) NULL;       -- indicateur_ref d'une question booléenne
```

`indicateur_ref` devient la clé `metric` de nos échanges (ex. `contacts_email`,
`rentabilite`). Une fois cette migration jouée, `import-catalogue.php` (ligne ~259, INSERT
dans `card_guide_indicateurs`) doit aussi écrire ces nouvelles colonnes quand elles sont
présentes dans le JSON — mais comme on est censés arrêter le flux JSON pour le contenu, ce
sera surtout renseigné par SQL direct carte par carte, comme pour C-006.

**Côté front, à réécrire** :
- `action-impact.js` : remplacer `const METRIC = 'contacts'` par une lecture dynamique de la
  liste des indicateurs de la carte (déjà exposée par `api/cards.php` dans
  `guide.mesure.indicateurs`, juste étendre la requête SQL ligne 170 pour aussi sélectionner
  `type, options_json, unit, cadence_jours, depends_on_metric`).
- Gérer plusieurs indicateurs par carte, avec cadence propre à chacun, et l'affichage
  conditionnel pour `depends_on_metric` (ne poser une question que si la question booléenne
  dont elle dépend a répondu "oui" ce cycle).
- Brancher la table `action_impact_schedule` (déjà actée, cf. décision précédente) pour le
  calcul de la prochaine échéance par (action, métrique) à partir de `cadence_jours`.

## 3. Objectif : nouveau, petit, sans mécanisme existant à réutiliser

Aucun équivalent aujourd'hui. Ajout simple :

```sql
-- #migration 2026_07_06_033
ALTER TABLE card_guide
  ADD COLUMN objectif_label            VARCHAR(200) NULL,
  ADD COLUMN objectif_metric_principale VARCHAR(40) NULL; -- doit correspondre à un
                                                            -- indicateur_ref existant pour la carte
```
Affichage : nouveau bloc en haut de `action-detail.js`, pas de dépendance à autre chose.

## 4. Contenu C-006 corrigé (renseignements_json au lieu de checklist_json)

```sql
UPDATE card_guide
SET renseignements_json = '{
  "fields": [
    {
      "id": "chk1",
      "type": "boolean",
      "label": "Préparer ton stand pour collecter des contacts",
      "detail": "Chaque marché doit générer des contacts, pas seulement des ventes. Un carnet de signatures pour les nouveautés, un QR code vers ta newsletter, une carte à glisser dans chaque sac. Objectif : repartir avec 10 emails minimum même si les ventes sont décevantes.",
      "requires_proof": false,
      "printable_worksheet": false
    },
    {
      "id": "chk2",
      "type": "boolean",
      "label": "Observer et noter ce qui se passe",
      "detail": "Quelles pièces attirent d'abord le regard ? Quelles questions reviennent ? Qu'est-ce qui fait décrocher les gens après avoir touché une pièce ? Ces observations guident ton offre et ta communication bien mieux que tes suppositions.",
      "requires_proof": false,
      "printable_worksheet": true,
      "worksheet_section": "observation"
    },
    {
      "id": "chk3",
      "type": "boolean",
      "label": "Faire un bilan chiffré après chaque marché",
      "detail": "CA total, nombre de clients, panier moyen, coût du stand + transport + temps. Calcule ta rentabilité réelle. Certains marchés ont l'air animés mais ne couvrent pas leurs coûts — d'autres sont discrets mais très rentables.",
      "requires_proof": true,
      "printable_worksheet": true,
      "worksheet_section": "bilan"
    }
  ]
}'
WHERE card_id = 'C-006';
```

## 5. Ordre de traitement recommandé pour Claude Code
1. Migration §1 (drop `checklist_json`) + §4 (contenu C-006 dans `renseignements_json`)
2. Migration §2 (étendre `card_guide_indicateurs`) + réécriture `action-impact.js` (metric
   dynamique) — **c'est le vrai préalable** avant de rédiger `mesure.questions` sur d'autres
   cartes, sinon ce sera à refaire.
3. Migration §3 (`objectif`) + petit ajout d'affichage
4. Petits ajouts front pour `detail` (toggle) et `printable_worksheet` (bouton d'impression)
5. Seulement après ces 4 étapes : reprendre `PROMPT_redaction_cartes.md` (corrigé, cf. §1)
   pour la rédaction en masse, carte par carte.
