fonzarely/regine-photos-archiverpublic Fork
⑂ main
Commits
⬇ Clone ▾
git clone https://git.rickub.com/fonzarely/regine-photos-archiver.git
git clone ssh://git@rickub.com/fonzarely/regine-photos-archiver.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

Download ZIP
tri raw/jpeg 02d8847 · on main · Fabien Champigny · Sep 22, 2026
spec.md · 135 lines · 23.5 KBmarkdown
Blame HistoryOpen raw

Feature Specification: Interface graphique de tri et de consultation

Feature Branch: [006-gui-tri-consultation]

Created: 2026-09-20

Status: Draft

Input: User description: "Interface graphique de Régine (GUI), cadrée dans docs/interface-cli-gui-architecture.md et docs/archivage-photo-elements-cles.md section 10, jamais encore spécifiée. Façade fine au-dessus de regine-core (Principe VI), aucune logique métier propre — importe la bibliothèque dans le même processus, pas de daemon. Trois modes d'usage : (1) tri/culling pendant l'édition sur un dossier checké out en local, avec regroupement visuel RAW+JPEG jumeau et navigation combinant plusieurs dossiers de format/sous-dossiers d'un même dossier ; (2) consultation en lecture seule de l'archive NAS sans checkout complet, avec recherche et restauration ciblée ; (3) import d'une carte mémoire, reprenant à l'identique les étapes déjà définies par specs/001-import-photos. Hors périmètre : planche-contact JPEG annotée, configuration du contexte de travail, choix de la technologie d'interface (décision de planification)."

User Scenarios & Testing (mandatory)

User Story 1 - Trier une sortie photo fraîchement importée (Priority: P1)

Un photographe vient d'importer une carte mémoire et d'obtenir une copie de travail locale (import, cf. specs/001, ou checkout explicite, cf. specs/005). Il ouvre ce dossier dans l'interface graphique de Régine pour repérer ses meilleures photos et les promouvoir à la racine du dossier (planche-contact directement consultable), sans que les paires RAW+JPEG d'une même capture ne l'obligent à jongler entre deux entrées séparées, et sans être limité à un seul sous-répertoire à la fois.

Why this priority: C'est l'usage le plus fréquent et le plus concret de la GUI — le geste que l'utilisateur répète après chaque sortie photo. Sans lui, la GUI n'apporte aucune valeur par rapport à un simple explorateur de fichiers.

Independent Test: Peut être testé en ouvrant, dans la GUI, un dossier local contenant des paires RAW+JPEG et des fichiers RAW seuls répartis entre raw/ et jpeg/, en promouvant certains fichiers à la racine, puis en vérifiant sur le système de fichiers que les fichiers promus sont bien à la racine du dossier et que les autres n'ont pas bougé — sans dépendre du mode consultation (User Story 2).

