# Documentation Complète de l'Ancrage Blockchain - LeCoffre.io **Dernière mise à jour** : 2025-11-24 **Version** : 3.1.2 Ce document consolide toute la documentation relative à l'ancrage blockchain des documents et dossiers dans LeCoffre.io. --- ## 📋 Table des Matières 1. [Vue d'Ensemble](#1-vue-densemble) 2. [Architecture V3](#2-architecture-v3) 3. [Processus d'Ancrage](#3-processus-dancrage) 4. [Certificats et ZIP](#4-certificats-et-zip) 5. [Vérification et Statuts](#5-vérification-et-statuts) 6. [Scripts et Maintenance](#6-scripts-et-maintenance) 7. [Troubleshooting](#7-troubleshooting) 8. [Références](#8-références) --- ## 1. Vue d'Ensemble ### Évolution des Versions | Version | Blockchain | Périmètre | Déclenchement | Filigrane | Fallback | |---------|-----------|-----------|---------------|-----------|----------| | **V1** | Tezos | Dossiers uniquement | Manuel | ❌ Non | ⚠️ Lecture seule | | **V2** | Bitcoin Signet | Docs + Dossiers | Auto | ❌ Non | - | | **V3** | Bitcoin Signet | Docs + Dossiers | Auto | ✅ Oui | ✅ Tezos masqué | ### Nouveautés V3 1. **Filigrane automatique** : "lecoffre.io" sur tous documents 2. **Double version** : Original + filigrané (conservés en BDD) 3. **ZIP enrichi** : Originaux + filigranés + certificats + preuves JSON 4. **Preuves structurées** : JSON standardisé pour vérification externe 5. **Ancrage dossier** : Hash du ZIP complet (pas seulement Merkle tree) 6. **Fallback Tezos** : Accès masqué aux anciens ancrages (lecture seule) ### Principes Fondamentaux - **Ancrage immédiat** : L'ancrage est déclenché automatiquement lors de la validation d'un document - **Hash filigrané** : Seule la version filigranée est ancrée sur blockchain - **Double hash** : Hash original et hash filigrané sont stockés pour vérification - **Preuve on-chain** : Le `tx_id` (transaction ID Bitcoin) est la seule preuve fiable d'ancrage --- ## 2. Architecture V3 ### Services Backend #### WatermarkService **Fichier** : `lecoffre-back-main/src/services/common/WatermarkService/WatermarkService.ts` **Responsabilités** : - Conversion documents → PDF (si nécessaire) - Ajout filigrane "lecoffre.io" (diagonal, 15% opacité) - Upload version filigranée vers S3/IPFS - Gestion formats : PDF, images, Word, PowerPoint **Méthodes principales** : ```typescript async addWatermarkAndUpload(fileUid: string): Promise<{ watermarkedS3Key: string; watermarkedSize: number; watermarkedMimetype: string; }> ``` #### DocumentAnchorsService **Fichier** : `lecoffre-back-main/src/services/notary/DocumentAnchorsService/DocumentAnchorsService.ts` **Workflow d'ancrage** : 1. Vérification ancrage Tezos existant (fallback) 2. Génération version filigranée si absente 3. Calcul hash version filigranée 4. Vérification ancrage Signet existant 5. Création ancrage `QUEUED` 6. Ancrage blockchain Bitcoin Signet 7. Génération `proof_data` (incluant fallback Tezos) 8. Mise à jour ancrage avec `tx_id` **Méthodes principales** : ```typescript async anchorDocument(documentUid: string, anchoredByUid?: string): Promise async getByDocumentUid(documentUid: string): Promise async getByFileHash(fileHash: string): Promise ``` #### OfficeFolderAnchorsService **Fichier** : `lecoffre-back-main/src/services/notary/OfficeFolderAnchorsService/OfficeFolderAnchorsService.ts` **Workflow d'ancrage dossier** : 1. Récupération tous documents validés 2. Génération filigranes manquants 3. Génération ZIP complet dossier 4. Upload ZIP vers S3 5. Ancrage hash ZIP complet 6. Génération preuve dossier **Structure ZIP** : ```text dossier_12345678/ ├── _LISEZ-MOI.txt ├── 01_originaux/ ├── 02_filigranes/ ├── 03_certificats/ └── 04_preuves/ ``` #### ProofDataService **Fichier** : `lecoffre-back-main/src/services/notary/ProofDataService/ProofDataService.ts` **Responsabilités** : - Génération JSON de preuve d'ancrage - Format standard pour vérification externe - Inclusion toutes données blockchain **Structure JSON** : ```json { "version": "3.0.0", "timestamp": "2025-10-29T16:30:00.000Z", "document": { "uid": "abc123...", "name": "Acte de vente", "original_hash": "e3b0c442...", "watermarked_hash": "5feceb66..." }, "anchor": { "blockchain": "BITCOIN_SIGNET", "status": "VERIFIED_ON_CHAIN", "txid": "a1b2c3d4...", "tx_link": "https://mempool.4nkweb.com/signet/tx/a1b2c3d4...", "block_height": 123456, "confirmations": 6 }, "tezos_fallback": { "legacy": true, "blockchain": "TEZOS", "txid": "old_tezos_tx..." } } ``` #### BitcoinSignetService **Fichier** : `lecoffre-back-main/src/services/common/BitcoinSignetService/BitcoinSignetService.ts` **Responsabilités** : - Ancrage hash sur Bitcoin Signet - Vérification statut transaction - Récupération métadonnées blockchain **Méthodes principales** : ```typescript async anchorHash(hash: string): Promise<{ txid: string; tx_hash: string; tx_link: string; }> async verifyAnchor(txId: string): Promise<{ confirmed: boolean; confirmations: number; block_height: number; }> ``` ### Base de Données #### Schéma Prisma **Table `files`** : ```prisma model Files { uid String @id @unique @default(uuid()) file_name String s3_key String? // V3 : Version filigranée watermarked_s3_key String? watermarked_at DateTime? original_hash String? // Hash fichier original document_uid String? document Documents? @relation(...) } ``` **Table `document_anchors`** : ```prisma model DocumentAnchors { uid String @id @unique @default(uuid()) document_uid String @unique // Hash de la version FILIGRANNÉE (V3) file_hash String blockchain EBlockchainName @default(BITCOIN_SIGNET) status EAnchoringStatus @default(QUEUED) // Données blockchain tx_id String? // ⚠️ CRITIQUE : Seul indicateur fiable tx_link String? tx_hash String? block_height Int? block_time DateTime? confirmations Int? // V3 : Données de preuve (JSON) proof_data Json? anchored_at DateTime? anchored_by_uid String? } ``` **Table `office_folder_anchors`** : ```prisma model OfficeFolderAnchors { uid String @id @unique @default(uuid()) // Hashs sources (Merkle tree) root_hash String // V3 : ZIP complet zip_hash String? zip_s3_key String? zip_size Float? blockchain EBlockchainName @default(BITCOIN_SIGNET) status EAnchoringStatus @default(QUEUED) // Données blockchain tx_id String? // ⚠️ CRITIQUE : Seul indicateur fiable tx_link String? tx_hash String? block_height Int? confirmations Int? // V3 : Données de preuve (JSON) proof_data Json? } ``` **Enums** : ```prisma enum EBlockchainName { TEZOS // ⚠️ Conservé pour fallback (lecture seule) BITCOIN_SIGNET } enum EAnchoringStatus { QUEUED // ⚠️ OBSOLÈTE : Non utilisé de manière fiable ATTEMPTING // ⚠️ OBSOLÈTE : Non utilisé de manière fiable VERIFIED_ON_CHAIN // ⚠️ OBSOLÈTE : Le système se base uniquement sur tx_id FAILED ABANDONED } ``` **⚠️ IMPORTANT** : Le champ `status` n'est plus utilisé de manière fiable. Le système vérifie uniquement la présence de `tx_id` : - `tx_id` présent = Ancrage réussi - `tx_id` absent = Ancrage non effectué --- ## 3. Processus d'Ancrage ### Séquence de Traitement (Upload) Pour **tous les documents** (Client, Tiers, Notaire invité, Notaire), la séquence est : 1. **Calcul hash original** (fichier original) 2. **Filigrane** (sur fichier original non chiffré) 3. **Calcul hash filigrané et ancrage blockchain** (hash filigrané, génération txid) 4. **Chiffrement** du document filigrané 5. **Upload IPFS** du document chiffré 6. **Stockage métadonnées** fichier (hash original + hash filigrané) 7. **Stockage certificat BDD** (document_anchor avec hash filigrané + hash original + txid) ### Ancrage Automatique lors de la Validation **Déclenchement** : Lors de la validation d'un document via `PUT /api/v1/notary/documents/:uid` **Fichier** : `lecoffre-back-main/src/app/api/notary/DocumentsController.ts` **Workflow** : ```typescript if (documentEntityUpdated.document_status === EDocumentStatus.VALIDATED && firstFileUid) { // Ancrage automatique (asynchrone, non bloquant) if (userUid) { void this.documentAnchorsService .anchorDocument(documentEntityUpdated.uid, userUid) .then((anchor) => { SafeLogger.info(`✅ Document ${documentEntityUpdated.uid} automatically anchored`); }) .catch((error) => { SafeLogger.error(`❌ Auto-anchoring failed: ${error}`); }); } } ``` **Points importants** : - ✅ L'ancrage est **asynchrone** (non bloquant) - ✅ L'ancrage est lancé en **arrière-plan** - ✅ Si l'ancrage échoue, le document reste validé ### Ancrage Document **Workflow détaillé** : 1. **Récupération document + fichier** 2. **Vérification ancrage Tezos existant** (fallback) 3. **Génération version filigranée** si absente 4. **Téléchargement version filigranée** et calcul hash 5. **Vérification ancrage Signet existant** 6. **Création ancrage `QUEUED`** 7. **Ancrage blockchain** via `BitcoinSignetService.anchorHash()` 8. **Génération `proof_data`** (incluant fallback Tezos) 9. **Mise à jour ancrage** avec `tx_id`, `tx_link`, `proof_data` ### Ancrage Dossier **Workflow détaillé** : 1. **Récupération tous documents validés** du dossier 2. **Génération filigranes manquants** pour tous documents 3. **Génération ZIP complet** du dossier : - Originaux (01_originaux/) - Filigranés (02_filigranes/) - Certificats (03_certificats/) - Preuves JSON (04_preuves/) 4. **Upload ZIP vers S3** 5. **Ancrage hash ZIP complet** sur blockchain 6. **Génération preuve dossier** 7. **Création/Mise à jour ancrage dossier** **Condition** : Le dossier doit être à **100% de complétion** (tous documents validés) --- ## 4. Certificats et ZIP ### Génération Automatique de Certificats #### Téléchargement Individuel (Document Validé et Ancré) **Endpoints** : - Notaire : `GET /api/v1/notary/files/download/:uid` - Client : `GET /api/v1/customer/files/download/:uid` **Comportement automatique** : Pour les documents validés (`VALIDATED`) et ancrés avec statut `VERIFIED_ON_CHAIN`, le téléchargement génère **automatiquement** un ZIP contenant : 1. **PDF filigrané** : Document avec filigrane appliqué (suffixe `_aplc.pdf`) 2. **Certificat d'ancrage** : Certificat PDF Bitcoin Signet (préfixe `certificat_`) **Exemple de ZIP** : ```text document_001_CNI_DUPONT_Jean_avec_certificat.zip ├── 001_CNI_DUPONT_Jean_aplc.pdf (PDF filigrané) └── certificat_001_CNI_DUPONT_Jean.pdf (Certificat d'ancrage) ``` #### Téléchargement Multiple (ZIP de Fichiers) **Service** : `ZipService.createZipFromFiles()` **Workflow de recherche d'ancrage** : 1. **PRIORITÉ** : Recherche par `document_uid` (plus fiable) 2. **FALLBACK** : Si pas trouvé, recherche par hash du fichier 3. **Vérification statut** : Le certificat n'est généré que si `status === VERIFIED_ON_CHAIN` #### Téléchargement Dossier Complet **Service** : `OfficeFolderAnchorsService.generateFolderZip()` **Structure ZIP** : ```text dossier_12345678_Acte_de_vente/ ├── _LISEZ-MOI.txt (Instructions vérification) ├── 01_originaux/ │ ├── acte_vente.pdf (Version originale) │ └── compromis_vente.pdf ├── 02_filigranes/ │ ├── acte_vente.pdf (⚠️ VERSION ANCRÉE avec filigrane) │ └── compromis_vente.pdf ├── 03_certificats/ │ ├── certificat_acte_vente.pdf (PDF certif blockchain) │ └── certificat_compromis_vente.pdf └── 04_preuves/ ├── preuve_acte_vente.json (JSON avec hashs + TX) └── preuve_compromis_vente.json ``` ### Contenu des Certificats PDF **Informations affichées** : 1. **Hashs complets** : - Empreinte SHA-256 (original) : Hash complet du document initial (64 caractères hex) - Empreinte SHA-256 (filigrané) : Hash complet du document avec filigrane (64 caractères hex) - Source : `proof_data.document.original_hash` et `proof_data.document.watermarked_hash` 2. **Lien de transaction** : - Format : `https://mempool.4nkweb.com/fr/tx/` - Construit automatiquement à partir de `anchor.tx_id` si disponible - Fallback sur `anchor.tx_link` si `tx_id` absent 3. **Autres informations** : - Identifiant unique du document - Informations du dossier (numéro, nom) - Informations de l'office notarial - Type de document - Déposant - Validateur (UID) - Nom de fichier normé - Blockchain utilisée (Bitcoin Signet Notaires) - Statut d'ancrage - ID de transaction - Hauteur de bloc (si disponible) - Date d'ancrage ### Filigrane Visuel **Spécifications** : - **Texte** : "lecoffre.io" - **Position** : Diagonal (45°), centré sur chaque page - **Opacité** : 15% (visible mais non gênant) - **Couleur** : Gris clair (#CCCCCC) - **Police** : Arial, 48pt - **Pages** : Toutes les pages du PDF --- ## 5. Vérification et Statuts ### Logique de Vérification **⚠️ IMPORTANT** : Le système d'ancrage V3 ne fonctionne plus avec des statuts intermédiaires. L'ancrage est maintenant **immédiat** : - ✅ **Ancré** : L'ancrage a un `tx_id` (transaction ID Bitcoin) - ❌ **Non ancré** : L'ancrage n'a pas de `tx_id` **Il n'y a plus d'étape intermédiaire** comme `ATTEMPTING`, `QUEUED`, ou `VERIFYING_ON_CHAIN`. ### Backend Le backend vérifie uniquement la présence de `tx_id` : ```typescript if (anchorStatus.tx_id) { setAnchorStatus(AnchorStatus.VERIFIED_ON_CHAIN); } else { setAnchorStatus(AnchorStatus.NOT_ANCHORED); } ``` ### Frontend Le frontend utilise l'enum `AnchorStatus` mais ne vérifie que `tx_id` : ```typescript export enum AnchorStatus { "VERIFIED_ON_CHAIN" = "VERIFIED_ON_CHAIN", "NOT_ANCHORED" = "NOT_ANCHORED", } // Vérification if (anchorStatus.tx_id) { setAnchorStatus(AnchorStatus.VERIFIED_ON_CHAIN); } else { setAnchorStatus(AnchorStatus.NOT_ANCHORED); } ``` ### Masquage du Statut "Ancrage en cours" **Objectif** : Améliorer l'expérience utilisateur en ne montrant pas le statut transitoire "Ancrage en cours" pour les documents validés. **Comportement** : Pour les documents avec `document_status === VALIDATED`, le statut "Ancrage en cours" (`ATTEMPTING`) n'est **pas affiché** dans l'interface utilisateur. **Composant `AnchorBadge`** : ```typescript if (documentStatus === "VALIDATED" && status === "ATTEMPTING") { return null; // Badge not displayed } ``` ### Vérification Publique **Endpoints** : - `GET /api/v1/public/verify/:hash` : Vérification par hash (SANS authentification) - `POST /api/v1/public/verify-file` : Vérification par upload fichier (SANS authentification) **Page frontend** : `/verify-document` **Fonctionnalités** : - Upload fichier (drag & drop ou sélection) - Calcul hash automatique (SHA256) - Appel API public (aucune authentification requise) - Affichage résultat (success/error) - Lien explorateur blockchain ### Procédure de Vérification **Pour utilisateur final** : 1. Télécharger ZIP complet du dossier 2. Extraire le ZIP 3. Ouvrir fichier dans `04_preuves/preuve_XXX.json` 4. Noter le `watermarked_hash` 5. Calculer hash du fichier dans `02_filigranes/` : ```bash shasum -a 256 02_filigranes/acte_vente.pdf ``` 6. Comparer les deux hashs (doivent être identiques) 7. Vérifier TX : Ouvrir `tx_link` du JSON dans navigateur 8. ✅ **Validé** si hash OK + TX confirmée sur blockchain **Pour audit technique** : 1. Parser JSON de preuve 2. Extraire `watermarked_hash`, `txid`, `block_height` 3. Requête API blockchain (Mempool Space) : ```bash curl https://mempool.4nkweb.com/signet/api/tx/{txid} ``` 4. Vérifier : - TX existe - Hash dans OP_RETURN correspond - Block confirmé 5. Recalculer hash fichier filigrané 6. Comparer avec `watermarked_hash` 7. ✅ **Preuve authentique** si tout correspond --- ## 6. Scripts et Maintenance ### Scripts Disponibles #### Audit des Ancrages Manquants **Script** : `audit-missing-anchors.js` **Usage** : ```bash ENV=prod npm run anchorage:audit ``` **Description** : - Analyse tous les documents validés sans ancrage - Analyse tous les dossiers archivés sans ancrage - Génère un CSV avec la liste des documents/dossiers à réancrer - Ne modifie aucune donnée (lecture seule) **Résultat** : - Affichage console avec statistiques - CSV généré : `logs/audit-missing-anchors_YYYYMMDD_HHMMSS.csv` #### Ancrage V3 de Dossiers Existants **Script** : `anchor-existing-folders-v3.js` **Usage** : ```bash # Ancrage tous dossiers LIVE + ARCHIVED (par défaut) ENV=prod npm run anchorage # Dry-run (simulation) ENV=prod npm run anchorage -- --all --batch=1 --dry-run # Ancrage réel avec limite batch ENV=prod npm run anchorage -- --all --batch=5 # Ancrage de dossiers spécifiques ENV=prod npm run anchorage -- --folder-uids=uid1,uid2,uid3 ``` **Options** : - `--all-archived` : Tous les dossiers ARCHIVED sans ancrage - `--all-validated` : Tous les dossiers VALIDATED sans ancrage - `--all` : Tous les dossiers VALIDATED + ARCHIVED - `--folder-uids=uid1,uid2,...` : Liste UIDs dossiers spécifiques - `--batch=N` : Nombre max de dossiers par batch (défaut: 10) - `--dry-run` : Simulation sans ancrage réel - `--skip-documents` : Ancrer seulement dossiers (pas documents individuels) #### Vérifications Systématisées des Colonnes d'Ancrage Depuis 2025-01-XX, les scripts de déploiement vérifient systématiquement la présence des colonnes indispensables pour l'ancrage avant d'exécuter le réancrage. **Colonnes vérifiées** : - `document_anchors.proof_data` (JSONB) - Données de preuve structurées - `document_anchors.confirmations` (INTEGER) - Nombre de confirmations blockchain - `document_anchors.anchor_job_id` (VARCHAR) - ID du job d'ancrage - `document_notary_anchors.proof_data` (JSONB) - Données de preuve structurées - `document_notary_anchors.confirmations` (INTEGER) - Nombre de confirmations blockchain **Garanties** : - ✅ Vérification de l'existence des tables avant toute modification - ✅ Ajout automatique des colonnes manquantes (8 points de vérification) - ✅ Blocage du réancrage si colonnes manquantes détectées - ✅ Messages d'erreur explicites indiquant les colonnes manquantes **Ordre d'exécution garanti** : ```text resetDatabase → migrateResolveDatabase → reanchorAll ↓ ↓ ↓ Base vide Colonnes ajoutées Vérification finale ↓ ↓ Si manquantes → Blocage si manquantes ``` 📖 Voir [README.md](./README.md#consolidation-operationnelle-ex-operationsmd) et [DEPLOYMENT.md](./DEPLOYMENT.md) pour les corrections sur les colonnes d'ancrage. #### Réancrage de Documents/Dossiers **Script** : `reanchor-documents.js` **Usage** : ```bash # Dry-run (simulation) ENV=prod npm run anchorage:reanchor -- --dry-run # Réancrage réel ENV=prod npm run anchorage:reanchor -- --document-uids=uid1,uid2 ``` **Options** : - `--document-uids=uid1,uid2,...` : Liste UIDs documents spécifiques - `--folder-uids=uid1,uid2,...` : Liste UIDs dossiers spécifiques - `--all-missing` : Réancrer TOUS les documents/dossiers sans ancrage (⚠️) - `--batch=N` : Nombre max de documents/dossiers par batch (défaut: 50) - `--dry-run` : Simulation sans ancrage réel #### Nettoyage Ancres Dossiers Incomplets **Script** : `clean-incomplete-folder-anchors.ts` **Contexte** : - Certains dossiers peuvent avoir été ancrés alors qu'ils n'étaient pas à 100% - Seuls les dossiers complets (100% documents validés) doivent être ancrés **Usage** : ```bash # Depuis le conteneur backend cd lecoffre-back-main npx ts-node src/scripts/clean-incomplete-folder-anchors.ts --dry-run npx ts-node src/scripts/clean-incomplete-folder-anchors.ts ``` **Actions** : - Identifie les dossiers ancrés avec complétion < 100% - Supprime les ancres correspondantes dans `office_folder_anchors` - Réinitialise les liens `folder_anchor_uid = NULL` dans `office_folders` ### ⚠️ IMPORTANT : Prérequis 1. **Colonnes V3** : La base doit avoir toutes les colonnes V3 (`watermarked_s3_key`, `watermarked_at`, `zip_hash`, `zip_s3_key`, `zip_size`, `proof_data`) 2. **Prisma Client** : Le client Prisma doit être généré avec le bon schéma 3. **Connexion BDD** : Les scripts utilisent `DATABASE_URL` (configurée sur le serveur ou via `.env.`) ### Workflow Recommandé 1. **Audit initial** : ```bash ENV=prod npm run anchorage:audit ``` 2. **Test avec dry-run** : ```bash ENV=prod npm run anchorage -- --all-archived --batch=1 --dry-run ``` 3. **Ancrage réel** : ```bash ENV=prod npm run anchorage -- --all-archived --batch=5 ``` --- ## 7. Troubleshooting ### Certificats Manquants dans le ZIP **Symptôme** : Lors de la validation d'un document, le document apparaît comme validé, mais le certificat d'ancrage n'est pas présent dans le ZIP téléchargé. **Root Cause** : 1. Recherche par hash uniquement (peut échouer) 2. Pas de vérification du statut avant génération **Solution** : 1. Recherche prioritaire par `document_uid` (plus fiable) 2. Fallback par hash si nécessaire 3. Vérification du statut (`status === VERIFIED_ON_CHAIN`) avant génération ### Timing et Synchronisation **Scénario typique** : 1. **T0** : Document validé → Ancrage lancé en arrière-plan 2. **T0+2s** : Ancrage créé avec `status = ATTEMPTING` 3. **T0+5s** : Transaction Bitcoin confirmée → `status = VERIFIED_ON_CHAIN` (après 6 confirmations) 4. **T0+10s** : Utilisateur télécharge le ZIP → Certificat inclus ✅ **Cas limite** : Si l'utilisateur télécharge le ZIP **immédiatement après validation** (avant que l'ancrage soit vérifié) : - ⚠️ L'ancrage peut être en statut `ATTEMPTING` ou `QUEUED` - ⚠️ Le certificat **ne sera pas inclus** dans le ZIP - ✅ L'utilisateur peut **relancer le téléchargement** plus tard pour obtenir le certificat ### Fichiers Sans Clé de Chiffrement (.expired) **Contexte** : Les dumps de base de données provenant de versions antérieures peuvent contenir des fichiers avec `key = null` (clé de chiffrement perdue). **Solution implémentée** : - `FilesService.download()` : Retourne fichier vide `.expired` si `key = null` - `WatermarkService.addWatermarkAndUpload()` : Upload fichier vide `.expired` sur IPFS - `DocumentAnchorsService.anchorDocument()` : Ancrage avec hash du buffer vide **Résultat** : - ✅ Scripts d'ancrage ne crashent plus sur fichiers sans clé - ✅ Fichiers `.expired` créés automatiquement - ✅ Ancrage blockchain avec hash du buffer vide - ⚠️ Utilisateur informé que fichier non récupérable ### Checklist de Vérification Pour diagnostiquer un problème de certificat manquant dans un ZIP : - [ ] Vérifier que le document est **validé** (`document_status === VALIDATED`) - [ ] Vérifier qu'un ancrage existe pour ce document (`document_anchors` table) - [ ] Vérifier le **statut de l'ancrage** (`status === VERIFIED_ON_CHAIN`) - [ ] Vérifier les **logs backend** pour voir si l'ancrage a été trouvé - [ ] Vérifier que `includeAnchors = true` lors de l'appel à `createZipFromFiles` - [ ] Vérifier que le fichier n'est pas un `isNotaryFiles` (pas d'ancrage pour les fichiers notaire) --- ## 8. Références ### Documentation Détaillée - **Architecture V3** : `docs/ANCRAGE_V3_ARCHITECTURE.md` - Architecture complète V3 - **Certificats et ZIP** : `docs/ANCRAGE_CERTIFICATS_ZIP.md` - Génération certificats et ZIP - **Scripts** : `docs/SCRIPTS.md` - Scripts d'audit et d'ancrage - **Statuts** : `docs/ANCHOR_STATUS_VERIFICATION.md` - Vérification des statuts d'ancrage - **Séquences de traitement** : `docs/DOCUMENT_PROCESSING_SEQUENCES_V2.md` - Séquence complète upload/ancrage ### Services Backend - **WatermarkService** : `lecoffre-back-main/src/services/common/WatermarkService/WatermarkService.ts` - **DocumentAnchorsService** : `lecoffre-back-main/src/services/notary/DocumentAnchorsService/DocumentAnchorsService.ts` - **OfficeFolderAnchorsService** : `lecoffre-back-main/src/services/notary/OfficeFolderAnchorsService/OfficeFolderAnchorsService.ts` - **ProofDataService** : `lecoffre-back-main/src/services/notary/ProofDataService/ProofDataService.ts` - **BitcoinSignetService** : `lecoffre-back-main/src/services/common/BitcoinSignetService/BitcoinSignetService.ts` - **AnchorCertificateService** : `lecoffre-back-main/src/services/notary/AnchorCertificateService/AnchorCertificateService.ts` - **ZipService** : `lecoffre-back-main/src/services/common/ZipService/ZipService.ts` ### Controllers - **DocumentsController** : `lecoffre-back-main/src/app/api/notary/DocumentsController.ts` - **FilesController (Notary)** : `lecoffre-back-main/src/app/api/notary/FilesController.ts` - **FilesController (Customer)** : `lecoffre-back-main/src/app/api/customer/FilesController.ts` - **PublicAnchorVerificationController** : `lecoffre-back-main/src/app/api/public/PublicAnchorVerificationController.ts` ### Scripts - **Audit** : `lecoffre-back-main/src/scripts/audit-missing-anchors.ts` - **Ancrage dossiers** : `lecoffre-back-main/src/scripts/anchor-existing-folders-v3.ts` - **Réancrage** : `lecoffre-back-main/src/scripts/reanchor-documents.ts` - **Nettoyage** : `lecoffre-back-main/src/scripts/clean-incomplete-folder-anchors.ts` ### Frontend - **Page vérification** : `lecoffre-front-main/src/pages/verify-document.tsx` - **Composant AnchorBadge** : `lecoffre-front-main/src/front/Components/DesignSystem/AnchorBadge/` --- **Dernière mise à jour** : 2025-11-24 **Version** : 3.1.2