labfy-investigation/docs/tickets/closed/TICKET-009.md
grayTerminal-sh 2bd29e6208 arbo
2026-07-13 13:57:25 +02:00

268 lines
5.2 KiB
Markdown

# Ticket #009
## Titre
Ajouter les relations parent/enfants à `InvestigationNode`.
---
## Objectif
Faire évoluer `InvestigationNode` afin qu'un nœud puisse appartenir à une arborescence.
Chaque nœud pourra :
- connaître son parent ;
- posséder plusieurs enfants ;
- exposer ses enfants en lecture seule via une API publique.
---
## Responsabilités
Le module `InvestigationNode` doit :
- mémoriser un pointeur vers son parent ;
- posséder un tableau dynamique d'enfants ;
- ajouter un enfant ;
- retourner un enfant par son index ;
- retourner le nombre d'enfants ;
- retourner son parent ;
- détruire récursivement les enfants qu'il possède.
---
## Hors périmètre
Ce ticket ne doit pas :
- parcourir le système de fichiers ;
- construire automatiquement une arborescence depuis un dossier ;
- afficher quoi que ce soit avec GTK ;
- communiquer avec SQLite ;
- gérer le tri des enfants ;
- gérer la suppression individuelle d'un enfant ;
- gérer le déplacement d'un nœud entre deux parents.
---
## Architecture
```text
InvestigationTreeModel
InvestigationNode
├── InvestigationNode
├── InvestigationNode
└── InvestigationNode
```
Le module appartient à la couche `core`.
Il peut dépendre de GLib, mais jamais de GTK.
---
## Gestion de la propriété
Un nœud devient propriétaire de chaque enfant ajouté avec :
```c
investigation_node_add_child(parent, child);
```
Après un ajout réussi :
- `parent` possède `child` ;
- le code appelant ne doit plus libérer `child` directement ;
- `child` conserve une référence non propriétaire vers `parent`.
Lors de la destruction du parent, tous ses enfants sont détruits récursivement.
---
## Structure interne attendue
```c
struct InvestigationNode
{
char *name;
InvestigationNodeType type;
InvestigationNode *parent;
GPtrArray *children;
};
```
La structure reste privée dans `investigation_node.c`.
---
## Interface publique attendue
Les fonctions existantes sont conservées :
```c
InvestigationNode *investigation_node_new(
const char *name,
InvestigationNodeType type
);
void investigation_node_free(
InvestigationNode *node
);
const char *investigation_node_get_name(
const InvestigationNode *node
);
InvestigationNodeType investigation_node_get_type(
const InvestigationNode *node
);
```
Les fonctions suivantes sont ajoutées :
```c
bool investigation_node_add_child(
InvestigationNode *parent,
InvestigationNode *child
);
const InvestigationNode *investigation_node_get_child(
const InvestigationNode *node,
size_t index
);
size_t investigation_node_get_children_count(
const InvestigationNode *node
);
const InvestigationNode *investigation_node_get_parent(
const InvestigationNode *node
);
```
---
## Comportement attendu
Exemple :
```c
InvestigationNode *root = NULL;
InvestigationNode *child = NULL;
root = investigation_node_new(
"Template",
INVESTIGATION_NODE_DIRECTORY
);
child = investigation_node_new(
"00_BaseDeDonnees",
INVESTIGATION_NODE_DIRECTORY
);
if (!investigation_node_add_child(root, child))
{
investigation_node_free(child);
investigation_node_free(root);
return;
}
```
Après l'ajout :
```text
Template
└── 00_BaseDeDonnees
```
Le nœud `root` devient propriétaire de `child`.
Le nettoyage correct est uniquement :
```c
investigation_node_free(root);
```
---
## Règles d'ajout
`investigation_node_add_child()` doit refuser :
- un parent `NULL` ;
- un enfant `NULL` ;
- un parent qui représente un fichier ;
- l'ajout d'un nœud comme enfant de lui-même ;
- un enfant possédant déjà un parent.
En cas d'échec, la propriété de l'enfant reste au code appelant.
---
## Dépendances
- C17 ;
- GLib.
Aucune dépendance GTK ou SQLite.
---
## Contraintes techniques
- structure opaque ;
- aucun état global ;
- utilisation de `GPtrArray` ;
- tableau créé avec une fonction de destruction ;
- documentation Doxygen ;
- compilation sans warning ;
- respect des conventions de nommage ;
- aucune modification directe du tableau en dehors du module.
---
## Critères d'acceptation
- [ ] Le projet compile sans warning.
- [ ] Un dossier peut posséder plusieurs enfants.
- [ ] Un fichier ne peut pas recevoir d'enfant.
- [ ] Un enfant connaît son parent.
- [ ] Le nombre d'enfants est correct.
- [ ] Un enfant peut être récupéré par son index.
- [ ] Un index invalide retourne `NULL`.
- [ ] Un enfant ne peut pas avoir deux parents.
- [ ] Un nœud ne peut pas être son propre enfant.
- [ ] La destruction d'un parent détruit récursivement ses enfants.
- [ ] Aucun code GTK.
- [ ] Aucun code SQLite.
---
## Tests
- créer un parent dossier ;
- ajouter un enfant dossier ;
- ajouter un enfant fichier ;
- vérifier le nombre d'enfants ;
- récupérer chaque enfant ;
- vérifier le parent d'un enfant ;
- tester un index invalide ;
- refuser l'ajout à un fichier ;
- refuser un parent `NULL` ;
- refuser un enfant `NULL` ;
- refuser l'auto-référence ;
- refuser un enfant possédant déjà un parent ;
- détruire un arbre complet ;
- appeler les getters avec `NULL`.
---
## Commit attendu
```text
feat(core): add investigation node hierarchy
```