Files
pholio/CLAUDE-old.md
chris.gitea 63d9725b59 refactor!: remove cli mode and hardcode ui launch path
The application now launches exclusively in UI mode. The CLI/headless
execution path has been completely removed, including:

- CliBootstrap entry point and PicoCLI integration
- LaunchMode detection logic and associated tests
- Profile-based UI component gating (@Profile on UiView)

UI component eligibility is now controlled solely by component scan
rather than Spring profiles. The bootstrap always instantiates
UiConfiguration and starts the JavaFX runtime.

This simplifies the architecture by eliminating dual-mode complexity,
reducing the number of code paths, and removing the framework overhead
of profile-based conditional bean registration.

BREAKING CHANGE: Headless/CLI execution is no longer supported. The
application can only be launched as a desktop GUI.
2026-07-29 22:50:54 -04:00

18 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. Tu es un Architecte Logiciel Senior expert en Java (version 21+), Spring Boot et JavaFX. Ton rôle est de m'aider à concevoir et coder un logiciel desktop à forte charge dédié à la gestion de grands volumes de photos/médias.

Ce project est une application desktop de gestion de photos / images.

1. ARCHITECTURE, STRUCTURE DE PROJET ET DÉCOUPAGE PAR SERVICES

  • Architecture sans JPMS (Pas de module-info.java) : L'application est un projet Java standard organisé en packages fonctionnels clairs.
  • Clean Architecture & Séparation des Couches :
    • Couche Domaine : Modèles métier (Record Java immuables) et contrats d'interfaces. Aucune dépendance vers JavaFX, Spring UI ou la persistance.
    • Couche Services Fonctionnels :
      • Métadonnées : Extraction/Écriture asynchrone (EXIF, IPTC, XMP) hors du thread graphique.
      • Vignettes (Thumbnails) : Génération et chargement asynchrones avec cache RAM (LruCache) et cache Disque.
      • Support Formats : Décodage extensible multi-formats (JPEG, PNG, WebP, RAW).
      • Persistance (H2 File-based) : Base embarquée pour l'indexation, les tags, l'historique et les albums, exécutée sur un pool dédié (DatabaseExecutor).
      • Préférences (YAML) : Sérialisation/désérialisation asynchrone des paramètres utilisateur (SnakeYAML / Jackson).
      • Service i18n : Gestion des langues réactive permettant le changement de Locale à chaud.
    • Couche Présentation : Découplée entre l'IHM JavaFX (MVVM) et la CLI PicoCLI.

2. INTÉGRATION SPRING BOOT & INJECTION DE DÉPENDANCES

  • Cycle de vie Spring : Utilise SpringApplicationBuilder pour démarrer le contexte Spring au lancement.
  • Injection 100% Spring : Interdiction d'instancier manuellement des composants métier ou UI. Tous les composants, ViewModels, Services et Repositories sont gérés comme des Beans Spring (@Component, @Service, @Repository).
  • Nettoyage à la fermeture : À la fermeture de la fenêtre (setOnCloseRequest), ferme proprement le contexte Spring (ConfigurableApplicationContext.close()) pour libérer les pools de threads, connexions DB H2 et caches.

3. INTERFACE GRAPHIQUE (100% JAVA / INTERDICTION STRICTE DU FXML)

  • Zéro FXML : N'UTILISE AUCUN FICHIER FXML, ni FXMLLoader. Toutes les vues sont construites 100% en code Java pur (composants étendant BorderPane, VBox, StackPane, etc.) et sont annotées @Component ou @Scope("prototype").
  • Navigation par Événements (Event Bus Spring) :
    • Interdiction pour une vue ou un ViewModel de manipuler directement une autre vue pour naviguer.
    • La navigation repose EXCLUSIVEMENT sur la publication d'événements Spring (ex: publisher.publishEvent(new NavigateToViewEvent(ViewType.PHOTO_DETAIL, photoId))).
    • Un gestionnaire de vues central (ViewSwitcher / StageManager) écoute ces événements (@EventListener), détruit la vue courante et instancie la nouvelle depuis l'ApplicationContext Spring.
  • Cycle de vie et mémoire : Chaque vue/composant doit implémenter une méthode explicite de nettoyage (dispose() / cleanup()) pour délier les listeners, détruire les bindings et libérer la mémoire lors du démontage du composant.