Acceptance Scenarios:

  1. Given un dossier local ouvert contenant une capture en RAW+JPEG (même nom hors extension, dans raw/ et jpeg/ respectivement), When l'utilisateur consulte la liste des photos, Then cette capture apparaît comme une seule entrée regroupée, pas comme deux entrées séparées.
  2. Given une entrée regroupée RAW+JPEG affichée, When l'utilisateur promeut cette entrée à la racine, Then le système lui permet de choisir de promouvoir le RAW, le JPEG, ou les deux — jamais une promotion automatique des deux fichiers sans confirmation individuelle (cf. docs/archivage-photo-elements-cles.md section 10 : le choix se fait fichier par fichier, pas par paire).
  3. Given un dossier local ouvert, When l'utilisateur navigue, Then il peut voir et parcourir ensemble les photos de plusieurs dossiers de format (raw/, jpeg/, tiff/) du même dossier, sans changer manuellement de répertoire à chaque fois.
  4. Given un dossier parent de voyage (avec ses sous-dossiers/étapes, cf. specs/004), When l'utilisateur l'ouvre dans la GUI, Then il peut voir la racine du dossier parent et les racines de ses sous-dossiers dans une même vue combinée.
  5. Given une photo déjà promue à la racine, When l'utilisateur la rétrograde, Then elle retourne à son dossier de format d'origine, sans être supprimée.
  6. Given une photo identifiée comme déchet évident (test d'exposition, déclenchement accidentel), When l'utilisateur demande sa suppression depuis la GUI, Then le système ne supprime rien immédiatement : la suppression est présentée comme un changement à valider explicitement au moment de la réconciliation (specs/005), jamais une suppression directe et silencieuse depuis l'écran de tri (Principe II).
  7. Given une action de promotion ou de rétrogradation, When l'utilisateur la déclenche, Then la même action est également exposée par une commande en ligne de commande équivalente (Principe CLI-first de la constitution) — la GUI ne peut pas être la seule façon d'accomplir cette action.

User Story 2 - Retrouver une photo dans l'archive sans tout rapatrier (Priority: P2)

Un photographe se souvient avoir pris une photo il y a plusieurs mois mais ne sait plus dans quel dossier, ou a supprimé par erreur un RAW de sa copie de travail locale. Plutôt que de faire un checkout complet du dossier concerné (potentiellement plusieurs dizaines de Go, cf. specs/005), il consulte l'archive directement en lecture seule depuis la GUI, retrouve la photo par une recherche, et en restaure une copie ciblée vers un emplacement local de son choix.

Why this priority: Un raffinement précieux mais moins fréquent que le tri (User Story 1) — un utilisateur qui ne perd jamais de fichier ou qui se souvient toujours de l'emplacement de ses dossiers peut se passer de cette fonctionnalité sans perdre l'essentiel de la valeur de la GUI.

Independent Test: Peut être testé en ouvrant la GUI en mode consultation sur une archive contenant plusieurs dossiers, en recherchant un dossier ou une photo par nom/date/texte, et en restaurant un fichier trouvé vers un dossier local vide, sans avoir réalisé de checkout complet au préalable.

Acceptance Scenarios:

  1. Given une archive accessible, When l'utilisateur ouvre le mode consultation, Then il peut parcourir les dossiers de l'archive sans qu'aucun fichier ne soit copié localement tant qu'il ne le demande pas explicitement.
  2. Given le mode consultation ouvert, When l'utilisateur recherche par nom de dossier, par date, ou par texte de titre, Then les dossiers et photos correspondants sont présentés, y compris à l'intérieur d'un dossier parent de voyage (dossier parent et ses sous-dossiers/étapes).
  3. Given une photo repérée en consultation, When l'utilisateur demande sa restauration, Then le système en copie une version vérifiée (somme de contrôle) vers un emplacement local choisi par l'utilisateur, sans verrouiller ni checkouter le dossier entier.
  4. Given le mode consultation, When l'utilisateur y navigue, Then aucune action d'écriture (promotion, suppression, modification) n'y est possible — ces actions restent réservées à une copie de travail réellement checkoutée (User Story 1).
  5. Given l'archive momentanément inaccessible (partage réseau non monté), When l'utilisateur ouvre le mode consultation, Then le système réutilise l'assistance au montage déjà prévue (specs/003) plutôt que d'échouer sans explication.

User Story 3 - Importer une carte mémoire depuis l'interface graphique (Priority: P3)

Un photographe qui utilise déjà l'interface graphique de Régine pour trier ses photos vient de débrancher une carte mémoire. Il veut lancer l'import directement depuis la GUI — analyse de la carte, découpage éventuel en groupes, choix de destination, titre, confirmation avant écriture — puis enchaîner sur le tri (User Story 1) du dossier fraîchement importé, sans repasser par la ligne de commande.

Why this priority: Confort d'usage pur — la CLI (regine import) couvre déjà 100% de ces capacités et continue de fonctionner à l'identique ; un utilisateur à l'aise avec la ligne de commande peut se passer entièrement de cet onglet. Priorité identique à celle de l'onglet de configuration (specs/003 User Story 4), pour la même raison.

Independent Test: Peut être testé en ouvrant l'onglet d'import de la GUI, en y import et une carte mémoire à une seule journée jamais importée, puis en vérifiant que le dossier obtenu dans l'espace de travail local (nom, classement par format, fichiers renommés) est strictement identique à celui que produirait regine import sur la même carte — sans qu'aucune écriture n'ait eu lieu sur l'archive NAS (cf. specs/001-import-photos, révision 2026-09-22).

Acceptance Scenarios:

  1. Given l'onglet d'import ouvert, When l'utilisateur y sélectionne une carte mémoire, Then la GUI affiche la répartition jour par jour (nombre de photos, plage horaire) calculée par regine_core.import, sans recalculer elle-même cette analyse (Principe VI).
  2. Given une répartition jour par jour affichée avec un jour mis en avant comme candidat au détachement, When l'utilisateur choisit de le détacher ou de conserver un seul groupe, Then la GUI applique exactement ce choix — jamais un détachement automatique sans validation (cf. FR-006 de specs/001-import-photos).
  3. Given un groupe prêt à être traité, When l'utilisateur choisit sa destination (nouveau dossier, nouveau sous-dossier, fusion, nouveau dossier parent de voyage) et saisit un titre, Then la GUI applique les mêmes règles de nommage, de répertoire racine et de détection de collision que la CLI (specs/001-import-photos FR-007/FR-010/FR-012), sans logique de validation propre à la GUI.
  4. Given un groupe prêt à être publié localement, When l'utilisateur confirme, Then la GUI présente d'abord le même résumé que la CLI (nombre de fichiers, taille, dossier de destination) et attend une confirmation explicite avant toute écriture dans l'espace de travail local — aucune écriture n'a lieu sur l'archive NAS à ce stade (cf. FR-018/019 de specs/001-import-photos, révision 2026-09-22 : l'archivage est une action distincte et ultérieure, regine reconcile).
  5. Given une collision de nom d'origine entre deux boîtiers nécessitant une désambiguïsation manuelle, When cette collision survient pendant un import déclenché depuis la GUI, Then la GUI présente les mêmes options de résolution (profil, numéro de série, étiquetage manuel) que la CLI, jamais une désambiguïsation inventée par la GUI (cf. specs/002-profil-boitiers-optionnel).
  6. Given un import en cours depuis cet onglet, When les fichiers sont copiés et vérifiés, Then l'utilisateur voit la progression, puis un résultat (fichiers importés, fichiers ignorés car déjà présents sur une carte précédemment importée, anomalies de date signalées) équivalent à celui que rapporterait la CLI.
  7. Given un import venant d'aboutir depuis cet onglet, When l'utilisateur veut revoir le résultat, Then il peut ouvrir directement le dossier importé dans l'onglet Tri (User Story 1) sans quitter la GUI.

