**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
34 KiB
Code Standards
Version : 2.0.0
Dernière mise à jour : 2026-01-28
Périmètre : Monorepo LeCoffre.io (lecoffre-front-main, lecoffre-back-main, lecoffre-ressources-dev)
Référence unique (checks de déploiement) : docs/DEPLOYMENT.md#cartographie-des-checks-de-déploiement-source-unique
📋 Table des Matières
- Qualité du Code
- Sécurité du Code
- Patterns et Bonnes Pratiques
- Règles métier - Documents
- Documentation Fonctionnelle
Qualité du Code
Principes Généraux
- Single Source of Truth : toute règle doit être appliquée automatiquement (ESLint/TS/CI) et documentée ici.
- Pas de dette cachée : lorsqu'une règle est impossible à satisfaire (legacy), consigner l'exception dans README.md ou un plan d'action.
- Symétrie Front/Back/Ressources : mêmes seuils par défaut (longueur fichiers/fonctions, style TypeScript).
Règles Automatisées
| Catégorie | Règle | Projet | Statut |
|---|---|---|---|
| TypeScript | @typescript-eslint/no-explicit-any → warn |
front/back/ressources | ✅ ESLint |
| TypeScript | @typescript-eslint/no-unused-vars + ignore _ |
front/back/ressources | ✅ ESLint |
| Hooks React | react-hooks/rules-of-hooks error |
front | ✅ ESLint |
| Hooks React | react-hooks/exhaustive-deps warn |
front | ✅ ESLint |
| Logs | no-console warn (front), off (back/ressources) |
front/back/ressources | ✅ ESLint |
| Taille fichier | max-lines 250 lignes (blancs/commentaires exclus) |
front/back/ressources | ✅ ESLint (warn front, error back) |
| Taille fonction | max-lines-per-function 40 lignes |
front/back/ressources | ✅ ESLint (warn front, error back) |
| Paramètres | max-params 4 |
front/back/ressources | ✅ ESLint |
| Profondeur | max-depth 4 |
front/back/ressources | ✅ ESLint |
| Complexité | complexity 10 |
front/back/ressources | ✅ ESLint |
| Callbacks | max-nested-callbacks 3 |
front/back/ressources | ✅ ESLint |
| Markdown | MD032, MD033, MD040 | docs, user_stories, etc. | ✅ markdownlint (npm run lint:markdown) |
| Typecheck | tsc --noEmit |
front/back/ressources | ✅ Scripts npm run typecheck (front) / npx tsc --noEmit (back & ressources) |
| Build | npm run build (tsc ou Next build) |
front/back/ressources | ✅ Pipelines |
| Exports inutilisés | ts-prune |
front/back/ressources | ✅ Scripts npm run find-deadcode (ressources/front/back/racine) |
Note
: Les règles
max-linesetmax-lines-per-functiongénèrent des warnings ESLint. Si un fichier legacy dépasse, documenter la dette (cf. §4).
Bonnes Pratiques Spécifiques
Frontend (Next.js/React)
- Préférer les hooks composables (
useX) plutôt que des composants "god object". - Découper
pages/en segments logiques (garder < 300 lignes par page). DocumentTables,FolderInformation,ClientView: surveiller particulièrement la taille (historique de dépassement).- Pas de mutation directe du DOM/Réf hors
useRef. - Logger via
LoggerServiceuniquement (pas deconsolebrute). - Logging dans React : Ne jamais logger dans le corps du composant ou dans le JSX. Toujours utiliser
useEffectpour les logs de debug/info afin d'éviter les boucles de logs et les re-rendus infinis. - Gestion des dépendances useEffect : Stabiliser les dépendances avec
useMemoetuseCallbackpour éviter les re-rendus en boucle. Ne dépendre que des valeurs qui doivent réellement déclencher l'effet. - Pattern Controller/Vue : toute page ou composant complexe doit suivre le triptyque
- Hook contrôleur (
useFeatureController) pour les états, appels API, calculs dérivés. - Sous-composants présentateurs pour découper l'UI (sections, cartes, listes).
- Helpers mutualisés (utils/services) lorsque les mêmes opérations sont utilisées par plusieurs écrans. Fonctions cible : < 40 lignes (voir
max-lines-per-function).
- Hook contrôleur (
- SuperAdmin Health : séparer systématiquement les widgets critiques en hooks spécialisés (
useHealthStatusTracker,useEndpointsHealthTester, etc.) afin de conserver < 200 lignes par bloc et d'orchestrer la page via un contrôleur unique. - Refactors en cours : les écrans
FolderInformation,ClientDashboard,DocumentTables,AddClientToFolder,DocumentsReminderHistory,AskDocuments,CreateCustomerNote,VerifyDocument,ThirdPartyLogin,AdminBlockchainont déjà adopté ce pattern. Toute nouvelle évolution doit s'aligner sur cette architecture et documenter les changements dans README.md. - Règle documentaire : chaque refactor structurant (nouveau hook ou découpe majeure) doit être :
- Référencé dans README.md (problème, impacts, root cause, correctifs).
- Documenté dans la consolidation documentaire pour suivre les efforts qualité.
Backend (Node/Express/TypeDI)
- Un service par responsabilité ; pas de "multi-purpose services".
- Routes courtes : privilégier middleware/service -> controller.
- Toujours typer les réponses (DTO communs dans
lecoffre-ressources-dev). - Logger via Winston centralisé (
@Common/LoggerService). - Pour les wrappers CJS/ESM (
src/common/resources/*.ts), toujours normaliser les constructeurs hydratables avec un helper d'unwrap (default.default->default-> module) avant exposition deHydratableClass.
Ressources TypeScript
- Ne jamais importer du code applicatif (seulement types/pure helpers).
- Garder les DTO < 200 lignes (si plus : split + ré-export).
Gestion des Dépassements
-
Détection : ESLint
max-lines/max-lines-per-functiondéclenche unwarn. -
Action :
- Découper immédiatement si faisable (extractions composant/service).
- Sinon, ouvrir un ticket et consigner dans README.md ou en ticket :
- fichier/fonction impacté(e)
- taille actuelle + cible
- plan de refactor + échéance
-
Exceptions temporaires : Ajouter un commentaire
// TODO(MAX_LINES)avec justificatif + lien vers ticket. -
Aucun override ESLint n'est autorisé ; toute fonction > 40 lignes doit être refactorée (warn front, error back).
-
Tout fichier > 250 lignes déclenche un avertissement (front) ou erreur (back) : planifier un découpage.
-
Documenter chaque dette résiduelle dans README.md (taille actuelle, cible, plan d'action, échéance) et ajouter un commentaire
// TODO(MAX_LINES)dans le fichier concerné. -
Les modules textuels (CGU, Privacy, etc.) doivent être synchronisés avec la base via
deploy/scripts/build-and-deploy-local-seedSiteTexts.shaprès modification. -
Toute fonction dépréciée doit être supprimée ou migrée vers l'implémentation actuelle avant clôture du ticket.
Process de Validation
npm run lint(front) /npm run lint(back) /npm run lint(ressources)npm run lint:markdown(racine, pour MD032/MD033/MD040)npm run typecheck(front) /npx tsc --noEmit(back & ressources)npm run build(tous)- Vérifications manuelles spécifiques (ex: Next build warnings si variables manquantes)
Clôture corrections/évolutions
À la fin de toute correction ou évolution, répondre systématiquement aux questions suivantes et implémenter les améliorations identifiées :
- Modifications similaires à produire ailleurs dans le code ?
- Optimisations, mutualisations ou centralisations possibles ?
- Fichiers corrigés exempts d'erreurs de lint ?
- Vérification des types du projet OK ?
- Projet compile ?
Si ces réponses ne sont pas fournies : les produire si pertinent et implémenter les améliorations identifiées (mutualisation, parties impactées).
La CI doit échouer si un warning "qualité" (taille, hooks, unused) est promu en
error. Actuellement enwarnpour migration progressive.
To-do Qualité
| Item | Statut | Commentaire |
|---|---|---|
Suivi dettes max-lines existantes |
🔄 | Règles actives (250/40). Documenter toute exception dans README.md + // TODO(MAX_LINES) dans le fichier ; prioriser fichiers > 250 lignes et fonctions > 40 lignes. |
Références Qualité
eslint.config.mjs(front/back/ressources)- FRONTEND.md, README.md pour dettes détaillées
- CI / Scripts
deploy/scripts/* FILES_TOO_MANY_LINES.md: Liste des fichiers avec plus de 250 lignes (générée automatiquement)FUNCTIONS_TOO_MANY_LINES.md: Liste des fonctions avec plus de 40 lignes (générée automatiquement)parse-lint-results-improved.js: Script pour générer les listes de fichiers et fonctions dépassant les limites
Sécurité du Code
Principes de Base
- Least Privilege : seules les routes/serveurs nécessaires sont exposés.
- Defense in Depth : validations au frontend, à l'API et au niveau ORM.
- Zero Trust : jamais de données "sûres" par défaut (même celles provenant d'intégrations tierces IdNot/Annuaire).
- No Secrets in Code : toute donnée sensible réside dans la base de configuration (
system_configuration) ou les services secrets (aucun.envpermanent).
Backend (Node/Express/TypeDI)
Authentification & Permissions
- JWT : généré côté backend via IdNot OAuth (Notaires) / login client / tiers.
- Champs obligatoires :
userId,office_Id,role,rules,hasActiveSubscription,isGuest. - Expiration : Access 1h, Refresh 7j (cf.
docs/ARCHITECTURE.md).
- Champs obligatoires :
- Middlewares :
authHandler: vérifie JWT (en-têteAuthorizationou paramètre de requêtetokenpour SSE uniquement, EventSource ne supportant pas les en-têtes), place l'utilisateur surreq.useretreq.body.user. L'URL est nettoyée avant log (paramètretokensupprimé). Voirdocs/ARCHITECTURE.mdetdocs/API.md.activeOfficeInjector: injectereq.activeOfficeUid.ruleHandler: s'assure que l'utilisateur dispose de la règle (resource/action).
- Multi-office :
FolderInformation& API utilisentfolder_office_uid+folder_sharings. Aucun fallback versoffice_uiddirect.
Validation des Entrées
- Class-validator : tous les DTOs exposés doivent étendre
BaseDto+ décorateurs@IsString,@IsUUID, etc. - Paramètre de requête
q: utiliserparseQueryParam<T>(req.query["q"], "GET /...")(voir#Common/utils/jsonHelpers.ts) pour tout parsing dereq.query["q"]. Ne jamais utiliserJSON.parse(req.query["q"])directement (risque de crash et de prototype pollution). - Prisma : aucun
whereconstruit à la main sans sanity-check (Obligation :deleted_at: nullpour toutes les entités soft-delete). - Payload externe (IdNot, API Annuaire) : vérifier les champs obligatoires avant insertion. Les erreurs (ex: payload incomplet) doivent être loggées, pas silencées.
Stockage Sensible
- RIB : AES-256-GCM (clé en base). Process et variables sensibles : voir DATABASE_COMPLETE.md.
- Fichiers : Pinata + S3. Seuls les hash + métadonnées sont gardés.
- Secrets : jamais dans le code. Toute nouvelle config doit transiter par
system_configuration.
Logging & Audits
- Winston standard (level info/warn/error) + Sentry (optionnel).
- Aucune donnée sensible (RIB, tokens OAuth, OTP) dans les logs.
- Les actions critiques (ancrages, partages, login IdNot) doivent être loggées avec
folder_uid,userId,office_uid.
Protection API
- Rate limiting (cf.
docs/DEPLOYMENT.md) : 4 niveaux (public/strict/auth/global). - Validation d'accès : les routes tierces (
/third-party/*) doivent vérifierfolder_uidetthird_party_uid. Aucun accès ne doit être accordé sans double filtre (folder + user). - Ancrage : l'état
tx_idest la seule preuve (pas destatus = ANCHOREDsans TX).
Antivirus Uploads
AntivirusService(Node) contacteclamavvia INSTREAM (TCP 3310) avant toute transformation.- Configuration dynamique (
system_configuration) :CLAMAV_HOST,CLAMAV_PORT(obligatoires)CLAMAV_SCAN_ENABLED(toggle exceptionnel),CLAMAV_CONNECTION_TIMEOUT_MS,CLAMAV_READ_TIMEOUT_MS,CLAMAV_MAX_FILE_SIZE_MB
- Blocage strict :
- Malware détecté →
400ErrorMessages.FILE_INFECTED(aucun fallback). - Timeout / indispo ClamAV →
500viahandleInternalError(upload interrompu).
- Malware détecté →
- Tous les services de fichiers (
FilesService,FilesNotaryService, copies buffer) appellentAntivirusServiceavant hash/filigrane/ancrage.
Frontend (Next.js/React)
Données & Permissions
- Stores (MobX) : ne jamais stocker de secrets (uniquement les règles/role/office).
- ActiveOfficeStore : toujours utiliser
activeOfficeStore.activeOffice?.office_uidplutôt que desidsen clair. - Invités :
DefaultCustomerDashboarddevient la seule vue (pas de fallback notaire). Tout bouton/action doit vérifierrolePermissionsStore.can(...).
API Calls
- Passer par
BaseApiService(ajouteAuthorization+ logger). - Jamais de fetch direct (ex:
fetch("/api/v1/...")). - Gestion d'erreurs utilisateur :
ToasterService, jamais dealert()brut (sauf fallback tiers). - Build : si les variables
NEXT_PUBLIC_*manquent, le build doit logguer l'avertissement (déjà en place).
XSS / DOM
- Utiliser systématiquement
dangerouslySetInnerHTMLuniquement si la donnée est whitelistée & sanitized (ex: templates Markdown validés). - Form inputs : valider côté frontend (
emailRegex,file size, etc.) avant de poster. document.cookien'est jamais manipulé en direct (uniquement viaAuthService).
Ressources TypeScript
- DTOs & enums ne doivent contenir aucune logique.
- Toute évolution de type doit être propagée dans le backend + frontend (contrôle croisé
npm run typecheck). - Les types
neverouanysont interdits dans les exports publics. Si usage interne, commenter le TODO.
Workflows Sécurité
| Vérification | Script / Étape |
|---|---|
| Lint (règles de taille, hooks, types) | npm run lint |
| TypeScript (front) | npm run typecheck |
| TypeScript (back/ressources) | npx tsc --noEmit |
| Build | npm run build |
| Hooks secrets (IdNot/Annuaire) | docs/API.md, docs/ID.NOT ... |
| Audit RIB | DATABASE_COMPLETE.md |
Checklist Pull Requests
npm run lint+npm run typechecksur les modules modifiés.- Vérifier que les logs ne divulguent aucune data sensible.
- Ajouter/Mettre à jour la doc (ce document pour la dette, section Sécurité du Code et README.md si nouvelles surfaces).
- Vérifier que toute nouvelle route tierce utilise
folder.uid+third_party.uid(pas d'identifiant libre). - Pour les parcours invités : s'assurer que
DefaultCustomerDashboardest utilisé (pas de fallback notaire).
Dettes & TODO Sécurité
| Sujet | Statut | Action |
|---|---|---|
Inventaire console.log backend |
🔄 | Passer sur Winston (phase 2). |
Références Sécurité
- ARCHITECTURE.md
- DATABASE_COMPLETE.md (configuration système, variables sensibles, ClamAV)
docs/API.md: rapport d'audit applicatif (logging tokens, parsingq, config sensible, token en URL SSE)- ANCRAGE_COMPLETE.md
- README.md pour les incidents précis
Patterns et Bonnes Pratiques
Ce document décrit les patterns réutilisables et les bonnes pratiques à suivre dans le projet LeCoffre.io.
Note
: Le contenu détaillé des patterns est consolidé dans ce document (sections Patterns et Bonnes Pratiques ci-dessous).
Patterns Principaux
Gestion d'Erreurs (Backend)
Modules :
lecoffre-back-main/src/common/utils/errorMessages.ts: Messages d'erreur centraliséslecoffre-back-main/src/common/utils/errorLoggers.ts: Patterns de logging standardiséslecoffre-back-main/src/common/utils/errorHandlers.ts: Gestion HTTP centraliséelecoffre-back-main/src/common/system/controller-pattern/BaseController.ts: Toutes les méthodeshttp*délèguent désormais aux helpers ci-dessus (log + message homogènes)
Fonctions principales :
handleInternalError(response, error, req?, operation?): Gère et répond à une erreur internehandleValidationError(response, error, req?, operation?): Gère et répond à une erreur de validationhandleNotFoundError(response, message?, req?, operation?): Gère et répond à une erreur 404handleForbiddenError(response, message?, req?, operation?): Gère et répond à une erreur 403handleBadRequestError(response, message?, req?, operation?): Gère et répond à une erreur 400logError(error, context?, operation?): Log une erreur avec format standardisé
Helpers Utilisateurs (Backend)
Module : lecoffre-back-main/src/common/utils/userHelpers.ts
Fonctions principales :
isSuperAdminUser(user, role?): Vérifie si un utilisateur est super-adminextractUserData(bodyUser, authUser, permissionContext): Extrait et normalise les données utilisateurgetStringFromRecord(record, key): Extrait une valeur string d'un recordgetBooleanFromRecord(record, key): Extrait une valeur boolean d'un record
Helpers proof_data (Backend)
Module : lecoffre-back-main/src/common/utils/proofDataHelpers.ts
Helpers pour la validation et l'extraction de la structure proof_data (V3.0.0).
Fonctions principales :
getAntivirusStatusFromProofData(proofData): Extraitantivirus_scan_atdeproof_data.documentisProofDataComplete(proofData): Vérifie si proof_data a la structure V3.0.0 complète (version, timestamp, document, anchor, verification)
Utilisé par : bilan-documents-pprod.ts, reprocess-all-documents-complete.ts, reprocess-incomplete-documents-from-ipfs.ts
Hook API Client (Frontend)
Module : lecoffre-front-main/src/front/Hooks/useApiClient.ts
Ce hook centralise la gestion des appels API frontend avec gestion standardisée des tokens, headers, et erreurs.
Usage :
import { useApiClient } from "@Front/Hooks/useApiClient";
const apiClient = useApiClient();
const data = await apiClient.get("/api/v1/notary/folders");
Pattern Controller/Vue (Frontend)
Structure :
- Hook contrôleur (
useFeatureController) : Gère les états, appels API, calculs dérivés - Sous-composants présentateurs : Découpent l'UI en sections logiques
- Hooks spécialisés : Extraient la logique métier complexe
Règles :
- Fonction principale : Doit rester < 40 lignes (orchestration uniquement, aligné sur
max-lines-per-function) - Hooks contrôleurs : Peuvent dépasser 40 lignes si la logique métier est complexe (documenter en TODO(MAX_LINES) si > 40)
- Sous-composants : Doivent rester < 40 lignes chacun
DTOs et Validation Centralisée (Backend)
Module : lecoffre-back-main/src/common/dtos/
Les DTOs (Data Transfer Objects) fournissent une validation forte des entrées API avec class-validator et class-transformer.
Helper de Validation :
import { validateRequestBody } from "@Common/utils/validationHelpers";
import { CreateDocumentDTO } from "@Common/dtos";
const dto = await validateRequestBody(
CreateDocumentDTO,
req.body,
req,
response,
"POST /notary/documents"
);
Patterns Réutilisables
Pour une documentation complète de tous les patterns disponibles, consulter :
- Backend : Helpers Prisma, SQL, UID extraction, Request helpers, Repository helpers, Date helpers, Array helpers, Type guards
- Frontend : Hooks (useDataLoader, useModal, useForm, useAsyncOperation, useSearchWithDebounce), Helpers (formatters, validators, error classifiers, retry helpers), Composants génériques (ConfirmModal, UpdateFormLayout, DocumentTableSection)
Helpers Documents (Frontend)
Modules : lecoffre-front-main/src/front/Utils/
documentNameHelpers.ts:hasDocumentName,getDocumentNameWithTypePriority(priorité : document_type.name > display_name > file_name > fallback)documentTypeHelpers.ts:getDocumentTypeNameLower,getDocumentTypeName,isDocumentNotaireType,isDocumentTypeAutresDocuments,DOCUMENT_NOTAIRE_TYPE,DOCUMENT_NOTAIRE_LABEL,AUTRES_DOCUMENTS_TYPEstatusHelpers.ts:statusUpper(normalisation casse des statuts document)
Notes Importantes
- Toujours utiliser les modules centralisés : Éviter de dupliquer la logique, utiliser les modules existants.
- Migration progressive : Migrer les fichiers au fur et à mesure, pas besoin de tout migrer d'un coup.
- Tests : Les modules centralisés sont plus faciles à tester unitairement.
- Documentation : Mettre à jour ce document si de nouveaux patterns sont ajoutés.
- Logging React : Ne jamais logger dans le corps du composant ou dans le JSX, toujours utiliser
useEffect. - DTOs : Utiliser les DTOs pour valider toutes les entrées API avec des messages d'erreur clairs.
- Hydratation : Utiliser les helpers d'hydratation pour une conversion cohérente des entités.
- Services Façade : Préférer les façades pour la simplicité, accéder aux services spécialisés pour les cas avancés.
- Pattern Controller/Vue : Appliquer systématiquement pour les composants > 40 lignes afin de respecter
max-lines-per-function. - Request Helpers : Utiliser les helpers
requestHelpers.tspour extraire les IDs depuis les requêtes au lieu de dupliquer la logique. - RequestWithPermissionContext : Le type de base
Request & { permissionContext?: PermissionContext }est exporté depuis#Common/utils/requestHelpers. L'importer pour typer les requêtes avec contexte de permission ; étendre localement si une route a besoin de champs supplémentaires (ex.body.user,user), par ex.type LocalReq = RequestWithPermissionContext & { body?: { user?: ... } }.
Orchestrateurs de sortie documents (Backend)
Pour les réponses API documents, utiliser exclusivement les orchestrateurs de post-hydratation :
documentsNotaryPostHydrationHelperpourDocumentsNotarydocumentsPostHydrationHelperpourDocuments
Règles :
- Ne pas reconstruire localement une sortie
plainavecinstanceToPlain+ merge manuel dans les controllers/helpers. - Utiliser les fonctions
build*PlainWithRelations/hydrate*ToPlainWithRelationspour les listes et mono-entités. - Conserver les garde-fous
log*FilesGuardpour détecter les incohérences defiles. - Toute nouvelle route documents doit réutiliser ces orchestrateurs.
- Pour
Documentscôtéadmin/super-admin, les fluxupdate,refuseetdeletedoivent retourner unplainconstruit viadocumentsPostHydrationHelper(pas dehydrateEntityretourné directement). - Pour les suppressions
Documents(notary,admin,super-admin), utiliser le helper communbuildDeletedDocumentPlainResponsepour réinjecterdocument_typesans duplication locale. - Pour les récupérations mono-entité
Documentsdestinées à une réponse API, utiliserfetchDocumentWithResponseIncludeafin d’unifierinclude(document_type+ include demandé) et éviter la duplication degetByUid(..., { document_type: true }). - Pour transformer une entité
Documentsrécupérée en payload API mono-entité, utiliserbuildPlainFromFetchedDocumentpour centraliserhydrateEntity + buildSingleDocumentPlainWithRelations. - Pour les flux mono-entité
update/refuse/restore/delete, utiliserbuildPlainResponseWithOptionalSourceDocumentTypepour unifier la réinjection optionnelle dedocument_type(source explicite si présente, sinon entité courante). - Pour
DocumentsNotarymono-entité, utiliserbuildDocumentNotaryPlainResponseWithOptionalSourcepour homogénéiser le renduplain(source optionnelle + réinjection fichiers). - Pour les contrôleurs
Documentsmono-entité (admin/super-admin/notary), privilégierfetchDocumentPlainOrHandleNotFoundquand le flux suit le patternfetch + not found + build plain. - Pour les contrôleurs
DocumentsNotarymono-entité, privilégierfetchDocumentNotaryPlainOrHandleNotFoundavecwithDocumentNotaryResponseIncludeafin d’imposer l’include de réponse et standardiser lenot found. - Pour les validations
not found + deletedsurDocuments, réutilisercreateValidateDocumentNotDeletedCallbackplutôt que redéfinir des closures locales. - Pour les règles d’accès
DocumentsNotaryen mono-entité, utilisercreateDocumentNotaryAccessValidatoren callback réutilisable afin d’éviter la duplicationverify...Accessentre contrôleurs. - Pour la visibilité/état
DocumentsNotary(statut métier, présence de fichiers visibles), utilisercreateDocumentNotaryVisibilityStateValidatoret l’injecter dansfetchDocumentNotaryPlainOrHandleNotFound. - Préférer le preset
createDocumentsNotarySentOrDownloadedVisibilityValidatorpour les routes de consultation/téléchargementDocumentsNotary(customer/notary) afin d’éviter la répétition desallowedStatuses. - Pour les endpoints de téléchargement
DocumentsNotary, utiliser le presetcreateDocumentsNotaryDownloadVisibilityValidator(requireAtLeastOneNonArchivedFile: true) afin de mutualiser la règle “document téléchargeable” (statut + au moins un fichier non archivé). - Pour les flux fallback
Documents(routesDocumentsNotaryqui basculent sur la tableDocuments) et les contrôles transverses, utiliser les helpers communsisDocumentSentOrDownloadedStatus/validateDocumentsSentOrDownloadedStatus(common/utils/documentsVisibilityStateHelpers.ts) afin d’éviter les checks locaux divergents. - Pour les usages métier où
VALIDATED,SENTetDOWNLOADEDsont traités comme “document validé/exploitable” (naming/ZIP/export), utiliserisDocumentValidatedOrSentOrDownloadedStatusafin d’éviter les tableaux de statuts locaux.
Règles métier - Documents
Évolution planifiée (Documents unifiés)
Voir ARCHITECTURE.md - Évolution planifiée - Documents unifiés pour :
- Flux d'envoi unifié avec destinataire de type union (
customer|third_party|office|invited_notary). - Métadonnée
emitter(uid, first_name, last_name, office_uid?, office_name?) sur toutes les réponses. - Constante
DOCUMENT_DISPLAY_BASE_INCLUDE(#Common/constants/DocumentsIncludeConstants) : inclureemitteraveccontactetfolderavecstakeholdersdans tous les contextes où les documents sont affichés. - Documents du notaire invité traités comme tiers/clients.
Statuts des documents
Les états des documents sont gérés par membre et par document. Un statut sur le document d'un membre n'affecte en aucun cas un autre membre.
- Chaque document (Documents ou DocumentsNotary) est lié à un destinataire unique (customer, tiers, confrère).
- Les mises à jour de statut (SENT, DOWNLOADED, VALIDATED, etc.) s'appliquent à un document identifié par son
uid. - Aucune mise à jour groupée ou propagation de statut entre documents de membres différents.
Tableau « Documents envoyés »
Dans les espaces clients, tiers et notaires invités (onglets participants du dossier), le tableau des documents envoyés par le notaire liste des documents (une ligne = un document), et non des fichiers.
- Chaque ligne du tableau correspond à une entrée
documents_notaryoudocuments. - L'affichage peut utiliser le nom du fichier PDF (ex.
document.pdf) pour identifier visuellement le document, mais l'entité représentée reste le document. - Un document peut contenir plusieurs fichiers fusionnés en un seul PDF ; la ligne représente le document, pas chaque fichier individuellement.
Upload : fusion et page de métadonnées
Tous les uploads (1 ou plusieurs fichiers) sont fusionnés en un seul PDF avec page de métadonnées (hash des fichiers originaux). FileMergeService, MergedFileCreationHelper, FileMergeHelpers (buildFilesMetadataForMerge, buildMergedMulterFile). Pas de shortcut pour 1 fichier : toujours fusion.
Validation d'accès document (deux entrées, convergence)
Deux chemins coexistent pour la validation d'accès aux documents ; l'objectif est de les faire converger vers une seule source de règles.
- Service central :
DocumentAccessValidationService(#Services/common/DocumentAccessValidationService) — valide l'accès selon le type (guest_notary, invited_notary, thirdparty, customer, notary). Utilisé par la couche API viacreateDocumentNotaryAccessValidator(voirdocumentsNotaryValidatorsHelpers.ts) : les helpers (DocumentsNotaryGetOneByUidHelper, DocumentsNotaryMarkAsViewedHelper, DocumentsNotaryCaseHandlers) fournissent un callbackvalidateAccessqui peut s'appuyer sur ce service. - Middlewares :
DocumentAccessValidationHelper(OfficeMembershipHandlers),FileHandlerAccessHelpers.validateDocumentAccess/validateFileAccess,DocumentHandlerAccessByUidHelper— chargent le document, vérifient l'accès au dossier viaensureFolderAccesset appliquent des règles métier similaires.
Convergence prévue : faire appeler par les middlewares le DocumentAccessValidationService.validateAccess en construisant un DocumentAccessContext à partir du contexte requête, afin d'éviter la double maintenance et les écarts de comportement. En attendant, toute modification des règles d'accès doit être répercutée dans les deux chemins ou documentée comme temporaire.
Documentation Fonctionnelle
Cette section décrit de façon fonctionnelle chaque fichier du projet, expliquant son intérêt dans le projet et ce qu'il fait de façon résumée.
Note
: Le contenu détaillé fichier par fichier est consolidé dans ce document (section Documentation Fonctionnelle ci-dessous).
Synthèse Optimisations Fiabilité & Simplicité (déc. 2025)
| Axe | État | Détails |
|---|---|---|
| Gestion d'erreurs | Terminé | errorHandlers.ts, errorLoggers.ts, errorMessages.ts et depuis 2025-12, toutes les méthodes http* du BaseController délèguent à ces helpers (logs Winston homogènes, messages centralisés). |
| Résolution permissions/rôles | Terminé | Découpage de RulesHandler en decisionHandlers, ruleMatcher, resourceResolver, roleResolver + helpers userHelpers.ts, roleNormalizer.ts, uidExtractors.ts. |
| API client frontend | Terminé | Hook useApiClient + helpers errorClassifiers, retryHelpers, formValidators, formatters pour supprimer les appels fetch dupliqués. |
| Duplication helpers JWT / extraction utilisateur | ✅ Terminé | Helpers centralisés dans userHelpers.ts (getStringFromRecord, getBooleanFromRecord, getStringArrayFromRecord, extractUserData) - tous les fichiers migrés. |
| Validation formulaires frontend | ✅ Terminé | Validations centralisées dans front/Utils/formValidators.ts (validateEmail, validatePassword, validateRequired, etc.) - regex inline remplacées. |
| Formatage prix / données | ✅ Terminé | Fonctions centralisées dans front/Utils/formatters.ts (formatPrice, formatDate, formatMonthString, truncateHash, etc.) - tous les fichiers utilisent les helpers centralisés. |
| Tests & documentation | En cours | Chaque lot migré doit être consigné dans README.md (root cause, impacts) et dans ce document (CODE_STANDARDS.md). |
Structure du Projet
Backend (lecoffre-back-main/src/)
- Entries : Points d'entrée (
App.ts,Cron.ts) - App : Configuration Express, middlewares, routes
- App/api/customer : Contrôleurs et helpers customer ; constantes statuts dans
api/customer/constants/documentStatusConstants.ts(DOCUMENTS_TO_SEND_STATUSES,DOCUMENT_STATUSES_RECEIVED_FROM_NOTARY) pour alignement sémantique avec le front et réutilisation (ex. filtre « documents à envoyer »).DocumentsQueryHelperet requêtes customer peuvent s'y référer (voir JSDoc). - Common : Utilitaires partagés (error handlers, helpers, DTOs, emails)
- Services : Services métier (Files, Documents, Folders, Users, etc.)
Frontend (lecoffre-front-main/src/)
- Pages : Pages Next.js (routes)
- Front : Composants, hooks, stores, API clients, utils
Ressources (lecoffre-ressources-dev/src/)
- Admin : Types et DTOs pour l'administration
- Customer : Types et DTOs pour les clients
- Notary : Types et DTOs pour les notaires
- SuperAdmin : Types et DTOs pour le super-admin
- MemberTypes : Types centralisés pour
userType(JWT),role(role_permissions_matrix) etUserContext(frontend). Constantes :USER_TYPE_THIRDPARTY,USER_TYPE_CUSTOMER,ROLE_CLIENT,ROLE_NOTARY,ROLE_GUEST_NOTARY,USER_CONTEXT_CUSTOMER,USER_CONTEXT_NOTARY,USER_CONTEXT_INVITED_NOTARY,USER_CONTEXT_THIRD_PARTY,THIRD_PARTY_UI_VARIANT,ROLES. Helpers :isRole,isThirdParty,isCustomer,isGuestNotary,isNotaryRole.
Documentation Complète
La documentation détaillée fichier par fichier a été archivée (voir historique Git). Les patterns et la structure sont dans les sections ci-dessus. README des sous-projets : lecoffre-back-main, lecoffre-front-main, lecoffre-ressources-dev.
Sécurité Applicative
Résumé : Chiffrement (clé maître FILE_ENCRYPTION_MASTER_KEY, AES-256-GCM, tous les fichiers) ; 2FA tiers (request-code/verify-code, codes 6 chiffres, JWT userType: 'thirdparty') ; Déconnexion (table revoked_tokens, POST /api/v1/auth/logout) ; ClamAV (AntivirusService, daemon clamd, config dans system_configuration). Détail : DATABASE_COMPLETE.md et SCRIPTS.md.
Références Générales
eslint.config.mjs(front/back/ressources)docs/ARCHITECTURE.md: Architecture générale du systèmedocs/DEPLOYMENT.md: Guide de déploiementdocs/API.md: Documentation des APIs externes- README.md : Documentation des problèmes et correctifs
- ARCHITECTURE.md et FRONTEND.md : Documentation des évolutions
Dernière mise à jour : 2026-02-27