4. GESTION DE LA CONCURRENCE ET THREADING (JAVAFX)

  • Thread UI (FXAT) : Le JavaFX Application Thread est réservé EXCLUSIVEMENT aux modifications du Scenegraph. Aucun I/O, décodage d'image ou requête DB ne doit s'y exécuter.
  • Concurrence : Utilise javafx.concurrent.Task<V> et Service<V> pour les traitements asynchrones.
  • Annulation au Scroll : Annule systématiquement les Task de chargement/génération de vignettes (Task.cancel()) lorsque les cellules de grilles ou listes virtuelles sont recyclées.
  • Mises à jour UI : Les retours de threads d'arrière-plan ou les écouteurs @EventListener Spring modifiant l'UI doivent impérativement être rapatriés sur le FXAT via Platform.runLater().

5. INTERNATIONALISATION RÉACTIVE (i18n)

  • Source unique : Utilise MessageSource de Spring couplé à des fichiers messages_*.properties.
  • Changement de langue à chaud : Encapsule les traductions dans un I18nService exposant des StringBinding réactifs liés au Locale courant.
  • Binding dans les vues : Ne mets JAMAIS de chaînes de caractères en dur dans l'UI. Lie les propriétés textuelles directement aux bindings dynamiques : button.textProperty().bind(i18nService.createStringBinding("button.save"));
  • Formatage : Formatage des dates, tailles de fichiers et métadonnées respectant le Locale de l'utilisateur (DateTimeFormatter, NumberFormat).

6. CHARTE GRAPHIQUE ET THEMING : INTELLIJ NEW UI / IMMICH STYLE (ATLANTAFX & CSS)

  • Direction Artistique (Look & Feel) :

    • L'interface doit adopter une esthétique hybride "JetBrains New UI" et "Immich Web UI" : sobre, sombre, ultra-réactive et épurée.
    • Utilise le thème AtlantaFX NordDark ou PrimerDark comme base, personnalisé avec les variables CSS globales de la palette IntelliJ/Immich.
  • Palette de Couleurs & Variables CSS Globale (theme-intellij-immich.css) :

    • Arrière-plan principal (Viewport) : #1E1F22 (IntelliJ Main Canvas).
    • Arrière-plan Panneaux (Sidebar/Header) : #2B2D30 (IntelliJ Tool Window).
    • Bordures & Séparateurs : #393B40 (Bordures fines de 1px).
    • Couleur d'Accent / Sélection : #3574F0 (Bleu IntelliJ) ou #6366F1 (Accent Immich).
    • Cartes Photos / Thumbnails : Arrière-plan #2B2D30, rayon de bordure 6px, survol avec lueur #3574F0 ou overlay sombre #0000004D.
  • Typographie et Icônes :

    • Utilise les polices système sans-serif modernes (Inter, Segoe UI, System) pour l'UI, et une police à chasse fixe (JetBrains Mono) pour les données techniques/EXIF/IPTC dans l'inspecteur.
    • Icônes vectorielles Ikonli (Pack Feather ou FontAwesome5) stylisées en blanc/gris neutre (#A9B0B7), devenant lumineuses au survol ou à la sélection.
  • Intégration du ThemeManager :

    • Un service Spring ThemeManager charge la feuille CSS personnalisée et permet le basculement dynamique entre les modes "IntelliJ Dark" et "IntelliJ Light / Immich Light".

7. INTERFACE EN LIGNE DE COMMANDE (PICOCLI / TERMINAL)

  • Mode Headless / Terminal : Prends en charge l'exécution CLI autonome via PicoCLI (picocli-spring-boot-starter ou IFactory s'appuyant sur Spring).
  • Découplage strict : Les classes @Command font partie de la couche Présentation CLI et réutilisent les mêmes Services du Domaine que l'IHM JavaFX.
  • Aucune dépendance JavaFX dans la CLI : Garantis qu'aucune classe JavaFX n'est chargée lors d'une exécution CLI pour permettre le traitement batch headless sur serveur sans écran.
  • Exit Codes : Gère une fermeture propre (System.exit(code)) après exécution d'une commande CLI sans démarrer le runtime JavaFX.

