labfy-investigation/docs/tickets/closed/TICKET-022.md
2026-07-15 13:39:39 +02:00

6.3 KiB

Ticket #022

Titre

Initialiser la base SQLite d'une enquête.


Objectif

Créer et initialiser correctement le fichier :

00_BaseDeDonnees/Enquete.sqlite

avec un premier schéma SQLite versionné.

La base doit contenir les métadonnées minimales permettant d'identifier l'enquête et la version du schéma.


Architecture

InvestigationProject
        │
        ▼
Database
        │
        ▼
SQLite

InvestigationProject orchestre la création de l'enquête.

Le module Database est seul responsable de l'ouverture de SQLite, de l'exécution du schéma et de la fermeture de la base.


Responsabilités

InvestigationProject

Le module doit :

  • créer l'arborescence ;
  • demander au module Database d'initialiser Enquete.sqlite ;
  • considérer la création comme échouée si l'initialisation SQLite échoue ;
  • nettoyer toute l'enquête créée en cas d'échec.

Database

Le module doit :

  • ouvrir ou créer le fichier SQLite ;
  • démarrer une transaction ;
  • créer le schéma initial ;
  • insérer les métadonnées ;
  • valider la transaction ;
  • annuler la transaction en cas d'erreur ;
  • fermer proprement la connexion.

Nouveaux fichiers

include/database/database.h
src/database/database.c

Éventuellement :

include/database/schema.h
src/database/schema.c

si le schéma devient trop volumineux pour rester dans database.c.

Pour ce ticket, un seul module database.c est acceptable.


Interface publique attendue

bool database_initialize(
    const char *database_path
);

La fonction retourne :

true

si la base a été correctement initialisée.

Elle retourne :

false

en cas d'erreur.


Schéma initial

Table metadata

CREATE TABLE metadata
(
    key   TEXT PRIMARY KEY,
    value TEXT NOT NULL
);

Métadonnées obligatoires

schema_version
application
created_at
investigation_uuid

Valeurs attendues :

schema_version     = 1
application        = Labfy Investigation
created_at         = date UTC ISO 8601
investigation_uuid = UUID unique

Exemple :

2026-07-14T18:42:15Z

Table investigation

Créer également une table minimale représentant l'enquête :

CREATE TABLE investigation
(
    id          INTEGER PRIMARY KEY CHECK (id = 1),
    name        TEXT NOT NULL,
    root_path   TEXT NOT NULL,
    created_at  TEXT NOT NULL
);

La table contient une seule ligne correspondant à l'enquête courante.


Données nécessaires

database_initialize() doit recevoir suffisamment d'informations pour initialiser correctement la base.

L'interface pourra donc évoluer vers :

bool database_initialize(
    const char *database_path,
    const char *investigation_name,
    const char *investigation_root_path
);

Cette signature est préférée pour éviter que le module Database reconstruise ou devine des informations métier.


UUID

L'UUID doit être généré avec GLib :

g_uuid_string_random()

La chaîne retournée doit être libérée avec :

g_free(uuid);

Date de création

La date doit être produite en UTC avec GLib.

Format attendu :

YYYY-MM-DDTHH:MM:SSZ

La date doit être enregistrée à la fois :

  • dans metadata.created_at ;
  • dans investigation.created_at.

Transaction

Toute l'initialisation doit se dérouler dans une transaction :

BEGIN IMMEDIATE;

Puis :

COMMIT;

En cas d'erreur :

ROLLBACK;

Une base partiellement initialisée ne doit jamais être considérée comme valide.


Intégration avec InvestigationProject

investigation_project_create() ne doit plus créer un fichier vide avec :

g_file_set_contents(...)

Il doit construire le chemin de la base puis appeler :

database_initialize(
    database_path,
    investigation_name,
    investigation_path
);

Si l'appel échoue :

  • le fichier SQLite éventuel est supprimé ;
  • tous les dossiers créés sont supprimés ;
  • investigation_project_create() retourne NULL.

Validation

À partir de ce ticket, investigation_project_validate() doit toujours vérifier la présence du fichier SQLite, mais pas encore son contenu SQL.

La validation du schéma sera ajoutée dans un prochain ticket dédié.


Hors périmètre

Ce ticket ne doit pas :

  • créer les tables Preuves ;
  • créer les tables Entites ;
  • créer les relations ;
  • gérer les migrations ;
  • ouvrir une enquête existante ;
  • modifier GTK ;
  • exposer directement sqlite3 * hors du module Database.

Contraintes techniques

  • C17 ;
  • SQLite3 ;
  • GLib ;
  • aucune dépendance GTK ;
  • aucun état global ;
  • requêtes SQL centralisées dans database.c ;
  • fermeture garantie de la connexion ;
  • transaction obligatoire ;
  • documentation Doxygen ;
  • compilation sans warning.

Tests

Créer :

tests/test_database.c

Le test doit :

  • créer un dossier temporaire ;
  • initialiser une base SQLite ;
  • vérifier que le fichier existe ;
  • ouvrir la base en lecture ;
  • vérifier la présence de la table metadata ;
  • vérifier la présence de la table investigation ;
  • vérifier schema_version = 1 ;
  • vérifier application = Labfy Investigation ;
  • vérifier que created_at n'est pas vide ;
  • vérifier que l'UUID n'est pas vide ;
  • vérifier la ligne unique de la table investigation ;
  • vérifier le nom et le chemin racine ;
  • vérifier qu'une initialisation sur un chemin invalide échoue ;
  • nettoyer complètement les fichiers temporaires.

Faire également évoluer :

tests/test_investigation_project.c

pour vérifier que la base créée n'est plus vide.


Critères d'acceptation

  • Le projet compile sans warning.
  • make test reste entièrement valide.
  • Enquete.sqlite est une vraie base SQLite.
  • La table metadata existe.
  • La table investigation existe.
  • schema_version vaut 1.
  • Une date UTC est enregistrée.
  • Un UUID est généré.
  • L'enquête est enregistrée dans la base.
  • L'initialisation est transactionnelle.
  • Toute erreur provoque un nettoyage complet.
  • Aucun type sqlite3 * n'est exposé publiquement.
  • Aucune dépendance GTK.

Commit attendu

feat(database): initialize investigation database