Nicolas Cantu 61cec6f430 Sync ia_dev: token resolution via .secrets/<env>/ia_token, doc updates
**Motivations:**
- Align master with current codebase (token from projects/<id>/.secrets/<env>/ia_token)
- Id resolution by mail To or by API token; no slug

**Root causes:**
- Token moved from conf.json to .secrets/<env>/ia_token; env from directory name

**Correctifs:**
- Server and scripts resolve project+env by scanning all projects and envs

**Evolutions:**
- tickets-fetch-inbox routes by To address; notary-ai agents and API doc updated

**Pages affectées:**
- ai_working_help/server.js, docs, project_config.py, lib/project_config.sh
- projects/README.md, lecoffreio/docs/API.md, gitea-issues/tickets-fetch-inbox.py
2026-03-16 15:00:23 +01:00

82 KiB
Raw Blame History

Documentation Frontend - LeCoffre.io

Dernière mise à jour : 2026-02-25

Ce document regroupe toute la documentation frontend : routes, pages, UI/UX, et gestion des collaborateurs.


📋 Table des Matières

  1. Routes et Navigation
  2. Pages et Composants
  3. Corrections UI/UX
  4. Agrégation des Collaborateurs
  5. Build et Tests
  6. Authentification IdNot et Logging
  7. Interface Espace Notaire - Onglets et Tableaux
  8. Consolidation évolutions et correctifs

1. Routes et Navigation

Routes de Dossiers

Routes Actives

  • /folders - Liste des dossiers actifs
  • /folders/[folderUid] - Détail d'un dossier actif
  • /folders/[folderUid]/add/clients - Ajouter un client
  • /folders/[folderUid]/add/third-party - Ajouter un tiers
  • /folders/[folderUid]/edit/informations - Modifier les informations
  • /folders/[folderUid]/edit/clients/[customerUid] - Modifier un client
  • /folders/[folderUid]/edit/collaborators - Modifier les collaborateurs
  • /folders/[folderUid]/documents-reminder-history - Historique des rappels
  • /folders/[folderUid]/send-documents - Envoyer des documents
  • /folders/[folderUid]/documents/[documentUid] - Détail d'un document

Routes Archivées

  • /folders/archived - Liste des dossiers archivés
  • /folders/archived/[folderUid] - Détail d'un dossier archivé

Routes Supprimées

  • /folders/deleted - Liste des dossiers supprimés (soft delete)

Détection des Pages de Détail

Le composant FolderInformation détecte automatiquement le type de route via la prop isArchived.

Regex de détection :

/\/folders\/(archived\/)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i

Format accepté :

  • /folders/[uuid] - Dossier actif
  • /folders/archived/[uuid] - Dossier archivé

Format rejeté :

  • /folders - Liste des dossiers
  • /folders/archived - Liste des dossiers archivés

Fichiers concernés :

  • lecoffre-front-main/src/front/Components/Layouts/Folder/FolderInformation/index.tsx
  • lecoffre-front-main/src/pages/folders/[folderUid]/index.tsx
  • lecoffre-front-main/src/pages/folders/archived/[folderUid]/index.tsx

2. Pages et Composants

Pages Identifiées pour Migration Collaborateurs

UpdateFolderCollaborators ⚠️ PRIORITÉ HAUTE

Fichier : lecoffre-front-main/src/front/Components/Layouts/Folder/UpdateFolderCollaborators/index.tsx

Action requise : Utiliser l'endpoint /api/v1/notary/users/aggregated pour afficher tous les collaborateurs (avec et sans compte).

Page concernée : /folders/[folderUid]/collaborators

SubscriptionManageCollaborators ⚠️ PRIORITÉ HAUTE

Fichier : lecoffre-front-main/src/front/Components/Layouts/Subscription/Manage/SubscriptionManageCollaborators/index.tsx

Action requise : Utiliser l'endpoint agrégé et filtrer pour ne garder que ceux avec compte (car seuls les utilisateurs avec compte peuvent avoir un siège).

Page concernée : /subscription/manage-collaborators

DefaultCollaboratorDashboard ⚠️ PRIORITÉ MOYENNE

Fichier : lecoffre-front-main/src/front/Components/LayoutTemplates/DefaultCollaboratorDashboard/index.tsx

Action requise : Utiliser l'endpoint agrégé et filtrer pour ne garder que ceux avec compte, ou afficher deux sections : "Avec compte" et "À inviter".

Page concernée : /collaborators (dashboard)

CreateFolder

Fichier : lecoffre-front-main/src/front/Components/Layouts/Folder/CreateFolder/index.tsx

État : Depuis novembre 2025, le formulaire de création ne gère plus l'ajout de collaborateurs, de confrères ou de tiers. Les stakeholders initiaux se limitent automatiquement au créateur.


3. Corrections UI/UX

Boutons de Civilité Invisibles

Date : 2025-01-27 Composant : AddClientToFolder Page : /folders/[folderUid]/add/clients

Problème

Les 3 boutons de sélection de civilité (Monsieur, Madame, Autre) apparaissaient vides/invisibles dans le formulaire "Créer un nouveau client".

Root Cause

Le CSS de la classe .civility-option ne définissait pas de couleur de texte par défaut. Seule la classe .civility-option-active (bouton sélectionné) avait une couleur définie.

Solution

Ajout d'une couleur de texte par défaut (var(--color-neutral-700)) et d'un fond blanc pour garantir la visibilité du texte.

Fichiers modifiés :

  • lecoffre-front-main/src/front/Components/Layouts/Folder/AddClientToFolder/classes.module.scss

Migration Sass : @import vers @use

Date : 2025-01-30 Version : 2.0.1+

Objectif

Éliminer les warnings de dépréciation Sass concernant l'utilisation de @import qui seront supprimés dans Dart Sass 3.0.0. Migrer tous les fichiers SCSS vers le système moderne @use/@forward de Sass.

Modifications

Changement de syntaxe :

  • Avant : @import "@Themes/constants.scss";
  • Après : @use "@Themes/constants.scss" as *;

Fichiers migrés : 138 fichiers SCSS dans lecoffre-front-main/src/

Compatibilité : L'utilisation de as * permet de conserver l'accès global aux variables Sass ($screen-m, $screen-s, $color-*) et aux variables CSS (var(--...)).

Documentation complète : Voir conventions Sass du projet (ARCHITECTURE, OPTIMIZATION_AXES).

Bouton supprimer, parties rattachées, page add/clients (2026-01-28)

Pages : /folders/[folderUid]/add/clients, fiche dossier.

Problèmes : (1) Clic sur supprimer (X) à côté d'un client ne retire pas l'item ; (2) après validation, aucune partie sur la fiche dossier ; (3) après création dossier, add/clients reste sur « Dossier chargé mais données invalides » (GET folder sans uid).

Root causes : Clés React en index (GenericExistingItemsList) → réutilisation de nœuds ; preventDefault/stopPropagation sur IconButton ; options avec id vide exclus du payload ; instanceToPlain omet uid sur GET /notary/folders/:uid.

Correctifs : getExistingItemKey / getPendingItemKey stables (ex. id, email) ; onClick sans preventDefault/stopPropagation ; filtrage des clients uid non vide et collecte UIDs stricte dans finalizePayloadHelpers ; OfficeFoldersGetOneByUidHydrationHelper : forcer plainFolder.uid = folderUid après instanceToPlain. Textes retirés : « Rien n'est envoyé… », « Associez un ou plusieurs clients… ».

Fichiers : AddClientToFolder (sections, GenericExistingItemsList, CustomersList), useCustomersManager, finalizePayloadHelpers, OfficeFoldersGetOneByUidHydrationHelper.

Invitation confrères validation avant envoi email (2026-03-12)

Composant : AddClientToFolder (onglet « Confrères ») Page : /folders/[folderUid]/add/clients

Problème : Lors de lajout dun confrère par email, le partage et lemail dinvitation étaient créés immédiatement au clic sur « Ajouter ». Si lutilisateur cliquait ensuite « Annuler », le confrère restait invité et avait déjà reçu lemail.

Root cause : Le flux confrères appelait shareFolder directement au clic « Ajouter », contrairement aux clients et tiers qui sont mis en attente puis persistés uniquement au clic « Valider ».

Correctifs : Alignement sur le flux clients/tiers. Les confrères ajoutés sont stockés dans pendingConfrereShares ; lAPI shareFolder et lenvoi demail sont exécutés dans addPendingConfrereShares lors du finalizeChanges. Les confrères en attente sont affichés avec « Sera invité lors de la validation » et peuvent être retirés via removePendingConfrere.

Fichiers : useConfreresManager, finalizeOperationsHelpers, useFinalizeHandler, ExistingConfreresList, ConfreresSection, SearchConfrereSection, StakeholdersContent, types.

Personne en charge du dossier ContactBox et écran collaborateurs (2026-03-12)

Composant : ClientDashboard/ContactBox, page « Modifier les collaborateurs » Pages : Espace client/tiers (contact de loffice), /folders/[folderUid]/edit/collaborators

Problème : Dans lespace client/tiers, les contacts de loffice affichés (email, téléphone) ne correspondaient pas à la personne en charge du dossier : le composant choisissait le contact de façon arbitraire parmi les stakeholders (priorité au rôle « Notaire », sinon premier de la liste). Aucune notion de « personne en charge » ou « interlocuteur principal » nexistait dans le modèle.

Root cause : Pas de champ dédié dans le modèle de données ; ContactBox utilisait uniquement stakeholders (ordre non garanti).

Évolution : Ajout de main_contact_uid sur le dossier (optionnel, FK vers users). La personne en charge est obligatoirement parmi les collaborateurs du dossier (stakeholders). Par défaut = créateur du dossier. Elle est choisie/modifiée dans lécran « Modifier les collaborateurs » via un champ « Personne en charge » (liste = collaborateurs effectifs : tout loffice ou sélection). ContactBox affiche désormais : main_contact puis created_by puis notaire puis premier stakeholder.

Fichiers : Prisma office_folders.main_contact_uid + relation main_contact ; ressources Notary OfficeFolder ; backend DTO, FolderHandler (validation), OfficeFoldersUpdateBuilder, OfficeFoldersRepository (create/update), OfficeFoldersGetOneByUidHydrationHelper ; frontend folderQueryBuilders, useFolderAndCustomer, ClientDashboard/ContactBox, UpdateFolderCollaborators (loader, controller, vue avec SelectField), commonUiI18nPart1 (mainContactLabel). Migration : 20260312120000_add_main_contact_uid_to_office_folders.