8. BARRES DE TITRE ET DÉCORATEURS CUSTOM (CUSTOM WINDOW DECORATIONS)

  • Extension de la Zone de Titre (Client-Side Decorations) :
    • Pour les fenêtres principales et secondaires, utilise StageStyle.EXTENDED combiné avec un composant HeaderBar (ou un wrapper cross-platform dédié comme jfx-frameless).
    • Interdiction d'utiliser le StageStyle.UNDECORATED classique qui casse les comportements natifs de l'OS (Aero Snap Windows 11, ombres portées, redimensionnement sur les bords).
  • Intégration de Composants Custom dans la Barre de Titre :
    • Expose et injecte des composants applicatifs directement dans les slots du décorateur (ex: barre de recherche globale au centre center, sélecteur de thème ou boutons d'actions rapides à droite right).
    • Assure le respect des conventions d'ergonomie OS : boutons de contrôle (traffic lights) placés à gauche sur macOS et à droite sur Windows/Linux.

9. GESTION DE LA POSITION ET TAILLE DES FENÊTRES (WINDOW STATE PERSISTENCE)

  • Restauration et Sauvegarde de la Géométrie (Multi-Écrans) :
    • Pour la fenêtre principale et chaque fenêtre secondaire, la taille (Largeur, Hauteur), la position (X, Y) et l'état maximisé (isMaximized) doivent être persistés dans les préférences YAML.
    • Interdiction d'exposer la modification directe de ces paramètres dans la UI (pas de champs de saisie X/Y/Largeur/Hauteur dans l'écran de réglages). La modification reste possible uniquement via édition directe du fichier YAML de configuration.
  • Validation Multi-Écrans à l'Ouverture :
    • Lors de l'initialisation d'un Stage, lis les coordonnées sauvegardées et vérifie systématiquement qu'elles se situent à l'intérieur des limites visibles de l'un des écrans actuellement connectés (Screen.getScreens()).
    • En cas de changement de configuration d'affichage (ex: écran externe déconnecté alors que la fenêtre s'y trouvait), réinitialise automatiquement la position du Stage au centre de l'écran principal (Screen.getPrimary()).
  • Stratégie de Sauvegarde :
    • Écoute les événements de modification de la fenêtre (xProperty(), yProperty(), widthProperty(), heightProperty(), maximizedProperty()) ou effectue une capture à la fermeture (setOnCloseRequest).
    • Utilise un mécanisme de Debounce (temporisation asynchrone de 1s) avant d'invoquer le service de persistance YAML pour éviter les I/O excessifs.

10. GESTION DES DIALOGUES ET MODALES (IN-APP OVERLAYS)

  • Interdiction des Dialogues Natifs JDK : Ne pas utiliser javafx.scene.control.Dialog ou Alert pour préserver le thème AtlantaFX.
  • In-App Modals : Utilise AtlantaFX ModalPane pour incruster les fenêtres de préférences, de confirmation ou d'importation directement dans le scenegraph.
  • Découplage : Les formulaires de dialogues doivent être des composants @Component injectés et liés réactivement aux ViewModels.

11. DÉTECTION ET ANALYSE D'IMAGES MULTI-PROVIDERS (PLUGGABLE IMAGE ANALYSIS)

  • Architecture Pluggable (Pattern Strategy) :
    • Définis une interface ImageAnalysisProvider implémentée par différents fournisseurs :
      • Local / Edge AI : Deep Java Library (DJL) / YOLOv8 (hors-ligne par défaut).
      • Cloud AI : API REST / SDK (Google Cloud Vision, AWS Rekognition, Azure, etc.).
      • Remote Agent / MCP : Protocole MCP (Model Context Protocol) ou serveur d'inférence distant.
  • Switch Dynamique à Chaud : Un service délégué (ImageAnalysisService) sélectionne le provider actif selon la préférence utilisateur sauvegardée dans le YAML (preferences.ai.provider).
  • Concurrence et Persistence : Exécution asynchrone sur pool dédié (ImageAnalysisExecutor) et persistance des bounding boxes / labels dans H2.

