Orchestrer l’import transactionnel d’une preuve #49

Closed
opened 2026-07-19 16:54:33 +02:00 by fy59 · 0 comments
Owner

Orchestrer l’import transactionnel d’une preuve

Objectif

Ajouter un service métier capable d’importer une preuve de bout en bout en combinant :

  1. la validation du fichier source ;
  2. la génération de l’identifiant de preuve ;
  3. la génération du nom interne ;
  4. la copie sûre dans l’enquête ;
  5. la création du EvidenceRecord ;
  6. l’insertion SQLite ;
  7. le nettoyage du fichier copié si la persistance échoue.

Ce ticket doit produire une opération cohérente : après succès, la copie et la ligne SQLite existent toutes les deux ; après échec, aucune preuve partielle ne doit rester.

Contexte

Les briques suivantes existent désormais :

  • EvidenceRecord ;
  • EvidenceDao ;
  • migration SQLite V2 ;
  • calcul SHA-256 ;
  • copie sûre avec vérification cryptographique.

Il manque maintenant le composant qui orchestre ces modules sans mélanger les responsabilités.

Périmètre

Créer :

include/core/evidence_importer.h
src/core/evidence_importer.c
tests/test_evidence_importer.c

Mettre à jour le Makefile.

API proposée

typedef enum
{
    EVIDENCE_IMPORTER_ERROR_INVALID_ARGUMENT,
    EVIDENCE_IMPORTER_ERROR_MEMORY,
    EVIDENCE_IMPORTER_ERROR_CANCELLED,
    EVIDENCE_IMPORTER_ERROR_DESTINATION,
    EVIDENCE_IMPORTER_ERROR_COPY,
    EVIDENCE_IMPORTER_ERROR_MODEL,
    EVIDENCE_IMPORTER_ERROR_DATABASE,
    EVIDENCE_IMPORTER_ERROR_ROLLBACK
} EvidenceImporterError;

#define EVIDENCE_IMPORTER_ERROR     evidence_importer_error_quark()

GQuark evidence_importer_error_quark(void);

typedef struct EvidenceImporter EvidenceImporter;

typedef struct EvidenceImportRequest
{
    const char *source_path;
    const char *destination_directory;
    const char *relative_directory;
    const char *type_identifier;
    const char *collected_at;
    const char *source;
    const char *description;
} EvidenceImportRequest;

EvidenceImporter *evidence_importer_new(
    Database *database,
    GError **error
);

void evidence_importer_free(
    EvidenceImporter *evidence_importer
);

EvidenceRecord *evidence_importer_import(
    EvidenceImporter *evidence_importer,
    const EvidenceImportRequest *request,
    GCancellable *cancellable,
    GError **error
);

L’API peut être adaptée à l’architecture existante, mais les responsabilités doivent rester clairement séparées.

Propriété des objets

EvidenceImporter emprunte la connexion Database.

Il ne doit jamais :

  • fermer la base ;
  • posséder la session d’enquête ;
  • conserver un EvidenceRecord après le retour ;
  • conserver un état d’import entre deux appels.

Après succès, le EvidenceRecord retourné appartient à l’appelant.

Après échec, aucun modèle ne doit être retourné.

Données générées

Identifiant

Chaque preuve doit recevoir un UUID généré avec une API GLib adaptée.

L’identifiant doit être valide selon :

g_uuid_string_is_valid()

Nom original

Le nom original doit provenir du dernier composant du chemin source.

Il doit être copié avant toute autre opération.

Nom interne

Le nom interne doit être indépendant du nom original afin d’éviter :

  • collisions ;
  • caractères problématiques ;
  • chemins ambigus ;
  • dépendance au nom fourni par la source.

Format recommandé :

<uuid><extension-normalisee>

Exemple :

8c775ad2-899f-43f1-8f42-ef764dbbc359.png