Autocomplétion Confrères clic suggestion non sélectionné (2026-02-22)

Composant : AddClientToFolder (onglet « Confrères ») Page : /folders/[folderUid]/add/clients

Problème : Dans « Notaire (recherche annuaire) », cliquer une suggestion ferme la liste sans sélectionner le notaire.

Root cause : La fermeture des suggestions était pilotée par onBlur sur le wrapper : le blur se déclenchait aussi lors dun passage de focus interne (champ → suggestion), et la fermeture temporisée rendait lévénement de sélection non fiable (clic) et cassait le parcours clavier.

Correctifs : SearchConfrereSection ferme les suggestions uniquement lorsque le focus sort réellement du wrapper (relatedTarget non contenu), et ferme aussi laffichage des résultats côté hook via setShowSuggestionsFromSearch(false).

Fichiers :

  • lecoffre-front-main/src/front/Components/Layouts/Folder/AddClientToFolder/sections/ConfreresSection/SearchConfrereSection.tsx
  • Correctif autocomplétion Confrères : voir README.md (clic suggestion non sélectionné).

Création dossier membres rattachés n'apparaissent pas (2026-01-28)

Problème : Après création d'un dossier avec collaborateurs, la section « Gestionnaire du projet » est vide sur add/clients et fiche dossier.

Root cause : Les requêtes GET folder ne demandaient ni stakeholders ni created_by.

Correctifs : Dans buildFolderQueryParams (FolderInformation / useFolderDataFetch) et dans le loader add/clients (useFolderDataInitialization), ajouter created_by et stakeholders avec includes contact, office_role, seats / subscription / office.

Création dossier reste sur « Chargement du dossier… » (2026-01-28)

Problème : Après création et redirection vers /folders/:uid/add/clients, la page reste bloquée sur chargement.

Causes : (1) GET dossier sans timeout ; (2) folderUid absent au premier rendu (router.query pas encore à jour après router.push).

Correctifs : Timeout 30 s sur le chargement (Promise.race) ; si timeout → toast, redirection /folders. Fallback folderUid : extraction par regex sur router.asPath (/\/folders\/([^/]+)\/add\/clients/) quand query["folderUid"] vide. Nettoyage des logs debug.

Fichiers : useFolderDataInitialization, useManageFolderStakeholdersController, createFolderSubmitHelpers.

Dossier membres absents sur la page détail (2026-01-28)

Problème : Dossier créé avec client/tiers/notaire invité, mais page détail affiche « Ajouter des clients » (NoClientView) au lieu des onglets participants.

Root cause : instanceToPlain peut omettre customers et folder_sharings ; doesFolderHaveClient reste faux.

Correctifs : Dans OfficeFoldersGetOneByUidHydrationHelper, après instanceToPlain, forcer customers et folder_sharings dans le plain lorsqu'ils sont présents sur l'entité brute mais absents ou vides dans le plain (même logique que uid).

Correctif frontend (2026-03-09) : voir docs/fixKnowledge/2026-03-09-folder-detail-participants-hidden-without-customers.md.

Création dossier validation failure (2026-01-27 / 2026-01-28)

Problème : « Dossier chargé mais données invalides », uid manquant en POST ou GET.

Root causes : POST retournait une instance de classe au lieu d'un plain ; instanceToPlain pouvait omettre uid. GET idem.

Correctifs backend : OfficeFoldersCreationHelper : instanceToPlain puis toujours plainFolder.uid = officeFolderEntity.uid. OfficeFoldersGetOneByUidHydrationHelper : forcer uid (et customers / folder_sharings / notes / folder_number si omis). Stripe 404 : StripeController + StripeService.isStripeNotFoundError() pour ne pas traiter 404 comme erreur utilisateur.

Correctifs frontend : Logs debug dans useFolderDataInitialization et createFolderSubmitHelpers ; délai 2000 ms avant redirection. Vérifier en déploiement que le correctif plainFolder.uid = officeFolderEntity.uid est bien présent dans le build.

Notes membres (notaires / collaborateurs) non affichées dans les onglets (2026-01-29)

Problème : Les notes n'apparaissent pas dans les onglets clients / notaires invités / tiers, mais sont visibles dans le formulaire de modification.

Root cause : instanceToPlain peut omettre le tableau notes ; seul le forçage de customers et folder_sharings existait.

Correctifs : Dans OfficeFoldersGetOneByUidHydrationHelper, forcer plainFolder.notes = rawNotes lorsque l'entité brute a des notes mais le plain les omet. Étendre FilteredEntityForPostProcess avec notes. Log « notes forcés (instanceToPlain les avait omis) ».

Supprimer un dossier modale ne s'affiche pas / champ confirmation (2026-01-28)

Problème : Clic « Supprimer le dossier » (menu ⋮) : modale semble ne pas s'ouvrir ou menu se ré-affiche par-dessus. Champ de confirmation : label « Confirmation » alors qu'il faut saisir le numéro de dossier → bouton grisé. Si folder_number absent, rien en gras.

Root causes : (1) Clic sur l'item déclenche onClose puis onClick ; l'événement remonte au root du Menu → toggle ré-ouvre le menu. (2) Items sans link avaient key={undefined} → clés dupliquées. (3) Label et expectedValue du champ de confirmation peu clairs. (4) folder_number parfois omis par instanceToPlain.

Correctifs : MenuItem : après onClose / onClick / navigation, appeler e.stopPropagation() si le clic est traité. Menu : clé stable item.link ?? \${item.text}-${index}`. DeleteModal : label « Numéro du dossier (répétez cidessus) », expectedValue= numéro,errorMessageexplicite ; si numéro vide, pas derequireConfirmation. ConfirmModal : si expectedValuevide, afficher « La valeur à saisir n'est pas disponible. Actualisez la page puis réessayez. » et garder le bouton désactivé. Backend : forcerfolder_numberdansOfficeFoldersGetOneByUidHydrationHelper` quand omis.

Fichiers : MenuItem, Menu, DeleteModal, ConfirmModal, OfficeFoldersGetOneByUidHydrationHelper.

Stripe 404 bannière abonnement (2026-01-29)

Problème : GET /api/v1/admin/stripe/:id en 404 (abonnement absent chez Stripe) → Toast « L'élément demandé n'existe pas », warn « Unable to load subscription banner » à chaque chargement.

Root cause : Aucune distinction 404 (ressource absente, cas acceptable) vs erreur technique ; onError systématique.

Correctifs : StripeFactory.getStripeSubscriptionByUid : en catch, si http_status === 404, ne pas appeler onError, puis rejeter. Header / useSubscriptionLoader : en catch, si 404, retourner sans logger.

Fichiers : StripeFactory, Header/index.tsx.

Demander les documents configuration du type de document non chargée

Page : « Demander des documents ».

Problème : Aucun type de document à sélectionner ; configuration deed / deed_type non chargée ou non exploitée.

Root causes : Backend : instanceToPlain peut omettre deed (et deed.document_types) ; aucun forçage de deed. Front : utilisation uniquement de deed.document_types, sans deed_type.document_types ni fallback lorsque toutes les sources sont vides.

Correctifs : Backend (OfficeFoldersGetOneByUidHydrationHelper) : forcer deed (et document_types) dans la réponse lorsquils sont présents sur lentité brute mais omis par instanceToPlain. Front (useAskDocumentsFolderData) : inclure deed_type avec document_types dans le q du fetch ; priorité deed_type.document_typesdeed.document_types → types déduits des documents existants ; si tout vide, fallback DocumentTypes.getInstance().get({}) ; log lorsque le fallback est utilisé.

Fichiers : OfficeFoldersGetOneByUidHydrationHelper, useAskDocumentsFolderData.


4. Agrégation des Collaborateurs

Vue d'Ensemble

La fonctionnalité d'agrégation des collaborateurs retourne les comptes utilisateurs existants d'un office (créés lors de la première connexion OAuth IdNot).

API Endpoint

GET /api/v1/notary/users/aggregated

Authentification : Requise (JWT) Permissions : authHandler, ruleHandler

Description : Retourne les collaborateurs de l'office disposant d'un compte utilisateur.

Réponse :

[
  {
    "uid": "uuid-user-1",
    "idNot": "123456",
    "contact": {
      "uid": "uuid-contact-1",
      "email": "notaire@example.com",
      "first_name": "Jean",
      "last_name": "Dupont",
      "phone": "+33123456789",
      "civility": "M."
    },
    "_metadata": {
      "source": "users",
      "has_user_account": true
    }
  }
]

11. Gestion des Documents

Visibilité et Affichage

Documents Déposés (DEPOSITED)

  • Pour le déposant (Client, Tiers, Notaire Invité) :
    • Le fichier n'est pas affiché (pas d'icône "œil", pas de téléchargement).
    • Seule la ligne avec la date de dépôt est visible.
    • Le module de dépôt n'est plus éditable pour empêcher la modification.
    • Accès direct URL : Message "En attente de validation..." sans contenu.
  • Pour le notaire en charge :
    • Accès complet (visualisation, validation, refus).