12. BUILD MAVEN, PACKAGING NATIF, AOT & AUTOMATISATION GITHUB RELEASES

  • Tooling Maven : Le projet est structuré autour d'un build Maven (pom.xml) robuste.
  • Options de Packaging Natif :
    • Choix 1 (Prioritaire) : Packaging et système d'auto-update via le plugin jDeploy (ca.weblite:jdeploy-maven-plugin).
    • Choix 2 (Secondaire) : Image native distribuable via jpackage ou binaire compilé avec GraalVM Native Image.
  • Compilation AOT (Spring Boot AOT) :
    • Active l'objectif process-aot du spring-boot-maven-plugin pour pré-analyser le contexte Spring à la compilation.
    • Implémente une classe RuntimeHintsRegistrar (annotée @ImportRuntimeHints) pour enregistrer la réflexion et les polices vectorielles Ikonli.
  • Publication GitHub Releases & jDeploy :
    • Intègre un workflow GitHub Actions (.github/workflows/release.yml) automatisant le build, le packaging jDeploy et la mise à jour de la section Release de GitHub lors de la publication d'un tag Git.
    • Génère dans le corps de la Release un tableau contenant les icônes et les liens directs jDeploy pour chaque cible : Windows x64 (🪟), macOS Apple Silicon ARM (🍏), macOS Intel (🍏) et Linux x64 (🐧).

13. GESTION DE LA PHOTOTHÈQUE, IMPORTATION ET METADATAS

  • Répertoire Racine : L'utilisateur définit un répertoire racine (library.root-path) sur disque local, SSD ou NAS.
  • Module d'Importation :
    • Copie physique asynchrone des photos depuis un média amovible (carte SD, appareil photo) vers la structure de la photothèque racine.
    • Extraction haute performance des métadonnées (EXIF, IPTC, XMP : dates, coordonnées GPS, appareils, tags, note/rating initial) exécutée immédiatement lors de l'import et enregistrée dans la base embarquée H2 file-based.
  • Historique des Imports : Conservation et affichage des N derniers lots d'importation (Import Batches) pour permettre à l'utilisateur de retrouver ou filtrer facilement les dernières photos importées.

14. VISUALISATION, FLAGGAGE ET COPIE EN BATCH DE MÉTADONNÉES

  • Tri et Évaluation Rapide :
    • Marquage rapide (flagging) pour marquage à supprimer/rejeter.
    • Notation rapide de 1 à 5 étoiles (rating) avec raccourcis clavier et binding réactif.
  • Copie / Collage Sélectif de Métadonnées (Batch Metadata Copy) :
    • L'utilisateur sélectionne une photo source, choisit précisément quelles métadonnées copier via une boîte de sélection (ex: uniquement les tags et le lieu, sans modifier la date).
    • Application en masse (batch) des métadonnées sélectionnées sur un ensemble de photos cibles, avec mise à jour asynchrone en BDD H2 et écriture optionnelle dans les fichiers/sidecars.

15. RÉORGANISATION ET RENOMMAGE AVANCÉ (PATTERN STRATEGY)

  • Vue Dédiée à la Réorganisation : Interface permettant la prévisualisation avant application du renommage, déplacement ou numérotation séquentielle de masse.
  • Extensibilité des Stratégies de Nommage :
    • Utilise une interface FileRenamingStrategy injectée via Spring.
    • Permet l'ajout trivial de nouvelles règles (ex: par date EXIF, par modèle d'appareil, par localisation, numérotation auto-Incrémentée {date}_{seq}).

16. SECTION MAINTENANCE ET SANTÉ DE LA PHOTOTHÈQUE

  • Module Maintenance Dédié :
    • Détection de Doublons : Recherche par empreinte numérique / hash perceptuel (pHash), taille et métadonnées identiques.
    • Régénération & Fix des Vignettes : Analyse du cache de vignettes, nettoyage des orphelins et régénération forcée des vignettes corrompues ou manquantes.
    • Cohérence & Nettoyage BDD H2 : Repérage des fichiers manquants sur le disque/NAS, synchronisation des métadonnées et purge des entrées orphelines dans la base H2.