L’extension :

  • peut être conservée depuis le nom original ;
  • doit être normalisée en minuscules ;
  • doit rester courte et sûre ;
  • ne doit contenir que des caractères alphanumériques ;
  • doit être omise si elle est absente ou invalide.

Le nom interne ne doit jamais contenir de séparateur de chemin.

Chemin relatif

Le chemin relatif enregistré dans EvidenceRecord doit être construit avec :

relative_directory + internal_name

Il doit rester relatif à la racine de l’enquête.

Le chemin absolu de copie et le chemin relatif SQLite ne doivent jamais être confondus.

Date d’import

La date d’import doit être générée en UTC au format strict :

YYYY-MM-DDTHH:MM:SSZ

La date doit être créée au moment de l’import, pas fournie par l’interface.

Déroulement de l’import

L’ordre attendu est :

  1. validation de la requête ;
  2. contrôle de l’annulation ;
  3. génération de l’UUID ;
  4. extraction du nom original ;
  5. génération du nom interne ;
  6. construction du chemin relatif ;
  7. copie sûre du fichier ;
  8. contrôle de l’annulation ;
  9. génération de imported_at ;
  10. création du EvidenceRecord ;
  11. insertion via EvidenceDao ;
  12. retour du modèle.

Cohérence fichier/base

SQLite ne peut pas annuler automatiquement une copie de fichier.

Le service doit donc implémenter une compensation explicite.

Échec avant copie

Aucun nettoyage fichier n’est nécessaire.

Échec pendant copie

EvidenceCopy doit supprimer lui-même tout fichier partiel.

Échec après copie mais avant insertion

Le fichier copié doit être supprimé.

Échec d’insertion SQLite

Le fichier copié doit être supprimé.

Échec du nettoyage

Si la suppression du fichier échoue :

  • l’erreur principale doit rester compréhensible ;
  • l’erreur doit indiquer qu’un fichier orphelin peut subsister ;
  • le chemin du fichier concerné doit être inclus dans le message.

Il est interdit de signaler un simple échec d’insertion tout en laissant silencieusement une copie non référencée.

Transaction SQLite

L’insertion doit être effectuée dans une transaction SQLite explicite.

Ordre recommandé :

  1. copie sûre terminée ;
  2. début de transaction ;
  3. insertion via EvidenceDao ;
  4. commit ;
  5. succès.

En cas d’échec :

  1. rollback SQLite si une transaction est active ;
  2. suppression de la copie ;
  3. retour de l’erreur.

Le service ne doit pas démarrer une transaction si la connexion en possède déjà une.

Une transaction déjà active doit produire une erreur claire.

Validation de la requête

Refuser :

  • EvidenceImporter absent ;
  • requête absente ;
  • chemin source vide ;
  • dossier destination vide ;
  • dossier relatif vide ;
  • type de preuve vide ;
  • chemin relatif absolu ;
  • composants . ou .. ;
  • séparateurs incohérents ;
  • GError déjà initialisé.

Les champs suivants sont facultatifs :

  • collected_at ;
  • source ;
  • description.

Les chaînes facultatives composées uniquement d’espaces doivent être normalisées à NULL, conformément au comportement de EvidenceRecord.

Annulation

Le GCancellable est facultatif.

L’annulation doit être vérifiée :

  • avant la génération des données ;
  • avant la copie ;
  • après la copie ;
  • avant le début de la transaction ;
  • avant l’insertion ;
  • avant le commit.

Après la copie, toute annulation doit déclencher la suppression de la copie.

Une annulation ne doit jamais laisser :

  • une ligne SQLite ;
  • une copie non référencée ;
  • une transaction active.

Gestion des erreurs

Le service doit convertir les erreurs des sous-modules dans son propre domaine tout en conservant le contexte.

Exemples :

Impossible de copier la preuve : <message EvidenceCopy>
Impossible de créer le modèle de preuve : <message EvidenceRecord>
Impossible d’enregistrer la preuve : <message EvidenceDao>

Les erreurs ne doivent pas être écrasées pendant le nettoyage.

