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
plan all a196f68 · on main · Fabien Champigny · Sep 18, 2026
quickstart.md · 74 lines · 3.4 KBmarkdown
Blame HistoryOpen raw

Quickstart : validation du profil de boîtiers optionnel

Ce guide valide les 3 user stories de spec.md via l'API interne décrite dans contracts/regine-core-api.md. Comme cette fonctionnalité n'a pas de surface CLI propre (elle s'intègre au futur flux de l'import, specs/001-import-photos), la validation se fait directement contre regine_core. À exécuter une fois regine_core.metadata.exif et regine_core.camera_profile implémentés (cf. tasks.md).

Prérequis

  • regine-core installé, exiftool disponible sur le poste (exiftool -ver).
  • Un petit jeu de fichiers de test avec métadonnées EXIF contrôlées (modèle, numéro de série) — via exiftool sur des copies jetables plutôt que sur des fichiers réels.

Scénario 1 — Aucune collision, aucune question (User Story 1, P1)

from regine_core.metadata.exif import read_camera_tags
from regine_core.camera_profile import resolve_collision

# Un seul fichier, ou deux fichiers de modèles différents (pas de collision de nom en amont) :
# resolve_collision ne doit même pas être appelée par l'appelant dans ce cas.

Résultat attendu : aucune question posée ; ce scénario valide surtout le contrat côté appelant (FR-003/FR-008 : ne jamais appeler resolve_collision hors collision réelle).

Scénario 2 — Collision résolue par le modèle (User Story 2, P2)

tags = [
    read_camera_tags(fichier_a),  # modele="Fujifilm X100V"
    read_camera_tags(fichier_b),  # modele="Ricoh GR III"
]
resolution = resolve_collision([fichier_a, fichier_b])
assert len(resolution.a_etiqueter) == 0
assert resolution.resolues[fichier_a] != resolution.resolues[fichier_b]

Résultat attendu : résolution automatique, a_etiqueter vide.

Scénario 3 — Collision résolue par le numéro de série (User Story 3, P3)

# Deux fichiers du même modèle, numéro de série différent et exploitable :
resolution = resolve_collision([fichier_a, fichier_b])
assert len(resolution.a_etiqueter) == 0
assert resolution.resolues[fichier_a] != resolution.resolues[fichier_b]

Résultat attendu : résolution automatique via le numéro de série, sans intervention utilisateur.

Scénario 4 — Étiquetage manuel en dernier recours

# Deux fichiers du même modèle, numéro de série absent ou identique :
resolution = resolve_collision([fichier_a, fichier_b])
assert [fichier_a, fichier_b] in resolution.a_etiqueter

from regine_core.camera_profile import assign_manual_source
id_a = assign_manual_source([fichier_a])
id_b = assign_manual_source([fichier_b])
assert id_a != id_b

Résultat attendu : le groupe apparaît dans a_etiqueter, jamais résolu arbitrairement ; assign_manual_source crée deux entrées distinctes.

Scénario 5 — Réutilisation d'une résolution déjà établie

# Réimporter un fichier du même boîtier déjà résolu (id_a) :
resolution2 = resolve_collision([fichier_c])  # même modele/numero_serie que fichier_a
assert resolution2.resolues[fichier_c] == id_a

Résultat attendu : aucune nouvelle question, le même id de boîtier est réutilisé (FR-006).

Critères de sortie

Les scénarios 2 à 5 doivent passer sans accès réseau (lecture EXIF locale, base de contexte locale). Le scénario 1 valide une règle de contrat côté appelant, pas un comportement testable isolément dans regine_core.

 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
# Quickstart : validation du profil de boîtiers optionnel

Ce guide valide les 3 user stories de `spec.md` via l'API interne décrite dans `contracts/regine-core-api.md`. Comme cette fonctionnalité n'a pas de surface CLI propre (elle s'intègre au futur flux de l'import, `specs/001-import-photos`), la validation se fait directement contre `regine_core`. À exécuter une fois `regine_core.metadata.exif` et `regine_core.camera_profile` implémentés (cf. `tasks.md`).

## Prérequis

- `regine-core` installé, `exiftool` disponible sur le poste (`exiftool -ver`).
- Un petit jeu de fichiers de test avec métadonnées EXIF contrôlées (modèle, numéro de série) — via `exiftool` sur des copies jetables plutôt que sur des fichiers réels.

## Scénario 1 — Aucune collision, aucune question (User Story 1, P1)

```python
from regine_core.metadata.exif import read_camera_tags
from regine_core.camera_profile import resolve_collision

# Un seul fichier, ou deux fichiers de modèles différents (pas de collision de nom en amont) :
# resolve_collision ne doit même pas être appelée par l'appelant dans ce cas.
```

**Résultat attendu** : aucune question posée ; ce scénario valide surtout le contrat côté appelant (FR-003/FR-008 : ne jamais appeler `resolve_collision` hors collision réelle).

## Scénario 2 — Collision résolue par le modèle (User Story 2, P2)

```python
tags = [
    read_camera_tags(fichier_a),  # modele="Fujifilm X100V"
    read_camera_tags(fichier_b),  # modele="Ricoh GR III"
]
resolution = resolve_collision([fichier_a, fichier_b])
assert len(resolution.a_etiqueter) == 0
assert resolution.resolues[fichier_a] != resolution.resolues[fichier_b]
```

**Résultat attendu** : résolution automatique, `a_etiqueter` vide.

## Scénario 3 — Collision résolue par le numéro de série (User Story 3, P3)

```python
# Deux fichiers du même modèle, numéro de série différent et exploitable :
resolution = resolve_collision([fichier_a, fichier_b])
assert len(resolution.a_etiqueter) == 0
assert resolution.resolues[fichier_a] != resolution.resolues[fichier_b]
```

**Résultat attendu** : résolution automatique via le numéro de série, sans intervention utilisateur.

## Scénario 4 — Étiquetage manuel en dernier recours

```python
# Deux fichiers du même modèle, numéro de série absent ou identique :
resolution = resolve_collision([fichier_a, fichier_b])
assert [fichier_a, fichier_b] in resolution.a_etiqueter

from regine_core.camera_profile import assign_manual_source
id_a = assign_manual_source([fichier_a])
id_b = assign_manual_source([fichier_b])
assert id_a != id_b
```

**Résultat attendu** : le groupe apparaît dans `a_etiqueter`, jamais résolu arbitrairement ; `assign_manual_source` crée deux entrées distinctes.

## Scénario 5 — Réutilisation d'une résolution déjà établie

```python
# Réimporter un fichier du même boîtier déjà résolu (id_a) :
resolution2 = resolve_collision([fichier_c])  # même modele/numero_serie que fichier_a
assert resolution2.resolues[fichier_c] == id_a
```

**Résultat attendu** : aucune nouvelle question, le même `id` de boîtier est réutilisé (FR-006).

## Critères de sortie

Les scénarios 2 à 5 doivent passer sans accès réseau (lecture EXIF locale, base de contexte locale). Le scénario 1 valide une règle de contrat côté appelant, pas un comportement testable isolément dans `regine_core`.