Edge Cases

  • Que se passe-t-il si l'utilisateur tente d'ouvrir en tri/culling (User Story 1) un dossier qui n'est pas réellement une copie de travail Régine (pas de structure par format reconnue) ? Le système DOIT le signaler clairement plutôt que d'afficher une liste vide ou une erreur technique.
  • Que se passe-t-il si deux fichiers de dossiers de format différents partagent le même nom hors extension mais ne sont pas une paire RAW+JPEG légitime (coïncidence de nommage) ? Le regroupement visuel reste purement indicatif ; aucune action destructive ne doit dépendre de cette supposition d'appariement.
  • Que se passe-t-il si l'utilisateur demande la restauration d'un fichier (User Story 2) vers un emplacement local qui contient déjà un fichier de même nom mais de contenu différent ? Le système DOIT refuser d'écraser silencieusement (cohérent avec le principe déjà appliqué à l'import et à l'archivage, specs/001).
  • Que se passe-t-il si l'utilisateur ferme la GUI avec des promotions/rétrogradations effectuées mais le dossier non encore réconcilié ? Rien ne doit être perdu : ces changements restent sur le système de fichiers local, à réconcilier plus tard (specs/005) comme n'importe quel autre changement local.
  • Que se passe-t-il si l'archive contient un très grand nombre de dossiers en mode consultation ? La recherche DOIT rester utilisable sans imposer de charger l'intégralité de l'archive en mémoire d'un coup.
  • Que se passe-t-il si l'utilisateur ferme l'onglet d'import (ou la GUI) pendant qu'une publication locale est en cours ? Le système DOIT empêcher la fermeture pendant l'écriture, ou garantir que celle-ci se termine ou échoue proprement avant de fermer, jamais laisser un dossier local partiellement écrit.
  • Que se passe-t-il si le partage réseau de l'archive n'est pas monté au moment d'un import déclenché depuis la GUI ? L'import DOIT pouvoir aboutir normalement (aucune écriture sur l'archive à ce stade, cf. specs/001-import-photos révision 2026-09-22) ; seule une note informative, jamais bloquante, rappelle que l'archivage ultérieur nécessitera que ce partage soit accessible.
  • Que se passe-t-il si l'emplacement sélectionné comme carte mémoire dans l'onglet d'import ne correspond pas à un support amovible réel (ex. sélection accidentelle d'un dossier de l'archive) ? La GUI DOIT signaler la même anomalie que la CLI le ferait, plutôt que de lancer un import sur une source invalide.

Requirements (mandatory)

Functional Requirements

  • FR-001: Le système DOIT afficher, pour un dossier de travail local ouvert, l'ensemble des photos réparties dans ses dossiers de format (raw/, jpeg/, tiff/...) et à sa racine, en une seule vue navigable.
  • FR-002: Le système DOIT regrouper visuellement, comme une seule entrée, un fichier RAW et son JPEG jumeau (même nom hors extension, capture en mode RAW+JPEG), même lorsqu'ils résident dans des dossiers de format différents.
  • FR-003: Le système DOIT permettre de promouvoir un fichier individuel (RAW ou JPEG, indépendamment de son jumeau éventuel) à la racine du dossier, et de le rétrograder — décision toujours prise fichier par fichier, jamais automatiquement par paire.
  • FR-004: Le système DOIT permettre de naviguer et visualiser ensemble plusieurs dossiers de format d'un même dossier, sans obliger l'utilisateur à changer manuellement de répertoire.
  • FR-005: Pour un dossier parent avec des sous-dossiers (voyage en plusieurs étapes, specs/004), le système DOIT permettre une vue combinant la racine du dossier parent et celles de ses sous-dossiers.
  • FR-006: Le système NE DOIT PAS supprimer un fichier directement depuis l'écran de tri : toute suppression proposée DOIT être présentée comme un changement à valider explicitement lors de la réconciliation (specs/005), jamais exécutée immédiatement (Principe II).
  • FR-007: Chaque action de promotion/rétrogradation exposée par la GUI DOIT être également accomplissable par une commande en ligne de commande équivalente (Principe CLI-first de la constitution) ; l'action sous-jacente (promotion à la racine de sélection) n'existe dans aucun module existant de regine-core et DOIT être construite comme telle, pas comme une logique propre à la GUI (Principe VI).
  • FR-008: Le système DOIT permettre de parcourir l'archive en lecture seule, par dossier, par date, ou par texte de titre, sans nécessiter de checkout complet préalable.
  • FR-009: Le système DOIT permettre de restaurer une copie vérifiée (somme de contrôle) d'un fichier repéré dans l'archive vers un emplacement local choisi par l'utilisateur, sans verrouiller ni checkouter le dossier entier dont il provient.
  • FR-010: Le système NE DOIT PAS permettre d'action d'écriture (promotion, suppression, modification) depuis le mode consultation en lecture seule — ces actions restent réservées à une copie de travail réellement checkoutée.
  • FR-011: Si l'archive est momentanément inaccessible au moment d'une consultation, le système DOIT réutiliser l'assistance au montage déjà prévue (specs/003) plutôt que d'échouer sans explication.
  • FR-012: Le système DOIT refuser d'écraser silencieusement un fichier local déjà présent lors d'une restauration ciblée (User Story 2) si son contenu diffère de celui restauré.
  • FR-013: Le système DOIT signaler clairement à l'utilisateur qu'un dossier ouvert en tri/culling n'a pas la structure attendue d'un dossier Régine, plutôt que d'afficher un résultat vide ou trompeur.
  • FR-014: Le système DOIT exposer, dans un onglet dédié de la GUI, l'ensemble des étapes de l'import d'une carte mémoire (analyse jour par jour, découpage en groupes, choix de destination, titre, confirmation, résultat) en appelant directement les mêmes fonctions de regine_core.import que la CLI (regine import), sans dupliquer la moindre règle d'analyse, de nommage, de collision ou de désambiguïsation (Principe VI) — toute règle déjà vraie côté CLI (specs/001-import-photos) reste vraie à l'identique depuis la GUI.
  • FR-015: Le système DOIT présenter, avant toute écriture locale déclenchée depuis l'onglet d'import, le même résumé de confirmation (nombre de fichiers, taille, dossier de destination) que celui déjà requis côté CLI (FR-018 de specs/001-import-photos), et attendre une confirmation explicite. Aucune écriture sur l'archive NAS ne DOIT survenir depuis cet onglet (FR-019 de specs/001-import-photos, révision 2026-09-22) : l'archivage reste une action distincte, hors périmètre de cet onglet pour l'instant (cf. Assumptions).
  • FR-016: Lorsqu'une collision de nom d'origine entre boîtiers nécessite une désambiguïsation manuelle (specs/002-profil-boitiers-optionnel), le système DOIT présenter depuis l'onglet d'import les mêmes options de résolution que la CLI, jamais une logique de désambiguïsation propre à la GUI.
  • FR-017: Le système DOIT afficher la progression et le résultat de l'import (fichiers copiés et vérifiés, fichiers ignorés car déjà importés, anomalies de date signalées) au fur et à mesure de son exécution depuis l'onglet d'import, sans obliger l'utilisateur à attendre la fin sans retour visuel.
  • FR-018: Chaque action de l'onglet d'import DOIT rester accomplissable de façon identique par la commande CLI équivalente (regine import) (Principe CLI-first de la constitution) — la GUI ne peut pas être la seule façon de réaliser un import.

Key Entities

  • Entrée regroupée : représentation à l'écran d'une capture, combinant son RAW et son JPEG jumeau quand les deux existent (même nom hors extension) ; purement visuelle, ne modifie jamais la relation entre les deux fichiers sur le système de fichiers.
  • Racine de sélection : niveau d'un dossier (ou d'un sous-dossier, ou de la racine d'un dossier parent) où vivent les fichiers promus, déjà défini par docs/archivage-photo-elements-cles.md section 10 — cette spécification n'en redéfinit pas la sémantique, seulement son exposition interactive.
  • Vue de consultation : navigation en lecture seule de l'archive, indépendante de toute copie de travail locale, sans manifeste ni verrou associés.
  • Restauration ciblée : copie vérifiée d'un ou plusieurs fichiers précis de l'archive vers un emplacement local, distincte d'un checkout complet de dossier (pas de manifeste, pas de verrou, pas de réconciliation attendue en retour).
  • Onglet d'import : façade GUI de l'import d'une carte mémoire, reprenant à l'identique les étapes déjà définies par specs/001-import-photos (analyse, découpage, destination, titre, confirmation, désambiguïsation de collision), sans logique métier propre ni règle de validation additionnelle.

Success Criteria (mandatory)

Measurable Outcomes

  • SC-001: Un utilisateur peut trier un dossier de 200 photos (avec paires RAW+JPEG) et promouvoir sa sélection à la racine sans jamais supprimer par erreur un fichier de la paire au seul motif de désencombrer l'affichage.
  • SC-002: 100% des paires RAW+JPEG d'un dossier ouvert en tri/culling apparaissent comme une entrée unique, jamais comme deux entrées séparées.
  • SC-003: Un utilisateur retrouve une photo précise dans une archive de plusieurs centaines de dossiers, par recherche, sans avoir à se souvenir du chemin exact ni à réaliser de checkout complet.
  • SC-004: 100% des restaurations ciblées depuis le mode consultation sont vérifiées par somme de contrôle avant d'être considérées réussies.
  • SC-005: 0% des suppressions déclenchées depuis l'écran de tri n'aboutissent à une perte de fichier sans confirmation explicite préalable à la réconciliation.
  • SC-006: Chaque action de promotion/rétrogradation disponible dans la GUI reste accomplissable via une commande CLI équivalente, sans exception.
  • SC-007: Un import réalisé depuis l'onglet GUI produit un dossier local strictement identique (même nom, mêmes fichiers renommés, même classement par format, même répertoire racine prévu) à celui qu'aurait produit le même import via la CLI — et aucune écriture n'a lieu sur l'archive NAS (cf. specs/001-import-photos, révision 2026-09-22).
  • SC-008: 0% des écritures locales déclenchées depuis l'onglet d'import ne surviennent sans confirmation explicite préalable de l'utilisateur.

Assumptions

  • La GUI ne lance pas et ne remplace pas l'outil d'édition RAW (DxO, Lightroom...) : elle offre son propre écran de tri/sélection, que l'utilisateur peut utiliser en complément ou à la place de DxO pour la seule promotion à la racine — le développement RAW (recadrage, étalonnage) continue de se faire dans l'outil du choix de l'utilisateur.
  • Cette version ne couvre pas la notation en étoiles ni les annotations visuelles (réservées à la planche-contact JPEG annotée, hors périmètre, docs/interface-cli-gui-architecture.md) : seule la promotion binaire à la racine est couverte ici.
  • La restauration ciblée (User Story 2) porte sur un fichier ou une petite sélection de fichiers, pas sur un dossier entier — restaurer un dossier entier reste le rôle du checkout complet déjà spécifié (specs/005).
  • Le mode consultation ne respecte ni ne vérifie le verrou applicatif d'un dossier (specs/005) : la lecture seule ne modifiant rien, elle n'entre jamais en conflit avec un checkout en cours ailleurs.
  • La promotion/rétrogradation à la racine de sélection est une capacité entièrement nouvelle de regine-core (aucun module existant ne la couvre) ; cette spécification suppose qu'elle sera conçue comme un module à part entière (probablement regine_core.dossier, qui porte déjà la notion de racine de sélection) plutôt que dupliquée entre la façade CLI et la façade GUI (Principe VI).
  • Le choix de la technologie d'interface graphique (PySide6 natif vs GUI web packagée, cf. docs/interface-cli-gui-architecture.md, non tranché) est une décision de planification, pas de cette spécification comportementale.
  • L'onglet d'import (User Story 3) réutilise l'infrastructure à onglets déjà en place dans regine-gui (app.py, QTabWidget) plutôt que d'introduire une nouvelle application ; il n'ajoute aucune capacité que la CLI (regine import, specs/001-import-photos) n'a pas déjà — à l'image de l'onglet Configuration (specs/003 User Story 4).
  • Révisé le 2026-09-22 : suite à la révision de specs/001-import-photos (l'import s'arrête à une copie de travail locale, jamais une écriture NAS), l'onglet d'import ne déclenche plus aucun archivage lui-même. L'archivage effectif (regine reconcile) reste CLI uniquement pour l'instant : cette spécification ne couvre pas de bouton ou d'écran GUI dédié à la réconciliation/l'archivage — à ajouter comme une User Story distincte le jour où ce besoin est exprimé, sans que cela remette en cause l'onglet d'import tel que décrit ici.
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# Feature Specification: Interface graphique de tri et de consultation

**Feature Branch**: `[006-gui-tri-consultation]`

**Created**: 2026-09-20

**Status**: Draft

**Input**: User description: "Interface graphique de Régine (GUI), cadrée dans docs/interface-cli-gui-architecture.md et docs/archivage-photo-elements-cles.md section 10, jamais encore spécifiée. Façade fine au-dessus de regine-core (Principe VI), aucune logique métier propre — importe la bibliothèque dans le même processus, pas de daemon. Trois modes d'usage : (1) tri/culling pendant l'édition sur un dossier checké out en local, avec regroupement visuel RAW+JPEG jumeau et navigation combinant plusieurs dossiers de format/sous-dossiers d'un même dossier ; (2) consultation en lecture seule de l'archive NAS sans checkout complet, avec recherche et restauration ciblée ; (3) import d'une carte mémoire, reprenant à l'identique les étapes déjà définies par `specs/001-import-photos`. Hors périmètre : planche-contact JPEG annotée, configuration du contexte de travail, choix de la technologie d'interface (décision de planification)."

## User Scenarios & Testing *(mandatory)*

### User Story 1 - Trier une sortie photo fraîchement importée (Priority: P1)

Un photographe vient d'importer une carte mémoire et d'obtenir une copie de travail locale (import, cf. `specs/001`, ou checkout explicite, cf. `specs/005`). Il ouvre ce dossier dans l'interface graphique de Régine pour repérer ses meilleures photos et les promouvoir à la racine du dossier (planche-contact directement consultable), sans que les paires RAW+JPEG d'une même capture ne l'obligent à jongler entre deux entrées séparées, et sans être limité à un seul sous-répertoire à la fois.

**Why this priority**: C'est l'usage le plus fréquent et le plus concret de la GUI — le geste que l'utilisateur répète après chaque sortie photo. Sans lui, la GUI n'apporte aucune valeur par rapport à un simple explorateur de fichiers.

**Independent Test**: Peut être testé en ouvrant, dans la GUI, un dossier local contenant des paires RAW+JPEG et des fichiers RAW seuls répartis entre `raw/` et `jpeg/`, en promouvant certains fichiers à la racine, puis en vérifiant sur le système de fichiers que les fichiers promus sont bien à la racine du dossier et que les autres n'ont pas bougé — sans dépendre du mode consultation (User Story 2).

**Acceptance Scenarios**:

1. **Given** un dossier local ouvert contenant une capture en RAW+JPEG (même nom hors extension, dans `raw/` et `jpeg/` respectivement), **When** l'utilisateur consulte la liste des photos, **Then** cette capture apparaît comme une seule entrée regroupée, pas comme deux entrées séparées.
2. **Given** une entrée regroupée RAW+JPEG affichée, **When** l'utilisateur promeut cette entrée à la racine, **Then** le système lui permet de choisir de promouvoir le RAW, le JPEG, ou les deux — jamais une promotion automatique des deux fichiers sans confirmation individuelle (cf. `docs/archivage-photo-elements-cles.md` section 10 : le choix se fait fichier par fichier, pas par paire).
3. **Given** un dossier local ouvert, **When** l'utilisateur navigue, **Then** il peut voir et parcourir ensemble les photos de plusieurs dossiers de format (`raw/`, `jpeg/`, `tiff/`) du même dossier, sans changer manuellement de répertoire à chaque fois.
4. **Given** un dossier parent de voyage (avec ses sous-dossiers/étapes, cf. `specs/004`), **When** l'utilisateur l'ouvre dans la GUI, **Then** il peut voir la racine du dossier parent et les racines de ses sous-dossiers dans une même vue combinée.
5. **Given** une photo déjà promue à la racine, **When** l'utilisateur la rétrograde, **Then** elle retourne à son dossier de format d'origine, sans être supprimée.
6. **Given** une photo identifiée comme déchet évident (test d'exposition, déclenchement accidentel), **When** l'utilisateur demande sa suppression depuis la GUI, **Then** le système ne supprime rien immédiatement : la suppression est présentée comme un changement à valider explicitement au moment de la réconciliation (`specs/005`), jamais une suppression directe et silencieuse depuis l'écran de tri (Principe II).
7. **Given** une action de promotion ou de rétrogradation, **When** l'utilisateur la déclenche, **Then** la même action est également exposée par une commande en ligne de commande équivalente (Principe CLI-first de la constitution) — la GUI ne peut pas être la seule façon d'accomplir cette action.

---

### User Story 2 - Retrouver une photo dans l'archive sans tout rapatrier (Priority: P2)

Un photographe se souvient avoir pris une photo il y a plusieurs mois mais ne sait plus dans quel dossier, ou a supprimé par erreur un RAW de sa copie de travail locale. Plutôt que de faire un checkout complet du dossier concerné (potentiellement plusieurs dizaines de Go, cf. `specs/005`), il consulte l'archive directement en lecture seule depuis la GUI, retrouve la photo par une recherche, et en restaure une copie ciblée vers un emplacement local de son choix.

**Why this priority**: Un raffinement précieux mais moins fréquent que le tri (User Story 1) — un utilisateur qui ne perd jamais de fichier ou qui se souvient toujours de l'emplacement de ses dossiers peut se passer de cette fonctionnalité sans perdre l'essentiel de la valeur de la GUI.

**Independent Test**: Peut être testé en ouvrant la GUI en mode consultation sur une archive contenant plusieurs dossiers, en recherchant un dossier ou une photo par nom/date/texte, et en restaurant un fichier trouvé vers un dossier local vide, sans avoir réalisé de checkout complet au préalable.

**Acceptance Scenarios**:

1. **Given** une archive accessible, **When** l'utilisateur ouvre le mode consultation, **Then** il peut parcourir les dossiers de l'archive sans qu'aucun fichier ne soit copié localement tant qu'il ne le demande pas explicitement.
2. **Given** le mode consultation ouvert, **When** l'utilisateur recherche par nom de dossier, par date, ou par texte de titre, **Then** les dossiers et photos correspondants sont présentés, y compris à l'intérieur d'un dossier parent de voyage (dossier parent et ses sous-dossiers/étapes).
3. **Given** une photo repérée en consultation, **When** l'utilisateur demande sa restauration, **Then** le système en copie une version vérifiée (somme de contrôle) vers un emplacement local choisi par l'utilisateur, sans verrouiller ni checkouter le dossier entier.
4. **Given** le mode consultation, **When** l'utilisateur y navigue, **Then** aucune action d'écriture (promotion, suppression, modification) n'y est possible — ces actions restent réservées à une copie de travail réellement checkoutée (User Story 1).
5. **Given** l'archive momentanément inaccessible (partage réseau non monté), **When** l'utilisateur ouvre le mode consultation, **Then** le système réutilise l'assistance au montage déjà prévue (`specs/003`) plutôt que d'échouer sans explication.

---

### User Story 3 - Importer une carte mémoire depuis l'interface graphique (Priority: P3)

Un photographe qui utilise déjà l'interface graphique de Régine pour trier ses photos vient de débrancher une carte mémoire. Il veut lancer l'import directement depuis la GUI — analyse de la carte, découpage éventuel en groupes, choix de destination, titre, confirmation avant écriture — puis enchaîner sur le tri (User Story 1) du dossier fraîchement importé, sans repasser par la ligne de commande.

**Why this priority**: Confort d'usage pur — la CLI (`regine import`) couvre déjà 100% de ces capacités et continue de fonctionner à l'identique ; un utilisateur à l'aise avec la ligne de commande peut se passer entièrement de cet onglet. Priorité identique à celle de l'onglet de configuration (`specs/003` User Story 4), pour la même raison.

**Independent Test**: Peut être testé en ouvrant l'onglet d'import de la GUI, en y import et une carte mémoire à une seule journée jamais importée, puis en vérifiant que le dossier obtenu dans l'espace de travail local (nom, classement par format, fichiers renommés) est strictement identique à celui que produirait `regine import` sur la même carte — sans qu'aucune écriture n'ait eu lieu sur l'archive NAS (cf. `specs/001-import-photos`, révision 2026-09-22).

**Acceptance Scenarios**:

1. **Given** l'onglet d'import ouvert, **When** l'utilisateur y sélectionne une carte mémoire, **Then** la GUI affiche la répartition jour par jour (nombre de photos, plage horaire) calculée par `regine_core.import`, sans recalculer elle-même cette analyse (Principe VI).
2. **Given** une répartition jour par jour affichée avec un jour mis en avant comme candidat au détachement, **When** l'utilisateur choisit de le détacher ou de conserver un seul groupe, **Then** la GUI applique exactement ce choix — jamais un détachement automatique sans validation (cf. FR-006 de `specs/001-import-photos`).
3. **Given** un groupe prêt à être traité, **When** l'utilisateur choisit sa destination (nouveau dossier, nouveau sous-dossier, fusion, nouveau dossier parent de voyage) et saisit un titre, **Then** la GUI applique les mêmes règles de nommage, de répertoire racine et de détection de collision que la CLI (`specs/001-import-photos` FR-007/FR-010/FR-012), sans logique de validation propre à la GUI.
4. **Given** un groupe prêt à être publié localement, **When** l'utilisateur confirme, **Then** la GUI présente d'abord le même résumé que la CLI (nombre de fichiers, taille, dossier de destination) et attend une confirmation explicite avant toute écriture dans l'espace de travail local — aucune écriture n'a lieu sur l'archive NAS à ce stade (cf. FR-018/019 de `specs/001-import-photos`, révision 2026-09-22 : l'archivage est une action distincte et ultérieure, `regine reconcile`).
5. **Given** une collision de nom d'origine entre deux boîtiers nécessitant une désambiguïsation manuelle, **When** cette collision survient pendant un import déclenché depuis la GUI, **Then** la GUI présente les mêmes options de résolution (profil, numéro de série, étiquetage manuel) que la CLI, jamais une désambiguïsation inventée par la GUI (cf. `specs/002-profil-boitiers-optionnel`).
6. **Given** un import en cours depuis cet onglet, **When** les fichiers sont copiés et vérifiés, **Then** l'utilisateur voit la progression, puis un résultat (fichiers importés, fichiers ignorés car déjà présents sur une carte précédemment importée, anomalies de date signalées) équivalent à celui que rapporterait la CLI.
7. **Given** un import venant d'aboutir depuis cet onglet, **When** l'utilisateur veut revoir le résultat, **Then** il peut ouvrir directement le dossier importé dans l'onglet Tri (User Story 1) sans quitter la GUI.

---

### Edge Cases

- Que se passe-t-il si l'utilisateur tente d'ouvrir en tri/culling (User Story 1) un dossier qui n'est pas réellement une copie de travail Régine (pas de structure par format reconnue) ? Le système DOIT le signaler clairement plutôt que d'afficher une liste vide ou une erreur technique.
- Que se passe-t-il si deux fichiers de dossiers de format différents partagent le même nom hors extension mais ne sont *pas* une paire RAW+JPEG légitime (coïncidence de nommage) ? Le regroupement visuel reste purement indicatif ; aucune action destructive ne doit dépendre de cette supposition d'appariement.
- Que se passe-t-il si l'utilisateur demande la restauration d'un fichier (User Story 2) vers un emplacement local qui contient déjà un fichier de même nom mais de contenu différent ? Le système DOIT refuser d'écraser silencieusement (cohérent avec le principe déjà appliqué à l'import et à l'archivage, `specs/001`).
- Que se passe-t-il si l'utilisateur ferme la GUI avec des promotions/rétrogradations effectuées mais le dossier non encore réconcilié ? Rien ne doit être perdu : ces changements restent sur le système de fichiers local, à réconcilier plus tard (`specs/005`) comme n'importe quel autre changement local.
- Que se passe-t-il si l'archive contient un très grand nombre de dossiers en mode consultation ? La recherche DOIT rester utilisable sans imposer de charger l'intégralité de l'archive en mémoire d'un coup.
- Que se passe-t-il si l'utilisateur ferme l'onglet d'import (ou la GUI) pendant qu'une publication locale est en cours ? Le système DOIT empêcher la fermeture pendant l'écriture, ou garantir que celle-ci se termine ou échoue proprement avant de fermer, jamais laisser un dossier local partiellement écrit.
- Que se passe-t-il si le partage réseau de l'archive n'est pas monté au moment d'un import déclenché depuis la GUI ? L'import DOIT pouvoir aboutir normalement (aucune écriture sur l'archive à ce stade, cf. `specs/001-import-photos` révision 2026-09-22) ; seule une note informative, jamais bloquante, rappelle que l'archivage ultérieur nécessitera que ce partage soit accessible.
- Que se passe-t-il si l'emplacement sélectionné comme carte mémoire dans l'onglet d'import ne correspond pas à un support amovible réel (ex. sélection accidentelle d'un dossier de l'archive) ? La GUI DOIT signaler la même anomalie que la CLI le ferait, plutôt que de lancer un import sur une source invalide.

## Requirements *(mandatory)*

### Functional Requirements

- **FR-001**: Le système DOIT afficher, pour un dossier de travail local ouvert, l'ensemble des photos réparties dans ses dossiers de format (`raw/`, `jpeg/`, `tiff/`...) et à sa racine, en une seule vue navigable.
- **FR-002**: Le système DOIT regrouper visuellement, comme une seule entrée, un fichier RAW et son JPEG jumeau (même nom hors extension, capture en mode RAW+JPEG), même lorsqu'ils résident dans des dossiers de format différents.
- **FR-003**: Le système DOIT permettre de promouvoir un fichier individuel (RAW ou JPEG, indépendamment de son jumeau éventuel) à la racine du dossier, et de le rétrograder — décision toujours prise fichier par fichier, jamais automatiquement par paire.
- **FR-004**: Le système DOIT permettre de naviguer et visualiser ensemble plusieurs dossiers de format d'un même dossier, sans obliger l'utilisateur à changer manuellement de répertoire.
- **FR-005**: Pour un dossier parent avec des sous-dossiers (voyage en plusieurs étapes, `specs/004`), le système DOIT permettre une vue combinant la racine du dossier parent et celles de ses sous-dossiers.
- **FR-006**: Le système NE DOIT PAS supprimer un fichier directement depuis l'écran de tri : toute suppression proposée DOIT être présentée comme un changement à valider explicitement lors de la réconciliation (`specs/005`), jamais exécutée immédiatement (Principe II).
- **FR-007**: Chaque action de promotion/rétrogradation exposée par la GUI DOIT être également accomplissable par une commande en ligne de commande équivalente (Principe CLI-first de la constitution) ; l'action sous-jacente (promotion à la racine de sélection) n'existe dans aucun module existant de `regine-core` et DOIT être construite comme telle, pas comme une logique propre à la GUI (Principe VI).
- **FR-008**: Le système DOIT permettre de parcourir l'archive en lecture seule, par dossier, par date, ou par texte de titre, sans nécessiter de checkout complet préalable.
- **FR-009**: Le système DOIT permettre de restaurer une copie vérifiée (somme de contrôle) d'un fichier repéré dans l'archive vers un emplacement local choisi par l'utilisateur, sans verrouiller ni checkouter le dossier entier dont il provient.
- **FR-010**: Le système NE DOIT PAS permettre d'action d'écriture (promotion, suppression, modification) depuis le mode consultation en lecture seule — ces actions restent réservées à une copie de travail réellement checkoutée.
- **FR-011**: Si l'archive est momentanément inaccessible au moment d'une consultation, le système DOIT réutiliser l'assistance au montage déjà prévue (`specs/003`) plutôt que d'échouer sans explication.
- **FR-012**: Le système DOIT refuser d'écraser silencieusement un fichier local déjà présent lors d'une restauration ciblée (User Story 2) si son contenu diffère de celui restauré.
- **FR-013**: Le système DOIT signaler clairement à l'utilisateur qu'un dossier ouvert en tri/culling n'a pas la structure attendue d'un dossier Régine, plutôt que d'afficher un résultat vide ou trompeur.
- **FR-014**: Le système DOIT exposer, dans un onglet dédié de la GUI, l'ensemble des étapes de l'import d'une carte mémoire (analyse jour par jour, découpage en groupes, choix de destination, titre, confirmation, résultat) en appelant directement les mêmes fonctions de `regine_core.import` que la CLI (`regine import`), sans dupliquer la moindre règle d'analyse, de nommage, de collision ou de désambiguïsation (Principe VI) — toute règle déjà vraie côté CLI (`specs/001-import-photos`) reste vraie à l'identique depuis la GUI.
- **FR-015**: Le système DOIT présenter, avant toute écriture locale déclenchée depuis l'onglet d'import, le même résumé de confirmation (nombre de fichiers, taille, dossier de destination) que celui déjà requis côté CLI (FR-018 de `specs/001-import-photos`), et attendre une confirmation explicite. Aucune écriture sur l'archive NAS ne DOIT survenir depuis cet onglet (FR-019 de `specs/001-import-photos`, révision 2026-09-22) : l'archivage reste une action distincte, hors périmètre de cet onglet pour l'instant (cf. Assumptions).
- **FR-016**: Lorsqu'une collision de nom d'origine entre boîtiers nécessite une désambiguïsation manuelle (`specs/002-profil-boitiers-optionnel`), le système DOIT présenter depuis l'onglet d'import les mêmes options de résolution que la CLI, jamais une logique de désambiguïsation propre à la GUI.
- **FR-017**: Le système DOIT afficher la progression et le résultat de l'import (fichiers copiés et vérifiés, fichiers ignorés car déjà importés, anomalies de date signalées) au fur et à mesure de son exécution depuis l'onglet d'import, sans obliger l'utilisateur à attendre la fin sans retour visuel.
- **FR-018**: Chaque action de l'onglet d'import DOIT rester accomplissable de façon identique par la commande CLI équivalente (`regine import`) (Principe CLI-first de la constitution) — la GUI ne peut pas être la seule façon de réaliser un import.

### Key Entities

- **Entrée regroupée** : représentation à l'écran d'une capture, combinant son RAW et son JPEG jumeau quand les deux existent (même nom hors extension) ; purement visuelle, ne modifie jamais la relation entre les deux fichiers sur le système de fichiers.
- **Racine de sélection** : niveau d'un dossier (ou d'un sous-dossier, ou de la racine d'un dossier parent) où vivent les fichiers promus, déjà défini par `docs/archivage-photo-elements-cles.md` section 10 — cette spécification n'en redéfinit pas la sémantique, seulement son exposition interactive.
- **Vue de consultation** : navigation en lecture seule de l'archive, indépendante de toute copie de travail locale, sans manifeste ni verrou associés.
- **Restauration ciblée** : copie vérifiée d'un ou plusieurs fichiers précis de l'archive vers un emplacement local, distincte d'un checkout complet de dossier (pas de manifeste, pas de verrou, pas de réconciliation attendue en retour).
- **Onglet d'import** : façade GUI de l'import d'une carte mémoire, reprenant à l'identique les étapes déjà définies par `specs/001-import-photos` (analyse, découpage, destination, titre, confirmation, désambiguïsation de collision), sans logique métier propre ni règle de validation additionnelle.

## Success Criteria *(mandatory)*

### Measurable Outcomes

- **SC-001**: Un utilisateur peut trier un dossier de 200 photos (avec paires RAW+JPEG) et promouvoir sa sélection à la racine sans jamais supprimer par erreur un fichier de la paire au seul motif de désencombrer l'affichage.
- **SC-002**: 100% des paires RAW+JPEG d'un dossier ouvert en tri/culling apparaissent comme une entrée unique, jamais comme deux entrées séparées.
- **SC-003**: Un utilisateur retrouve une photo précise dans une archive de plusieurs centaines de dossiers, par recherche, sans avoir à se souvenir du chemin exact ni à réaliser de checkout complet.
- **SC-004**: 100% des restaurations ciblées depuis le mode consultation sont vérifiées par somme de contrôle avant d'être considérées réussies.
- **SC-005**: 0% des suppressions déclenchées depuis l'écran de tri n'aboutissent à une perte de fichier sans confirmation explicite préalable à la réconciliation.
- **SC-006**: Chaque action de promotion/rétrogradation disponible dans la GUI reste accomplissable via une commande CLI équivalente, sans exception.
- **SC-007**: Un import réalisé depuis l'onglet GUI produit un dossier local strictement identique (même nom, mêmes fichiers renommés, même classement par format, même répertoire racine prévu) à celui qu'aurait produit le même import via la CLI — et aucune écriture n'a lieu sur l'archive NAS (cf. `specs/001-import-photos`, révision 2026-09-22).
- **SC-008**: 0% des écritures locales déclenchées depuis l'onglet d'import ne surviennent sans confirmation explicite préalable de l'utilisateur.

## Assumptions

- La GUI ne lance pas et ne remplace pas l'outil d'édition RAW (DxO, Lightroom...) : elle offre son propre écran de tri/sélection, que l'utilisateur peut utiliser en complément ou à la place de DxO pour la seule promotion à la racine — le développement RAW (recadrage, étalonnage) continue de se faire dans l'outil du choix de l'utilisateur.
- Cette version ne couvre pas la notation en étoiles ni les annotations visuelles (réservées à la planche-contact JPEG annotée, hors périmètre, `docs/interface-cli-gui-architecture.md`) : seule la promotion binaire à la racine est couverte ici.
- La restauration ciblée (User Story 2) porte sur un fichier ou une petite sélection de fichiers, pas sur un dossier entier — restaurer un dossier entier reste le rôle du checkout complet déjà spécifié (`specs/005`).
- Le mode consultation ne respecte ni ne vérifie le verrou applicatif d'un dossier (`specs/005`) : la lecture seule ne modifiant rien, elle n'entre jamais en conflit avec un checkout en cours ailleurs.
- La promotion/rétrogradation à la racine de sélection est une capacité entièrement nouvelle de `regine-core` (aucun module existant ne la couvre) ; cette spécification suppose qu'elle sera conçue comme un module à part entière (probablement `regine_core.dossier`, qui porte déjà la notion de racine de sélection) plutôt que dupliquée entre la façade CLI et la façade GUI (Principe VI).
- Le choix de la technologie d'interface graphique (PySide6 natif vs GUI web packagée, cf. `docs/interface-cli-gui-architecture.md`, non tranché) est une décision de planification, pas de cette spécification comportementale.
- L'onglet d'import (User Story 3) réutilise l'infrastructure à onglets déjà en place dans `regine-gui` (`app.py`, `QTabWidget`) plutôt que d'introduire une nouvelle application ; il n'ajoute aucune capacité que la CLI (`regine import`, `specs/001-import-photos`) n'a pas déjà — à l'image de l'onglet Configuration (`specs/003` User Story 4).
- **Révisé le 2026-09-22** : suite à la révision de `specs/001-import-photos` (l'import s'arrête à une copie de travail locale, jamais une écriture NAS), l'onglet d'import ne déclenche plus aucun archivage lui-même. L'archivage effectif (`regine reconcile`) reste CLI uniquement pour l'instant : cette spécification ne couvre pas de bouton ou d'écran GUI dédié à la réconciliation/l'archivage — à ajouter comme une User Story distincte le jour où ce besoin est exprimé, sans que cela remette en cause l'onglet d'import tel que décrit ici.