Sécurité

Le service ne doit jamais :

  • utiliser une commande shell ;
  • exécuter le fichier source ;
  • écrire dans le fichier source ;
  • suivre un lien symbolique source ;
  • écraser une destination existante ;
  • accepter un chemin relatif sortant de l’enquête ;
  • construire un chemin avec sprintf() ou concaténation fragile.

Utiliser les API GLib de construction et de normalisation des chemins.

Tests obligatoires

Import valide complet

Créer une enquête temporaire et un fichier source.

Vérifier :

  • copie créée ;
  • ligne SQLite créée ;
  • EvidenceRecord retourné ;
  • UUID valide ;
  • nom original correct ;
  • nom interne conforme ;
  • chemin relatif correct ;
  • SHA-256 correct ;
  • taille correcte ;
  • date UTC valide ;
  • type correct ;
  • champs facultatifs conservés.

Import avec champs facultatifs absents

Vérifier que :

  • collected_at est NULL ;
  • source est NULL ;
  • description est NULL.

Fichier vide

Vérifier l’import d’un fichier vide.

Fichier binaire

Vérifier l’import d’un fichier contenant des octets nuls.

Nom original complexe

Tester un nom comprenant :

  • espaces ;
  • majuscules ;
  • plusieurs points ;
  • caractères non ASCII.

Le nom original doit être conservé dans le modèle.

Le nom interne doit rester sûr.

Extension absente

Vérifier que le nom interne reste valide sans extension.

Extension invalide

Tester une extension trop longue ou contenant des caractères inhabituels.

L’import doit réussir avec un nom interne sans extension ou avec une extension normalisée sûre.

Type inconnu

Vérifier :

  • échec avant validation finale ;
  • aucune ligne SQLite ;
  • aucune copie restante.

Destination déjà existante

Forcer une collision sur le nom interne grâce à un crochet de test déterministe.

Vérifier :

  • absence d’écrasement ;
  • aucune ligne SQLite ;
  • fichier préexistant inchangé.

Échec d’insertion SQLite

Simuler une erreur du DAO après la copie.

Exemples acceptables :

  • contrainte provoquée volontairement ;
  • crochet interne de test ;
  • transaction rendue invalide de manière contrôlée.

Vérifier :

  • rollback SQLite ;
  • suppression de la copie ;
  • aucun EvidenceRecord retourné.

Échec de commit

Prévoir un mécanisme de test déterministe.

Vérifier :

  • rollback tenté ;
  • copie supprimée ;
  • aucune transaction active après retour.

Annulation avant copie

Vérifier qu’aucune destination n’est créée.

Annulation après copie

Utiliser un crochet de test pour annuler juste après la réussite de EvidenceCopy.

Vérifier :

  • copie supprimée ;
  • aucune ligne SQLite.

Échec de suppression compensatoire

Simuler un nettoyage impossible.

Vérifier que l’erreur finale signale explicitement le risque de fichier orphelin et contient son chemin.

Appels successifs

Importer plusieurs preuves distinctes avec la même instance.

Vérifier :

  • UUID distincts ;
  • noms internes distincts ;
  • lignes SQLite distinctes ;
  • aucun état résiduel entre les imports.

Transaction déjà active

Démarrer une transaction avant l’appel.

Vérifier :

  • refus propre ;
  • transaction appelante toujours active ;
  • aucune copie créée.

Cohérence finale

Après chaque test d’échec :

nombre de lignes preuve = 0
nombre de fichiers importés = 0
aucune transaction active

Crochets réservés aux tests

Les scénarios suivants peuvent nécessiter des crochets internes :

  • UUID imposé ;
  • annulation après copie ;
  • erreur avant insertion ;
  • erreur de commit ;
  • échec de nettoyage.

Ils doivent être compilés uniquement avec une macro dédiée :

EVIDENCE_IMPORTER_ENABLE_TEST_HOOKS

La version de production ne doit exposer ni état global modifiable ni API de test.

