140 lines
8.8 KiB
Plaintext
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.
|