Feature #82
closedAméliorer la génération de PDF pour les contrats avec design professionnel et signatures configurables
100%
ÉPIC découpé (PO : sous-tâche backend éclatée en 3). Génération PDF contrats pro + signatures configurables. Sous-tâches : #90 Backend moteur de rendu (police, logo, marges 2cm, schéma réglages) [socle] ; #91 Backend signatures configurables + mentions [dép. #90] ; #92 Backend numéro unique (séquence Postgres) + enregistrement/téléchargement/email après contre-signature [dép. #90] ; #93 Frontend config modèle (police/logo/emplacement) [partage le schéma #90, design requis] ; #94 Frontend avertissement balises manquantes [indépendant]. Entité Contract : html_template_id, signature_data, internal_signature_id, internal_signed_pdf_url.
Description
### Problème
Actuellement, la génération de PDF des contrats dans l'onglet "Édition de contrat" produit un rendu peu professionnel, basé sur une copie brute de l'HTML. Le design manque de cohérence (polices, marges, alignements) et les signatures ne sont pas intégrées de manière flexible ou esthétique. Cela nuit à l'image professionnelle de l'application et complique le processus de validation des contrats.
### Contexte
- Les utilisateurs sélectionnent un modèle de contrat (créé dans les paramètres avec des balises comme `{{nom_artiste}}`) et remplacent ces balises par les données de l'événement.
- Le PDF généré doit être envoyé via un formulaire sans identification pour validation et signature par le destinataire.
- Les signatures (expéditeur et destinataire) doivent être intégrées automatiquement et positionnées de manière configurable.
- Un numéro de contrat unique doit être généré et affiché dans le PDF pour faciliter le suivi.
### Comportement proposé
1. **Design du PDF** :
- Utiliser la police choisie lors de la création du modèle de contrat.
- Intégrer le logo de la structure (configurable dans les paramètres du modèle) en haut à gauche, avec une ligne de séparation.
- Appliquer des marges de 2 cm et une mise en page soignée (alignements, espacements).
2. **Signatures** :
- Permettre de choisir l'emplacement des signatures (bas à droite, bas à gauche, côte à côte) dans les paramètres du modèle.
- Intégrer automatiquement la signature de l'expéditeur (depuis les paramètres) et celle du destinataire (après signature en ligne) aux emplacements choisis.
- Ajouter des mentions sous les signatures (ex: "Signé par [Nom] le [date]").
3. **Numéro de contrat** :
- Générer un numéro unique (ex: "CONTRAT-2024-001") et l'afficher en pied de page.
- Incrémenter automatiquement ce numéro pour chaque nouveau contrat.
4. **Gestion des erreurs** :
- Afficher un message d'avertissement si une balise est manquante avant génération, avec les options "Ignorer et générer" ou "Corriger".
## Acceptance criteria
- [ ] Le PDF généré respecte la police et la mise en page définies dans le modèle de contrat.
- [ ] Le logo de la structure peut être intégré en haut à gauche du PDF (option configurable dans les paramètres du modèle).
- [ ] Les marges de 2 cm sont appliquées sur tous les côtés du PDF.
- [ ] Les signatures (expéditeur et destinataire) sont intégrées aux emplacements configurables dans les paramètres du modèle.
- [ ] Les mentions "Signé par [Nom] le [date]" sont ajoutées sous chaque signature.
- [ ] Un numéro de contrat unique est généré et affiché en pied de page du PDF.
- [ ] Le numéro de contrat est incrémenté automatiquement pour chaque nouveau contrat.
- [ ] Un message d'avertissement s'affiche si une balise est manquante avant génération, avec les options "Ignorer et générer" ou "Corriger".
- [ ] Le PDF final est enregistré dans l'application et peut être téléchargé après contresignature.
- [ ] Le PDF est envoyé par email au destinataire après contresignature.
## Classification
- feature
## Complexity
- 7/10 — La complexité est modérée en raison de l'intégration de plusieurs fonctionnalités (design PDF, gestion des signatures, numéro de contrat, gestion des erreurs) et de la nécessité de configurer des paramètres flexibles dans les modèles de contrat.
Files
RA Updated by Redmine Admin about 2 months ago
- Status changed from Submitted to Spec
Spec en cours (factory). Transition Submitted → Spec.
RA Updated by Redmine Admin about 2 months ago
- Subtask #90 added
RA Updated by Redmine Admin about 2 months ago
- Subtask #91 added
RA Updated by Redmine Admin about 2 months ago
- Subtask #92 added
RA Updated by Redmine Admin about 2 months ago
- Subtask #93 added
RA Updated by Redmine Admin about 2 months ago
- Subtask #94 added
RA Updated by Redmine Admin about 2 months ago
- spec_ref updated (diff)
RA Updated by Redmine Admin about 2 months ago
RA Updated by Redmine Admin about 2 months ago
RA Updated by Redmine Admin about 2 months ago
- File 82-maquette-contrat.html 82-maquette-contrat.html added
RA Updated by Redmine Admin about 2 months ago
- Status changed from Spec to Design
**Design terminé** (factory designer). Transition Spec → Design.
**Maquettes avant/après attachées** : `82-avant-contrat-brut.png` (état actuel — copie HTML brute, reconstruction HTML car l'app live n'était pas accessible) vs `82-apres-contrat-pdf-pro.png` (PDF professionnel proposé) + `82-maquette-contrat.html`. Section ajoutée au design system : `docs/design/design-system.md`.
**Brief (Atomic Design — React/Vite + shadcn/ui, FR inline) :**
- **PDF (serveur pdf-lib, #90/#91/#92)** : en-tête logo haut-gauche + filet, marges 2 cm, corps serif / labels sans-serif, blocs signature à emplacement configurable (bas droite/gauche/côte à côte) avec mention « Signé par [Nom] le [date] », numéro de contrat unique en en-tête + pied de page.
- **UI config modèle (#93, HtmlContractTemplateManager.jsx)** : atoms réutilisés `Select` (police) / upload (logo) / `RadioGroup` (emplacement) ; molecule « Présentation du PDF » ; organism = formulaire de modèle existant.
- **Avertissement balises manquantes (#94)** : `AlertDialog` shadcn listant les `{{balises}}` non substituées, actions « Ignorer et générer » / « Corriger ».
- États : empty (logo absent → placeholder), loading (génération), error (balise manquante → dialog), populated. Aucune nouvelle couleur de marque.
Sous-tâches prêtes pour le dev après design : #90 (socle rendu), #91 (signatures), #92 (numéro + délivrance), #93 (config UI), #94 (avertissement).
RA Updated by Redmine Admin about 2 months ago
- Status changed from Design to QA
**Épic #82 — rollup → QA.** Les 5 sous-tâches sont mergées sur `dev` et en QA : #90 (moteur rendu) · #91 (signatures) · #92 (numéro + délivrance) · #93 (config UI) · #94 (avertissement balises). Tous gates verts. Validation visuelle du PDF (rendu, signatures aux 3 emplacements, logo, numéro) à faire en préprod.
RA Updated by Redmine Admin about 2 months ago
RA Updated by Redmine Admin about 2 months ago
**Smoke préprod ✅ (partiel)** — app + auth OK en live (dashboard avec données réelles, capture jointe). L'UI de config du modèle (#93) et l'avertissement balises (#94) sont déployés. **Le rendu PDF lui-même (logo, marges, signatures aux 3 emplacements, numéro) reste à valider en générant un vrai contrat** (nécessite un événement + modèle + données) — à faire lors de la validation fonctionnelle client.
RA Updated by Redmine Admin about 2 months ago
**Bugs trouvés en validation préprod du contrat → corrigés & déployés en préprod (build #12).**
1. **Onglet « Édition contrat » bloqué sur un spinner infini** quand l'événement n'a pas encore de contrat (le contrat naît du formulaire de confirmation). → Remplacé par un **état vide actionnable** : « Aucun contrat… allez dans l'onglet Gestion créer le formulaire de confirmation » (plus de spinner trompeur).
2. **413 PayloadTooLargeError** sur **signHtmlContract** (signature dessinée = data-URI base64), génération et téléchargement de PDF. Cause : `main.ts` ne fixait aucune limite de corps → défaut Express 100 kb. → bodyParser à **25mb**. **Vérifié en live** : un corps de 150 kb renvoyait 413, renvoie désormais 201.
3. **Logo en-tête** : il est rendu côté serveur dans le PDF ; il n'apparaissait pas faute de pouvoir générer/télécharger (bloqué par le 413). Maintenant que la génération passe, le logo doit apparaître — **à confirmer visuellement** en téléchargeant un PDF de contrat (validation client).
PR #22 (dev) → #23 (préprod). Gates verts. La validation visuelle finale du PDF (logo, signatures, numéro) reste côté client.
RA Updated by Redmine Admin about 2 months ago
- Subtask #377 added
RA Updated by Redmine Admin about 2 months ago
- Status changed from QA to Preprod
Déployé en préprod (https://preprod-scobby.omdev.tech). Passage QA → Preprod (épic + sous-tâches #90–#94 + refonte #377 livrés).
RA Updated by Redmine Admin about 2 months ago
- Subtask #1110 added
RA Updated by Redmine Admin about 1 month ago
- Status changed from Preprod to Ready to ship
Épopée livrée sur master (dev = preprod = master). Tous les sous-tickets sont sur master : #90 (PR #8/#19), #91 (PR #11), #92 (PR #14), #93 (PR #10), #94 (PR #7). Refonte rendu PDF (#377) également livrée. Passage en **Ready to ship** — à passer en *Shipped* après confirmation du déploiement prod (gate manuel Jenkins) sur scobby.fr.
RA Updated by Redmine Admin about 1 month ago
- deploy_status set to deployed
- deployed_at set to 06/23/2026
Déploiement PROD confirmé live sur scobby.fr (gate manuel Jenkins approuvé le 2026-06-23). Passage en **Shipped**.
RA Updated by Redmine Admin about 1 month ago
RA Updated by Redmine Admin about 1 month ago
Correctif : ce ticket **ne passe pas en Shipped** car il reste un sous-ticket ouvert — **#1110** « Améliorer le format/design du PDF de contrat (polish visuel, champs vides, identité Le Bijou) », encore en *Spec*. 6 des 7 sous-tickets (#90, #91, #92, #93, #94, #377) sont livrés en prod ; l'épopée reste ouverte jusqu'à la livraison de #1110. (Mon message précédent « épopée complète » était inexact.)