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
refactor 19cf29c · on main · Fabien Champigny · Sep 24, 2026
data-model.md · 104 lines · 8.2 KBmarkdown
Blame HistoryOpen raw

Data Model: Configuration du contexte de travail de Régine

Entités dérivées de spec.md § Key Entities et Functional Requirements.

Configuration globale (nouvelle, 2026-09-23/24)

Fichier SQLite minimal, propre à la machine, à un emplacement fixe (~/.regine/config.sqlite3) — table contexte uniquement, mêmes champs qu'avant la séparation. Ne contient jamais les boîtiers, catégories, ni l'historique d'imports (FR-014, FR-007).

Champ Type Règles
temp_dir chemin absolu Doit exister ou être proposé à la création (FR-003) ; DOIT être différent de local_work_dir (Edge Case, avertissement sinon)
local_work_dir chemin absolu Doit exister ou être proposé à la création (FR-003) ; changement refusé si un travail non réconcilié y est présent (FR-010, cf. état ci-dessous)
archive_smb_path chemin réseau (partage SMB) DOIT correspondre à un partage réseau, pas à un dossier local (Edge Case)
smb_last_known_state énumération : mounted | unavailable | unknown Alimenté par la vérification de disponibilité avant chaque opération (FR-004/FR-005)

Règle d'état : local_work_dir ne peut être modifié que si aucun checkout ni import n'y est en cours de réconciliation/archivage (cf. Clarification 2026-09-18 n°1, FR-010, Acceptance Scenario 5 de User Story 1). Cette vérification interroge les manifestes de l'archive (via son point de montage local), pas un fichier sous local_work_dir lui-même — cf. écart déjà documenté dans contracts/regine-core-api.md.

Contexte de travail (entité logique de spec.md) = Configuration globale + Base de contexte centralisée ci-dessous, réunies par regine_core.config.environnement.ouvrir_environnement().

