---
title: "Restitutions — Cahier de recette (tests manuels)"
module: isi-nova
type: functional
status: active
updated: 2026-07-20
---

# Restitutions — Cahier de recette (tests manuels)

Plan de test manuel du module **Restitutions** (ISI Nova). À dérouler dans le
navigateur, étape par étape. Chaque case `[ ]` est un point à valider.

> Doc liée : `docs/isi-nova/restitutions.md` (fonctionnel) ·
> `.claude/technical-docs/isi-nova/restitutions.md` (technique).

---

## 0. Prérequis

### Compte de test
- [ ] Être connecté avec un utilisateur du **tenant ISI-Groupe**
  (`session('user.info._id') === 1`). ⚠️ Tout autre tenant → **403** sur tout le module.
- [ ] Cet utilisateur a au moins le droit **R** sur le module Core Model `50040101`
  (et **C/U/D** pour créer / éditer / supprimer).
- [ ] Au moins un **client** existe dans ISI-Groupe, idéalement avec son **Core Model
  renseigné** (pour une génération IA riche à l'étape Génération).

### Fichiers modèles à uploader
Générés dans `storage/app/restitution-samples/` (récupère-les depuis le serveur) :

| Fichier | Sert à tester |
|---|---|
| `01-modele-word-avec-titres.docx` | Parsing **structurel** Word (chaque Heading = 1 section) |
| `02-modele-word-avec-marqueurs.docx` | Détection des marqueurs `[ISI_PRATIQUE]` / `[ITIL_PRATIQUE]` |
| `03-modele-word-sans-titres-fallback-ia.docx` | **Fallback IA** (document sans Heading → découpage par IA) |
| `04-modele-powerpoint.pptx` | Parsing **slides** + rendu livrable .pptx (châssis OOXML complet) |

> Régénérer si besoin :
> `php artisan tinker` puis appeler `Tests\Fixtures\Restitution\TemplateFixtures::*`.

### Environnement
- [ ] Workers de queue `ai-fills` actifs (`php artisan queue:work --queue=ai-fills`)
  pour les étapes IA (mapping, génération, rendu automatique du livrable). Sinon les
  jobs restent en attente.
- [ ] Quota IA tenant suffisant (les appels IA sont facturés au tenant ISI-Groupe).

---

## 1. Accès & contrôle d'accès (ACL)

| Cas | Action | Résultat attendu |
|---|---|---|
| Tenant non ISI-Groupe | Visiter `/param-dsi/core-model/admin/restitutions` | **403 / Accès Refusé** |
| ISI-Groupe sans droit U | Ouvrir la liste | Liste visible **sans** bouton « Créer une Restitution » ni boutons d'édition |
| ISI-Groupe avec droits | Ouvrir la liste | Liste + boutons d'action visibles |

- [ ] Les 3 cas ci-dessus se comportent comme attendu.
- [ ] **Liste vide, aucun filtre** : empty state « Aucune Restitution » + CTA « Créer une Restitution ».
- [ ] **Liste filtrée sans résultat** : message « Aucun résultat avec ces filtres ».

---

## 2. Étape 1 — Créer une Restitution + uploader des documents

- [ ] Cliquer « Créer une Restitution » (liste) ou, depuis Suivi clients,
  ouvrir la modale « Restitutions » du client puis cliquer « Nouvelle
  Restitution » (`_idclient` pré-rempli et masqué dans ce cas).
- [ ] **Validation** : enregistrer en laissant le **client cible vide** (cas liste)
  → message « Le client est obligatoire » (PAS d'erreur 500).
- [ ] Remplir Titre + Client cible (si non pré-rempli) + Date du diagnostic
  (+ Contexte optionnel) → **Enregistrer** → redirection vers l'onglet
  **Documents** de l'écran d'édition, toast « Restitution créée ».
- [ ] **Plusieurs Restitutions par client** : créer une 2e Restitution pour un
  client qui en a déjà une → aucune erreur, les deux coexistent et apparaissent
  toutes les deux dans la modale « Restitutions » du client (Suivi clients).
- [ ] Rouvrir la Restitution en édition, onglet **Infos** → le champ client
  n'est **pas modifiable** (immuable après création).

### Upload de templates (onglet Documents)
- [ ] Uploader `01-modele-word-avec-titres.docx` → toast « Template ajouté
  (N sections détectées) », N = nombre de Headings ; la ligne apparaît dans le
  tableau avec le badge **« Mapping requis »**.
- [ ] Uploader `04-modele-powerpoint.pptx` → sections = nombre de slides.
- [ ] Uploader `03-modele-word-sans-titres-fallback-ia.docx` → le **fallback IA**
  se déclenche de façon transparente, des sections sont quand même créées.
- [ ] Uploader `02-modele-word-avec-marqueurs.docx` → les sections contenant
  `[ISI_PRATIQUE]` / `[ITIL_PRATIQUE]` sont marquées (visible en étape Génération).
- [ ] **Cas d'échec** : uploader un fichier non `.docx/.pptx` ou > 20 Mo → rejet + message.
- [ ] Supprimer un template (bouton corbeille de la ligne, confirm dialog) → le
  fichier, ses sections **et** son éventuel livrable disparaissent.

---

## 3. Étape 2 — Le wizard de génération (mapping → génération)

### Action de ligne « Générer »
- [ ] Sur un document dont le mapping n'est pas validé, cliquer « Générer »
  → le **wizard s'ouvre en modale**, démarrant à l'étape **Mapping**.
- [ ] Sur un document déjà mappé mais pas encore généré, cliquer « Générer »
  → le wizard s'ouvre **directement** à l'étape **Génération** (pas de repassage
  par le mapping).
- [ ] Sur un document déjà généré (sections en attente de révision), cliquer
  « Générer » → **le wizard est sauté**, l'écran de révision s'ouvre directement.
- [ ] Sur un document déjà finalisé (livrable prêt), l'action de ligne est
  **« Télécharger »**, pas « Générer ».

### Étape Mapping (dans le wizard)
- [ ] « Proposer le mapping » → l'IA propose une dimension par section + score de
  confiance (vert / amber / rouge) + justification au clic sur le badge.
- [ ] Corriger une dimension via le sélecteur d'une ligne.
- [ ] Bouton « Valider le mapping » **désactivé** tant qu'une section n'a pas de
  dimension assignée.
- [ ] « Valider le mapping » → toutes les sections passent validées, le wizard
  passe au **document suivant** (si action groupée sur plusieurs documents non
  mappés, indicateur « Document X sur N ») ou à l'étape **Génération**.
- [ ] Re-lancer « Proposer le mapping » sur un template déjà mappé → **confirm
  dialog** (la nouvelle proposition écrase les corrections existantes).

### Étape Génération (dans le wizard)
- [ ] « Lancer la génération » → traitement en arrière-plan ; la modale affiche
  une barre de progression qui se rafraîchit automatiquement (~3 s).
- [ ] Fermer le wizard pendant que la génération tourne, puis rouvrir « Générer »
  sur le même document → le wizard réévalue l'état réel (reprend à l'étape
  Génération si toujours en cours, ou affiche directement « Voir les résultats »
  si terminé entretemps — rien n'est perdu).
- [ ] **Verrouillage** : tenter de lancer une seconde génération pendant qu'une
  autre est en cours (sur la même Restitution) → message d'attente, pas de
  double lancement.
- [ ] **Reprise après échec** : si des sections sont en échec, relancer ne
  retraite que les sections pending/failed (les générées sont conservées).
- [ ] Génération terminée → bouton **« Voir les résultats »** apparaît ; cliquer
  dessus ouvre l'écran de révision (remplace le wizard, pas d'empilement de modales).

### Action groupée
- [ ] Sélectionner plusieurs documents à des stades différents (checkbox) →
  « Générer la sélection » : seuls ceux qui ont encore besoin de mapping ou de
  génération sont traités ; les documents déjà finalisés gardent leur action
  « Télécharger » et sont ignorés par ce lancement.

---

## 4. Étape 3 — Réviser et valider le contenu (Document Reviewer)

- [ ] Vue 2 colonnes : sommaire (gauche, un ou plusieurs documents selon
  l'origine — ligne ou action groupée) + détail section (droite), badges de
  statut (bleu généré / vert validé / rouge échec / amber en cours).
- [ ] **Modifier** une section (éditeur WYSIWYG) → sauvegarde → marquée « Éditée ».
- [ ] **Régénérer** une section (avec consigne optionnelle) → régénération en
  arrière-plan ; si la section était éditée manuellement, **confirmation** avant
  écrasement.
- [ ] **Valider** une section → figée (non modifiable tant que non dé-validée).
- [ ] Section en **échec** → « Relancer cette section ».
- [ ] **« Valider toutes »** → valide en bloc les sections « Générée » (confirm avant).
- [ ] Bouton **« Fermer »** du header modal → ferme sans forcer de validation.
- [ ] Depuis la liste des documents, retour sur l'onglet Documents → le badge
  « à valider » de l'onglet s'est mis à jour.

---

## 5. Étape 4 — Livrable automatique

- [ ] Dès que **toutes** les sections d'un document sont validées (validation
  individuelle ou « Valider toutes »), **sans action manuelle**, le badge de la
  ligne passe à « Livrable en cours » puis à un bouton **« Télécharger »**
  (quelques secondes, le temps que `RenderDeliverableJob` s'exécute).
- [ ] **Télécharger** → le fichier .docx/.pptx se télécharge ; il **réutilise la
  charte du template uploadé** (styles, en-têtes/pieds, slideMaster) avec le
  contenu IA.
- [ ] **.pptx — identité visuelle du modèle restituée** : ouvrir le livrable .pptx
  généré et vérifier que la **mise en forme des slides de contenu** du modèle est
  reprise (couleurs/polices du titre et du corps, bandeaux/formes décoratives) — le
  rendu clone une vraie slide de contenu et n'en remplace que le texte. ⚠️ Vérifier
  aussi qu'**aucun texte de guidage** du modèle (ex. « Points clés attendus », puces
  d'exemple, pied « x/N ») ne « fuit » sur les slides générées. Éléments non repris
  (attendu) : numéro de section, sous-titre par slide, pied de page authored. Un rendu
  « tout blanc / générique » = repli (le modèle n'a aucune slide de contenu exploitable).
- [ ] Bouton « Uploader un livrable » (icône dédiée sur la ligne) → modale
  d'upload manuel de secours → badge « Uploadé » après envoi.
- [ ] **Point d'attention** : dévalider une section d'un document déjà finalisé,
  la recorriger, puis la revalider → le livrable **n'est pas régénéré tant que
  toutes les sections ne repassent pas validées** (comportement volontaire, pas
  un bug).

> ⚠️ **Limitations MVP attendues (ce ne sont PAS des bugs)** :
> - images du `.pptx` → remplacées par « [Image: nom_du_fichier] » dans le rendu .pptx ;
> - sections en échec → « [Section non disponible — à compléter manuellement] » ;
> - rendu `.docx` lossy (SmartArt/macros/champs avancés peuvent être perdus) ;
> - pas d'historique des livrables (re-upload = écrasement).

---

## 5bis. Réactivité UI sans rechargement — points sensibles ⚠️

> **Section critique — validation manuelle OBLIGATOIRE.** Ces comportements
> reposent sur la réactivité client (store Alpine, morphing DOM Livewire,
> `wire:key`, polling) et **ne sont couverts par aucun test automatisé** (ni
> PHPUnit — rendu serveur seulement — ni Dusk — bloqué hors ISI-Groupe). C'est
> ici que sont apparues des régressions passées. À dérouler **sans jamais
> rafraîchir la page (F5)** : tout le sel du test est là.

- [ ] **Bouton « Générer un livrable » après ajout d'un modèle** : onglet Livrables
  vide (aucun modèle) → le bouton est désactivé (« Ajoutez d'abord un modèle »).
  Ajouter un modèle dans l'onglet **Modèles**, revenir à **Livrables** **sans F5**
  → le bouton **« Générer un livrable » / « Générer tout » devient actif**.
- [ ] **« Reprendre la révision (N) »** : après une génération produisant des
  sections à réviser, le bouton **apparaît sans rechargement** avec le bon compteur
  (y compris après une génération partiellement en échec).
- [ ] **Badges d'onglets (Modèles / Livrables)** : se réactualisent sans F5 à
  l'ajout/suppression d'un modèle ou d'un livrable.
- [ ] **Bouton « Valider » après dévalidation** (révision) : sur une section
  **Validée**, cliquer « Annuler la validation » → la section repasse **Générée** et
  le bouton **« Valider » réapparaît immédiatement** (sans F5). *(morphing DOM —
  régression historique #7).*
- [ ] **Colonnes de la révision à scroll indépendant** : faire défiler le
  **sommaire** (gauche) ne fait **pas** défiler le **détail** (droite), et
  inversement — sélectionner une section en bas du sommaire laisse le détail visible.
- [ ] **Polling de génération / rendu** : la barre de progression (wizard) et
  l'apparition d'un livrable (onglet Livrables) se mettent à jour **toutes les
  quelques secondes sans action**, et **s'arrêtent** une fois terminé.

> Dépendances **IA / queue** (pré-requis §0) — si un de ces points échoue, vérifier
> d'abord le worker `ai-fills` et le quota IA avant de conclure à un bug :
> - [ ] **Proposition de mapping (IA)** aboutit sans **erreur 400** (schéma
>   function-calling). *(régression historique #1).*
> - [ ] Après validation des sections, le **livrable se génère** et apparaît ;
>   si le fichier modèle est **inaccessible**, un **message clair** s'affiche
>   (pas d'erreur brute) et l'alerte « N livrables n'ont pas pu être générés »
>   remonte. *(régressions historiques #3/#4).*

---

## 6. Suppression d'une Restitution

- [ ] Bouton « Supprimer la Restitution » → **confirm dialog** (action irréversible).
- [ ] Après confirmation → redirection vers la liste, la Restitution n'apparaît plus.
- [ ] Vérifier (BDD) que sections, jobs, livrables **et fichiers physiques** sont supprimés
  (hard delete cascade).

---

## 7. Récapitulatif d'exécution

| Étape | Statut (OK / KO) | Remarques |
|---|---|---|
| 1. ACL | | |
| 2. Création + upload templates | | |
| 3. Wizard (mapping + génération) | | |
| 4. Révision | | |
| 5. Livrable automatique | | |
| 5bis. Réactivité UI (sans F5) ⚠️ | | |
| 6. Suppression | | |

**Bugs / anomalies relevés :**
- …