Intégration au Makefile

Ajouter la cible :

tests/test_evidence_importer

Elle doit compiler au minimum :

tests/test_evidence_importer.c
src/core/evidence_importer.c
src/core/evidence_copy.c
src/core/file_hash.c
src/models/evidence_record.c
src/dao/evidence_dao.c
src/database/database.c
src/database/schema.c
src/database/statement.c
src/database/transaction.c
src/database/error.c

Ajouter le module aux sources du binaire principal.

Critères d’acceptation

Le ticket est validé lorsque :

  • l’import réussi crée exactement une copie et une ligne SQLite ;
  • le modèle retourné correspond aux données persistées ;
  • aucun échec ne laisse de copie partielle ;
  • aucun échec ne laisse de ligne SQLite ;
  • aucune transaction ne reste active ;
  • les noms internes sont sûrs et uniques ;
  • les chemins relatifs ne peuvent pas sortir de l’enquête ;
  • l’annulation est propre ;
  • les erreurs conservent leur contexte ;
  • aucun appel shell n’est utilisé ;
  • tous les tests passent ;
  • git diff --check ne signale rien ;
  • Valgrind ne détecte aucune perte définie ou indirecte.

Commandes de validation

make clean
make
make test
git diff --check

Test ciblé :

./tests/test_evidence_importer

Valgrind :

valgrind \
    --leak-check=full \
    --show-leak-kinds=all \
    --track-origins=yes \
    --errors-for-leak-kinds=definite,indirect \
    --error-exitcode=1 \
    ./tests/test_evidence_importer

Résultats indispensables :

definitely lost: 0 bytes
indirectly lost: 0 bytes
ERROR SUMMARY: 0 errors

Hors périmètre

Ce ticket ne doit pas encore :

  • afficher une boîte de dialogue GTK ;
  • sélectionner le fichier source ;
  • demander les métadonnées à l’utilisateur ;
  • lancer l’import dans un BackgroundTask ;
  • rafraîchir une liste de preuves ;
  • produire un journal d’audit complet ;
  • extraire des métadonnées avec ExifTool.

Suite prévue

Le ticket suivant ajoutera l’interface GTK d’import de preuve et lancera ce service dans un BackgroundTask, avec progression, annulation et affichage des erreurs.

