---
suivi: 1375
date: 2026-08-31
sujet: siwi_vignette_programme_cree
chantier: reprise_siwi
type: feature
statut: poussé
hash: cf1b97bf
fichiers:
  - app/Services/SiwiImportPageService.php
  - resources/js/Pages/SiwiImport/Index.vue
  - tests/Unit/SiwiVignetteProgrammeCree1375Test.php
  - database/data/journal_mises_a_jour_post_2026_06_12.php
  - public/build/
---

## PROMPT ENVOYÉ

SUIVI #1375 — vignette `/siwi-import` : badge « Créé — {code_envol} » cliquable
(nouvel onglet) quand le programme ERP est lié. Pas de 5ᵉ filtre. Pas de N+1.
Pas de migration. Ne pas toucher bandeau / filtres / actions / AppShell.

## FICHES LUES

- **#1359** — liaison déjà visible en détail (`programme_hectarion_id` /
  `est_lie`) ; cas VILLMINE00 / AROME → programme #18.
- **#1326** — colonnes TRAVAIL `programme_hectarion_id`,
  `etat_liaison_programme` (`cree` / `rattache`) ; `SiwiOperation::estLie()`.
- **#1365** (réf. prompt) — `programmes.code_envol` existe ; `programmes.code`
  n’existe pas (confirmé migration `2026_04_23_100000` + modèle ; MySQL local
  refusé → pas de `SHOW COLUMNS` live).

## SYNTHÈSE

### Lien existant (pas de 2ᵉ mécanisme)
`siwi_operations.programme_hectarion_id` → `programmes.id` +
`etat_liaison_programme` ∈ {`cree`,`rattache`}. `estLie()` déjà utilisé au
détail (#1359). Remonté dans `serializeOperationSummary` + batch
`codeEnvolByProgrammeIds` (1× `WHERE id IN (...)`).

### Badge vignette
- Affiché si `estLie()` et `etat_programme !== non_repris`.
- Libellé : `Créé — {code_envol}` ou `Rattaché — {code_envol}` selon
  `etat_liaison_programme` (la colonne **distingue** créé / rattaché —
  même style de badge, libellé fidèle).
- Clic → `window.open(/programmes/{id}/edit, _blank)` ; `@click.stop` pour
  ne pas sélectionner la vignette. HTML : `span[role=link]` dans le
  `<button>` (pas de `<a>` imbriqué).
- Sans lien ERP : aucun badge.
- « Ne pas reprendre » : impossible si déjà lié (garde CDC D6) ; filet
  `affiche_badge_programme_erp = false` si `non_repris`.

### Perf SQL
Liste vignettes (sans sélection) :
- **AVANT** : 0 requête `programmes` pour les cartes.
- **APRÈS** : **+1** `SELECT id, code_envol FROM programmes WHERE id IN (...)`
  — **indépendant de 85**. Pas de N+1.
Détail sélectionné : +1 requête pour 1 id (hors boucle vignettes).
MySQL local indisponible → mesure structurelle + test unitaire source.

### Non touché
Bandeau avancement, 4 filtres, export CSV, actions vignette/détail,
qualification staging, compteurs, AppShell, useFormatters,
ObjectSubNavBar, #1372–#1374.

## DÉPLOIEMENT-TEST

```bash
git pull origin main
php artisan optimize:clear
php artisan view:clear
php artisan journal:sync
```

Tests manuels :
1. `/siwi-import` — vignette liée : badge « Créé — {code_envol} » (ex.
   PUISSERG00 / LE SAVIGNOL → HEC34-003 ; VILLMINE00 / AROME → code du #18).
2. Clic badge → fiche programme nouvel onglet ; SIWI reste ouvert.
3. Vignette non liée : pas de badge.
4. Bandeau + 4 filtres inchangés.

## LEÇON

Le détail montrait déjà le rattachement ; l’oubli était uniquement le
**payload liste**. Remonter `programme_hectarion_id` + `code_envol` en
batch évite 85 clics et un N+1. `etat_liaison_programme` distingue
créé/rattaché — ne pas aplatir en « Créé » si la donnée porte la nuance.
