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
chargement plus rapide des photos, async eca67cf · on main · Fabien Champigny · Sep 22, 2026
plan.md · 119 lines · 11.8 KBmarkdown
Blame HistoryOpen raw

Implementation Plan: Interface graphique de tri et de consultation

Branch: 006-gui-tri-consultation | Date: 2026-09-20 | Spec: spec.md

Input: Feature specification from /specs/006-gui-tri-consultation/spec.md

Summary

Une façade graphique de bureau (regine-gui, PySide6) couvrant trois usages : le tri/culling d'un dossier de travail local déjà checkouté (regroupement visuel RAW+JPEG, promotion/rétrogradation individuelle à la racine de sélection, vue combinant plusieurs dossiers de format et, pour un dossier parent, ses sous-dossiers) ; la consultation en lecture seule de l'archive NAS (recherche, restauration ciblée d'un fichier sans checkout complet) ; et, depuis l'ajout de la User Story 3 (2026-09-21), l'import d'une carte mémoire (analyse jour par jour, découpage en groupes, destination, titre, confirmation), en appelant directement les fonctions déjà définies et testées par specs/001-import-photos (regine_core.import_carte), jamais l'orchestration interactive propre à regine_cli.import_cmd (cf. research.md § 6). La promotion/rétrogradation à la racine de sélection est une capacité entièrement nouvelle de regine-core (aucun module existant ne la couvre) : par le Principe CLI-first de la constitution, elle est d'abord construite comme fonctions de bibliothèque + sous-commande CLI, la GUI n'en étant qu'une façade supplémentaire au même titre que la CLI (Principe VI) — jamais l'inverse. L'onglet d'import (US3), lui, n'introduit aucune nouvelle fonction regine_core : la CLI (regine import) couvre déjà toutes les règles, la GUI n'en est qu'une seconde façade.

Technical Context

Language/Version: Python 3.11+ (cohérent avec le reste de regine-core/regine-cli)

Primary Dependencies: PySide6 (interface graphique native Qt, cf. research.md § 1) pour regine-gui uniquement. Aucune nouvelle dépendance pour regine-core/regine-cli (bibliothèque standard, pathlib/shutil, cohérent avec le reste du projet).

Storage: Aucune nouvelle base. Le tri/culling (US1) opère sur une copie de travail déjà checkoutée (manifeste/verrou existants, specs/005) ; la consultation (US2) est purement en lecture, sans manifeste ni verrou (cf. Assumptions de spec.md).

Testing: pytest pour regine-core/regine-cli (logique de sélection, recherche, restauration, contrat CLI) — couverture exhaustive comme pour le reste du projet. La GUI elle-même n'est pas couverte par des tests automatisés dans cette itération (cf. research.md § 2) : validée manuellement via quickstart.md, la logique métier qu'elle appelle étant, elle, entièrement testée côté regine-core.

Target Platform: Poste de travail de bureau, macOS en priorité (cohérent avec le reste du projet, cf. specs/003 research.md § 1)

Project Type: Application de bureau (façade regine-gui) + extension CLI, dans le monorepo existant (regine-core, regine-cli, regine-gui)

Performance Goals: Pas de cible chiffrée spécifique ; la vue combinée (US1 FR-004/005) doit rester fluide sur l'ordre de grandeur d'une sortie photo (quelques centaines à low-thousands de fichiers), sans imposer de charger l'archive entière en mémoire pour la recherche (US2 Edge Case)

Constraints: Un seul processus par lancement, pas de démon (contrainte technique de la constitution) ; aucune écriture depuis le mode consultation (FR-010) ; chaque action de promotion/rétrogradation DOIT être accomplissable en CLI, pas seulement en GUI (FR-007, Principe CLI-first)

Scale/Scope: Usage mono-utilisateur, mono-poste, cohérent avec le reste du projet (cf. specs/003 Assumptions)

Constitution Check

GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.

Principe / contrainte Évaluation Justification
I. Fichier maître intouchable PASS La promotion/rétrogradation est un déplacement (rename/move) au sein d'un même dossier, jamais une modification de contenu — le hash reste stable (cohérent avec docs/archivage-photo-elements-cles.md section 10 : « ce deuxième déplacement est un cas de plus couvert par la détection de déplacement par hash »).
II. Confirmation explicite avant toute action destructive PASS FR-006 : aucune suppression directe depuis l'écran de tri, toujours différée à la réconciliation (specs/005) avec confirmation explicite.
III. Identité par contenu, jamais par nom de fichier seul PASS Le déplacement physique d'une promotion est retrouvé par regine_core.archive.reconciliation.comparer via le hash, sans code dédié à construire ici (déjà prouvé par test_whole_folder_move_detected_as_move_for_every_file, specs/005).
IV. Métadonnées ouvertes et embarquées N/A Cette fonctionnalité ne lit ni n'écrit de métadonnées descriptives/de droits.
V. L'utilisateur décide, Régine suggère PASS FR-003 : la promotion/rétrogradation reste toujours une action manuelle explicite, jamais automatique — y compris pour une paire RAW+JPEG (fichier par fichier, pas par paire).
VI. Bibliothèque centrale, façades minces PASS Toute la logique (regroupement, promotion, recherche, restauration) vit dans regine-core ; regine-cli et regine-gui n'en sont que deux façades appelant les mêmes fonctions, sans logique dupliquée.
CLI-first PASS (structurant) FR-007 impose explicitement qu'aucune action de la GUI ne soit possible sans équivalent CLI — la sous-commande CLI fait partie des tâches Foundational de ce plan, avant l'implémentation de la GUI elle-même. FR-018 (US3) impose la même règle pour l'import : regine import existe déjà (specs/001-import-photos), livré avant la GUI — rien à construire côté CLI pour US3.
VI. Bibliothèque centrale, façades minces (US3) PASS L'onglet d'import appelle directement regine_core.import_carte (déjà utilisée par regine_cli.import_cmd), jamais l'orchestration interactive (input()) de ce dernier — aucune règle dupliquée, aucune fonction nouvelle (research.md § 6, contracts/regine-core-api.md).
Exécution sans démon PASS PySide6 tourne dans le même processus Python que le reste, importe regine-core directement — pas de service ni de serveur local à superviser.
Formats ouverts et documentés N/A Aucun nouveau format de stockage introduit par cette fonctionnalité.

Aucune violation identifiée ; la section Complexity Tracking reste vide.

Re-check post ajout US3 (2026-09-21) : import_view.py (nouveau, GUI) et import_cmd.py (déjà existant, specs/001-import-photos, inchangé) sont deux façades indépendantes de regine_core.import_carte — aucun nouveau module regine_core, aucune duplication de règle (cf. research.md § 6). Toutes les évaluations PASS ci-dessus restent valables.

Re-check post Phase 1 (après génération de data-model.md, contracts/, quickstart.md) : le découpage en deux modules regine_core.dossier.selection (racine de sélection, US1) et regine_core.archive.consultation (lecture seule, US2) — distincts de regine_core.dossier.root (répertoire racine archive, specs/004, sémantique différente malgré le mot « racine » commun, cf. docs/lexique.md § Point de vigilance) — confirme chaque évaluation PASS ci-dessus. Aucune violation nouvelle introduite par la conception détaillée.

Project Structure

Documentation (this feature)

specs/006-gui-tri-consultation/
├── plan.md              # This file (/speckit-plan command output)
├── research.md          # Phase 0 output (/speckit-plan command)
├── data-model.md        # Phase 1 output (/speckit-plan command)
├── quickstart.md        # Phase 1 output (/speckit-plan command)
├── contracts/           # Phase 1 output (/speckit-plan command)
│   ├── cli-dossier-selection.md
│   ├── cli-archive-consultation.md
│   └── regine-core-api.md
└── tasks.md             # Phase 2 output (/speckit-tasks command - NOT created by /speckit-plan)

Source Code (repository root) — monorepo existant

packages/
├── regine-core/
│   ├── src/regine_core/
│   │   ├── dossier/
│   │   │   ├── root.py                 # existant (specs/004) — répertoire racine archive, INCHANGÉ
│   │   │   └── selection.py            # NOUVEAU — racine de sélection : regroupement RAW+JPEG,
│   │   │                                 promotion/rétrogradation individuelle (US1)
│   │   └── archive/
│   │       └── consultation.py         # NOUVEAU — parcours lecture seule + restauration ciblée (US2)
│   └── tests/
│       ├── unit/
│       │   ├── test_selection_grouping.py
│       │   ├── test_selection_promotion.py
│       │   └── test_consultation_search.py
│       └── integration/
│           ├── test_selection_combined_view.py   # dossier parent + sous-dossiers, US1
│           └── test_consultation_restore.py       # restauration ciblée vérifiée, US2
│
├── regine-cli/
│   ├── src/regine_cli/
│   │   └── dossier_cmd.py              # NOUVEAU — `regine dossier promote/demote/list`,
│   │                                     réponse CLI-first à FR-007 ; l'archive_cmd.py existant
│   │                                     (specs/005) est étendu pour `regine archive browse/restore` (US2)
│   └── tests/contract/
│       ├── test_cli_dossier.py
│       └── test_cli_archive_consultation.py
│
└── regine-gui/                          # première implémentation réelle de cette façade réservée
    ├── pyproject.toml                   # dépendance PySide6 ajoutée ici
    ├── src/regine_gui/
    │   ├── app.py                       # point d'entrée, lance l'application PySide6
    │   ├── tri_view.py                  # écran de tri/culling (US1) — appelle regine_core.dossier.selection
    │   ├── consultation_view.py         # écran de consultation (US2) — appelle regine_core.archive.consultation
    │   ├── config_view.py               # écran de configuration (specs/003 US4) — appelle regine_core.config
    │   └── import_view.py               # NOUVEAU (US3) — écran d'import, appelle regine_core.import_carte
    │                                     # directement (jamais regine_cli.import_cmd, cf. research.md § 6) ;
    │                                     # aucune nouvelle fonction regine_core requise (specs/001 déjà complet)
    └── (pas de suite de tests automatisée pour l'UI elle-même cette itération, cf. research.md § 2 —
        validée manuellement via quickstart.md ; toute la logique qu'elle appelle est testée côté regine-core)

Structure Decision: Extension du monorepo à 4 paquets déjà en place (specs/003 research.md § 5) : regine-gui passe de paquet réservé (scaffold vide) à première implémentation réelle. Deux nouveaux modules regine-core distincts pour ne pas mélanger deux sens différents du mot « racine » (dossier.selection pour la racine de sélection à l'intérieur d'un dossier vs dossier.root déjà existant pour le répertoire racine d'archive année/catégorie, cf. docs/lexique.md § Point de vigilance). La sous-commande CLI (regine dossier ...) est un prérequis Foundational de ce plan — construite avant la GUI elle-même, jamais après, conformément au Principe CLI-first et à FR-007. Pour US3 (import), aucun prérequis Foundational CLI supplémentaire : regine import (specs/001-import-photos) existe déjà et n'est pas modifié — seul import_view.py est nouveau.

Complexity Tracking

Aucune violation de gate à justifier — section laissée vide intentionnellement.

  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
# Implementation Plan: Interface graphique de tri et de consultation

**Branch**: `006-gui-tri-consultation` | **Date**: 2026-09-20 | **Spec**: [spec.md](./spec.md)

**Input**: Feature specification from `/specs/006-gui-tri-consultation/spec.md`

## Summary

Une façade graphique de bureau (`regine-gui`, PySide6) couvrant trois usages : le tri/culling d'un dossier de travail local déjà checkouté (regroupement visuel RAW+JPEG, promotion/rétrogradation individuelle à la racine de sélection, vue combinant plusieurs dossiers de format et, pour un dossier parent, ses sous-dossiers) ; la consultation en lecture seule de l'archive NAS (recherche, restauration ciblée d'un fichier sans checkout complet) ; et, depuis l'ajout de la User Story 3 (2026-09-21), l'import d'une carte mémoire (analyse jour par jour, découpage en groupes, destination, titre, confirmation), en appelant directement les fonctions déjà définies et testées par `specs/001-import-photos` (`regine_core.import_carte`), jamais l'orchestration interactive propre à `regine_cli.import_cmd` (cf. research.md § 6). La promotion/rétrogradation à la racine de sélection est une capacité entièrement nouvelle de `regine-core` (aucun module existant ne la couvre) : par le Principe CLI-first de la constitution, elle est d'abord construite comme fonctions de bibliothèque + sous-commande CLI, la GUI n'en étant qu'une façade supplémentaire au même titre que la CLI (Principe VI) — jamais l'inverse. L'onglet d'import (US3), lui, n'introduit aucune nouvelle fonction `regine_core` : la CLI (`regine import`) couvre déjà toutes les règles, la GUI n'en est qu'une seconde façade.

## Technical Context

**Language/Version**: Python 3.11+ (cohérent avec le reste de `regine-core`/`regine-cli`)

**Primary Dependencies**: PySide6 (interface graphique native Qt, cf. research.md § 1) pour `regine-gui` uniquement. Aucune nouvelle dépendance pour `regine-core`/`regine-cli` (bibliothèque standard, `pathlib`/`shutil`, cohérent avec le reste du projet).

**Storage**: Aucune nouvelle base. Le tri/culling (US1) opère sur une copie de travail déjà checkoutée (manifeste/verrou existants, `specs/005`) ; la consultation (US2) est purement en lecture, sans manifeste ni verrou (cf. Assumptions de spec.md).

**Testing**: `pytest` pour `regine-core`/`regine-cli` (logique de sélection, recherche, restauration, contrat CLI) — couverture exhaustive comme pour le reste du projet. La GUI elle-même n'est pas couverte par des tests automatisés dans cette itération (cf. research.md § 2) : validée manuellement via `quickstart.md`, la logique métier qu'elle appelle étant, elle, entièrement testée côté `regine-core`.

**Target Platform**: Poste de travail de bureau, macOS en priorité (cohérent avec le reste du projet, cf. `specs/003` research.md § 1)

**Project Type**: Application de bureau (façade `regine-gui`) + extension CLI, dans le monorepo existant (`regine-core`, `regine-cli`, `regine-gui`)

**Performance Goals**: Pas de cible chiffrée spécifique ; la vue combinée (US1 FR-004/005) doit rester fluide sur l'ordre de grandeur d'une sortie photo (quelques centaines à low-thousands de fichiers), sans imposer de charger l'archive entière en mémoire pour la recherche (US2 Edge Case)

**Constraints**: Un seul processus par lancement, pas de démon (contrainte technique de la constitution) ; aucune écriture depuis le mode consultation (FR-010) ; chaque action de promotion/rétrogradation DOIT être accomplissable en CLI, pas seulement en GUI (FR-007, Principe CLI-first)

**Scale/Scope**: Usage mono-utilisateur, mono-poste, cohérent avec le reste du projet (cf. `specs/003` Assumptions)

## Constitution Check

*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*

| Principe / contrainte | Évaluation | Justification |
|---|---|---|
| I. Fichier maître intouchable | PASS | La promotion/rétrogradation est un déplacement (`rename`/`move`) au sein d'un même dossier, jamais une modification de contenu — le hash reste stable (cohérent avec `docs/archivage-photo-elements-cles.md` section 10 : « ce deuxième déplacement est un cas de plus couvert par la détection de déplacement par hash »). |
| II. Confirmation explicite avant toute action destructive | PASS | FR-006 : aucune suppression directe depuis l'écran de tri, toujours différée à la réconciliation (`specs/005`) avec confirmation explicite. |
| III. Identité par contenu, jamais par nom de fichier seul | PASS | Le déplacement physique d'une promotion est retrouvé par `regine_core.archive.reconciliation.comparer` via le hash, sans code dédié à construire ici (déjà prouvé par `test_whole_folder_move_detected_as_move_for_every_file`, specs/005). |
| IV. Métadonnées ouvertes et embarquées | N/A | Cette fonctionnalité ne lit ni n'écrit de métadonnées descriptives/de droits. |
| V. L'utilisateur décide, Régine suggère | PASS | FR-003 : la promotion/rétrogradation reste toujours une action manuelle explicite, jamais automatique — y compris pour une paire RAW+JPEG (fichier par fichier, pas par paire). |
| VI. Bibliothèque centrale, façades minces | PASS | Toute la logique (regroupement, promotion, recherche, restauration) vit dans `regine-core` ; `regine-cli` et `regine-gui` n'en sont que deux façades appelant les mêmes fonctions, sans logique dupliquée. |
| CLI-first | PASS (structurant) | FR-007 impose explicitement qu'aucune action de la GUI ne soit possible sans équivalent CLI — la sous-commande CLI fait partie des tâches Foundational de ce plan, avant l'implémentation de la GUI elle-même. FR-018 (US3) impose la même règle pour l'import : `regine import` existe déjà (`specs/001-import-photos`), livré avant la GUI — rien à construire côté CLI pour US3. |
| VI. Bibliothèque centrale, façades minces (US3) | PASS | L'onglet d'import appelle directement `regine_core.import_carte` (déjà utilisée par `regine_cli.import_cmd`), jamais l'orchestration interactive (`input()`) de ce dernier — aucune règle dupliquée, aucune fonction nouvelle (research.md § 6, contracts/regine-core-api.md). |
| Exécution sans démon | PASS | PySide6 tourne dans le même processus Python que le reste, importe `regine-core` directement — pas de service ni de serveur local à superviser. |
| Formats ouverts et documentés | N/A | Aucun nouveau format de stockage introduit par cette fonctionnalité. |

Aucune violation identifiée ; la section Complexity Tracking reste vide.

**Re-check post ajout US3 (2026-09-21)** : `import_view.py` (nouveau, GUI) et `import_cmd.py` (déjà existant, `specs/001-import-photos`, inchangé) sont deux façades indépendantes de `regine_core.import_carte` — aucun nouveau module `regine_core`, aucune duplication de règle (cf. research.md § 6). Toutes les évaluations PASS ci-dessus restent valables.

**Re-check post Phase 1** (après génération de `data-model.md`, `contracts/`, `quickstart.md`) : le découpage en deux modules `regine_core.dossier.selection` (racine de sélection, US1) et `regine_core.archive.consultation` (lecture seule, US2) — distincts de `regine_core.dossier.root` (répertoire racine archive, specs/004, sémantique différente malgré le mot « racine » commun, cf. `docs/lexique.md` § Point de vigilance) — confirme chaque évaluation PASS ci-dessus. Aucune violation nouvelle introduite par la conception détaillée.

## Project Structure

### Documentation (this feature)

```text
specs/006-gui-tri-consultation/
├── plan.md              # This file (/speckit-plan command output)
├── research.md          # Phase 0 output (/speckit-plan command)
├── data-model.md        # Phase 1 output (/speckit-plan command)
├── quickstart.md        # Phase 1 output (/speckit-plan command)
├── contracts/           # Phase 1 output (/speckit-plan command)
│   ├── cli-dossier-selection.md
│   ├── cli-archive-consultation.md
│   └── regine-core-api.md
└── tasks.md             # Phase 2 output (/speckit-tasks command - NOT created by /speckit-plan)
```

### Source Code (repository root) — monorepo existant

```text
packages/
├── regine-core/
│   ├── src/regine_core/
│   │   ├── dossier/
│   │   │   ├── root.py                 # existant (specs/004) — répertoire racine archive, INCHANGÉ
│   │   │   └── selection.py            # NOUVEAU — racine de sélection : regroupement RAW+JPEG,
│   │   │                                 promotion/rétrogradation individuelle (US1)
│   │   └── archive/
│   │       └── consultation.py         # NOUVEAU — parcours lecture seule + restauration ciblée (US2)
│   └── tests/
│       ├── unit/
│       │   ├── test_selection_grouping.py
│       │   ├── test_selection_promotion.py
│       │   └── test_consultation_search.py
│       └── integration/
│           ├── test_selection_combined_view.py   # dossier parent + sous-dossiers, US1
│           └── test_consultation_restore.py       # restauration ciblée vérifiée, US2
│
├── regine-cli/
│   ├── src/regine_cli/
│   │   └── dossier_cmd.py              # NOUVEAU — `regine dossier promote/demote/list`,
│   │                                     réponse CLI-first à FR-007 ; l'archive_cmd.py existant
│   │                                     (specs/005) est étendu pour `regine archive browse/restore` (US2)
│   └── tests/contract/
│       ├── test_cli_dossier.py
│       └── test_cli_archive_consultation.py
│
└── regine-gui/                          # première implémentation réelle de cette façade réservée
    ├── pyproject.toml                   # dépendance PySide6 ajoutée ici
    ├── src/regine_gui/
    │   ├── app.py                       # point d'entrée, lance l'application PySide6
    │   ├── tri_view.py                  # écran de tri/culling (US1) — appelle regine_core.dossier.selection
    │   ├── consultation_view.py         # écran de consultation (US2) — appelle regine_core.archive.consultation
    │   ├── config_view.py               # écran de configuration (specs/003 US4) — appelle regine_core.config
    │   └── import_view.py               # NOUVEAU (US3) — écran d'import, appelle regine_core.import_carte
    │                                     # directement (jamais regine_cli.import_cmd, cf. research.md § 6) ;
    │                                     # aucune nouvelle fonction regine_core requise (specs/001 déjà complet)
    └── (pas de suite de tests automatisée pour l'UI elle-même cette itération, cf. research.md § 2 —
        validée manuellement via quickstart.md ; toute la logique qu'elle appelle est testée côté regine-core)
```

**Structure Decision**: Extension du monorepo à 4 paquets déjà en place (`specs/003` research.md § 5) : `regine-gui` passe de paquet réservé (scaffold vide) à première implémentation réelle. Deux nouveaux modules `regine-core` distincts pour ne pas mélanger deux sens différents du mot « racine » (`dossier.selection` pour la racine de sélection à l'intérieur d'un dossier vs `dossier.root` déjà existant pour le répertoire racine d'archive année/catégorie, cf. `docs/lexique.md` § Point de vigilance). La sous-commande CLI (`regine dossier ...`) est un prérequis Foundational de ce plan — construite avant la GUI elle-même, jamais après, conformément au Principe CLI-first et à FR-007. Pour US3 (import), aucun prérequis Foundational CLI supplémentaire : `regine import` (`specs/001-import-photos`) existe déjà et n'est pas modifié — seul `import_view.py` est nouveau.

## Complexity Tracking

*Aucune violation de gate à justifier — section laissée vide intentionnellement.*