# Orchestrer l’import transactionnel d’une preuve ## Objectif Ajouter un service métier capable d’importer une preuve de bout en bout en combinant : 1. la validation du fichier source ; 2. la génération de l’identifiant de preuve ; 3. la génération du nom interne ; 4. la copie sûre dans l’enquête ; 5. la création du `EvidenceRecord` ; 6. l’insertion SQLite ; 7. le nettoyage du fichier copié si la persistance échoue. Ce ticket doit produire une opération cohérente : après succès, la copie et la ligne SQLite existent toutes les deux ; après échec, aucune preuve partielle ne doit rester. ## Contexte Les briques suivantes existent désormais : - `EvidenceRecord` ; - `EvidenceDao` ; - migration SQLite V2 ; - calcul SHA-256 ; - copie sûre avec vérification cryptographique. Il manque maintenant le composant qui orchestre ces modules sans mélanger les responsabilités. ## Périmètre Créer : ```text include/core/evidence_importer.h src/core/evidence_importer.c tests/test_evidence_importer.c ``` Mettre à jour le `Makefile`. ## API proposée ```c typedef enum { EVIDENCE_IMPORTER_ERROR_INVALID_ARGUMENT, EVIDENCE_IMPORTER_ERROR_MEMORY, EVIDENCE_IMPORTER_ERROR_CANCELLED, EVIDENCE_IMPORTER_ERROR_DESTINATION, EVIDENCE_IMPORTER_ERROR_COPY, EVIDENCE_IMPORTER_ERROR_MODEL, EVIDENCE_IMPORTER_ERROR_DATABASE, EVIDENCE_IMPORTER_ERROR_ROLLBACK } EvidenceImporterError; #define EVIDENCE_IMPORTER_ERROR evidence_importer_error_quark() GQuark evidence_importer_error_quark(void); typedef struct EvidenceImporter EvidenceImporter; typedef struct EvidenceImportRequest { const char *source_path; const char *destination_directory; const char *relative_directory; const char *type_identifier; const char *collected_at; const char *source; const char *description; } EvidenceImportRequest; EvidenceImporter *evidence_importer_new( Database *database, GError **error ); void evidence_importer_free( EvidenceImporter *evidence_importer ); EvidenceRecord *evidence_importer_import( EvidenceImporter *evidence_importer, const EvidenceImportRequest *request, GCancellable *cancellable, GError **error ); ``` L’API peut être adaptée à l’architecture existante, mais les responsabilités doivent rester clairement séparées. ## Propriété des objets `EvidenceImporter` emprunte la connexion `Database`. Il ne doit jamais : - fermer la base ; - posséder la session d’enquête ; - conserver un `EvidenceRecord` après le retour ; - conserver un état d’import entre deux appels. Après succès, le `EvidenceRecord` retourné appartient à l’appelant. Après échec, aucun modèle ne doit être retourné. ## Données générées ### Identifiant Chaque preuve doit recevoir un UUID généré avec une API GLib adaptée. L’identifiant doit être valide selon : ```c g_uuid_string_is_valid() ``` ### Nom original Le nom original doit provenir du dernier composant du chemin source. Il doit être copié avant toute autre opération. ### Nom interne Le nom interne doit être indépendant du nom original afin d’éviter : - collisions ; - caractères problématiques ; - chemins ambigus ; - dépendance au nom fourni par la source. Format recommandé : ```text <uuid><extension-normalisee> ``` Exemple : ```text 8c775ad2-899f-43f1-8f42-ef764dbbc359.png ``` L’extension : - peut être conservée depuis le nom original ; - doit être normalisée en minuscules ; - doit rester courte et sûre ; - ne doit contenir que des caractères alphanumériques ; - doit être omise si elle est absente ou invalide. Le nom interne ne doit jamais contenir de séparateur de chemin. ### Chemin relatif Le chemin relatif enregistré dans `EvidenceRecord` doit être construit avec : ```text relative_directory + internal_name ``` Il doit rester relatif à la racine de l’enquête. Le chemin absolu de copie et le chemin relatif SQLite ne doivent jamais être confondus. ### Date d’import La date d’import doit être générée en UTC au format strict : ```text YYYY-MM-DDTHH:MM:SSZ ``` La date doit être créée au moment de l’import, pas fournie par l’interface. ## Déroulement de l’import L’ordre attendu est : 1. validation de la requête ; 2. contrôle de l’annulation ; 3. génération de l’UUID ; 4. extraction du nom original ; 5. génération du nom interne ; 6. construction du chemin relatif ; 7. copie sûre du fichier ; 8. contrôle de l’annulation ; 9. génération de `imported_at` ; 10. création du `EvidenceRecord` ; 11. insertion via `EvidenceDao` ; 12. retour du modèle. ## Cohérence fichier/base SQLite ne peut pas annuler automatiquement une copie de fichier. Le service doit donc implémenter une compensation explicite. ### Échec avant copie Aucun nettoyage fichier n’est nécessaire. ### Échec pendant copie `EvidenceCopy` doit supprimer lui-même tout fichier partiel. ### Échec après copie mais avant insertion Le fichier copié doit être supprimé. ### Échec d’insertion SQLite Le fichier copié doit être supprimé. ### Échec du nettoyage Si la suppression du fichier échoue : - l’erreur principale doit rester compréhensible ; - l’erreur doit indiquer qu’un fichier orphelin peut subsister ; - le chemin du fichier concerné doit être inclus dans le message. Il est interdit de signaler un simple échec d’insertion tout en laissant silencieusement une copie non référencée. ## Transaction SQLite L’insertion doit être effectuée dans une transaction SQLite explicite. Ordre recommandé : 1. copie sûre terminée ; 2. début de transaction ; 3. insertion via `EvidenceDao` ; 4. commit ; 5. succès. En cas d’échec : 1. rollback SQLite si une transaction est active ; 2. suppression de la copie ; 3. retour de l’erreur. Le service ne doit pas démarrer une transaction si la connexion en possède déjà une. Une transaction déjà active doit produire une erreur claire. ## Validation de la requête Refuser : - `EvidenceImporter` absent ; - requête absente ; - chemin source vide ; - dossier destination vide ; - dossier relatif vide ; - type de preuve vide ; - chemin relatif absolu ; - composants `.` ou `..` ; - séparateurs incohérents ; - `GError` déjà initialisé. Les champs suivants sont facultatifs : - `collected_at` ; - `source` ; - `description`. Les chaînes facultatives composées uniquement d’espaces doivent être normalisées à `NULL`, conformément au comportement de `EvidenceRecord`. ## Annulation Le `GCancellable` est facultatif. L’annulation doit être vérifiée : - avant la génération des données ; - avant la copie ; - après la copie ; - avant le début de la transaction ; - avant l’insertion ; - avant le commit. Après la copie, toute annulation doit déclencher la suppression de la copie. Une annulation ne doit jamais laisser : - une ligne SQLite ; - une copie non référencée ; - une transaction active. ## Gestion des erreurs Le service doit convertir les erreurs des sous-modules dans son propre domaine tout en conservant le contexte. Exemples : ```text Impossible de copier la preuve : <message EvidenceCopy> Impossible de créer le modèle de preuve : <message EvidenceRecord> Impossible d’enregistrer la preuve : <message EvidenceDao> ``` Les erreurs ne doivent pas être écrasées pendant le nettoyage. ## Sécurité Le service ne doit jamais : - utiliser une commande shell ; - exécuter le fichier source ; - écrire dans le fichier source ; - suivre un lien symbolique source ; - écraser une destination existante ; - accepter un chemin relatif sortant de l’enquête ; - construire un chemin avec `sprintf()` ou concaténation fragile. Utiliser les API GLib de construction et de normalisation des chemins. ## Tests obligatoires ### Import valide complet Créer une enquête temporaire et un fichier source. Vérifier : - copie créée ; - ligne SQLite créée ; - `EvidenceRecord` retourné ; - UUID valide ; - nom original correct ; - nom interne conforme ; - chemin relatif correct ; - SHA-256 correct ; - taille correcte ; - date UTC valide ; - type correct ; - champs facultatifs conservés. ### Import avec champs facultatifs absents Vérifier que : - `collected_at` est `NULL` ; - `source` est `NULL` ; - `description` est `NULL`. ### Fichier vide Vérifier l’import d’un fichier vide. ### Fichier binaire Vérifier l’import d’un fichier contenant des octets nuls. ### Nom original complexe Tester un nom comprenant : - espaces ; - majuscules ; - plusieurs points ; - caractères non ASCII. Le nom original doit être conservé dans le modèle. Le nom interne doit rester sûr. ### Extension absente Vérifier que le nom interne reste valide sans extension. ### Extension invalide Tester une extension trop longue ou contenant des caractères inhabituels. L’import doit réussir avec un nom interne sans extension ou avec une extension normalisée sûre. ### Type inconnu Vérifier : - échec avant validation finale ; - aucune ligne SQLite ; - aucune copie restante. ### Destination déjà existante Forcer une collision sur le nom interne grâce à un crochet de test déterministe. Vérifier : - absence d’écrasement ; - aucune ligne SQLite ; - fichier préexistant inchangé. ### Échec d’insertion SQLite Simuler une erreur du DAO après la copie. Exemples acceptables : - contrainte provoquée volontairement ; - crochet interne de test ; - transaction rendue invalide de manière contrôlée. Vérifier : - rollback SQLite ; - suppression de la copie ; - aucun `EvidenceRecord` retourné. ### Échec de commit Prévoir un mécanisme de test déterministe. Vérifier : - rollback tenté ; - copie supprimée ; - aucune transaction active après retour. ### Annulation avant copie Vérifier qu’aucune destination n’est créée. ### Annulation après copie Utiliser un crochet de test pour annuler juste après la réussite de `EvidenceCopy`. Vérifier : - copie supprimée ; - aucune ligne SQLite. ### Échec de suppression compensatoire Simuler un nettoyage impossible. Vérifier que l’erreur finale signale explicitement le risque de fichier orphelin et contient son chemin. ### Appels successifs Importer plusieurs preuves distinctes avec la même instance. Vérifier : - UUID distincts ; - noms internes distincts ; - lignes SQLite distinctes ; - aucun état résiduel entre les imports. ### Transaction déjà active Démarrer une transaction avant l’appel. Vérifier : - refus propre ; - transaction appelante toujours active ; - aucune copie créée. ### Cohérence finale Après chaque test d’échec : ```text nombre de lignes preuve = 0 nombre de fichiers importés = 0 aucune transaction active ``` ## Crochets réservés aux tests Les scénarios suivants peuvent nécessiter des crochets internes : - UUID imposé ; - annulation après copie ; - erreur avant insertion ; - erreur de commit ; - échec de nettoyage. Ils doivent être compilés uniquement avec une macro dédiée : ```text EVIDENCE_IMPORTER_ENABLE_TEST_HOOKS ``` La version de production ne doit exposer ni état global modifiable ni API de test. ## Intégration au Makefile Ajouter la cible : ```text tests/test_evidence_importer ``` Elle doit compiler au minimum : ```text tests/test_evidence_importer.c src/core/evidence_importer.c src/core/evidence_copy.c src/core/file_hash.c src/models/evidence_record.c src/dao/evidence_dao.c src/database/database.c src/database/schema.c src/database/statement.c src/database/transaction.c src/database/error.c ``` Ajouter le module aux sources du binaire principal. ## Critères d’acceptation Le ticket est validé lorsque : - l’import réussi crée exactement une copie et une ligne SQLite ; - le modèle retourné correspond aux données persistées ; - aucun échec ne laisse de copie partielle ; - aucun échec ne laisse de ligne SQLite ; - aucune transaction ne reste active ; - les noms internes sont sûrs et uniques ; - les chemins relatifs ne peuvent pas sortir de l’enquête ; - l’annulation est propre ; - les erreurs conservent leur contexte ; - aucun appel shell n’est utilisé ; - tous les tests passent ; - `git diff --check` ne signale rien ; - Valgrind ne détecte aucune perte définie ou indirecte. ## Commandes de validation ```bash make clean make make test git diff --check ``` Test ciblé : ```bash ./tests/test_evidence_importer ``` Valgrind : ```bash valgrind \ --leak-check=full \ --show-leak-kinds=all \ --track-origins=yes \ --errors-for-leak-kinds=definite,indirect \ --error-exitcode=1 \ ./tests/test_evidence_importer ``` Résultats indispensables : ```text definitely lost: 0 bytes indirectly lost: 0 bytes ERROR SUMMARY: 0 errors ``` ## Hors périmètre Ce ticket ne doit pas encore : - afficher une boîte de dialogue GTK ; - sélectionner le fichier source ; - demander les métadonnées à l’utilisateur ; - lancer l’import dans un `BackgroundTask` ; - rafraîchir une liste de preuves ; - produire un journal d’audit complet ; - extraire des métadonnées avec ExifTool. ## Suite prévue Le ticket suivant ajoutera l’interface GTK d’import de preuve et lancera ce service dans un `BackgroundTask`, avec progression, annulation et affichage des erreurs.
fy59 closed this issue 2026-07-19 21:08:47 +02:00
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: fy59/labfy-investigation#49
No description provided.