# nyora-notes-tt — liaison Mail<->RAG<->OneDrive : hash manquant, Phase 2 extraction PJ, deux bugs Docker **Date** : 07/08/2026 **Tags** : nyora-notes-tt, attachments, onedrive, docker, sqlite-wal ## Contexte Chantier demande par Nabil : joindre les PJ mail (`attachments`) aux documents OneDrive (`onedrive_documents`) deja indexes. Diagnostic initial : `attachments.content_hash` existait dans le schema mais n'etait jamais calcule (0/41), rendant tout JOIN avec `onedrive_documents.content_hash` structurellement vide. `attachments_vec` n'existait pas du tout -- decision du 31/07 actee mais jamais implementee. ## Fixes appliques - `download_attachments_phase1.py` patche : calcul MD5 (meme methode que `onedrive_catalog.py:hash_file()`, blocs de 1 Mo) juste apres le telechargement, ecrit en DB. Backfill fait sur les PJ deja telechargees (17/20 -- 3 introuvables sur disque, chemin `/mnt/pj-archive/...` non monte dans ce conteneur, a creuser separement). - `attachments_vec` cree en 2048d (`vec0`), meme modele NVIDIA NIM `llama-nemotron-embed-vl-1b-v2` que `onedrive_vec` -- generalisation NVIDIA NIM actee. - Colonnes ajoutees a `attachments` : `document_type`, `ao_reference`, `date_document` (parite avec `onedrive_documents`), `extraction_status` (pending/processed/error, separee de `status` qui reste le statut de telechargement -- le CHECK constraint existant sur `status` empeche d'y ajouter une valeur sans recreer la table). - Nouveau `extract_attachments_phase2.py` : appelle `nyora-convert-api` en mode **upload multipart** (`files={"file": ...}`, pas de `nas_root` dedie pour les PJ mail -- inutile de monter un nouveau volume, `/convert` accepte deja un fichier en flux direct). Meme contrat de reponse que `onedrive_process.py` (markdown, resume, document_type, ao_reference, date_document). - Nouveau `embed_attachments.py`, copie fidele de `embed_onedrive_docs.py`. ## Resultat Phase 2 (test sur les 20 PJ deja telechargees) 14 traitees avec succes, 6 en erreur (3 fichiers introuvables sur disque -- meme cause que le backfill hash ; 1 `.zip`, format non gere par nyora-convert-api ; 2 autres a verifier). 14 embeddings crees dans `attachments_vec`, 0 erreur. ## Le vrai enseignement : content_hash vide, ao_reference fonctionne JOIN exact sur `content_hash` : 0 correspondance. Pas un bug -- les PJ testees sont des documents 2026 tout frais, l'archive OneDrive scannee ne les a pas encore. Structurel, va se peupler avec le volume. JOIN approximatif sur `ao_reference` (regex `\d{1,3}/\d{4}`, normalisation legere) : **4 PJ distinctes sur 14 trouvent au moins un document OneDrive du meme dossier AO**. Preuve concrete que cette cle fonctionne des maintenant, contrairement au hash exact. Confirme l'hypothese testee le meme jour sur le permalien OWA (non exploitable comme pointeur stable) : la fiabilite de la liaison passe par une cle de recherche (reference AO structuree), pas par un identifiant unique stocke a l'ingestion. Suite logique, pas encore faite : exposer ce rapprochement comme une vraie fonction de recherche cote `mcp_server.py` (aujourd'hui c'est une requete Python ad hoc, pas un endpoint), plutot que de le refaire a la main a chaque fois. ## Deux pieges Docker decouverts en cours de route (transversal, pas specifique a ce projet) 1. **`docker restart` ne recharge JAMAIS une image fraichement buildee.** Il relance le meme conteneur fige sur l'image ID qu'il avait a sa creation. Verifie : apres un rebuild + `docker restart`, `docker inspect --format='{{.Image}}'` pointait toujours sur l'ancien digest, alors que `docker images ...:latest` montrait le nouveau. Deux cycles de patch perdus avant diagnostic. **Seul `docker compose up -d ` recree reellement le conteneur sur la derniere image.** 2. **Perte silencieuse de DDL (ALTER TABLE) au redemarrage sans checkpoint WAL.** Des `ALTER TABLE` executes via `docker exec` (commit() fait) ont disparu apres un `docker restart` suivant, alors que le fichier `.db` est un bind mount hote persistant normalement inchange par un redemarrage de conteneur. Cause precise non confirmee (connexion WAL non checkpointee coupee au SIGTERM/SIGKILL du conteneur, plausible). **Fix applicable** : `conn.execute("PRAGMA wal_checkpoint(TRUNCATE)")` + `commit()` juste apres toute DDL, avant de toucher au conteneur. Reapplique et verifie stable. ## A faire ensuite - Elucider le montage manquant `/mnt/pj-archive` (3 PJ introuvables sur disque). - Exposer le rapprochement `ao_reference` comme fonction de recherche MCP plutot que requete ad hoc. - Continuer le sweep (66 notes restantes au 07/08/2026 21h58, relance en cours) puis relancer Phase 2 + embedding sur le volume complet une fois le telechargement termine.