Files
LoreMindMJ/progress.txt

140 lines
8.8 KiB
Plaintext

# LoreMind — feature "Illustrations & images"
# Plan d'execution en 6 etapes. Mets a jour apres chaque etape terminee.
# ==========================================================================
## Etape 1 — Shared Kernel images + MinIO [x] TERMINEE (2026-04-20 sess.5)
Backend Java pur. Aucune integration metier. Tout est testable via curl.
Fichiers crees/modifies :
- docker-compose.yml (nouveau, service minio + minio-init)
- core/pom.xml (+ dep io.minio:minio:8.5.11)
- core/src/main/resources/application.properties (+ config minio.*, multipart 10MB)
- core/src/main/java/com/loremind/domain/images/Image.java
- core/src/main/java/com/loremind/domain/images/ports/ImageRepository.java
- core/src/main/java/com/loremind/domain/images/ports/ImageStorage.java
- core/src/main/java/com/loremind/application/images/ImageService.java
- core/src/main/java/com/loremind/infrastructure/persistence/entity/ImageJpaEntity.java
- core/src/main/java/com/loremind/infrastructure/persistence/jpa/ImageJpaRepository.java
- core/src/main/java/com/loremind/infrastructure/persistence/postgres/PostgresImageRepository.java
- core/src/main/java/com/loremind/infrastructure/storage/MinioConfig.java
- core/src/main/java/com/loremind/infrastructure/storage/MinioImageStorageAdapter.java
- core/src/main/java/com/loremind/infrastructure/web/dto/images/ImageDTO.java
- core/src/main/java/com/loremind/infrastructure/web/controller/ImageController.java
- docs/academy/object-storage.md
- docs/academy/shared-kernel.md
Validation : `mvn compile` OK (exit 0).
Tests manuels a faire par l'utilisateur :
1. docker-compose up -d
2. mvn spring-boot:run (dans /core)
3. curl -F file=@test.jpg http://localhost:8080/api/images
4. Verifier la reponse JSON avec id et url
5. Ouvrir http://localhost:8080/api/images/<id>/content dans le navigateur
## Etape 2 — Composants Angular partages [x] TERMINEE (2026-04-20 sess.5)
Fichiers crees :
- web/src/app/services/image.model.ts
- web/src/app/services/image.service.ts (upload, getById, delete, contentUrl)
- web/src/app/shared/image-uploader/ (ts + html + scss)
* Mode drop-zone standard OU compact (bouton "+ ajouter" pour galerie)
* Validation client MIME/taille alignee avec le backend
* Spinner + gestion erreur 413 et erreur generique
- web/src/app/shared/image-gallery/ (ts + html + scss)
* Grille de vignettes 120x120, lazy-loading
* Mode editable=true : bouton "+ ajouter" via app-image-uploader compact
* Bouton X par vignette, supprime cote serveur + emet nouvelle liste
* Lightbox plein ecran au clic (clic hors image pour fermer)
Validation : npx tsc --noEmit OK (exit 0).
## Etape 3 — Illustrations sur Scene / Chapter / Arc [x] TERMINEE (2026-04-20 sess.5)
Backend :
- domain/campaigncontext/{Arc,Chapter,Scene}.java : + List<String> illustrationImageIds
- persistence/entity/{Arc,Chapter,Scene}JpaEntity.java : colonne JSON illustration_image_ids
- persistence/postgres/Postgres{Arc,Chapter,Scene}Repository.java : mapping 2 sens
- web/dto/campaigncontext/{Arc,Chapter,Scene}DTO.java : + champ illustrationImageIds
- web/mapper/{Arc,Chapter,Scene}Mapper.java : propage dans les 2 sens
- application/campaigncontext/{Arc,Chapter,Scene}Service.java : update inclut le champ
Frontend :
- services/campaign.model.ts : + champ sur Arc/Chapter/Scene + leurs Create
- arc-view/chapter-view/scene-view : import + section "Illustrations" en haut (lecture)
- arc-edit/chapter-edit/scene-edit : import + propriete illustrationImageIds,
section galerie editable en tete de form, propagation dans submit()
Validation : mvn compile OK, npx tsc --noEmit OK.
## Etape 4 — Refactor Template.fields [x] TERMINEE (2026-04-21 sess.6)
Backend :
- domain/lorecontext/FieldType.java (enum TEXT | IMAGE)
- domain/lorecontext/TemplateField.java (VO name + type)
- domain/lorecontext/Template.java : fields devient List<TemplateField>,
helper textFieldNames() pour ne garder que les noms TEXT (use cases IA)
- persistence/converter/TemplateFieldListJsonConverter.java : lit le legacy
["name",...] ET le nouveau [{name,type}], ecrit toujours au nouveau format.
Migration automatique a la premiere sauvegarde.
- persistence/entity/TemplateJpaEntity.java : converter swap
- persistence/postgres/PostgresTemplateRepository.java : mapping typé
- web/dto/lorecontext/TemplateFieldDTO.java (nouveau)
- web/dto/lorecontext/TemplateDTO.java : fields -> List<TemplateFieldDTO>
- web/mapper/TemplateFieldMapper.java (nouveau, tolerance type inconnu -> TEXT)
- web/mapper/TemplateMapper.java : delegue au fieldMapper
- application/lorecontext/TemplateService.java : signature createTemplate
- web/controller/TemplateController.java : conversion DTO -> domain
- application/generationcontext/GeneratePageValuesUseCase.java : n'envoie
a l'IA que les champs TEXT (via textFieldNames()), erreur claire si aucun
- application/generationcontext/StreamChatForLoreUseCase.java : idem
Frontend :
- services/template.model.ts : FieldType + TemplateField
- template-create : liste TemplateField[], selecteur de type, toggle
- template-edit : idem + normalisation legacy en TEXT cote client
- page-view : rendu TEXT vs placeholder IMAGE (complete etape 5)
- page-edit : hydrate TEXT only, mergeSuggestions filtree, placeholder IMAGE
- page-create wizard prompt : ne liste que les TEXT fields
- Styles : chip verte (TEXT) vs indigo (IMAGE), bouton toggle inline
Validation : mvn compile OK, npx tsc --noEmit OK.
## Etape 5 — Support champs IMAGE dans Pages [x] TERMINEE (2026-04-21 sess.6)
Backend :
- persistence/converter/StringListMapJsonConverter.java (nouveau,
convertit Map<String, List<String>> <-> JSON pour Page.imageValues)
- domain/lorecontext/Page.java : + champ imageValues + helpers
setImageFieldValue/getImageFieldValue
- persistence/entity/PageJpaEntity.java : colonne image_values_json
- persistence/postgres/PostgresPageRepository.java : mapping 2 sens
- web/dto/lorecontext/PageDTO.java : + champ imageValues
- web/mapper/PageMapper.java : propage le champ
- application/lorecontext/PageService.java : update inclut imageValues
Frontend :
- services/page.model.ts : + imageValues?: Record<string, string[]>
- page-view : import ImageGalleryComponent + helper imageIdsOf()
+ rendu galerie (readonly) pour chaque champ IMAGE
- page-edit : import ImageGalleryComponent + propriete imageValues
+ hydrate separe TEXT/IMAGE + save propage imageValues + UI galerie editable
Validation : mvn compile OK, npx tsc --noEmit OK.
## Etape 6 — Brain Python : synchro DTOs [x] TERMINEE (2026-04-21 sess.6)
Backend Java :
- domain/generationcontext/CampaignStructuralContext.java : +illustrationCount
sur ArcSummary, ChapterSummary, SceneSummary
- application/generationcontext/CampaignStructuralContextBuilder.java : populate
depuis Arc/Chapter/Scene.getIllustrationImageIds() (null-safe)
- infrastructure/ai/BrainAiChatClient.java : serialise illustration_count dans
le JSON envoye au Brain (UNIQUEMENT si > 0, pour payload leger)
Brain Python :
- domain/models.py : +illustration_count: int = 0 sur les 3 summaries
- main.py : +illustration_count sur les 3 DTOs Pydantic + propagation dans
_to_campaign_context. Les champs inconnus (ex: illustrationImageIds envoyes
par le Core pour les pages) sont ignores par defaut par Pydantic v2.
- application/chat.py : nouveau helper _illustration_hint() ; les lignes
arcs/chapters/scenes du prompt affichent " [N illustrations]" si presentes.
Validation : mvn compile OK, python ast-parse OK, demo runtime prompt OK
(" - A (arc) [2 illustrations]", " - S (scène) [1 illustration]").
NON couvert (scope residuel evident, si besoin) :
- PageSummary ne porte pas encore de signal sur les imageValues des pages.
Les pages Lore exposent deja des values text via LoreStructuralContext ;
on pourrait ajouter le nombre d'images par champ IMAGE la aussi.
## Notes transverses
- Docker-compose pour l'instant ne couvre QUE MinIO. Postgres/brain/web restent lances a la main.
- Les ports `ImageRepository` et `ImageStorage` sont volontairement separes (SRP).
- Le binaire est stocke dans MinIO bucket `loremind-images` (cree auto par minio-init).
- L'URL publique d'une image est `/api/images/{id}/content` (proxy via backend Java).
- Validation MIME cote ImageService : jpeg/png/webp/gif uniquement. Max 10 Mo.