Base de contexte centralisée (révisée le 2026-09-23/24 — déplacée, fusionnée avec l'ex-« base de données de travail »)

Base SQLite unique, à la racine du répertoire de travail local (<local_work_dir>/contexte.sqlite3, FR-006/FR-015) — plus à ~/.regine/. Remplace à la fois l'ancienne base de contexte centralisée (boîtiers) et l'ancienne « base de données de travail par dossier » : cette dernière, au schéma manifeste (fichiers/verrou) jamais réellement exploité (le verrou vit en réalité uniquement côté archive, cf. Notes d'implémentation de contracts/regine-core-api.md), est retirée — une seule base par local_work_dir, pas une par dossier.

Table boitiers (possédée par regine_core.camera_profile, cf. specs/002-profil-boitiers-optionnel)

Champ Type Règles
id identifiant interne Clé primaire
modele texte Tag EXIF Model, enregistré à chaque import (FR-008)
numero_serie texte, nullable Tag EXIF BodySerialNumber, quand présent et exploitable (cf. specs/002-profil-boitiers-optionnel)
nom_lisible texte, nullable Attribué par l'utilisateur (FR-008/FR-009) ; NULL tant que non nommé
premiere_rencontre horodatage Date du premier import ayant révélé ce boîtier
source texte modele/numero_serie/manuel (désambiguïsation à l'import, specs/002) ou parcours_nas (FR-012)

Table categories (possédée par regine_core.config.categories, cf. specs/004-categorisation-dossiers) et table checksums_importes (possédée par regine_core.import_carte.historique, cf. specs/001-import-photos FR-004) : schémas inchangés par cette révision, seul leur emplacement physique change (même fichier, nouveau chemin).

Règle d'unicité (boitiers) : unique sur (modele, numero_serie) quand numero_serie est exploitable ; sinon unique sur modele seul, jusqu'à ce qu'une collision réelle (détectée par le module import, cf. specs/002-profil-boitiers-optionnel) force la création d'une entrée distincte.

Relation : nom_lisible, une fois défini, DOIT être réutilisé par tout module identifiant ce même boîtier par la suite (FR-009) — relation de référence, pas de duplication de la donnée.

Réplication vers l'archive (FR-016) : copie vérifiée par somme de contrôle de ce fichier entier vers <archive_root>/.regine-contexte.sqlite3 (emplacement fixe, racine de l'archive — symétrique à son emplacement local), déclenchée après un regine reconcile réussi. Toujours un remplacement complet du fichier de sauvegarde précédent (pas une fusion ligne à ligne) — cohérent avec l'Edge Case déjà tranché (pas de fusion de contextes divergents).

Restauration depuis l'archive (FR-017) : si <local_work_dir>/contexte.sqlite3 n'existe pas mais que <archive_root>/.regine-contexte.sqlite3 existe, copie vérifiée dans l'autre sens — déclenchée après la configuration initiale des trois chemins, ou après un premier regine checkout réussi sur cette machine, selon lequel des deux survient en premier.

Table boitiers

Champ Type Règles
id identifiant interne Clé primaire
modele texte Tag EXIF Model, enregistré à chaque import (FR-008)
numero_serie texte, nullable Tag EXIF BodySerialNumber, quand présent et exploitable (cf. specs/002-profil-boitiers-optionnel)
nom_lisible texte, nullable Attribué par l'utilisateur (FR-008/FR-009) ; NULL tant que non nommé
premiere_rencontre horodatage Date du premier import ayant révélé ce boîtier
source énumération : import | parcours_nas Distingue une entrée alimentée automatiquement à l'import (FR-008) d'une entrée trouvée par le parcours volontaire du NAS (FR-012)

Règle d'unicité : unique sur (modele, numero_serie) quand numero_serie est exploitable ; sinon unique sur modele seul, jusqu'à ce qu'une collision réelle (détectée par le module import, cf. specs/002-profil-boitiers-optionnel) force la création d'une entrée distincte.

Relation : nom_lisible, une fois défini, DOIT être réutilisé par tout module identifiant ce même boîtier par la suite (FR-009) — relation de référence, pas de duplication de la donnée.

Boîtier nommé

Vue logique sur une ligne de la table boitiers dont nom_lisible n'est pas NULL. Pas une entité de stockage séparée — introduite dans spec.md pour la lisibilité côté utilisateur.

État / transitions

[Répertoire de travail local]
        │
        │ configuré (FR-001)
        ▼
   ┌───────────┐   travail non réconcilié présent    ┌──────────────────────┐
   │  Libre     │ ───────────────────────────────────▶│ Occupé (bloquant)    │
   │ (modifiable)│                                     │ (changement refusé,  │
   └───────────┘ ◀─────────────────────────────────── │  FR-010)             │
        ▲            réconciliation / archivage        └──────────────────────┘
        │            du dossier concerné
        │ changement de chemin autorisé
[Boîtier]
   Détecté (source=import, nom_lisible=NULL)
        │ utilisateur attribue un nom (FR-008/009)
        ▼
   Nommé (nom_lisible défini)

Extension du 2026-09-21 (User Story 4) : aucune nouvelle entité. L'onglet de configuration de la GUI lit et écrit exactement le même Contexte de travail et les mêmes Boîtier/Boîtier nommé que la CLI, via les mêmes fonctions (contracts/regine-core-api.md) — pas un second modèle de données parallèle.

Extension du 2026-09-23/24 (User Story 5) :

[Base de contexte centralisée]  (<local_work_dir>/contexte.sqlite3)
   Présente localement
        │ regine reconcile réussi (FR-016)
        ▼
   Répliquée sur l'archive (<archive_root>/.regine-contexte.sqlite3)

[Nouvelle machine, local_work_dir vide]
   Absente localement, présente sur l'archive
        │ configuration initiale des 3 chemins (FR-001), ou premier `regine checkout` (FR-017)
        ▼
   Restaurée localement — boîtiers/catégories/historique identiques à l'ancienne machine
  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
# Data Model: Configuration du contexte de travail de Régine

Entités dérivées de `spec.md` § Key Entities et Functional Requirements.

## Configuration globale *(nouvelle, 2026-09-23/24)*

Fichier SQLite minimal, propre à la machine, à un emplacement fixe (`~/.regine/config.sqlite3`) — table `contexte` uniquement, mêmes champs qu'avant la séparation. Ne contient jamais les boîtiers, catégories, ni l'historique d'imports (FR-014, FR-007).

| Champ | Type | Règles |
|---|---|---|
| `temp_dir` | chemin absolu | Doit exister ou être proposé à la création (FR-003) ; DOIT être différent de `local_work_dir` (Edge Case, avertissement sinon) |
| `local_work_dir` | chemin absolu | Doit exister ou être proposé à la création (FR-003) ; changement refusé si un travail non réconcilié y est présent (FR-010, cf. état ci-dessous) |
| `archive_smb_path` | chemin réseau (partage SMB) | DOIT correspondre à un partage réseau, pas à un dossier local (Edge Case) |
| `smb_last_known_state` | énumération : `mounted` \| `unavailable` \| `unknown` | Alimenté par la vérification de disponibilité avant chaque opération (FR-004/FR-005) |

**Règle d'état** : `local_work_dir` ne peut être modifié que si aucun checkout ni import n'y est en cours de réconciliation/archivage (cf. Clarification 2026-09-18 n°1, FR-010, Acceptance Scenario 5 de User Story 1). Cette vérification interroge les manifestes de l'archive (via son point de montage local), pas un fichier sous `local_work_dir` lui-même — cf. écart déjà documenté dans `contracts/regine-core-api.md`.

**Contexte de travail** (entité logique de `spec.md`) = Configuration globale + Base de contexte centralisée ci-dessous, réunies par `regine_core.config.environnement.ouvrir_environnement()`.

## Base de contexte centralisée *(révisée le 2026-09-23/24 — déplacée, fusionnée avec l'ex-« base de données de travail »)*

Base SQLite unique, à la racine du répertoire de travail local (`<local_work_dir>/contexte.sqlite3`, FR-006/FR-015) — plus à `~/.regine/`. Remplace à la fois l'ancienne base de contexte centralisée (boîtiers) et l'ancienne « base de données de travail par dossier » : cette dernière, au schéma manifeste (`fichiers`/`verrou`) jamais réellement exploité (le verrou vit en réalité uniquement côté archive, cf. Notes d'implémentation de `contracts/regine-core-api.md`), est retirée — une seule base par `local_work_dir`, pas une par dossier.

**Table `boitiers`** (possédée par `regine_core.camera_profile`, cf. `specs/002-profil-boitiers-optionnel`)

| Champ | Type | Règles |
|---|---|---|
| `id` | identifiant interne | Clé primaire |
| `modele` | texte | Tag EXIF `Model`, enregistré à chaque import (FR-008) |
| `numero_serie` | texte, nullable | Tag EXIF `BodySerialNumber`, quand présent et exploitable (cf. `specs/002-profil-boitiers-optionnel`) |
| `nom_lisible` | texte, nullable | Attribué par l'utilisateur (FR-008/FR-009) ; `NULL` tant que non nommé |
| `premiere_rencontre` | horodatage | Date du premier import ayant révélé ce boîtier |
| `source` | texte | `modele`/`numero_serie`/`manuel` (désambiguïsation à l'import, specs/002) ou `parcours_nas` (FR-012) |

**Table `categories`** (possédée par `regine_core.config.categories`, cf. `specs/004-categorisation-dossiers`) et **table `checksums_importes`** (possédée par `regine_core.import_carte.historique`, cf. `specs/001-import-photos` FR-004) : schémas inchangés par cette révision, seul leur emplacement physique change (même fichier, nouveau chemin).

**Règle d'unicité** (`boitiers`) : unique sur (`modele`, `numero_serie`) quand `numero_serie` est exploitable ; sinon unique sur `modele` seul, jusqu'à ce qu'une collision réelle (détectée par le module import, cf. `specs/002-profil-boitiers-optionnel`) force la création d'une entrée distincte.

**Relation** : `nom_lisible`, une fois défini, DOIT être réutilisé par tout module identifiant ce même boîtier par la suite (FR-009) — relation de référence, pas de duplication de la donnée.

**Réplication vers l'archive (FR-016)** : copie vérifiée par somme de contrôle de ce fichier entier vers `<archive_root>/.regine-contexte.sqlite3` (emplacement fixe, racine de l'archive — symétrique à son emplacement local), déclenchée après un `regine reconcile` réussi. Toujours un remplacement complet du fichier de sauvegarde précédent (pas une fusion ligne à ligne) — cohérent avec l'Edge Case déjà tranché (pas de fusion de contextes divergents).

**Restauration depuis l'archive (FR-017)** : si `<local_work_dir>/contexte.sqlite3` n'existe pas mais que `<archive_root>/.regine-contexte.sqlite3` existe, copie vérifiée dans l'autre sens — déclenchée après la configuration initiale des trois chemins, ou après un premier `regine checkout` réussi sur cette machine, selon lequel des deux survient en premier.

**Table `boitiers`**

| Champ | Type | Règles |
|---|---|---|
| `id` | identifiant interne | Clé primaire |
| `modele` | texte | Tag EXIF `Model`, enregistré à chaque import (FR-008) |
| `numero_serie` | texte, nullable | Tag EXIF `BodySerialNumber`, quand présent et exploitable (cf. `specs/002-profil-boitiers-optionnel`) |
| `nom_lisible` | texte, nullable | Attribué par l'utilisateur (FR-008/FR-009) ; `NULL` tant que non nommé |
| `premiere_rencontre` | horodatage | Date du premier import ayant révélé ce boîtier |
| `source` | énumération : `import` \| `parcours_nas` | Distingue une entrée alimentée automatiquement à l'import (FR-008) d'une entrée trouvée par le parcours volontaire du NAS (FR-012) |

**Règle d'unicité** : unique sur (`modele`, `numero_serie`) quand `numero_serie` est exploitable ; sinon unique sur `modele` seul, jusqu'à ce qu'une collision réelle (détectée par le module import, cf. `specs/002-profil-boitiers-optionnel`) force la création d'une entrée distincte.

**Relation** : `nom_lisible`, une fois défini, DOIT être réutilisé par tout module identifiant ce même boîtier par la suite (FR-009) — relation de référence, pas de duplication de la donnée.

## Boîtier nommé

Vue logique sur une ligne de la table `boitiers` dont `nom_lisible` n'est pas `NULL`. Pas une entité de stockage séparée — introduite dans `spec.md` pour la lisibilité côté utilisateur.

## État / transitions

```text
[Répertoire de travail local]
        │
        │ configuré (FR-001)
        ▼
   ┌───────────┐   travail non réconcilié présent    ┌──────────────────────┐
   │  Libre     │ ───────────────────────────────────▶│ Occupé (bloquant)    │
   │ (modifiable)│                                     │ (changement refusé,  │
   └───────────┘ ◀─────────────────────────────────── │  FR-010)             │
        ▲            réconciliation / archivage        └──────────────────────┘
        │            du dossier concerné
        │ changement de chemin autorisé
```

```text
[Boîtier]
   Détecté (source=import, nom_lisible=NULL)
        │ utilisateur attribue un nom (FR-008/009)
        ▼
   Nommé (nom_lisible défini)
```

**Extension du 2026-09-21 (User Story 4)** : aucune nouvelle entité. L'onglet de configuration de la GUI lit et écrit exactement le même `Contexte de travail` et les mêmes `Boîtier`/`Boîtier nommé` que la CLI, via les mêmes fonctions (`contracts/regine-core-api.md`) — pas un second modèle de données parallèle.

**Extension du 2026-09-23/24 (User Story 5)** :

```text
[Base de contexte centralisée]  (<local_work_dir>/contexte.sqlite3)
   Présente localement
        │ regine reconcile réussi (FR-016)
        ▼
   Répliquée sur l'archive (<archive_root>/.regine-contexte.sqlite3)

[Nouvelle machine, local_work_dir vide]
   Absente localement, présente sur l'archive
        │ configuration initiale des 3 chemins (FR-001), ou premier `regine checkout` (FR-017)
        ▼
   Restaurée localement — boîtiers/catégories/historique identiques à l'ancienne machine
```