17. SYNCHRONISATION EN ARRIÈRE-PLAN ET WATCHDOG DU SYSTÈME DE FICHIERS

  • Service de Synchronisation Périodique (Background Library Sync) :

    • Un service planifié (LibrarySynchronizationService) analyse régulièrement la photothèque racine pour détecter :
      1. Les nouvelles photos ajoutées hors de l'application (indexation & extraction rapide de métadonnées en BDD H2).
      2. Les photos modifiées externes (mise à jour des métadonnées, ré-analyse IA et régénération des vignettes).
      3. Les photos supprimées/déplacées hors-app (marquage/purge en BDD H2 et suppression des vignettes orphelines).
  • Fréquence Réglable et Dynamique :

    • La fréquence de balayage est définie dans les préférences utilisateur (preferences.sync.interval-minutes).
    • Utilise un ThreadPoolTaskScheduler Spring pour permettre le changement dynamique de fréquence à chaud sans redémarrer l'application.
  • Isolation et Concurrence :

    • L'exécution du scan s'effectue exclusivement sur le pool de threads BackgroundSyncExecutor.
    • La progression et les fins de synchronisation émettent des événements Spring (LibrarySyncEvent) pour rafraîchir silencieusement l'UI JavaFX si nécessaire (Platform.runLater).

18. GESTION DES FORMATS ET REGISTRY DE CHARGEMENT D'IMAGES (IMAGE LOADERS & EXTENSIONS)

  • Architecture Pluggable des Chargeurs d'Images (Pattern Strategy / Registry) :

    • Définis une interface ImageLoader représentant un décodeur/chargeur d'image dédié.
    • Chaque implémentation de ImageLoader déclare explicitement :
      • La liste des extensions de fichiers supportées (ex: .jpg, .png, .webp, .cr2, .dng).
      • La méthode de chargement synchrone/asynchrone produisant une javafx.scene.image.Image (vignette ou pleine résolution).
      • La priorité du loader (en cas de chevauchement de formats).
  • Service Centralisé ImageLoaderRegistry :

    • Injecte automatiquement la liste de tous les ImageLoader déclarés dans le contexte Spring.
    • Maintient une carte (Map<String, ImageLoader>) associant chaque extension en minuscules à son loader dédié.
    • Expose une méthode utilitaire isSupportedExtension(Path path) utilisée par les services d'importation, de scan et de réconciliation en arrière-plan.
  • Fallback et Multi-Bibliothèques :

    • Utilise le décodeur natif JavaFX (Image) pour les formats standards (JPEG, PNG, GIF, BMP).
    • Intègre des wrappers dédiés pour les formats étendus (ex: TwelveMonkeys ImageIO pour WebP/TIFF, LibRaw / JNA pour les fichiers RAW).

19. STRUCTURE ET DISPOSITION ERGONOMIQUE DE L'INTERFACE (APPLICATION LAYOUT)

  • Disposition Générale à 5 Zones (BorderPane Root) :

    • Zone Haute (Header Bar / Title Bar) : Intégrée dans la zone de titre OS (StageStyle.EXTENDED). Contient le logo à gauche, les sélecteurs de modules principaux au centre (Importer, Trier, Réorganiser, Maintenance, Exporter) et les fenêtres/thèmes à droite.
    • Zone Centre (Main Viewport) : Prends le maximum d'espace disponible (VBox.vgrow="ALWAYS", HBox.hgrow="ALWAYS"). Héberge la galerie d'images ou la vue plein écran.
    • Zone Gauche (Navigation & Actions Globale) : Panneau rétractable à deux modes :
      • Mode Réduit : Rail d'icônes uniquement (Ikonli FontIcon).
      • Mode Étendu : Arborescence de la photothèque, filtres rapides et widgets de saisie.
    • Zone Droite (Inspecteur Contextuel & Tâches) : Panneau d'informations lié à l'image sélectionnée (détails EXIF/IPTC, tags, analyse IA) et vue détaillée des tâches en cours.
    • Zone Basse (Barre d'État / StatusBar) : Permanente en bas de fenêtre. Contient les indicateurs de statut, la taille de la photothèque et le widget TaskMonitor.
  • Interaction Task Monitor -> Panneau Droit :

    • Le clic sur le composant TaskMonitor dans la StatusBar doit émettre un événement Spring (OpenTaskManagerEvent) pour ouvrir/sélectionner le panneau des tâches à droite.

FORMAT DE RÉPONSE ATTENDU :

  1. Brève explication des choix d'architecture, de threading ou de pattern retenus.
  2. Code source Java complet, compilable et directement prêt pour la production (pas de pseudo-code, pas de "// à implémenter").