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

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

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

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

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

34 KiB
Raw Permalink Blame History

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

  1. Qualité du Code
  2. Sécurité du Code
  3. Patterns et Bonnes Pratiques
  4. Règles métier - Documents
  5. 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-anywarn 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-lines et max-lines-per-function gé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 LoggerService uniquement (pas de console brute).
  • Logging dans React : Ne jamais logger dans le corps du composant ou dans le JSX. Toujours utiliser useEffect pour 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 useMemo et useCallback pour é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
    1. Hook contrôleur (useFeatureController) pour les états, appels API, calculs dérivés.
    2. Sous-composants présentateurs pour découper l'UI (sections, cartes, listes).
    3. 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).
  • 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, AdminBlockchain ont 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 de HydratableClass.

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-function déclenche un warn.

  • Action :

    1. Découper immédiatement si faisable (extractions composant/service).
    2. 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.sh aprè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

  1. npm run lint (front) / npm run lint (back) / npm run lint (ressources)
  2. npm run lint:markdown (racine, pour MD032/MD033/MD040)
  3. npm run typecheck (front) / npx tsc --noEmit (back & ressources)
  4. npm run build (tous)
  5. 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 en warn pour 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

  1. Least Privilege : seules les routes/serveurs nécessaires sont exposés.
  2. Defense in Depth : validations au frontend, à l'API et au niveau ORM.
  3. Zero Trust : jamais de données "sûres" par défaut (même celles provenant d'intégrations tierces IdNot/Annuaire).
  4. No Secrets in Code : toute donnée sensible réside dans la base de configuration (system_configuration) ou les services secrets (aucun .env permanent).

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).
  • Middlewares :
    • authHandler : vérifie JWT (en-tête Authorization ou paramètre de requête token pour SSE uniquement, EventSource ne supportant pas les en-têtes), place l'utilisateur sur req.user et req.body.user. L'URL est nettoyée avant log (paramètre token supprimé). Voir docs/ARCHITECTURE.md et docs/API.md.
    • activeOfficeInjector : injecte req.activeOfficeUid.
    • ruleHandler : s'assure que l'utilisateur dispose de la règle (resource/action).
  • Multi-office : FolderInformation & API utilisent folder_office_uid + folder_sharings. Aucun fallback vers office_uid direct.

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 : utiliser parseQueryParam<T>(req.query["q"], "GET /...") (voir #Common/utils/jsonHelpers.ts) pour tout parsing de req.query["q"]. Ne jamais utiliser JSON.parse(req.query["q"]) directement (risque de crash et de prototype pollution).
  • Prisma : aucun where construit à la main sans sanity-check (Obligation : deleted_at: null pour 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érifier folder_uid et third_party_uid. Aucun accès ne doit être accordé sans double filtre (folder + user).
  • Ancrage : l'état tx_id est la seule preuve (pas de status = ANCHORED sans TX).

Antivirus Uploads

  • AntivirusService (Node) contacte clamav via 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é → 400 ErrorMessages.FILE_INFECTED (aucun fallback).
    • Timeout / indispo ClamAV → 500 via handleInternalError (upload interrompu).
  • Tous les services de fichiers (FilesService, FilesNotaryService, copies buffer) appellent AntivirusService avant 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_uid plutôt que des ids en clair.
  • Invités : DefaultCustomerDashboard devient la seule vue (pas de fallback notaire). Tout bouton/action doit vérifier rolePermissionsStore.can(...).

API Calls

  • Passer par BaseApiService (ajoute Authorization + logger).
  • Jamais de fetch direct (ex: fetch("/api/v1/...")).
  • Gestion d'erreurs utilisateur : ToasterService, jamais de alert() 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 dangerouslySetInnerHTML uniquement 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.cookie n'est jamais manipulé en direct (uniquement via AuthService).

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 never ou any sont 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

  1. npm run lint + npm run typecheck sur les modules modifiés.
  2. Vérifier que les logs ne divulguent aucune data sensible.
  3. Ajouter/Mettre à jour la doc (ce document pour la dette, section Sécurité du Code et README.md si nouvelles surfaces).
  4. Vérifier que toute nouvelle route tierce utilise folder.uid + third_party.uid (pas d'identifiant libre).
  5. Pour les parcours invités : s'assurer que DefaultCustomerDashboard est 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é


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és
  • lecoffre-back-main/src/common/utils/errorLoggers.ts : Patterns de logging standardisés
  • lecoffre-back-main/src/common/utils/errorHandlers.ts : Gestion HTTP centralisée
  • lecoffre-back-main/src/common/system/controller-pattern/BaseController.ts : Toutes les méthodes http* 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 interne
  • handleValidationError(response, error, req?, operation?) : Gère et répond à une erreur de validation
  • handleNotFoundError(response, message?, req?, operation?) : Gère et répond à une erreur 404
  • handleForbiddenError(response, message?, req?, operation?) : Gère et répond à une erreur 403
  • handleBadRequestError(response, message?, req?, operation?) : Gère et répond à une erreur 400
  • logError(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-admin
  • extractUserData(bodyUser, authUser, permissionContext) : Extrait et normalise les données utilisateur
  • getStringFromRecord(record, key) : Extrait une valeur string d'un record
  • getBooleanFromRecord(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) : Extrait antivirus_scan_at de proof_data.document
  • isProofDataComplete(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 :

  1. Hook contrôleur (useFeatureController) : Gère les états, appels API, calculs dérivés
  2. Sous-composants présentateurs : Découpent l'UI en sections logiques
  3. 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_TYPE
  • statusHelpers.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.ts pour 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 :

  • documentsNotaryPostHydrationHelper pour DocumentsNotary
  • documentsPostHydrationHelper pour Documents

Règles :

  1. Ne pas reconstruire localement une sortie plain avec instanceToPlain + merge manuel dans les controllers/helpers.
  2. Utiliser les fonctions build*PlainWithRelations / hydrate*ToPlainWithRelations pour les listes et mono-entités.
  3. Conserver les garde-fous log*FilesGuard pour détecter les incohérences de files.
  4. Toute nouvelle route documents doit réutiliser ces orchestrateurs.
  5. Pour Documents côté admin / super-admin, les flux update, refuse et delete doivent retourner un plain construit via documentsPostHydrationHelper (pas de hydrateEntity retourné directement).
  6. Pour les suppressions Documents (notary, admin, super-admin), utiliser le helper commun buildDeletedDocumentPlainResponse pour réinjecter document_type sans duplication locale.
  7. Pour les récupérations mono-entité Documents destinées à une réponse API, utiliser fetchDocumentWithResponseInclude afin dunifier include (document_type + include demandé) et éviter la duplication de getByUid(..., { document_type: true }).
  8. Pour transformer une entité Documents récupérée en payload API mono-entité, utiliser buildPlainFromFetchedDocument pour centraliser hydrateEntity + buildSingleDocumentPlainWithRelations.
  9. Pour les flux mono-entité update/refuse/restore/delete, utiliser buildPlainResponseWithOptionalSourceDocumentType pour unifier la réinjection optionnelle de document_type (source explicite si présente, sinon entité courante).
  10. Pour DocumentsNotary mono-entité, utiliser buildDocumentNotaryPlainResponseWithOptionalSource pour homogénéiser le rendu plain (source optionnelle + réinjection fichiers).
  11. Pour les contrôleurs Documents mono-entité (admin/super-admin/notary), privilégier fetchDocumentPlainOrHandleNotFound quand le flux suit le pattern fetch + not found + build plain.
  12. Pour les contrôleurs DocumentsNotary mono-entité, privilégier fetchDocumentNotaryPlainOrHandleNotFound avec withDocumentNotaryResponseInclude afin dimposer linclude de réponse et standardiser le not found.
  13. Pour les validations not found + deleted sur Documents, réutiliser createValidateDocumentNotDeletedCallback plutôt que redéfinir des closures locales.
  14. Pour les règles daccès DocumentsNotary en mono-entité, utiliser createDocumentNotaryAccessValidator en callback réutilisable afin déviter la duplication verify...Access entre contrôleurs.
  15. Pour la visibilité/état DocumentsNotary (statut métier, présence de fichiers visibles), utiliser createDocumentNotaryVisibilityStateValidator et linjecter dans fetchDocumentNotaryPlainOrHandleNotFound.
  16. Préférer le preset createDocumentsNotarySentOrDownloadedVisibilityValidator pour les routes de consultation/téléchargement DocumentsNotary (customer/notary) afin déviter la répétition des allowedStatuses.
  17. Pour les endpoints de téléchargement DocumentsNotary, utiliser le preset createDocumentsNotaryDownloadVisibilityValidator (requireAtLeastOneNonArchivedFile: true) afin de mutualiser la règle “document téléchargeable” (statut + au moins un fichier non archivé).
  18. Pour les flux fallback Documents (routes DocumentsNotary qui basculent sur la table Documents) et les contrôles transverses, utiliser les helpers communs isDocumentSentOrDownloadedStatus / validateDocumentsSentOrDownloadedStatus (common/utils/documentsVisibilityStateHelpers.ts) afin déviter les checks locaux divergents.
  19. Pour les usages métier où VALIDATED, SENT et DOWNLOADED sont traités comme “document validé/exploitable” (naming/ZIP/export), utiliser isDocumentValidatedOrSentOrDownloadedStatus afin 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) : inclure emitter avec contact et folder avec stakeholders dans 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_notary ou documents.
  • 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.

  1. 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 via createDocumentNotaryAccessValidator (voir documentsNotaryValidatorsHelpers.ts) : les helpers (DocumentsNotaryGetOneByUidHelper, DocumentsNotaryMarkAsViewedHelper, DocumentsNotaryCaseHandlers) fournissent un callback validateAccess qui peut s'appuyer sur ce service.
  2. Middlewares : DocumentAccessValidationHelper (OfficeMembershipHandlers), FileHandlerAccessHelpers.validateDocumentAccess / validateFileAccess, DocumentHandlerAccessByUidHelper — chargent le document, vérifient l'accès au dossier via ensureFolderAccess et 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 »). DocumentsQueryHelper et 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) et UserContext (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ème
  • docs/DEPLOYMENT.md : Guide de déploiement
  • docs/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