# Charger structures et personnes

> **En bref :**
> Charger les structures, puis les personnes, par deux traitements Airflow de Directory Bridge ; IKG les reçoit par le bus et les écrit dans le graphe.
> Statut : **Non exécuté** ; noms de traitements, de files et de relations vérifiés dans le code. Inutile pour le POC de novembre.

## Pourquoi ce tutoriel

Tout le reste s'appuie sur l'annuaire : une publication n'est moissonnée que pour une personne connue, et une unité n'a de contenu que si des chercheurs y sont rattachés. **L'ordre compte** : un rattachement vers une structure absente est ignoré, sans erreur visible.

Étape 2 sur 4. Le trajet complet de la donnée est décrit dans [Comprendre CRISalid](/03-crisalid/00-reperes/comprendre-crisalid).

## Avant de commencer

- Le socle démarré et les fichiers corrigés ([étape 1](./preparer-donnees-et-pile)).
- Les profils `cdb` et `cdb-db` ajoutés à la commande de démarrage : ils lancent Airflow et Directory Bridge.

## Étapes

### Étape 1 — Placer et trier les fichiers

**Pourquoi :** le traitement ne lit que des chemins et colonnes précis ; un fichier mal placé ou mal trié échoue en silence.

Les chemins lus sont `STRUCTURE_SPREADSHEET_PATH` et `PEOPLE_SPREADSHEET_PATH`, préparés par `configure_cdb.sh`. Trier les structures, parents avant enfants, sur une copie :

```bash
cd official-crisalid/crisalid-directory-bridge
python scripts/sort_structures.py data/structures.csv
```

Le fichier national des structures de recherche (`data/fr-esr-structures-recherche-publiques-actives.csv`) n'est lu par **aucun** traitement : il faudrait d'abord le convertir au format de `structures.csv`.

### Étape 2 — Charger les structures

**Pourquoi :** les personnes ne peuvent être rattachées qu'à des structures déjà présentes.

Dans Airflow, déclencher `load_spreadsheet_structures`. Il déclenche `broadcast_entities`, qui publie sur l'échange `directory`. Attendre que la file `crisalid-ikg-structures-batch` revienne à zéro.

### Étape 3 — Charger les personnes

**Pourquoi :** c'est le rattachement des personnes qui rend une unité visible.

Déclencher `load_spreadsheet_people`, puis surveiller `crisalid-ikg-people-batch` et sa file de rebut `dlq.crisalid-ikg-people-batch`.

### Étape 4 — Vérifier dans le graphe

**Pourquoi :** une personne créée sans rattachement ne produit pas d'erreur ; seule une requête la révèle.

Les noms ci-dessous sont ceux du code ; leur correspondance avec ceux de l'instance est donnée à l'[étape 4 du parcours](./verifier-le-graphe-et-api#les-noms-du-code-et-ceux-de-linstance).

```cypher
// Structures et leur identifiant local
MATCH (s:OrganizationUnit)-[:HAS_IDENTIFIER]->(i:AgentIdentifier {type: 'local'})
RETURN i.value AS local_id, labels(s) AS labels, s.uid ORDER BY local_id;

// Personnes sans rattachement de recherche
MATCH (p:Person) WHERE NOT (p)-[:MEMBER_OF]->()
RETURN p.uid, p.display_name;
```

## Ce que vous devez obtenir

- Autant de structures dans le graphe que de lignes dans `structures.csv`.
- Aucune personne renvoyée par la seconde requête.
- Les files revenues à zéro, la file de rebut vide.

## Limites

- **Non exécuté** : comportements à l'exécution **à confirmer**.
- Les rattachements sont créés sans dates ([modèle de données](/03-crisalid/01-donnees/modele-de-donnees)).
- Une disparition calculée par le Bridge n'est pas propagée au graphe ([suppressions non propagées](/03-crisalid/01-donnees/contrats-api-evenements#suppressions-non-propagées)).
- Ce que l'annuaire perd en route est mesuré par les contrôles [Directory Bridge](../02-preuves/preparer-directory-bridge) et [Bridge → IKG](../02-preuves/verifier-contrat-bridge-ikg).

## Et ensuite

Étape 3 sur 4 : [moissonner les publications](./enrichir-les-publications).

Révision lue : `crisalid-directory-bridge` `95be05d7`, `crisalid-ikg` `ebdaae75`.
