**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
82 KiB
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
- Routes et Navigation
- Pages et Composants
- Corrections UI/UX
- Agrégation des Collaborateurs
- Build et Tests
- Authentification IdNot et Logging
- Interface Espace Notaire - Onglets et Tableaux
- 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.tsxlecoffre-front-main/src/pages/folders/[folderUid]/index.tsxlecoffre-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 l’ajout d’un confrère par email, le partage et l’email d’invitation étaient créés immédiatement au clic sur « Ajouter ». Si l’utilisateur cliquait ensuite « Annuler », le confrère restait invité et avait déjà reçu l’email.
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 ; l’API shareFolder et l’envoi d’email 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 l’office), /folders/[folderUid]/edit/collaborators
Problème : Dans l’espace client/tiers, les contacts de l’office 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 » n’existait 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 l’office 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 d’un 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 l’affichage 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 ci‑dessus) », 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 lorsqu’ils sont présents sur l’entité brute mais omis par instanceToPlain. Front (useAskDocumentsFolderData) : inclure deed_type avec document_types dans le q du fetch ; priorité deed_type.document_types → deed.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) dansDesignSystem/helpers/fileUploadUiI18n.ts, et les CTA communs de modales (Annuler,Confirmer) sont centralisés dansDesignSystem/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 deDesignSystem/helpers/commonUiI18n.tset 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.tsvia les namespaceshealthetadminTools, 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,usersMessagesetdocumentMessagesdecommonUiI18n.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.tspour éviter la concaténation dans les composants (votesSuperAdmin, message de dépôt en attente dans le viewer). - Les écrans dossier hors scope upload initial (
AddThirdParty,AskDocuments,Folderlanding, sections NoClient, modales de suppression client/document) sont alignés surfolderMessages/formMessageset 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) etbuildDeedTypeDeleteModalPayload(type d'acte), avec centralisation detitle/message/confirmLabelet des messages d'erreur. - La confirmation de suppression avec saisie du numéro de dossier est factorisée via
buildFolderDeleteRequireConfirmationPayloadpour éviter la duplicationlabel/placeholder/errorMessagedans les modales. - Les anciens
alert()des flux de téléchargement documents/certificats et création de dossier (helpersFolderInformation/InvitedView/CreateFolder) sont migrés versToasterServiceavec messages centralisés danscommonUiI18n.tset composition d'erreur agrégée viabuildAggregatedCertificateErrorMessage. - Le flux de désarchivage dossier n'utilise plus
confirm(): il passe désormais par uneConfirmModaldédiée pilotée viauseFolderModals(unarchiveModal) et payloadbuildUnarchiveFolderConfirmPayload. - Les erreurs de téléchargement ZIP/certificat sont unifiées via le helper global
showDownloadErrorToast(Utils/documentDownloadHelpers.ts) et réutilisées dansFolderetClientDashboard. - Les flux
SuperAdmin/SiteTexts(create/update/publish/archive/load) n'utilisent plusalert()/confirm(): feedback viaToasterService+ modale de confirmation d'archivage. - Les toasts de succès de téléchargement sont aussi centralisés via
showDownloadSuccessToastdansUtils/documentDownloadHelpers.tset réutilisés par les fluxFolder,ClientDashboard,singleFileDownloadHelperetDocumentDownloadService. - 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 d’information/validation. - Les flux
Folder/AskDocuments,Folder/SendDocumentsetFolder/AddClientToFolderutilisent désormais les mêmes helpersshowBusinessErrorToast/showBusinessWarningToastet des builders dédiéscommonUiMessageBuilders.tspour supprimer lesToasterService.getInstance().warn/errormétier locaux. - Les builders
folderMessagessont regroupés par sous-domaines (parameterDocuments,askDocuments,sendDocuments,stakeholders) viaDesignSystem/helpers/folderToastMessageBuilders.tset exposés parcommonUiMessageBuilders.ts. - Les builders non-folder sont aussi extraits par domaine pour limiter la croissance de
commonUiMessageBuilders.ts:DesignSystem/helpers/clientDashboardMessageBuilders.tsDesignSystem/helpers/clientDashboardToastMessageBuilders.tsDesignSystem/helpers/collaboratorToastMessageBuilders.tsDesignSystem/helpers/createCustomerNoteToastMessageBuilders.tsDesignSystem/helpers/siteTextsMessageBuilders.tsDesignSystem/helpers/siteTextsToastMessageBuilders.tsDesignSystem/helpers/subscriptionToastMessageBuilders.tsDesignSystem/helpers/deedTypesToastMessageBuilders.tsDesignSystem/helpers/folderInformationToastMessageBuilders.tsDesignSystem/helpers/folderViewDocumentsToastMessageBuilders.tsDesignSystem/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.tscentralise le pattern de re-export des builders*ToastMessageBuilders.ts.commonUiMessageBuilders.tsconserve un re-export de compatibilité.
- Les écrans
ClientDashboard/ViewDocumentSent,ClientDashboard/ViewDocumentsNotaryetFolder/ViewDocumentsn’utilisent plus deToasterService.getInstance().errorinline pour les erreurs métier de chargement/validation. - Les layouts métier ciblés
Folder,ClientDashboardetDeedTypesn’utilisent plus deToasterService.getInstance().warn/errordirect : les flux sont alignés surshowBusinessErrorToast/showBusinessWarningToastavec payloads centralisés. - Les succès métier peuvent aussi être injectés via payload (
title+description) dansshowBusinessSuccessToast, ce qui permet d’alignerFolder/ViewDocumentsetDeedTypessans libellés inline dans les hooks. - Les flux
subscription-plansn'utilisent plusalert()/confirm(): confirmations viaConfirmModal+ 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émonstrationButtonIconMenuSectionet le fallback techniqueToasterHelper.
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_atdesc), 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 (
getUniqueFilesdansfileHelpers.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 buildexécute désormaisnpm run typecheckpuisnode ./scripts/run-next-build.cjs. Ce script Node applique les variables d'environnement requises (TURBOPACK_ROOT,NEXT_TELEMETRY_DISABLED) avant d'invoquernext buildvianext/dist/bin/next. Cette approche garantit un comportement identique sous Windows (où les affectationsVAR=valuen'étaient pas interprétées parcmd.exe) et sous Linux/macOS.- Le fichier
lecoffre-front-main/scripts/run-next-build.cjsest responsable du lancement denext 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(ouReact.JSX.Element | nullpour un rendu conditionnel). - Les composants de classe utilisent
render(): React.ReactNode. - Les props de contenu (
children,title,text,icon,footer, etc.) utilisentReact.ReactNode. - Le shim global
declare namespace JSXn'est plus utilisé danscustom.d.ts. - Les usages
JSX.Elementsont 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 l’UI.
- 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,documentQueryBuildersdans ClientDashboard) pour éviter desq/includedivergents 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 n’est 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 :
UpdateFolderCollaboratorsSubscriptionManageCollaboratorsCreateFolder- 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 :
-
Turbopack (bundler Next.js 16) : Détecte statiquement que
jwt-decodev4 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 -
Environnement de build : En build de production, TypeScript résout
jwt-decodecomme un module CJS (/repo/lecoffre-front-main/node_modules/jwt-decode/build/cjs/index), et détecte statiquement que la propriétédefaultn'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
typeofavant les assertions pour garantir la sécurité - Utilisation de
if/elseexplicites 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.tslecoffre-front-main/src/front/Services/TokenRefreshService/TokenRefreshService.tslecoffre-front-main/src/proxy.tslecoffre-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 logslecoffre-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 d’utilisateurs, connexion IdNot) et logs IdNot au login.
Nettoyage silencieux des sessions expirées sur les pages publiques
- Les appels publics (
BasePublic→SiteTextsApi,IncidentReportApi) n'imposent plus de redirection vershttps://qual-connexion.idnot.fr/quand unleCoffreAccessTokenexpiré est présent mais que le refresh token a disparu. BaseApiService.checkJwtToken()détecte toujours le flag IdNot, maisBasePublicsurcharge désormaisshouldEnforceIdNotLogoutOnExpiredSession()pour renvoyerfalse. 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
SessionRefreshServicedé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.tsxClientView/ClientBox/index.tsxClientView/SharedNotaryBox/index.tsx
Changements :
-
ThirdPartyBox :
- ❌ Suppression du bouton "Renvoyer l'invitation"
- ❌ Suppression du bouton "Supprimer"
- ✅ Bouton unique "Modifier la note" (remplace le menu)
-
ClientBox :
- ✅ Texte du bouton de note changé en "Modifier la note" (au lieu de "Rajouter/modifier une note")
-
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.tsxClientView/DocumentTables/useDocumentTablesController.tsClientView/DocumentTables/hooks/useDocumentRows.tsxClientView/DocumentTables/helpers/tableHeaders.tsClientView/DocumentTables/helpers/documentConformity.tsClientView/DocumentTables/components/DocumentTablesHeader.tsxClientView/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_keyoufile_pathdans 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 :
-
"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.
-
"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é
-
"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 :
useDocumentTablesDataorchestre Documents et DocumentsNotary avec paramètres centralisés par onglet - Centralisation onglets (2026-03) :
useDocumentRowsDataextrait danshooks/useDocumentRowsData.ts;filterDocumentsForTabMembermutualise Asked/Refused ;filterAndDeduplicateDocumentsByStatusmutualise Validated (ClientView, InvitedView, ClientDashboard) ;buildParticipantTabfactory pour participant tabs ;filterOutDeletedDocumentsmutualise le filtrage des documents soft-deleted ;hasDocumentWithDownloadableFile/filterDocumentsWithDownloadableFilemutualise le filtrage documents avec fichier ;deduplicateDocumentsdéplacé vers module partagé ;getDocumentNameFromFirstFilemutualise l'extraction du nom ;buildValidatedDocumentRowfactorise les 3 contextes (ClientView, InvitedView, ClientDashboard) ; renommagedocumentFilterTabMemberHelpersetdocumentFilterToSendHelperspour clarifier les deux fichiers documentFilterHelpers - Sélections indépendantes :
selectedValidatedDocumentsetselectedSentDocumentspour é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
DocumentNotaryavec 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épendantesClientView/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 conditionnellesClientView/DocumentTables/hooks/useDocumentRowsData.ts: Orchestration des lignes (Asked, Validated, Sent, Refused) et calcul progressionClientView/DocumentTables/helpers/documentFilterHelpers.ts:filterDocumentsForTabMemberpour Asked/RefusedClientView/DocumentTables/helpers/documentFilterStatusHelpers.ts:filterAndDeduplicateDocumentsByStatuspour ValidatedClientView/DocumentTables/helpers/documentFilterDeletionHelpers.ts:filterOutDeletedDocumentspour documents soft-deleted (documentsDataLoader, receivedDocumentsLoaderHelpers)ClientView/DocumentTables/helpers/documentFilterFilesHelpers.ts:hasDocumentWithDownloadableFile,filterDocumentsWithDownloadableFileClientView/DocumentTables/helpers/documentDeduplicationHelpers.ts:deduplicateDocumentsClientView/DocumentTables/helpers/documentFilterTabMemberHelpers.ts:filterDocumentsForTabMember,filterDocumentByActiveMember(ex-documentFilterHelpers)ClientDashboard/helpers/documentFilterToSendHelpers.ts:filterDocumentsToSend, constantes statuts (ex-documentFilterHelpers)ClientView/helpers/participantTabsHelpers.tsx:buildParticipantTabfactoryClientView/DocumentTables/helpers/tableHeaders.ts: Mise à jour des en-têtes de tableauxClientView/DocumentTables/components/DocumentTablesHeader.tsx: Suppression du compteurClientView/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 l’extension (ex.document (validé).pdf). S’applique 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.logoubliés au profit deLoggerService. - 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_uidpointant vers l'office du notaire propriétaire apparaissent maintenant dans les onglets des membres du dossier - Modification dans
useDocumentTablesController.ts: ajout de la conditionshared_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.tsDesignSystem/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.
- contexte explicite (
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
- Wrappers reçus:
- Spécificités :
- source unique des intitulés partagés
Nom,Type de document,Statut,Envoyé le,Action - presets de colonnes prêts à l’emploi :
buildReceivedDocumentsColumnTitles(),buildDefaultReceivedDocumentsColumns(),buildDetailedReceivedDocumentsColumns(),buildDocumentTypeStatusActionHeaders(),buildDocumentTypeStatusSentAtActionHeaders(),buildNameStatusSentAtActionHeaders(),buildDocumentTypeStatutHeaders(),buildStatusActionHeaders().
- source unique des intitulés partagés
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 d’upload 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 d’extraction dédié
DesignSystem/Form/helpers/formValueExtractionHelpers.ts(source unique pour la collecte des valeursFormData) - La couche legacy
BaseApiServiceRequestsest supprimée : le socle API transite désormais viaBaseApiServiceFactoryet ses helpers partagés - Les query params complexes (
q, objets sérialisés) sont centralisés viaApi/helpers/queryParamHelpers.tset réutilisés dans les builders d’endpoints 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.tset réutilisés par les modules Documents, Customers, FolderSharing et DocumentReminders - L’harmonisation est étendue aux modules SuperAdmin (
SiteTexts,Health,Folders) avec réutilisation des builders partagésbuildEmptyPayload,buildPayloadOrEmptyetbuildStatusUpdatePayload - Les builders CRUD typés par domaine (
documents,folders,users) sont appliqués aux factoriesAdmin/SuperAdminrestantes (DocumentsFactory,UsersFactory) pour homogénéiser les payloads create/update - Les builders CRUD typés sont étendus aux domaines
deeds,deedTypes,documentTypes,roles,customerset appliqués uniformément dans les factories/helpersAdmin,Notary,SuperAdmin - Les domaines restants
officeRoles,stripe,files,notifications,health,liveVotessont aussi alignés via des builders dédiés dansApi/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) :
filterDocumentsdansDocumentTables/helpers/documentTablesDataHelpers.ts;filterReceivedDocumentsdansInvitedView/ReceivedDocuments/helpers/receivedDocumentsFilterHelpers.tsetInvitedView/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]; composantViewDocumentSent(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) ; utiliseDOCUMENTS_TO_SEND_STATUSESpour « 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+ normalisationuidavant renduValidatedDocumentsListSection
7. Received counters source unique
- Fichier :
ClientDashboard/helpers/receivedDocumentsCenterHelpers.ts - Utilisation :
ClientDashboard/ReceivedDocumentsSection.tsxetClientDashboard/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.tsLayouts/Folder/FolderInformation/ClientView/DocumentTables/helpers/zipDownloadHelpers.tsServices/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.tsxInvitedView/components/InvitedAdditionalDocumentsSection.tsxFolder/AskDocuments/hooks/useAskDocumentsPermissions.tsDocumentTables/helpers/documentTablesDownloadHelpers.ts
10. Design identique partie centrale (client / tiers / notaires invités)
- Objectif : Aligner la présentation et l’ordre 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-documentsalignées sur ClientDashboard.InvitedView/components/InvitedDocumentsToSendSection.tsx:wrapperClassName/contentClassNameidentiques à 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.tsxClientView/ClientBox/index.tsxClientView/SharedNotaryBox/index.tsx
Changements :
-
ThirdPartyBox :
- ❌ Suppression du bouton "Renvoyer l'invitation"
- ❌ Suppression du bouton "Supprimer"
- ✅ Bouton unique "Modifier la note" (remplace le menu)
-
ClientBox :
- ✅ Texte du bouton de note changé en "Modifier la note" (au lieu de "Rajouter/modifier une note")
-
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.tsxClientView/DocumentTables/hooks/useDocumentRows.tsxClientView/DocumentTables/helpers/tableHeaders.tsClientView/DocumentTables/helpers/documentConformity.tsClientView/DocumentTables/components/DocumentTablesHeader.tsxClientView/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_keyoufile_pathdans 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 :
-
"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
ASKEDne sont jamais vérifiés pour la conformité et affichent toujours "DEMANDE"
-
"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é
-
"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
DocumentNotaryavec 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ésClientView/DocumentTables/hooks/useDocumentRows.tsx: Refonte complète des hooks pour les nouveaux tableauxClientView/DocumentTables/helpers/tableHeaders.ts: Mise à jour des en-têtes de tableauxClientView/DocumentTables/components/DocumentTablesHeader.tsx: Suppression du compteurClientView/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 l’identité des onglets membres (customer, third_party, shared_notary) et centraliser la résolution d’identité pour la sélection d’onglet, la synchronisation URL et la validation des onglets.
Root cause : l’onglet shared_notary utilisait selon les zones soit l’identité de partage (sharing.uid), soit l’UID d’office invité (shared_to_office.uid). Cette divergence pouvait créer des collisions d’identité d’onglets et des comportements non homogènes.
Correctifs :
-
Centralisation de l’identité membre dans un helper dédié :
FolderInformation/ClientView/helpers/participantTabIdentityHelpers.tsgetParticipantTabMemberUid(...)pour l’identité de sélection/navigation.getSharedNotaryOfficeUid(...)pour le contexte de fetch des documents.
-
Centralisation de la construction des paramètres de navigation d’onglet :
FolderInformation/ClientView/helpers/participantTabNavigationHelpers.tsbuildParticipantTabNavigationParams(...)pour construiretabNavigationParams.buildParticipantTabQueryPatch(...)pour la mise à jourrouter.querysans 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).- s’appuie sur
Utils/participantTabNavigationHelpers.tspour 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.tsshareUidest désormais écrit avec l’identité membre (sharing.uid/id).- compatibilité maintenue pour anciens liens
shareUid=<shared_to_office.uid>en lecture. - sur les futurs flux de navigation d’onglets membres, utiliser systématiquement
extractParticipantTabNavigationParamsFromQuery(...)+appendParticipantTabQueryToPath(...)(interdiction de mapping localcustomerUid/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 d’onglets :
FolderInformation/ClientView/helpers/participantTabsValidationHelpers.tsx- détection UID manquant/dupliqué basée sur le helper d’identité central.
-
Alignement du rendu des tableaux documents :
FolderInformation/ClientView/components/ParticipantDocumentTables.tsx- clé de rendu shared notary basée sur l’identité membre.
tabNavigationParams.shareUidbasé sur l’identité membre.- contexte de fetch conservé sur l’UID d’office invité (
shared_to_office.uid). - les modules
DocumentTables/*réutilisent désormais le type partagéParticipantTabNavigationParamsau 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 :
backwardPathdes pages d'édition (UpdateClient, UpdateThirdParty, UpdateSharedNotary) inclut désormais les paramètres de requête d'onglet (customerUid,thirdPartyUid,shareUid) viaappendParticipantTabQueryToPath.- Ajout de
appendQueryParam(path, key, value)dansUtils/participantTabNavigationHelpers.tspour gérer correctement l'ajout derefreshlorsque 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:ValidatedDocumentsListWrapperavecisCustomerOrThirdParty={true}ClientView/DocumentTables/hooks/useValidatedDocumentsRows.ts:resolvedContext.isInvitedNotaryinclus dansisCustomerOrThirdParty
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()depuissrc/front/Utils/zipValidatedSuffixHelper.ts - suppression de la logique locale redondante dans
src/front/Utils/zipDownloadHelpers/zipStructureHelpers.ts
- réutilisation de
- Règle unique : ne pas réappliquer un suffixe déjà normalisé (
... (validé).aplc.pdf).