Refactoring du code pour améliorer la lisibilité de ce dernier coté core
Correction sur l'export / import : les images n'étaient pas bien liées à la campagne lors de l'export / import et provoquait un bug d'affichage des images
lorsqu'on voulait ouvrir une campagne importée.
Livret PDF (export campagne) :
- refonte lisibilité façon livre de JdR : sommaire paginé, libellés de champs
en tête de ligne, encadrés « À lire aux joueurs » / secrets MJ / combat,
ligne de contexte des scènes, en-tête courant, tables zébrées
- reflète la fusion quête/conteneur : arc SYSTEM masqué, quêtes de hub
fusionnées dans leur chapitre, partie « Quêtes » sans doublon
- contenu complété : sorties de scènes, ennemis liés au bestiaire, pièces
explorables, partie « Tables aléatoires »
- polices DejaVu embarquées (couverture Unicode, licence incluse) et harness
visuel PdfExportPreviewTest (Mockito pur, tourne sans Postgres)
Graphe des liens :
- déplacé du Lore vers la campagne (les PNJ sont des entités de campagne) ;
endpoint /api/npcs/lore/{id} supprimé
- layout retravaillé (anti-chevauchement des libellés, éventail des feuilles
autour des hubs), scènes et quêtes ajoutées, libellés sur 2 lignes,
filtres de légende mémorisés, focus au survol
- positions drag & drop persistées sur la campagne (migration V23,
PUT /api/campaigns/{id}/graph-positions, bouton « Disposition auto »)
Divers :
- ImportService découpé en classes dédiées (parser d'archive, remapper d'ids,
inserters campagne/lore/état de jeu, conversion legacy des quêtes)
- fuites d'abonnements corrigées (takeUntilDestroyed sur paramMap) sur ~15 écrans
- garde-fou i18n fragments/consolidés branché sur npm run build (check-i18n.mjs),
budget SCSS anyComponentStyle relevé à 12 ko
mode séance, battlemaps multiples et export Foundry ciblé
- Quêtes (Niveau 1) : entité Quest orthogonale à l'arbre, rattachée à un arc HUB
ou libre (migrations V9-V12, V18, V20 ; réconciliation des jumeaux V10).
Fusion quête/conteneur dans la sidebar, progression par partie (statuts
disponible/en cours/terminée), et quêtes libres avec espace de scènes créé
automatiquement (arc technique « Quêtes libres », V21 : levée de la
contrainte arcs.type héritée du baseline).
- Guidage (Pilier B) : bilan de préparation 100 % dérivé (règles arc/chapitre/
scène/quête), panneau « Prochaines étapes » avec boutons « Corriger », et
pastilles détaillées (tooltip des manques) dans l'arbre.
- Assistant IA (Pilier A) : étoffage champ par champ (scène, chapitre, arc) et
brouillons de scènes en propose→applique (brain : narrative-fields,
scene-drafts).
- Horloges & menaces (V15-V17) : clocks à segments avec déclencheurs, fronts.
- Mode séance : préparation de séance (readiness + quêtes dispo), scène
épinglée (V19), récap « précédemment » (brain : session-recap), onglet
« Partie » du panneau de référence, graphe amélioré (pan/zoom, éditeur de
liens).
- Perf : endpoint agrégé GET /api/campaigns/{id}/tree — la sidebar charge en
1 requête au lieu de ~15.
- Battlemaps multiples par scène (variantes jour/nuit, étages…) : liste JSON
étiquetée (V22, reprise automatique de la carte existante), rendu PDF avec
légendes, export/import rétro-compatible.
- Export Foundry ciblé : modale de périmètre (cartes+ennemis / journaux /
tables), bundle filtré côté serveur (zip allégé), module Foundry à jour
(respect du périmètre + une Scene Foundry par variante de carte,
rétro-compatible anciens bundles).
Refonte du système de templates de lore en assemblage de blocs (façon Lore
d'Amsel), plus le support des cartes DungeonDraft (.dd2vtt) sur les scènes.
Templates de lore — éditeur de blocs en grille :
- Builder partagé `block-grid-builder` : palette de types de blocs à glisser sur
une grille 12 colonnes, placement LIBRE (x/y) et redimensionnement en largeur
ET hauteur par poignées, renommage en place. Remplace la liste + flèches de
template-create/template-edit (dédupliqués).
- Rendu : page-view (aperçu) honore largeur ET hauteur (grille à lignes fixes) ;
page-edit garde les colonnes (côte-à-côte) avec des hauteurs naturelles pour
l'édition. Repli empilé pour les templates sans mise en page.
- Modèle : `TemplateField` gagne `id` (clé stable) et `pos {x,y,w,h}`. Les valeurs
de page sont ancrées sur l'`id` (repli sur le nom) → renommer un bloc ne perd
plus son contenu. Sérialisation JSON additive, aucune migration ; correction au
passage de la non-relecture de `foundryPath` dans le converter.
Bloc image :
- Nouveau composant `image-block` (remplace la galerie pour les pages de lore) :
plusieurs images plein cadre (carrousel), déplacement (recadrage) et zoom
persistés PAR image et PAR page. Rendu `object-fit: contain` (image entière,
bordures noires) avec zoom 0,4×–4×.
- Stockage : `Page.imageFraming` (fieldKey → imageId → {x,y,scale}), colonne
`image_framing` (migration V8), DTO/mapper + passthrough export/import.
Scènes — source de carte au choix :
- Sélecteur Dungeon Alchemist (image/vidéo + .json, inchangé) / DungeonDraft
(.dd2vtt). Le .dd2vtt embarque l'image en base64 : extraction à l'upload
(→ média) + sidecar allégé (→ données) pour que l'export Foundry et le module
fonctionnent sans changement. Mode déduit à la relecture de l'extension.
Front-only, sans migration.
i18n fr/en, tests (converters back + helper front) et specs e2e mis à jour.
Export / import de contenu (format v2)
- Export SÉLECTIF : on peut exporter une seule campagne (sa clôture : arcs →
chapitres → scènes, PNJ, ennemis, catalogues, tables, système de jeu lié) au
lieu de tout exporter. Options par export : inclure le lore, l'espace de jeu,
les images. L'export global devient « Sauvegarde complète ».
- ESPACE DE JEU désormais exporté/importé : parties (Playthrough), séances,
journal, flags, progression de quêtes, et feuilles de perso (Character.playthroughId
préservé au lieu d'être annulé). Remapping complet des références à l'import.
- Format v2 rétro-compatible : un export v1 (sans section jeu) s'importe toujours
(champs absents → null → traités comme vides).
- Correction d'un bug latent : collectReferencedStorageKeys traitait les références
d'images comme des clés de stockage alors que ce sont des IDs → les binaires
d'images n'étaient en réalité pas embarqués dans le zip. Résolution ID → clé.
- Images des Rooms d'une scène (illustration + plan) désormais collectées (elles
étaient oubliées des deux collecteurs).
- Endpoint : GET /api/admin/data/export?campaignId=&includeLore=&includePlay=&includeImages=
; écran « Sauvegarde des données » avec choix campagne + cases à cocher.
- Tests : round-trip étendu au jeu + binaire image réel, export sélectif par
campagne, import d'archive v1, et DataTransferController.
Correction : nombre de joueurs non persisté
- playerCount était saisi à la création mais jeté par le backend (absent du
domaine/entité/DTO/mapper) → affichage « 0 joueurs ». Ajouté sur toute la stack
+ migration V7 (défaut 4 pour les campagnes existantes) + intégré à l'export.
Ergonomie de l'espace de jeu et des listes
- Description de campagne repliable (clamp 3 lignes + « Voir plus / moins »).
- Dossiers repliables (chevron + compteur) dans les listes PNJ et Ennemis, sur la
page campagne ET les pages dédiées.
- Renommage en place des parties (« Mes parties ») via un crayon.
- Panneau de session : onglets sur 2 rangs (« Scènes » n'est plus rogné) ; scènes
triées par ordre manuel ; arcs repliables (repliés par défaut) ; PJ/PNJ repliables
et PNJ regroupés par dossier.
Corrections fonctionnelles
- order initialisé à la création des pages et dossiers de lore (nextOrderFor) :
un nouvel élément se place désormais en dernier de sa fratrie au lieu de 0
- storePortrait : type MIME canonique dérivé de l'extension du fichier
(un data URL "image/jpg" n'est plus rejeté silencieusement)
- takeUntilDestroyed ajouté sur les abonnements paramMap de arc-view,
folder-view et campaign-detail (fuites mémoire)
Factorisation (suppression de duplication)
- shared/folder-grouping.util.ts : groupByFolder + byOrder + byFolderName
mutualisés entre npc-list, enemy-list, campaign-detail et la sidebar
(folderChildren). Le tri des dossiers est désormais cohérent entre la
sidebar et les vues cartes (insensible casse/accents partout)
- DataSyncService.onChange()/persist() remplacent le câblage
changed$ + reorder recopié dans 5 vues
- campaign-detail : loadCampaignBundle()/applyCampaignBundle() éliminent
le forkJoin dupliqué entre ngOnInit et reload
- ReorderSupport (domain/shared) : squelette générique remplaçant les
8 boucles de réordonnancement copiées dans les services
- FoundryExportService : GameSystem résolu une seule fois dans buildBundle
- module Foundry : walkScalars mutualise la récursion de flattenStats et
flattenStructure (comportements préservés) ; esc() de l'importer aligné
sur foundry.utils.escapeHTML
Suppression de code mort
- characterService/characters retirés de loadCampaignTreeData et de ses
16 appelants (arguments, injections, imports et littéraux CampaignTreeData)
- CSS orphelin : .tree-row.cdk-drop-list-receiving et .btn-back
- BottomPanel.initiallyOpen (jamais lu) retiré de l'interface et de l'appelant
- commentaire trompeur du PDF corrigé
Tests
- mise à jour de 3 tests obsolètes de campaign-tree.helper.spec qui
vérifiaient encore l'ancien comportement (tri alphabétique, non-classés
en enfants directs) → alignés sur le modèle actuel (tri par order +
pseudo-dossier "Sans dossier")
Mise en place de tests unitaires coté Python et Angular
Mise en place de la couverture de test directement dans le workflow : le programme ne build pas si jamais un test échoue
Passage en v0.16.2 en conséquence
Ajout du mock EnemyRepository manquant (dependance ajoutee au
constructeur lors du referencement des ennemis). Sans ce mock,
@InjectMocks injectait null -> NPE sur enemyRepository.findByCampaignId.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Dorénavant, l'IA est capable de prendre en compte le format des quêtes, chapitres, Arc.... pour proposer des blocs plus complets.
Les ennemis sont également référençables directement dans la campagne.
Les références vers les ennemis dans la partie "donjon" est en cours d'ajout