Dépôt côté déposant (Client / Tiers / Notaire invité)

  • La section Documents à envoyer utilise le même module d'ajout que Documents supplémentaires (facultatif) : ouverture via Ajouter un document, gestion de la sélection locale (ajout/retrait), puis envoi explicite via Déposer le document.
  • Le dépôt n'est plus déclenché au glisser-déposer : le glisser-déposer alimente uniquement la sélection locale dans la modale.
  • Après validation du dépôt, le rafraîchissement garde le comportement de ligne existant dans le tableau (mise à jour de statut/date selon le document).
  • Les libellés de dépôt sont centralisés par contexte (generic, modal, otherDocuments, rib) dans DesignSystem/helpers/fileUploadUiI18n.ts, et les CTA communs de modales (Annuler, Confirmer) sont centralisés dans DesignSystem/helpers/commonUiI18n.ts.
  • Les libellés d'actions métier de modales/layouts (Valider, Supprimer, Enregistrer, Créer, Ajouter, Continuer, Quitter) sont regroupés dans les namespaces dédiés de DesignSystem/helpers/commonUiI18n.ts et réutilisés dans les modales existantes.
  • Les libellés métier composés sont regroupés par domaine dans DesignSystem/helpers/commonUiI18n.ts (folder, subscription, member, role) pour éviter les chaînes actionnelles locales dans les vues et menus.
  • Les CTA et labels de tests SuperAdmin sont aussi centralisés dans commonUiI18n.ts via les namespaces health et adminTools, y compris les libellés de titres secondaires d'actions (boutons détails, liens utilitaires, titres de consultation).
  • Les textes descriptifs non actionnels sont centralisés dans les namespaces healthMessages, folderMessages, demoMessages, subscriptionMessages, userMessages, usersMessages et documentMessages de commonUiI18n.ts (cartes de test SuperAdmin, modales d'archive/suppression dossier, sections de démonstration du DesignSystem, écrans abonnement, écrans utilisateurs et viewer documentaire).
  • Les placeholders et libellés de formulaires métier longs sont centralisés dans formMessages (commonUiI18n.ts) pour les flux de préparation de dossier (tiers, confrères) et d'envoi documentaire.
  • Les messages dynamiques sont composés par des helpers dédiés dans DesignSystem/helpers/commonUiMessageBuilders.ts pour éviter la concaténation dans les composants (votes SuperAdmin, message de dépôt en attente dans le viewer).
  • Les écrans dossier hors scope upload initial (AddThirdParty, AskDocuments, Folder landing, sections NoClient, modales de suppression client/document) sont alignés sur folderMessages/formMessages et réutilisent les helpers de composition pour les messages conditionnels de permissions/chargement.
  • Les messages "chargement dossier / droits insuffisants" passent par un helper dédié à objet de configuration (buildFolderPermissionOrLoadingMessage) et les modales de suppression mutualisent leurs feedbacks succès/erreur via des helpers dédiés.
  • Les flux de suppression utilisent des payload helpers dédiés par domaine : buildDocumentDeleteModalPayload (documents), buildCustomerDeleteModalPayload (client de dossier), buildFolderDeleteModalPayload (suppression dossier soft/hard), buildThirdPartyDeleteModalPayload (tiers du dossier), buildRibDeleteModalPayload (RIB) et buildDeedTypeDeleteModalPayload (type d'acte), avec centralisation de title/message/confirmLabel et des messages d'erreur.
  • La confirmation de suppression avec saisie du numéro de dossier est factorisée via buildFolderDeleteRequireConfirmationPayload pour éviter la duplication label/placeholder/errorMessage dans les modales.
  • Les anciens alert() des flux de téléchargement documents/certificats et création de dossier (helpers FolderInformation/InvitedView/CreateFolder) sont migrés vers ToasterService avec messages centralisés dans commonUiI18n.ts et composition d'erreur agrégée via buildAggregatedCertificateErrorMessage.
  • Le flux de désarchivage dossier n'utilise plus confirm(): il passe désormais par une ConfirmModal dédiée pilotée via useFolderModals (unarchiveModal) et payload buildUnarchiveFolderConfirmPayload.
  • Les erreurs de téléchargement ZIP/certificat sont unifiées via le helper global showDownloadErrorToast (Utils/documentDownloadHelpers.ts) et réutilisées dans Folder et ClientDashboard.
  • Les flux SuperAdmin/SiteTexts (create/update/publish/archive/load) n'utilisent plus alert()/confirm() : feedback via ToasterService + modale de confirmation d'archivage.
  • Les toasts de succès de téléchargement sont aussi centralisés via showDownloadSuccessToast dans Utils/documentDownloadHelpers.ts et réutilisés par les flux Folder, ClientDashboard, singleFileDownloadHelper et DocumentDownloadService.
  • Les toasts de succès métier hors téléchargement (create/update/publish/archive) sont harmonisés via showBusinessSuccessToast (Utils/businessOperationToastHelpers.ts) avec payload centralisé (buildBusinessSuccessToastPayload).
  • Les erreurs métier hors téléchargement sont harmonisées via showBusinessErrorToast (Utils/businessOperationToastHelpers.ts) avec payload builders par domaine (collaboratorMessages, clientDashboardMessages, folderMessages) pour éviter les descriptions codées en dur.
  • Les warnings métier hors téléchargement sont harmonisés via showBusinessWarningToast (Utils/businessOperationToastHelpers.ts) avec payload builders de domaine (subscriptionMessages, folderMessages) pour homogénéiser les flux dinformation/validation.
  • Les flux Folder/AskDocuments, Folder/SendDocuments et Folder/AddClientToFolder utilisent désormais les mêmes helpers showBusinessErrorToast/showBusinessWarningToast et des builders dédiés commonUiMessageBuilders.ts pour supprimer les ToasterService.getInstance().warn/error métier locaux.
  • Les builders folderMessages sont regroupés par sous-domaines (parameterDocuments, askDocuments, sendDocuments, stakeholders) via DesignSystem/helpers/folderToastMessageBuilders.ts et exposés par commonUiMessageBuilders.ts.
  • Les builders non-folder sont aussi extraits par domaine pour limiter la croissance de commonUiMessageBuilders.ts :
    • DesignSystem/helpers/clientDashboardMessageBuilders.ts
    • DesignSystem/helpers/clientDashboardToastMessageBuilders.ts
    • DesignSystem/helpers/collaboratorToastMessageBuilders.ts
    • DesignSystem/helpers/createCustomerNoteToastMessageBuilders.ts
    • DesignSystem/helpers/siteTextsMessageBuilders.ts
    • DesignSystem/helpers/siteTextsToastMessageBuilders.ts
    • DesignSystem/helpers/subscriptionToastMessageBuilders.ts
    • DesignSystem/helpers/deedTypesToastMessageBuilders.ts
    • DesignSystem/helpers/folderInformationToastMessageBuilders.ts
    • DesignSystem/helpers/folderViewDocumentsToastMessageBuilders.ts
    • DesignSystem/helpers/toastPayloadBuilderHelpers.ts : helper générique partagé pour construire les payloads error/warning/success (évite la répétition dans chaque *ToastMessageBuilders).
    • DesignSystem/helpers/toastMessageBuilders/index.ts centralise le pattern de re-export des builders *ToastMessageBuilders.ts.
    • commonUiMessageBuilders.ts conserve un re-export de compatibilité.
  • Les écrans ClientDashboard/ViewDocumentSent, ClientDashboard/ViewDocumentsNotary et Folder/ViewDocuments nutilisent plus de ToasterService.getInstance().error inline pour les erreurs métier de chargement/validation.
  • Les layouts métier ciblés Folder, ClientDashboard et DeedTypes nutilisent plus de ToasterService.getInstance().warn/error direct : les flux sont alignés sur showBusinessErrorToast / showBusinessWarningToast avec payloads centralisés.
  • Les succès métier peuvent aussi être injectés via payload (title + description) dans showBusinessSuccessToast, ce qui permet daligner Folder/ViewDocuments et DeedTypes sans libellés inline dans les hooks.
  • Les flux subscription-plans n'utilisent plus alert()/confirm() : confirmations via ConfirmModal + payload helpers (buildSubscriptionPlanSetDefaultConfirmPayload, buildSubscriptionPlanDeleteConfirmPayload) et feedback centralisé.
  • Les derniers usages résiduels de alert()/confirm() côté front ont été retirés, y compris dans la section de démonstration ButtonIconMenuSection et le fallback technique ToasterHelper.

Documents Envoyés (SENT)

  • Tableau "Documents envoyés" : La colonne "Type de document" est renommée "Nom du document".
  • Notaire Invité :
    • Les documents de type "Document notaire" (envoyés par le notaire gestionnaire) sont exclus de la section "Documents à envoyer".
    • Ils apparaissent uniquement dans "Documents reçus".
    • L'encart de notification ("X documents reçus") est aligné avec le nombre réel de documents affichés (excluant les doublons techniques).

Visualisation (Viewer)

  • Sélection du fichier : En cas de multiples fichiers (ex: refus puis re-dépôt), le viewer affiche par défaut le plus récent (tri par created_at desc), et non le premier de la liste (souvent l'ancien refusé).
  • Batch : L'affichage d'un document issu d'un batch (ex: pièce d'identité) ne montre que les fichiers de ce document spécifique (docUid), sans fusionner avec les autres documents du même batch.

Téléchargement

Logique ZIP vs Fichier Unique

  • Alignement : La logique de téléchargement utilise le même dédoublonnage que l'affichage (getUniqueFiles dans fileHelpers.ts).
  • Comportement :
    • Si 1 seul fichier unique (après dédoublonnage par nom) : Téléchargement direct du fichier.
    • Si > 1 fichiers uniques : Téléchargement d'un ZIP.
    • Évite de créer un ZIP inutile pour un document qui n'a qu'une seule version pertinente visible.

Refactoring & Helpers

  • fileHelpers.ts : Centralise la logique de dédoublonnage (getUniqueFiles, getFileDisplayName) partagée entre l'affichage (tableColumnHelpers) et le téléchargement (documentDownloadHelpers).
  • documentFilterHelpers.ts : Centralise les statuts (DOCUMENTS_TO_SEND_STATUSES, etc.) pour garantir la cohérence entre les vues Client, Tiers et Invité.

5. Build et Tests

  • npm run build exécute désormais npm run typecheck puis node ./scripts/run-next-build.cjs. Ce script Node applique les variables d'environnement requises (TURBOPACK_ROOT, NEXT_TELEMETRY_DISABLED) avant d'invoquer next build via next/dist/bin/next. Cette approche garantit un comportement identique sous Windows (où les affectations VAR=value n'étaient pas interprétées par cmd.exe) et sous Linux/macOS.
  • Le fichier lecoffre-front-main/scripts/run-next-build.cjs est responsable du lancement de next build. Il doit être conservé à jour si des arguments supplémentaires sont nécessaires.

Convention de typage JSX (React 19)

  • Les composants fonctionnels utilisent React.JSX.Element (ou React.JSX.Element | null pour un rendu conditionnel).
  • Les composants de classe utilisent render(): React.ReactNode.
  • Les props de contenu (children, title, text, icon, footer, etc.) utilisent React.ReactNode.
  • Le shim global declare namespace JSX n'est plus utilisé dans custom.d.ts.
  • Les usages JSX.Element sont interdits dans le frontend pour éviter les incompatibilités de typage entre runtime JSX et React 19.

Stratégie couche API (useApiClient vs BaseApiService)

  • useApiClient (hook React) : cible pour tout appel API depuis un composant ou un hook. Gère le token, les erreurs et le base URL. Privilégier pour les nouveaux usages dans lUI.
  • BaseApiService / getInstance() (services sous LeCoffreApi/) : utilisé par les factories (Folders, Documents, etc.) pour les appels hors composants (loaders, services partagés). Conservé pour compatibilité et contexte non-React.
  • Déduplication : réutiliser les builders de paramètres de requête (@Front/Utils/folderQueryBuilders, documentQueryBuilders dans ClientDashboard) pour éviter des q / include divergents entre écrans.
  • Règle : nouveau code dans un composant ou hook → préférer useApiClient ; code dans un service/factory existant → garder BaseApiService tant que la migration nest pas planifiée.

Appliqué (dossiers notary) : les appels API dossiers notary passent par useApiClient via le hook useNotaryFoldersApi et les helpers @Front/Utils/notaryFoldersApiEndpoints et @Front/Utils/folderQueryBuilders. Migrés : liste et détail (useFolderListData, useFolderDataFetch), mise à jour / suppression / création (UpdateFolderMetadata, DeleteModal, DeleteFolderModal, createFolderSubmitHelpers, finalizePayloadHelpers), chargement dossier (useFolderDataInitialization, useAskDocumentsFolderData), archive / unarchive / restore (ArchiveModal, folderInformationControllerCallbacksHelpers onUnarchive, ArchiveAlertWarning), collaborateurs et participants (useFolderCollaboratorsLoader, useUpdateFolderCollaboratorsController, useParticipantDeletions), envoi documents et invités (dataLoaders SendDocuments, useInvitedCustomerFolders), validation numéro dossier (useFolderNumberValidation), redirection auto (useFolderAutoRedirect), documents reçus invité (useInvitedReceivedDocumentsController), page corbeille (pages/folders/deleted : liste supprimés + restauration), en-tête client dossier (UserFolderHeader, refactor classe → FC). Appliqué (dossiers customer) : les appels API dossiers customer (clients, tiers, notaires invités) passent par useApiClient via le hook useCustomerFoldersApi et les helpers @Front/Utils/customerFoldersApiEndpoints. Migrés : liste et détail (useCustomerFolders, useOfficeChangeRedirect, folderLoaders SelectFolder), chargement dossier et client (useFolderAndCustomer ClientDashboard et ReceivedDocuments, useClientAccountLoader), notes (useNoteLoaderUnified), CreateCustomerNote (loadFolderWithIncludes, useFolderAndCustomerLoader, loadAndProcessFolder).

Utilisation Frontend

Ancien Code

const userQuery: IGetUsersParams = {
  include: {
    contact: {
      select: {
        first_name: true,
        last_name: true,
      },
    },
  },
};

const availableCollaborators = await Users.getInstance().get(userQuery);

Nouveau Code

// Utiliser le nouvel endpoint aggregated
const response = await axios.get('/api/v1/notary/users/aggregated', {
  headers: { Authorization: `Bearer ${token}` }
});

const availableCollaborators = response.data;

// Les collaborateurs sont déjà au bon format
const selectOptions = availableCollaborators.map(collaborator => ({
  label: `${collaborator.contact?.first_name} ${collaborator.contact?.last_name}`,
  id: collaborator.uid,
  // Optionnel : afficher une indication visuelle pour les collaborateurs sans compte
  badge: collaborator._metadata?.has_user_account ? null : 'Pas de compte'
}));

Points d'Attention

UID des Collaborateurs sans Compte

Les collaborateurs sans compte ont un uid au format sync:{idnot}.

Important : Ne jamais utiliser cet UID pour créer des enregistrements en base.

// ❌ MAUVAIS
await createStakeholder({
  user_uid: collaborator.uid, // Si c'est "sync:123", ça va échouer
  folder_uid: folderUid,
});

// ✅ BON
if (collaborator._metadata?.has_user_account) {
  await createStakeholder({
    user_uid: collaborator.uid,
    folder_uid: folderUid,
  });
} else {
  // Créer le compte d'abord OU afficher un message
  alert('Ce collaborateur doit d\'abord créer un compte');
}

Gestion des Sièges d'Abonnement

Les collaborateurs sans compte ne peuvent pas avoir de siège d'abonnement.

Filtrer les collaborateurs pour n'afficher que ceux avec compte dans la gestion des sièges.

Migration Progressive

L'ancien endpoint /api/v1/notary/users reste disponible pour assurer la compatibilité.

La migration peut se faire progressivement composant par composant :

  1. UpdateFolderCollaborators
  2. SubscriptionManageCollaborators
  3. CreateFolder
  4. Autres composants utilisant la sélection de collaborateurs

Service API Frontend Recommandé

Fichier : lecoffre-front-main/src/front/Api/CollaboratorsService.ts

import { apiClient } from './ApiClient';

export class CollaboratorsService {
  static getInstance(): CollaboratorsService {
    // Singleton pattern
  }

  async getAggregated(): Promise<AggregatedCollaborator[]> {
    const response = await apiClient.get('/api/v1/notary/users/aggregated');
    return response.data;
  }

  async getWithAccounts(): Promise<AggregatedCollaborator[]> {
    const all = await this.getAggregated();
    return all.filter(c => c._metadata.has_user_account === true);
  }

  async getWithoutAccounts(): Promise<AggregatedCollaborator[]> {
    const all = await this.getAggregated();
    return all.filter(c => c._metadata.has_user_account === false);
  }
}

5. Architecture Technique

Wrapper jwt-decode

Date : 2025-11-24 Version : 2.0.1+ Dernière mise à jour : 2025-11-24

Problème

Deux problèmes principaux ont été rencontrés avec jwt-decode v4 :

  1. Turbopack (bundler Next.js 16) : Détecte statiquement que jwt-decode v4 n'a pas d'export par défaut dans le build ESM, causant l'erreur :

    Export default doesn't exist in target module
    The export default was not found in module [project]/node_modules/jwt-decode/build/esm/index.js
    
  2. Environnement de build : En build de production, TypeScript résout jwt-decode comme un module CJS (/repo/lecoffre-front-main/node_modules/jwt-decode/build/cjs/index), et détecte statiquement que la propriété default n'existe pas, causant l'erreur :

    Property 'default' does not exist on type 'typeof import("/repo/lecoffre-front-main/node_modules/jwt-decode/build/cjs/index")'
    

Solution

Un wrapper a été créé pour gérer les différences entre ESM et CJS, avec des assertions de type explicites pour garantir la sécurité TypeScript :

Fichier : lecoffre-front-main/src/front/Utils/jwtDecodeWrapper.ts

import * as jwtDecodeModule from "jwt-decode";

// Type pour gérer les différentes formes d'export de jwt-decode
type JwtDecodeFunction = (token: string) => unknown;

// Type pour le module jwt-decode avec toutes ses formes possibles
type JwtDecodeModuleType = JwtDecodeFunction | { default?: JwtDecodeFunction; jwtDecode?: JwtDecodeFunction } | Record<string, unknown>;

// Type assertion pour gérer les différences entre ESM et CJS
const jwtDecodeModuleAny = jwtDecodeModule as unknown as JwtDecodeModuleType;

// Vérification à l'exécution pour déterminer comment accéder à la fonction
// Utilisation de if/else explicites pour une meilleure inférence de type
let jwtDecodeFunction: JwtDecodeFunction;

if (typeof jwtDecodeModuleAny === "function") {
	jwtDecodeFunction = jwtDecodeModuleAny as JwtDecodeFunction;
} else {
	const moduleObj = jwtDecodeModuleAny as Record<string, unknown>;
	const defaultExport = moduleObj["default"];
	const namedExport = moduleObj["jwtDecode"];
	if (typeof defaultExport === "function") {
		jwtDecodeFunction = defaultExport as JwtDecodeFunction;
	} else if (typeof namedExport === "function") {
		jwtDecodeFunction = namedExport as JwtDecodeFunction;
	} else {
		// Fallback: essayer d'utiliser le module directement
		jwtDecodeFunction = jwtDecodeModuleAny as JwtDecodeFunction;
	}
}

export const jwtDecode = jwtDecodeFunction as <T = unknown>(token: string) => T;

Points clés de l'implémentation :

  • Utilisation d'assertions de type explicites (as JwtDecodeFunction) pour garantir la sécurité TypeScript
  • Vérification à l'exécution (runtime) avec typeof avant les assertions pour garantir la sécurité
  • Utilisation de if/else explicites pour une meilleure inférence de type TypeScript
  • Support de plusieurs formats d'export :
    • Fonction directe (CJS)
    • Export default (ESM)
    • Export nommé jwtDecode
    • Fallback sur le module entier

Utilisation

Avant :

import jwtDecode from "jwt-decode";
const decoded = jwtDecode(token);

Après :

import { jwtDecode } from "@Front/Utils/jwtDecodeWrapper";
const decoded = jwtDecode(token);

Fichiers Modifiés

  • lecoffre-front-main/src/front/Api/BaseApiService.ts
  • lecoffre-front-main/src/front/Services/TokenRefreshService/TokenRefreshService.ts
  • lecoffre-front-main/src/proxy.ts
  • lecoffre-front-main/src/front/Stores/ActiveOfficeStore.ts

Avantages

  • Compatible avec Turbopack (Next.js 16)
  • Gère automatiquement les différences ESM/CJS
  • Fonctionne en build de production (résolution CJS)
  • Évite les erreurs TypeScript statiques grâce à as any
  • Vérification à l'exécution pour déterminer le format d'export
  • Type-safe avec TypeScript (casting final)

6. Authentification IdNot et Logging

Logging des Données API IdNot au Login

Date : 2025-01-XX Version : 2.0.1+

Vue d'Ensemble

Des logs détaillés ont été ajoutés dans la console du navigateur pour tracer les données API reçues d'IdNot lors du processus d'authentification, permettant de diagnostiquer les problèmes d'authentification et de suivre le flux complet.

Logs Disponibles

Tous les environnements :

  • Logs de la présence des tokens (hasAccessToken, hasRefreshToken) sans jamais logger les valeurs
  • Logs du JWT décodé avec informations utilisateur (userId, officeId, role, règles)
  • Logs des erreurs avec contexte détaillé

Fichiers Concernés

  • lecoffre-front-main/src/front/Api/Auth/IdNot/index.ts : Service d'authentification IdNot avec logs
  • lecoffre-front-main/src/front/Components/Layouts/LoginCallback/hooks/helpers/idNotAuthHelpers.ts : Échange code → tokens (sans log des valeurs de tokens)
  • lecoffre-front-main/src/front/Components/Layouts/LoginCallback/index.tsx : Callback de login avec logs détaillés

Exemples de Logs

[Front] 🔄 [IdNot] Exchanging authorization code for JWT tokens
[Front] ✅ [LoginCallback] IdNot tokens received, connecting user { hasAccessToken: true, hasRefreshToken: true }
[Front] ✅ [LoginCallback] JWT decoded successfully { userId: "...", officeId: "...", role: "admin", hasRules: true, rulesCount: 15 }

Sécurité

  • Tokens (accessToken, refreshToken) jamais loggés, quel que soit l'environnement (risque de fuite via agrégation de logs)
  • Seuls les 10 premiers caractères du code d'autorisation sont loggés
  • Uniquement des indicateurs booléens (hasAccessToken, hasRefreshToken) sont loggés après réception des tokens

Documentation complète : Voir ARCHITECTURE (Types dutilisateurs, connexion IdNot) et logs IdNot au login.

Nettoyage silencieux des sessions expirées sur les pages publiques

  • Les appels publics (BasePublicSiteTextsApi, IncidentReportApi) n'imposent plus de redirection vers https://qual-connexion.idnot.fr/ quand un leCoffreAccessToken expiré est présent mais que le refresh token a disparu.
  • BaseApiService.checkJwtToken() détecte toujours le flag IdNot, mais BasePublic surcharge désormais shouldEnforceIdNotLogoutOnExpiredSession() pour renvoyer false. Le SDK se contente alors de supprimer les cookies locaux au lieu de forcer une navigation.
  • Toutes les API privées continuent de déclencher la redirection Id.Not dès que l'utilisateur tente d'appeler un endpoint protégé avec un token expiré ou invalide.
  • Cette séparation évite la "redirection instantanée" depuis / tout en conservant la synchronisation stricte des sessions sur les pages authentifiées.

Rafraîchissement automatique des sessions (2025-12)

  • Nouveau service SessionRefreshService démarré depuis _app.tsx
  • Lit en continu le refresh token (leCoffreRefreshToken) pour calculer sa date d'expiration (exp)
  • Programme un rafraîchissement 2 minutes avant l'expiration (fallback toutes les 10 minutes)
  • S'appuie sur TokenRefreshService (qui reçoit désormais un refresh token rotated à chaque appel)
  • Ré-écoute les événements UserStore / CustomerStore (onConnect / onDisconnect) pour relancer ou arrêter les timers quand un utilisateur change d'état
  • Empêche les expirations silencieuses malgré une activité continue dans l'UI, tout en journalisant les succès / échecs côté front

7. Interface Espace Notaire - Onglets et Tableaux

Refonte des onglets membres et tableaux documents

Date : 2025-01-XX Version : 2.0.1+ Page : /folders/[folderUid] - Vue ClientView

Vue d'Ensemble

Refonte complète de l'interface des onglets des membres et des tableaux de documents dans l'espace notaire pour améliorer la clarté et la conformité des documents.

Modifications des Onglets Membres

Composants modifiés :

  • ClientView/ThirdPartyBox/index.tsx
  • ClientView/ClientBox/index.tsx
  • ClientView/SharedNotaryBox/index.tsx

Changements :

  1. ThirdPartyBox :

    • Suppression du bouton "Renvoyer l'invitation"
    • Suppression du bouton "Supprimer"
    • Bouton unique "Modifier la note" (remplace le menu)
  2. ClientBox :

    • Texte du bouton de note changé en "Modifier la note" (au lieu de "Rajouter/modifier une note")
  3. SharedNotaryBox :

    • Texte du bouton de note changé en "Modifier la note"
    • Menu conservé avec option "Modifier les informations" (si disponible)

Modifications des Tableaux de Documents

Composants modifiés :

  • ClientView/DocumentTables/index.tsx
  • ClientView/DocumentTables/useDocumentTablesController.ts
  • ClientView/DocumentTables/hooks/useDocumentRows.tsx
  • ClientView/DocumentTables/helpers/tableHeaders.ts
  • ClientView/DocumentTables/helpers/documentConformity.ts
  • ClientView/DocumentTables/components/DocumentTablesHeader.tsx
  • ClientView/DocumentTables/components/ValidatedDocumentsSection.tsx

Nouvelle fonctionnalité : Vérification de conformité

Un nouveau helper documentConformity.ts vérifie la conformité des documents :

  • Lien IPFS : Présence de watermarked_s3_key ou file_path dans les fichiers
  • Ancrage : Présence de document_anchor
  • Données d'ancrage : Présence de document_anchor.proof_data

Si l'un de ces éléments manque, le statut du document devient "NON CONFORME".

⚠️ Exception importante : Documents demandés (ASKED)

Les documents avec le statut ASKED (demandés mais pas encore déposés) ne sont jamais vérifiés pour la conformité car :

  • Ils n'ont pas encore de fichier déposé
  • Ils ne peuvent donc pas avoir de filigrane, d'ancrage ou de métadonnées
  • La vérification de conformité ne s'applique qu'aux documents déposés (DEPOSITED)

Les documents ASKED affichent toujours le statut "DEMANDE" et jamais "NON CONFORME".

Nouveaux tableaux :

  1. "Documents demandés" (sans nombre entre parenthèses) :

    • Statuts : DEMANDES, A VALIDER, NON CONFORME
    • Colonnes : Type de document, Statut, Déposé le, Action (voir)
    • Note : Pas de colonne "Nom du document" car les documents ASKED n'ont pas encore de fichiers déposés
    • Note : Pas de case à cocher pour les documents ASKED et DEPOSITED
    • Note : Vérification de conformité uniquement pour les documents DEPOSITED (les documents ASKED affichent toujours "DEMANDE")
    • Fichier : useAskedDocumentsRows() - Combine ASKED et DEPOSITED avec vérification conformité uniquement pour DEPOSITED
    • DEPOSITED (À VALIDER) : L'icône « voir » (œil) est affichée pour le notaire afin de visualiser et valider le document. Pour le déposant (client/tiers/notaire invité), la ligne avec la date de dépôt reste visible mais le fichier n'est pas affiché ni modifiable sur la page de visualisation.
  2. "Documents validés" (sans nombre entre parenthèses) :

    • Statuts : VALIDE, TELECHARGE, NON CONFORME
    • Colonnes : case à cocher, Nom du document, Type de document, Déposé le, Action (télécharger, voir)
    • Boutons : Télécharger ZIP et Télécharger Certificat (selon les coches)
    • Fichier : useValidatedDocumentsRows() - Combine VALIDATED et DOWNLOADED avec vérification conformité
  3. "Documents envoyés" (sans nombre entre parenthèses) :

    • Statuts : ENVOYE, NON CONFORME
    • Colonnes : case à cocher, Nom du document, Statut, Déposé le, Action (télécharger, supprimer)
    • Boutons : Télécharger ZIP et Télécharger Certificat (selon les coches)
    • Fichier : useSentDocumentsRows() - Filtre SENT avec vérification conformité

Homogénéisation Documents envoyés (2026-03) : Le notaire envoie de la même façon aux clients, tiers et notaires invités (emails différents selon le type). Affichage centralisé via getSentDocumentsForTab() : clients=DocumentsNotary, tiers=Documents(third_party_depositor), invités=Documents(shared_to_office). Envoi unifié via POST /notary/documents_notary/send (un appel par destinataire).

Modifications techniques :

  • Suppression du compteur de progression dans DocumentTablesHeader
  • Suppression des nombres entre parenthèses dans les titres des sections
  • Ajout de cases à cocher pour la sélection multiple dans les tableaux "Documents validés" et "Documents envoyés"
  • Homogénéisation récupération données : useDocumentTablesData orchestre Documents et DocumentsNotary avec paramètres centralisés par onglet
  • Centralisation onglets (2026-03) : useDocumentRowsData extrait dans hooks/useDocumentRowsData.ts ; filterDocumentsForTabMember mutualise Asked/Refused ; filterAndDeduplicateDocumentsByStatus mutualise Validated (ClientView, InvitedView, ClientDashboard) ; buildParticipantTab factory pour participant tabs ; filterOutDeletedDocuments mutualise le filtrage des documents soft-deleted ; hasDocumentWithDownloadableFile/filterDocumentsWithDownloadableFile mutualise le filtrage documents avec fichier ; deduplicateDocuments déplacé vers module partagé ; getDocumentNameFromFirstFile mutualise l'extraction du nom ; buildValidatedDocumentRow factorise les 3 contextes (ClientView, InvitedView, ClientDashboard) ; renommage documentFilterTabMemberHelpers et documentFilterToSendHelpers pour clarifier les deux fichiers documentFilterHelpers
  • Sélections indépendantes : selectedValidatedDocuments et selectedSentDocuments pour éviter que la sélection dans une section n'affecte l'autre
  • Intégration de la vérification de conformité dans les hooks de génération de lignes (uniquement pour les documents avec fichiers)
  • Support des documents DocumentNotary avec statut DOWNLOADED dans "Documents validés"
  • Colonnes conditionnelles : Pas de colonne "Nom du document" pour "Documents demandés" (documents ASKED sans fichiers)
  • Cases à cocher conditionnelles : Pas de case à cocher pour les documents ASKED et DEPOSITED dans "Documents demandés"

Fichiers créés :

  • ClientView/DocumentTables/helpers/documentConformity.ts : Fonctions de vérification de conformité

Fichiers modifiés :

  • ClientView/DocumentTables/index.tsx : Réorganisation des sections, ajout des boutons pour documents envoyés, sélections indépendantes
  • ClientView/DocumentTables/useDocumentTablesController.ts : Ajout de deux sélections séparées (selectedValidatedDocuments, selectedSentDocuments)
  • ClientView/DocumentTables/hooks/useDocumentRows.tsx : Refonte complète des hooks pour les nouveaux tableaux avec colonnes conditionnelles
  • ClientView/DocumentTables/hooks/useDocumentRowsData.ts : Orchestration des lignes (Asked, Validated, Sent, Refused) et calcul progression
  • ClientView/DocumentTables/helpers/documentFilterHelpers.ts : filterDocumentsForTabMember pour Asked/Refused
  • ClientView/DocumentTables/helpers/documentFilterStatusHelpers.ts : filterAndDeduplicateDocumentsByStatus pour Validated
  • ClientView/DocumentTables/helpers/documentFilterDeletionHelpers.ts : filterOutDeletedDocuments pour documents soft-deleted (documentsDataLoader, receivedDocumentsLoaderHelpers)
  • ClientView/DocumentTables/helpers/documentFilterFilesHelpers.ts : hasDocumentWithDownloadableFile, filterDocumentsWithDownloadableFile
  • ClientView/DocumentTables/helpers/documentDeduplicationHelpers.ts : deduplicateDocuments
  • ClientView/DocumentTables/helpers/documentFilterTabMemberHelpers.ts : filterDocumentsForTabMember, filterDocumentByActiveMember (ex-documentFilterHelpers)
  • ClientDashboard/helpers/documentFilterToSendHelpers.ts : filterDocumentsToSend, constantes statuts (ex-documentFilterHelpers)
  • ClientView/helpers/participantTabsHelpers.tsx : buildParticipantTab factory
  • ClientView/DocumentTables/helpers/tableHeaders.ts : Mise à jour des en-têtes de tableaux
  • ClientView/DocumentTables/components/DocumentTablesHeader.tsx : Suppression du compteur
  • ClientView/DocumentTables/components/ValidatedDocumentsSection.tsx : Suppression du nombre dans le titre

8. Consolidation évolutions et correctifs

Cette section consolide les éléments issus des documents de travail intégrés dans la documentation frontend pérenne.

Upload, contexte utilisateur et tables

  • Le module d'upload “Ajouter un document” est unifié entre documents à envoyer et documents supplémentaires avec sélection locale avant envoi explicite.
  • Helpers clés : Utils/documentUploadByRoleHelper.ts, Utils/userContextResolver.ts, Hooks/useResolvedUserContext.ts, DesignSystem/DepositOtherDocument.
  • Le routage des uploads par rôle est centralisé (customer, third_party, invited_notary) et les contrats de dépôt sont typés.
  • La résolution de contexte utilisateur (dashboard, vues document, sélection de dossier) est mutualisée via des helpers/hook dédiés.
  • Les wrappers legacy ont été alignés sur des composants partagés pour réduire les branches spécifiques par rôle.
  • Les textes et colonnes des tableaux de documents reçus sont construits via des builders mutualisés.
  • L'identité des onglets membres (customer/third_party/shared notary) est unifiée avec helpers dédiés pour navigation et sélection.

Téléchargements et nommage

  • Le téléchargement des documents demandés côté notaire est aligné sur un flux PDF unique (et non ZIP par défaut).
  • Le dédoublonnage des noms de fichiers est renforcé (normalisation Unicode + normalisation extension .pdf) pour stabiliser la décision ZIP/PDF.
  • Le nommage ZIP multi-téléchargement suit le format dossier/tableau (<folder_number>.<nom du tableau>.(validé).zip).
  • Les fichiers validés téléchargés (tableau Documents validés, page visualisation, côté tiers/clients/notaire invité) ont le suffixe (validé) avant lextension (ex. document (validé).pdf). Sapplique aux statuts VALIDATED, SENT, DOWNLOADED.

Correctifs de fiabilité frontend

  • Migration des signatures JSX vers les conventions React 19 (React.JSX.Element, React.ReactNode) et suppression de la dépendance au shim global JSX.
  • Nettoyage des console.log oubliés au profit de LoggerService.
  • Suppression du code mort ID360 (routes, composants, API front inutilisés).

Upload : fusion systématique et page de métadonnées

Tous les uploads (1 ou plusieurs fichiers) sont fusionnés et incluent la page de métadonnées (hash des fichiers originaux) dans le PDF filigrané. FileUploadHelper, ThirdPartyUploadService, GuestNotaryDocumentService, RIB, POST /notary/documents_notary : toujours fusion via FileMergeService. Module Deposit unifié : DepositContent partagé, configs par scope (documents, rib, sendDocuments).

Retour sur l'onglet membre après modification

Après validation ou annulation lors de la modification des informations d'un membre (client, tiers, notaire invité), le backwardPath inclut les paramètres d'onglet (customerUid, thirdPartyUid, shareUid) pour que useParticipantTabs sélectionne le bon onglet. Fichiers : participantTabNavigationHelpers.appendQueryParam, useUpdateClientController, useUpdateSharedNotaryController, updateThirdPartyFormHelpers.

Restriction téléchargement/visualisation tableaux notaires

Dans les onglets clients/tiers/notaires invités du dossier (vue notaire propriétaire) : documents DEPOSITED (À VALIDER) affichent l'icône œil pour que le notaire puisse visualiser et valider ; documents REFUSED n'affichent pas d'icône œil. Documents VALIDATED et SENT conservent téléchargement et visualisation. Page ViewDocuments : showDownload limité aux documents VALIDATED, SENT, DOWNLOADED. Espaces clients, tiers, notaires invités non impactés.

Centralisation aperçu fichiers (file preview)

Helpers centralisés dans @Front/Utils/filePreviewHelpers.ts : FilePreviewState, createFilePreviewState, revokeFileUrl, loadFilePreviewDocumentNotary, loadFilePreviewDocument. ViewDocumentsNotary et ViewDocumentSent utilisent ces helpers. Variables SCSS : $document-preview-min-height, $document-file-container-min-height dans @Themes/constants.scss.

8. Opérations Batch Frontend

Envoi Batch Documents

Frontend :

  • Page : /folders/[folderUid]/send-documents
  • Composant : SendDocuments
  • Fonctionnalités : Sélection multiple + progression

Filtres Avancés

Frontend :

  • Page : /folders/select (sélection avec filtres)
  • Autocomplétion : Recherche via appels API (IdNot/Annuaire) et dans third_parties

Certificat Agrégé Documents

Frontend :

  • Bouton "Télécharger Certificat" dans les tableaux de documents
  • Disponible pour les documents validés et les documents envoyés
  • Vérification que tous les documents sélectionnés sont ancrés

ZIP :

  • Les ZIP téléchargés incluent automatiquement le certificat agrégé si des documents ancrés sont présents
  • Support séparé pour Documents et DocumentsNotary (deux certificats si nécessaire)

9. Envoi de Documents par Notaires Invités

Statut : 100% | Version : 2.0.1

Vue d'Ensemble

Les modifications permettent aux notaires invités de créer des documents avec shared_to_office_uid pointant vers l'office du notaire propriétaire (au lieu de leur propre office). Ces documents ont le statut DEPOSITED et sont visibles par le notaire propriétaire.

ClientView - DocumentTables (Notaire propriétaire)

Impact : Géré

  • Les documents créés par les notaires invités avec shared_to_office_uid pointant vers l'office du notaire propriétaire apparaissent maintenant dans les onglets des membres du dossier
  • Modification dans useDocumentTablesController.ts : ajout de la condition shared_to_office: { uid: folderOfficeUid } dans la clause OR

InvitedView (Notaire invité)

Impact : Géré

  • Nouvelle section "Documents à envoyer" pour les documents ASKED
  • Nouvelle section "Documents supplémentaires" pour créer des documents "Autres documents"
  • Les documents créés apparaissent dans la section appropriée

Points de Vigilance

Distinction entre documents envoyés PAR et envoyés AU notaire invité

Les documents avec shared_to_office_uid peuvent être :

  • Envoyés PAR le notaire propriétaire AU notaire invité : shared_to_office_uid = office invité, statut SENT, pas de depositor
  • Envoyés PAR le notaire invité AU notaire propriétaire : shared_to_office_uid = office propriétaire, statut DEPOSITED, pas de depositor

Impact : La logique de filtrage doit distinguer ces deux cas selon le contexte (InvitedView vs ClientView)

Documents "Autres documents" créés par les notaires invités

Les documents créés via "Documents supplémentaires" ont :

  • Type : "Autres documents"
  • Statut : DEPOSITED
  • shared_to_office_uid : office du notaire propriétaire

Impact : Ces documents doivent être visibles par le notaire propriétaire dans les onglets des membres, mais pas dans les onglets des notaires invités

Emails et Notifications

Comportement : Pas d'impact (comportement attendu)

  • sendDocumentEmails() ne gère que les statuts ASKED, REFUSED (VALIDATED désactivé)
  • Documents DEPOSITED : Les documents créés par les notaires invités pour le notaire propriétaire ont le statut DEPOSITED et ne génèrent pas d'email
  • Raison : Le notaire gestionnaire du dossier verra le document dans son interface sans avoir besoin d'une notification par email

10. Mutualisation des Espaces Client / Tiers / Dossiers Invités

Statut : COMPLÉTÉ | Version : 2.0.0

Vue d'Ensemble

Réduction de la duplication de code entre les trois espaces utilisateurs tout en préservant leurs spécificités fonctionnelles.

Résultats

  • 5 composants/services/helpers génériques créés
  • 7 fichiers refactorisés
  • ~1190 lignes de code dupliqué → ~980 lignes mutualisées
  • ~82% de réduction du code dupliqué
  • 0 régression : tous les comportements préservés

Mutualisations Implémentées

Phase 1 : Composants UI

1. GenericDocumentsToSendSection

  • Fichier : components/GenericDocumentsToSendSection.tsx
  • Réduction : ~290 lignes → ~15 lignes par wrapper
  • Utilisation : ClientDashboard, InvitedView
  • Spécificités : Exclusion "Document notaire", gestion refusedDocuments, styles personnalisés

2. GenericReceivedDocumentsPage

  • Fichier : components/GenericReceivedDocumentsPage.tsx
  • Réduction : ~300 lignes → ~60 lignes par wrapper
  • Utilisation : ClientDashboard, InvitedView
  • Spécificités : Colonnes configurables, tracking personnalisé, routes flexibles

2.b. ReceivedDocumentsNotification

  • Fichier : ClientDashboard/components/ReceivedDocumentsNotification.tsx
  • Utilisation : ClientDashboardHeader, InvitedViewContent
  • Spécificités : même composant, seul le texte métier (votre notaire / confrère) change selon l'espace

2.c. Legacy ReceivedDocuments wrapper alignment

  • Fichier : ClientDashboard/ReceivedDocumentsSection.tsx
  • Utilisation : wrapper legacy aligné sur les helpers partagés du centre
  • Spécificités : calcul des documents reçus/counters délégué à ClientDashboard/helpers/receivedDocumentsCenterHelpers.ts

2.d. Received labels builder

  • Fichiers :
    • DesignSystem/helpers/commonUiI18n.ts
    • DesignSystem/helpers/commonUiMessageBuilders.ts
  • Utilisation : ClientDashboardHeader, InvitedViewContent, ReceivedDocumentsSection
  • Spécificités : textes "documents envoyés par ..." centralisés via builders selon le contexte (notary / peerNotary)

2.e. ReceivedDocumentsTextContext

  • Fichier : DesignSystem/helpers/commonUiMessageBuilders.ts
  • Type : ReceivedDocumentsTextContext
  • Spécificités :
    • contexte explicite (sender) pour la source métier,
    • stratégie de grammaire (pluralStrategy) pour singular/plural (strict/inclusive),
    • réutilisé pour notifications, titres de pages "Documents reçus" et noms de ZIP.

2.f. Table Presets Builder

  • Fichier : Layouts/helpers/tablePresetsBuilder.ts
  • Utilisation :
    • Wrappers reçus: ClientDashboard/ReceivedDocuments/index.tsx, InvitedView/ReceivedDocuments/index.tsx
    • Tables dossier: DocumentTables/helpers/tableHeaders.ts, DocumentsReminderHistory/index.tsx
    • Sections non-dossier: Layouts/DesignSystem/sections/TableSection.tsx, Layouts/SuperAdmin/SiteTexts/constants.ts
  • Spécificités :
    • source unique des intitulés partagés Nom, Type de document, Statut, Envoyé le, Action
    • presets de colonnes prêts à lemploi : buildReceivedDocumentsColumnTitles(), buildDefaultReceivedDocumentsColumns(), buildDetailedReceivedDocumentsColumns(), buildDocumentTypeStatusActionHeaders(), buildDocumentTypeStatusSentAtActionHeaders(), buildNameStatusSentAtActionHeaders(), buildDocumentTypeStatutHeaders(), buildStatusActionHeaders().

Phase 2 : Services

3. DocumentDownloadService

  • Fichier : Services/DocumentDownloadService/DocumentDownloadService.ts
  • Réduction : ~400 lignes dupliquées → service centralisé (~350 lignes)
  • Utilisation : ClientDashboard, InvitedView, tous les téléchargements
  • Fonctionnalités :
    • Téléchargement individuel et groupé
    • Marquage comme "vu" selon contexte
    • Gestion d'erreurs et toasts uniforme
    • Support de tous les types de documents
    • Dépôt multi-fichiers (ClientDashboard) : envoi batch unique par document pour client, tiers et notaire invité afin de déclencher la fusion backend en un PDF unique
    • Dispatch dupload unifié par rôle via Utils/documentUploadByRoleHelper.ts (réutilisé par ClientDashboard et DepositOtherDocument)
    • Un dépôt multi-fichiers sur un document produit un unique PDF fusionné actif côté backend (les anciens fichiers actifs du document sont archivés)
    • Les formulaires HTML génériques utilisent un helper dextraction dédié DesignSystem/Form/helpers/formValueExtractionHelpers.ts (source unique pour la collecte des valeurs FormData)
    • La couche legacy BaseApiServiceRequests est supprimée : le socle API transite désormais via BaseApiServiceFactory et ses helpers partagés
    • Les query params complexes (q, objets sérialisés) sont centralisés via Api/helpers/queryParamHelpers.ts et réutilisés dans les builders dendpoints dossiers notary/customer
    • Les payloads fichiers/téléchargements (download multiple, aggregated certificate, send documents) sont centralisés via Api/LeCoffreApi/helpers/fileRequestPayloadHelpers.ts
    • Les payloads JSON métier récurrents (hors fichiers) sont centralisés via Api/LeCoffreApi/helpers/businessRequestPayloadHelpers.ts et réutilisés par les modules Documents, Customers, FolderSharing et DocumentReminders
    • Lharmonisation est étendue aux modules SuperAdmin (SiteTexts, Health, Folders) avec réutilisation des builders partagés buildEmptyPayload, buildPayloadOrEmpty et buildStatusUpdatePayload
    • Les builders CRUD typés par domaine (documents, folders, users) sont appliqués aux factories Admin/SuperAdmin restantes (DocumentsFactory, UsersFactory) pour homogénéiser les payloads create/update
    • Les builders CRUD typés sont étendus aux domaines deeds, deedTypes, documentTypes, roles, customers et appliqués uniformément dans les factories/helpers Admin, Notary, SuperAdmin
    • Les domaines restants officeRoles, stripe, files, notifications, health, liveVotes sont aussi alignés via des builders dédiés dans Api/LeCoffreApi/helpers/businessRequestPayloadHelpers.ts (suppression des payloads inline restants dans leurs factories/helpers)
    • Une convention transversale de suppression par identifiant est ajoutée via buildDeletePayloadByUid(...), puis déclinée en wrappers métier (buildLiveVotesDeletePayload(...)) pour compléter la convention CRUD (create/update/archive/restore/delete)
    • La vérification des helpers UI/API récemment touchés est exécutée (lint + typecheck), sans régression de signature détectée

3.b. Office RIB consultation hook

  • Fichier : ClientDashboard/hooks/useOfficeRibDownload.ts
  • Utilisation : ClientDashboard/ContactBox, Folder/FolderInformation/InvitedView/InvitedViewContent
  • Spécificités : chargement et téléchargement RIB unifiés pour client, tiers et notaire invité

Phase 3 : Helpers

4. documentFilterHelpers

  • Fichier : ClientDashboard/helpers/documentFilterHelpers.ts
  • Constantes (source unique) :
    • DOCUMENTS_TO_SEND_STATUSES : ASKED, REFUSED, VALIDATED (« Documents à envoyer » ; DEPOSITED, SENT, DOWNLOADED exclus).
    • DOCUMENT_STATUSES_RECEIVED_FROM_NOTARY : SENT, DOWNLOADED (table documents).
    • DOCUMENT_NOTARY_STATUSES_RECEIVED_FROM_NOTARY : SENT, DOWNLOADED (table documents_notary).
  • Fonction exportée :
    • statusUpper(s) : normalise le statut en majuscules (comparaisons API).
  • Fonctions :
    • filterDocumentsToSend : Filtrage « Documents à envoyer » (utilise DOCUMENTS_TO_SEND_STATUSES).
    • filterValidThirdPartyDocuments : Filtrage documents tiers valides par customerUid.
    • deduplicateDocuments : Suppression doublons par uid.
  • Autres filtres (autres fichiers) : filterDocuments dans DocumentTables/helpers/documentTablesDataHelpers.ts ; filterReceivedDocuments dans InvitedView/ReceivedDocuments/helpers/receivedDocumentsFilterHelpers.ts et InvitedView/helpers/filterReceivedDocuments.ts.
  • Visualisation documents envoyés (tiers) : en « Documents reçus », le clic œil ouvre la page de visualisation du Document (table documents) pour les tiers ; route ClientDashboard.ViewDocument/client-dashboard/[folderUid]/document/[documentUid] ; composant ViewDocumentSent (Documents.getByUid, Files.download, DocumentViewer, markAsViewed). Les clients restent sur ViewDocumentsNotary (DocumentNotary).

5. documentQueryBuilders

  • Fichier : ClientDashboard/helpers/documentQueryBuilders.ts
  • Builders :
    • buildCustomerDocumentsQuery : Requêtes ClientDashboard (client et tiers) ; utilise DOCUMENTS_TO_SEND_STATUSES pour « Documents à envoyer ».
    • buildDocumentsInclude : Construction clauses include (files, document_anchor, document_history, document_type, depositor/third_party_depositor, folder).

6. Validated documents shared wrapper

  • Fichier : ClientDashboard/components/ValidatedDocumentsListWrapper.tsx
  • Utilisation : ClientDashboard/components/ValidatedDocumentsSection.tsx, Folder/FolderInformation/InvitedView/components/InvitedDocumentsSection.tsx
  • Spécificités : source unique de filtrage VALIDATED + normalisation uid avant rendu ValidatedDocumentsListSection

7. Received counters source unique

  • Fichier : ClientDashboard/helpers/receivedDocumentsCenterHelpers.ts
  • Utilisation : ClientDashboard/ReceivedDocumentsSection.tsx et ClientDashboard/useClientDashboardDocuments.ts
  • Spécificités : total + unread calculés via le même helper pour client et tiers

8. Received ZIP naming builder

  • Fichiers :
    • DesignSystem/helpers/commonUiMessageBuilders.ts
    • Layouts/Folder/FolderInformation/ClientView/DocumentTables/helpers/zipDownloadHelpers.ts
    • Services/DocumentDownloadService/DocumentDownloadService.ts
  • Spécificités : nommage ZIP centralisé et aligné au contexte (notary / peerNotary) au lieu de chaînes inline.

9. Extended contextual document labels

  • Fichier : DesignSystem/helpers/clientDashboardMessageBuilders.ts
  • Builders :
    • buildAdditionalDocumentsDescription(...)
    • buildAskDocumentsPageTitle(...)
    • buildReceivedDocumentsTransferLabel(...)
  • Utilisation :
    • ClientDashboard/AdditionalDocumentsSection.tsx
    • InvitedView/components/InvitedAdditionalDocumentsSection.tsx
    • Folder/AskDocuments/hooks/useAskDocumentsPermissions.ts
    • DocumentTables/helpers/documentTablesDownloadHelpers.ts

10. Design identique partie centrale (client / tiers / notaires invités)

  • Objectif : Aligner la présentation et lordre des sections dans les espaces client, tiers et notaires invités.
  • Ordre unifié : Documents envoyés par le notaire (encart) → RIB → Documents à envoyer (incl. refusés) → Documents validés → Documents supplémentaires (facultatif).
  • Fichiers modifiés :
    • ClientDashboard/index.tsx : ValidatedDocumentsSection affiché pour client et tiers (plus seulement tiers).
    • ClientDashboard/DocumentsToSendSection.tsx : excludeValidated={true} pour client et tiers (documents validés dans section dédiée).
    • InvitedView/components/InvitedViewContent.tsx : ordre des sections (ReceivedDocumentsNotification avant RIB).
    • InvitedView/classes.module.scss : classes .documents, .content, .rib-actions, .deposit-documents alignées sur ClientDashboard.
    • InvitedView/components/InvitedDocumentsToSendSection.tsx : wrapperClassName/contentClassName identiques à ClientDashboard.
    • InvitedView/components/InvitedAdditionalDocumentsSection.tsx : showWrapper={false}, typo par défaut pour cohérence.
  • Documents validés : même présentation (ValidatedDocumentsListSection) pour client, tiers et notaires invités.

Bénéfices Obtenus

Maintenabilité

  • Logique centralisée : modifications futures plus faciles
  • Moins de duplication : moins de risques d'incohérences
  • Code plus lisible : structure claire et organisée

Cohérence

  • Comportement uniforme entre les espaces
  • Gestion d'erreurs standardisée
  • Logging et toasts cohérents

Flexibilité

  • Configuration via props/options
  • Spécificités préservées par contexte
  • Extensibilité facilitée

📚 Références

  • ARCHITECTURE.md - Architecture rôles et permissions
  • API.md - API Annuaire
  • Évolutions espace client : voir section « documentFilterHelpers » ci-dessus (visualisation documents envoyés tiers).

Dernière mise à jour : 2026-02-25


7. Interface Espace Notaire - Onglets et Tableaux

Refonte des onglets membres et tableaux documents

Date : 2025-01-XX Version : 2.0.1+ Page : /folders/[folderUid] - Vue ClientView

Vue d'Ensemble

Refonte complète de l'interface des onglets des membres et des tableaux de documents dans l'espace notaire pour améliorer la clarté et la conformité des documents.

Modifications des Onglets Membres

Composants modifiés :

  • ClientView/ThirdPartyBox/index.tsx
  • ClientView/ClientBox/index.tsx
  • ClientView/SharedNotaryBox/index.tsx

Changements :

  1. ThirdPartyBox :

    • Suppression du bouton "Renvoyer l'invitation"
    • Suppression du bouton "Supprimer"
    • Bouton unique "Modifier la note" (remplace le menu)
  2. ClientBox :

    • Texte du bouton de note changé en "Modifier la note" (au lieu de "Rajouter/modifier une note")
  3. SharedNotaryBox :

    • Texte du bouton de note changé en "Modifier la note"
    • Menu conservé avec option "Modifier les informations" (si disponible)

Modifications des Tableaux de Documents

Composants modifiés :

  • ClientView/DocumentTables/index.tsx
  • ClientView/DocumentTables/hooks/useDocumentRows.tsx
  • ClientView/DocumentTables/helpers/tableHeaders.ts
  • ClientView/DocumentTables/helpers/documentConformity.ts
  • ClientView/DocumentTables/components/DocumentTablesHeader.tsx
  • ClientView/DocumentTables/components/ValidatedDocumentsSection.tsx

Nouvelle fonctionnalité : Vérification de conformité

Un nouveau helper documentConformity.ts vérifie la conformité des documents :

  • Lien IPFS : Présence de watermarked_s3_key ou file_path dans les fichiers
  • Ancrage : Présence de document_anchor
  • Données d'ancrage : Présence de document_anchor.proof_data

Si l'un de ces éléments manque, le statut du document devient "NON CONFORME".

⚠️ Exception importante : Documents demandés (ASKED)

Les documents avec le statut ASKED (demandés mais pas encore déposés) sont toujours considérés comme conformes car :

  • Ils n'ont pas encore de fichier déposé
  • Ils ne peuvent donc pas avoir de filigrane, d'ancrage ou de métadonnées
  • La vérification de conformité ne s'applique qu'aux documents déposés (DEPOSITED)

La fonction isDocumentConform() retourne automatiquement true pour tous les documents en statut ASKED, garantissant qu'ils s'affichent toujours avec le statut "DEMANDE" et jamais "NON CONFORME".

Nouveaux tableaux :

  1. "Documents demandés" (sans nombre entre parenthèses) :

    • Statuts : DEMANDES, A VALIDER, NON CONFORME
    • Colonnes : Type de document, Statut, Déposé le, Action (voir)
    • Fichier : useAskedDocumentsRows() - Combine ASKED et DEPOSITED avec vérification conformité
    • Note : Pas de colonne "Nom du document" car les documents ASKED n'ont pas encore de fichiers déposés
    • Note : Pas de case à cocher pour les documents ASKED et DEPOSITED
    • Note : Les documents ASKED ne sont jamais vérifiés pour la conformité et affichent toujours "DEMANDE"
  2. "Documents validés" (sans nombre entre parenthèses) :

    • Statuts : VALIDE, TELECHARGE, NON CONFORME
    • Colonnes : case à cocher, Nom du document, Type de document, Déposé le, Action (télécharger, voir)
    • Boutons : Télécharger ZIP et Télécharger Certificat (selon les coches)
    • Fichier : useValidatedDocumentsRows() - Combine VALIDATED et DOWNLOADED avec vérification conformité
  3. "Documents envoyés" (sans nombre entre parenthèses) :

    • Statuts : ENVOYE, NON CONFORME
    • Colonnes : case à cocher, Nom du document, Statut, Déposé le, Action (télécharger, supprimer)
    • Boutons : Télécharger ZIP et Télécharger Certificat (selon les coches)
    • Fichier : useSentDocumentsRows() - Filtre SENT avec vérification conformité

Homogénéisation Documents envoyés (2026-03) : Le notaire envoie de la même façon aux clients, tiers et notaires invités (emails différents selon le type). Affichage centralisé via getSentDocumentsForTab() : clients=DocumentsNotary, tiers=Documents(third_party_depositor), invités=Documents(shared_to_office). Envoi unifié via POST /notary/documents_notary/send (un appel par destinataire).

Modifications techniques :

  • Suppression du compteur de progression dans DocumentTablesHeader
  • Suppression des nombres entre parenthèses dans les titres des sections
  • Ajout de cases à cocher pour la sélection multiple dans tous les tableaux
  • Intégration de la vérification de conformité dans tous les hooks de génération de lignes
  • Support des documents DocumentNotary avec statut DOWNLOADED dans "Documents validés"

Fichiers créés :

  • ClientView/DocumentTables/helpers/documentConformity.ts : Fonctions de vérification de conformité

Fichiers modifiés :

  • ClientView/DocumentTables/index.tsx : Réorganisation des sections et ajout des boutons pour documents envoyés
  • ClientView/DocumentTables/hooks/useDocumentRows.tsx : Refonte complète des hooks pour les nouveaux tableaux
  • ClientView/DocumentTables/helpers/tableHeaders.ts : Mise à jour des en-têtes de tableaux
  • ClientView/DocumentTables/components/DocumentTablesHeader.tsx : Suppression du compteur
  • ClientView/DocumentTables/components/ValidatedDocumentsSection.tsx : Suppression du nombre dans le titre

Unification identité onglets membres (2026-02-26)

Page : /folders/[folderUid] (vue notaire gestionnaire, ClientView)

Objectif : unifier lidentité des onglets membres (customer, third_party, shared_notary) et centraliser la résolution didentité pour la sélection donglet, la synchronisation URL et la validation des onglets.

Root cause : longlet shared_notary utilisait selon les zones soit lidentité de partage (sharing.uid), soit lUID doffice invité (shared_to_office.uid). Cette divergence pouvait créer des collisions didentité donglets et des comportements non homogènes.

Correctifs :

  • Centralisation de lidentité membre dans un helper dédié :

    • FolderInformation/ClientView/helpers/participantTabIdentityHelpers.ts
    • getParticipantTabMemberUid(...) pour lidentité de sélection/navigation.
    • getSharedNotaryOfficeUid(...) pour le contexte de fetch des documents.
  • Centralisation de la construction des paramètres de navigation donglet :

    • FolderInformation/ClientView/helpers/participantTabNavigationHelpers.ts
    • buildParticipantTabNavigationParams(...) pour construire tabNavigationParams.
    • buildParticipantTabQueryPatch(...) pour la mise à jour router.query sans logique locale dupliquée.
    • buildParticipantTabLogKey(...) pour la construction unique des clés de logs par onglet (client-*, thirdparty-*, shared-*).
    • normalizeParticipantTabNavigationParams(...) pour produire un objet stable mutualisé (plus de normalizer local dans les hooks de data loading).
    • sappuie sur Utils/participantTabNavigationHelpers.ts pour mutualiser extraction query, patch query, sérialisation URL et log key.
  • Alignement de la sélection et du query param shareUid :

    • FolderInformation/ClientView/helpers/participantTabsSelectionHelpers.ts
    • shareUid est désormais écrit avec lidentité membre (sharing.uid/id).
    • compatibilité maintenue pour anciens liens shareUid=<shared_to_office.uid> en lecture.
    • sur les futurs flux de navigation donglets membres, utiliser systématiquement extractParticipantTabNavigationParamsFromQuery(...) + appendParticipantTabQueryToPath(...) (interdiction de mapping local customerUid/thirdPartyUid/shareUid).
    • flux migrés : ClientDashboard/ViewDocumentsNotary/helpers/navigationHelpers.ts, Folder/ViewDocuments/helpers/viewDocumentsBackUrlHelpers.ts, Folder/AskDocuments/hooks/helpers/askDocumentsNavigationHelpers.ts.
  • Alignement de la validation donglets :

    • FolderInformation/ClientView/helpers/participantTabsValidationHelpers.tsx
    • détection UID manquant/dupliqué basée sur le helper didentité central.
  • Alignement du rendu des tableaux documents :

    • FolderInformation/ClientView/components/ParticipantDocumentTables.tsx
    • clé de rendu shared notary basée sur lidentité membre.
    • tabNavigationParams.shareUid basé sur lidentité membre.
    • contexte de fetch conservé sur lUID doffice invité (shared_to_office.uid).
    • les modules DocumentTables/* réutilisent désormais le type partagé ParticipantTabNavigationParams au lieu de signatures inline.

Retour sur l'onglet membre après modification (2026-02-27)

Objectif : Après validation ou annulation lors de la modification des informations d'un membre (client, tiers, notaire invité), revenir sur l'onglet du membre concerné.

Correctifs :

  • backwardPath des pages d'édition (UpdateClient, UpdateThirdParty, UpdateSharedNotary) inclut désormais les paramètres de requête d'onglet (customerUid, thirdPartyUid, shareUid) via appendParticipantTabQueryToPath.
  • Ajout de appendQueryParam(path, key, value) dans Utils/participantTabNavigationHelpers.ts pour gérer correctement l'ajout de refresh lorsque l'URL contient déjà des paramètres.
  • Documentation : section « Retour sur l'onglet membre après modification » dans ce document.

Correctifs flux invité notaire et ZIP validés (2026-03-02)

Contexte invité notaire (téléchargement document validé) :

  • Le flux invité notaire pouvait appeler l'API notaire (/v1/notary/files/download) au lieu du chemin client/guest, ce qui provoquait un 401/403 et une déconnexion côté front.
  • Le paramétrage est aligné pour traiter l'invité notaire comme un flux client/tiers sur le téléchargement de document validé :
    • InvitedView/documentTableHelpers.tsx : downloadValidatedDocument(..., { isCustomerOrThirdParty: true })
    • InvitedView/InvitedDocumentsSection.tsx : ValidatedDocumentsListWrapper avec isCustomerOrThirdParty={true}
    • ClientView/DocumentTables/hooks/useValidatedDocumentsRows.ts : resolvedContext.isInvitedNotary inclus dans isCustomerOrThirdParty

Contexte ZIP documents validés :

  • Le suffixe (validé) pouvait être dupliqué dans certains noms de fichiers ZIP (ex: ... (validé).aplc (validé).pdf).
  • La normalisation du suffixe est centralisée et mutualisée :
    • réutilisation de addValidatedSuffixToFileName() depuis src/front/Utils/zipValidatedSuffixHelper.ts
    • suppression de la logique locale redondante dans src/front/Utils/zipDownloadHelpers/zipStructureHelpers.ts
  • Règle unique : ne pas réappliquer un suffixe déjà normalisé (... (validé).aplc.pdf).