ia_dev/projects/lecoffreio/docs/Code-Standards.md
Nicolas Cantu dd9f5e6188 docs(lecoffreio): sync project docs from LeCoffre repository
**Motivations:**
- Keep projects/lecoffreio/docs aligned with lecoffre_ng_test docs for push-by-script prerequisites

**Root causes:**
- N/A

**Correctifs:**
- N/A

**Evolutions:**
- Sync Code-Standards.md and related copies from project docs/

**Pages affectées:**
- projects/lecoffreio/docs/
2026-03-23 13:07:07 +01:00

173 lines
20 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Code-Standards Lint, refactors, rôles et droits
**Auteur** : Équipe 4NK
## Lint backend (lecoffre-back-main) refactors restants
Après `npm run lint:fix`, les erreurs ESLint non auto-fixables sont traitées par refactors ciblés. Règles concernées (sans contournement ni désactivation) :
- **max-params** : regrouper les paramètres en objet doptions typé.
- **max-lines-per-function** : extraire sous-fonctions ou helpers.
- **max-lines** : découper les fichiers en modules plus petits (helpers, sous-services).
- **complexity** : simplifier les conditions, extraire des branches en fonctions.
### Corrections déjà réalisées (exemples)
- `FilesNotaryController` : constructeur 5→4 params via objet de dépendances (@Service).
- `ExecuteFilesNotaryDownloadOptions` pour réduire le nombre de paramètres.
- `NotificationBuilder` : 5→4 params via deps.
- `OfficeFoldersGetOneByUidHydrationHelper`, `OfficeRibGetHelper`, `FolderHandler`, `FolderNotaryAIIncludeHelper` : réduction complexité/lignes via extraction de helpers.
- `DatabaseOperationHelper` : `executeWithTimeoutAndRetry` et helpers en objet doptions.
- Variables inutilisées supprimées ; types extraits (`UserHydrated`) ; extraction de fonctions de log et de validation (`getEmailHintForLog`, `validateFolderNumberStep`, `hasSameOfficeAccess`, `checkSharingAccess`, etc.).
### À faire (refactors lourds)
- `validationHelpers.ts` : `validateRequestBody`, `validateQueryParams`, `validateEntity` (56 params) → objet doptions ; mettre à jour tous les appels.
- Fichiers > 250 lignes : découpage en modules (DocumentAccessValidationHelper, RulesHandler, DocumentEmailService, etc.).
- Fonctions > 40 lignes et complexité > 10 : extraction systématique (FolderNotaryAIController, FolderNotaryAIContextBuilder, decisionHandlers, ruleMatcher, EmailBuilder, services notary/common).
- Constructeurs et méthodes > 4 paramètres : classes @Service de dépendances ou types doptions.
Vérification : `npm run lint`, `npm run lint:fix` dans lecoffre-back-main. Référence : `.cursor/rules/cloture-evolution.mdc`, agent fix-lint.
### Historique des correctifs lint (batches)
- **max-params via option objects (backend)** : ruleMatcher, decisionHandlers, RulesHandler ; EmailBuilder, NotificationEmailService, ThirdPartyEmailService, DocumentEmailService, DocumentEmailBatchHelper ; ConnectionPoolMonitor, AntivirusService, WatermarkService, DocumentRemindersService, FolderAnchorCertificatePdfHelpers, OfficesRibService, DocumentAnchorsBatchHelper, ZipService, OfficeFoldersRepository, etc. Backend 361 → 311 errors.
- **Batch 50+ (max-params, max-lines-per-function)** : AggregatedCertificatePdf*Helpers, ZipFileContextBuilder, RulesHelper, ConnectionPoolMonitor, MergedFileCreationHelper, DocumentWithMergedFilesHelper, OfficeFolderAnchorsService, AffiliationSyncRattachementHelper, FolderSearchService, OfficesRibService, UserOfficeAffiliationsGuestFoldersHelper, DocumentAnchorsBatchHelper, ZipPdfMetadataHelper, DocumentBatchCleanupHelper. Backend 312 → 284.
- **Batch 75 (2026-03)** : N0 = 170 → objectif ≥ 75 corrigées. Batch 1 : explicit return type (ProcessingStepsAggregate), max-lines (extractions ThirdPartyCodeDevLogger, OfficeFolderAnchorsReadmeSections, V1ToV2MergeConstants, FolderSearchFormatHelper, OfficesRibUtils, etc.), max-params (DocumentAnchorsBatchHelper, DocumentBatchCreationHelper options). Batch 2 : max-params (EmailBuilder, AuthService, ZipService, FileProcessingService, FilesNotaryService, DocumentAnchorsService, DocumentWithMergedFilesHelper, OfficeFoldersController handlers, NotificationEmailService, AntivirusService, DocumentAnchoringBlockchainHelper, IdNotOfficeService, OfficeFolderAnchorsService, FileProcessingStepHelper, FilesService, DocumentAnchoringFinalizationHelper, AggregatedCertificateService, IdNotService, CustomersService, NotaryFolderAIService, etc.), max-lines (extractions ThirdPartyUploadPermissionHelper, HealthChecksServiceUtils, HealthChecksServiceAnchorHelper, UserOfficeAffiliationsLicenseFilterHelper, IdNotDirectoryApiSearchHelper, DocumentBatchAnchoringErrorHelper, etc.), complexity et max-lines-per-function (helpers dans DocumentAnchoringFinalizationHelper, DocumentBatchProofDataHelper, IdNotRoleService, MailchimpService, RolePermissionsMatrixService, FolderBusinessService, OfficeFolderAnchorsVerificationHelper, CollaboratorsAggregationService, WatermarkBufferProcessorHelper, MailchimpEmailSenderHelper, IpfsService, IdNotDirectoryService, DeedTypeListSettingsService, DocumentRemindersService, DocumentAnchoringWatermarkHelper, AnchorCertificatePdfDrawingHelpers, IdNotSiteBaseSearchHelper, DocumentWithMergedFilesHelper). N_final = 85, 76 corrigées, objectif atteint. Reste 85 erreurs (max-lines, complexity) ; poursuivre avec option objects et extractions.
- **validationHelpers, userHelpers, FolderSharingSearchHelper** : ValidateRequestContext ; validateRequestBody/validateQueryParams/validateEntity(context) ; extractUserData → extractPayloadStrings, computeExtractedUserFields, getOfficeAndIdentityFields ; searchOffices → runOfficeSearch, logOfficeSearchResult, sendOfficeSearchUnconfiguredResponse ; getUserIdFromRequest → getUserIdFromPermissionContext, getUserIdFromBodyOrRequestUser. Backend 364 → 361.
- **FolderNotaryAIController, FolderNotaryAIContextBuilder** : buildMembersSummary, buildDocumentsSummary, getDocumentTypesForDeed ; rejectIfThirdPartyUser, getUidAndQuestion, executePostAiQuestionBody, executeGetAiResponseBody, sendAiResponseResult. Backend 370 → 364.
- **Frontend (unused vars, return types)** : useConfreresManager (_folderUid), useThirdPartiesData (_currentThirdPartyUid) ; FolderListStatsPanel, DocumentTables, useSyncV1Status, OfficeInformations, _document.tsx types explicites. Frontend 1010 → 1001 warnings.
- **Objectif 27 (2026-03-18)** : FileMergeService (FileMergeMetadataPageHelper), DocumentBatchProcessingHelper (Types, DocumentBatchSharedOfficeHelper), FolderBusinessService (FolderBusinessServiceWhereBuilder), WatermarkService (Types, WatermarkNotaryFlowHelper), RulesHandler (RulesHandlerEvaluation, RulesHandlerFallback, RulesHandlerTypes). N0 = 27 → N_final = 22 (5 corrigées). Reste : appliquer le même type dextraction aux 22 fichiers restants.
- **Objectif 75 (session 2026-03-18)** : max-params (RolePermissionsMatrixService, WatermarkBufferProcessorHelper), max-lines (IdNotApiService/IdNotApiTypes, OfficeFolderAnchorsService/OfficeFolderAnchorsRegenerateHelper, DocumentsService/DocumentsServiceTypes, DocumentAnchoringFinalizationHelper/Types), complexity (MailchimpEmailSenderHelper, AnchorCertificatePdfDrawingHelpers, IdNotRoleService). N0 = 85 → N_final = 77 (8 corrigées). Objectif 75 non atteint ; poursuivre batches (max-lines, complexity, max-lines-per-function). Modalités : `cd lecoffre-back-main && npm run lint`.
- **fix-lint (2026-03-19)** : Priorité amont (config qualité + bypass). Frontend : lot 1 (exhaustive-deps useOfficeMembers, max-depth documentDownloadHelpers via tryCriticalErrorSessionFailure), lot 2 (downloadMultipleFiles → DownloadMultipleFilesOptions, processResponse/handleResponseText → options/context). Bypass : 1 supprimé (frontend), justifiés documentés par périmètre (voir section « Configuration qualité et inventaire des bypass » ci-dessous). N0 frontend ≈ 1004 → 996 warnings.
---
## Exécution exhaustive des agents lancés
Tout agent sous `.cursor/agents` doit veiller à l'exécution exhaustive des agents qu'il lance (ou des phases qu'il exécute) : vérification avant clôture ; en cas d'incomplétude : pas de clôture, documenter les manques, améliorer les instructions, relancer jusqu'à exécution exhaustive.
- **Agents de délégation** (agent-loop, fix, evol, docupdate, push-by-script, fix-search, deploy-by-script, fix-lint, gitea-issues-process, code, branch-align-by-script-from-test, change-to-all-branches, deploy-pprod-or-prod, notary-ai-process, notary-ai-loop) : section « Exécution exhaustive des agents lancés » avec vérification obligatoire avant clôture ; en cas d'incomplétude : 1) ne pas clôturer et documenter, 2) améliorer les instructions, 3) relancer l'agent concerné.
- **Agent E2E** (e2e-lecoffre-notary-full) : même logique appliquée aux phases 1 à 12 du scénario.
Aucun déploiement applicatif ; prise en compte à la prochaine invocation des agents.
---
## Vérifications rôles et droits (import v1, offices, notaire invité)
- **Import v1 rôles et droits dossiers/offices** : vérification que limport v1 préserve les rôles et droits sur les dossiers et offices (verification-import-v1-roles-et-droits-dossiers-offices).
- **Office notaire / notaire invité** : vérification des cas notaire titulaire vs notaire invité (verification-office-notaire-notaire-invite).
- **API annuaire idNot et requêtes** : vérification des requêtes annuaire et usage idNot (verification-api-annuaire-idnot-requetes).
Ces vérifications alimentent les tests manuels et les scripts danalyse (voir Operations.md).
---
## Configuration qualité et inventaire des bypass
**Date**: 2026-03-19
**Contexte**: Agent fix-lint projet lecoffreio — priorité amont (règles de qualité + bypass).
### Règles et exigences de qualité — état par sous-projet
#### Frontend (lecoffre-front-main)
- **ESLint** : `eslint.config.mjs` (flat config). Règles activées : `@typescript-eslint/recommended`, Prettier, `no-explicit-any` (warn), `explicit-function-return-type` (warn), `explicit-module-boundary-types` (warn), `max-lines` (250), `max-lines-per-function` (40), `max-params` (4), `max-depth` (4), `complexity` (10), `react-hooks/rules-of-hooks` (error), `react-hooks/exhaustive-deps` (warn). Plugin `unused-imports` pour variables/imports inutilisés. Aucune règle désactivée globalement.
- **TypeScript** : `tsconfig.json` avec `strict: true`, `noImplicitAny: true`, `strictNullChecks: true`.
- **Prettier** : `.prettierrc.json` présent.
#### Backend (lecoffre-back-main)
- **ESLint** : `eslint.config.mjs` (flat config). Règles en `error` : `no-explicit-any`, `explicit-function-return-type`, `explicit-module-boundary-types`, `no-non-null-assertion`, `no-require-imports`, `max-lines`, `max-lines-per-function`, `max-params`, `max-depth`, `complexity`, `max-nested-callbacks`. Plugin `unused-imports`.
- **TypeScript** : `tsconfig.json` avec `strict: true`, `noImplicitAny: true`, `strictNullChecks: true`.
- **Prettier** : `.prettierrc.json` présent.
#### Ressources partagées (lecoffre-ressources-dev)
- **ESLint** : `eslint.config.mjs` (flat config). Règles : `no-explicit-any` (error), `explicit-function-return-type` / `explicit-module-boundary-types` (off), `max-lines`, `max-lines-per-function`, `max-params`, `max-depth`, `complexity`. Pas de plugin `unused-imports` (usage de `no-unused-vars` natif).
- **TypeScript** : `tsconfig.json` avec `strict: true`, `noImplicitAny: true`.
- **Prettier** : `.prettierrc.json` présent.
Aucune config manquante ou désactivée de façon injustifiée. Les écarts (ex. return-type « off » en ressources) sont documentés ici.
### Bypass — inventaire et justification
#### Frontend
| Fichier / zone | Type | Justification ou action |
|----------------|------|-------------------------|
| `LoggerServiceClass.ts` | `/* eslint-disable no-console */` | **Justifié** : service de log dédié ; sortie console intentionnelle. |
| `Api/helpers/dynamicFactoryLoader.ts` | `/* eslint-disable @typescript-eslint/no-require-imports */` (fichier entier) | **Traité** : loader unique qui centralise tous les `require()` des factories LeCoffreApi et Auth ; les modules API (LeCoffreApi/**) et Auth/** n'ont plus de bypass et appellent `getLazyFactoryGetter(key)`. Un seul bypass restant (dans le loader) pour compatibilité Webpack/Next (lazy init, évitement TDZ). |
| Plusieurs hooks (useThirdPartiesData, useBurgerModalOfficeItems, useOfficeItemsFilter, etc.) | `// eslint-disable-next-line react-hooks/exhaustive-deps` | **À traiter** : soit ajouter les dépendances manquantes (ex. `useOfficeMembers` : ajout de `selectedOffice?.collaborators`), soit documenter l'exception (ex. `SiteTextsContext.tsx` avec commentaire explicite). |
| `SiteTextsContext.tsx` | `react-hooks/exhaustive-deps` avec commentaire | **Justifié** : commentaire indique que `preloadCacheKey` encode locale + scopes + textKeys et que le corps de l'effet utilise les valeurs courantes depuis la closure. |
**Bypass supprimés (2026-03-19)** : 1 — `useOfficeMembers.ts` : dépendance `selectedOffice?.collaborators` ajoutée au tableau de deps, suppression du besoin de bypass exhaustive-deps. 2 — `useInvitedDocuments.ts` (2026-03-19) : dépendances `currentOfficeUid`, `normalizedEmail` ajoutées au useCallback `loadDocuments` ; useEffect déclenché par `[loadDocuments]` ; suppression du `eslint-disable-next-line react-hooks/exhaustive-deps`.
**Bypass justifiés documentés** : LoggerServiceClass (no-console), SiteTextsContext (exhaustive-deps). **no-require-imports** : centralisation réalisée dans `Api/helpers/dynamicFactoryLoader.ts` ; tous les modules API (LeCoffreApi/**) et Auth (Auth/Customer, Auth/IdNot, Auth/IdNot/User) utilisent désormais `getLazyFactoryGetter(key)` ; un seul bypass reste dans le loader. Les exhaustive-deps sans commentaire restent à justifier ou corriger dans les prochains batches. Autres fichiers avec require (Stores, Toasts, etc.) : requestHelpers, headerHelpers, useApiClient, ConfigRuntime, ApiErrorHandlerService, Toasts.tsx — chargement optionnel / circulaire ; justifiés et laissés en l'état.
#### Backend
| Fichier / zone | Type | Justification ou action |
|----------------|------|-------------------------|
| `LogSanitizer.ts` | `/* eslint-disable no-console */` | **Justifié** : utilitaire de sanitization des logs, sortie console désignée. |
| `V1ToV2MergeHelper.ts` | (refactor 2026-03-19) | **Bypass supprimés** : options objects pour upsertBatch/mergeTable ; handlers dans V1ToV2MergeTableHandlers.ts ; plus aucun eslint-disable. |
| `import-stripe-subscriptions.ts` | `// @ts-expect-error` (x2) | **Justifié** : conflit de types Stripe.Subscription vs modèle local Subscription ; commentaire explicite sur place. |
**Bypass supprimés** : 1 (V1ToV2MergeHelper.ts — refactor complet).
**Bypass justifiés** : 2 (no-console, @ts-expect-error). **max-params / max-lines-per-function / complexity** : non justifiables ; tout bypass doit être supprimé et le code refactoré.
#### Ressources partagées
Aucun bypass trouvé.
### Synthèse par périmètre
- **Frontend** : bypass supprimés 1 + no-require-imports centralisés (loader unique) ; justifiés (no-console 1, exhaustive-deps 1 avec commentaire, no-require-imports 1 dans dynamicFactoryLoader uniquement). Exhaustive-deps sans commentaire : à justifier ou corriger en priorité.
- **Backend** : bypass supprimés 0 ; justifiés 2 (no-console, @ts-expect-error typage Stripe). max-params / max-lines-per-function / complexity : non justifiables, à corriger par refactor.
- **Ressources** : bypass supprimés 0 ; justifiés 0 (aucun bypass).
### Corrections effectuées (2026-03-19)
- **Lot 2 (max-params)** : useNavigationEffects, useMenuEffects, useSplashVisibility, useFolderListData (processAndSortFolders, executeFolderLoad, useFolderListLoader), useExternalFoldersBootstrap, useCustomerFoldersLoader, useFolderSelectionCallback, createOfficeItem (officeItems.tsx), useNumberPickerValue — paramètres regroupés en options objects.
- **Lot 4 (max-lines-per-function)** : SearchOfficesFactory (normalizeSearchOfficesError + doSearchOffices), SearchNotariesFactory (id.), CircleProgress (useCircleProgressAnimation), HealthFactory (buildHealthTriggers), DeedsFactory, DeedTypesFactory, DocumentTypesFactory, CustomersFactory, DocumentsFactory (SuperAdmin), SiteTextsFactory, ThirdParty DocumentsFactory, DefaultCollaboratorDashboard (loadCollaborators), DefaultDeedTypeDashboard (loadDeedTypes), DefaultDocumentTypesDashboard (loadDocumentTypes), useSubscriptionLoader (loadSubscriptionCancelState), buildConfirmModalHandlers, DepositContent (DepositDropZone), processUpload (createDocumentAndUpload), EyeWithThumbnailTooltip (THUMBNAIL_TOOLTIP_SLOT_PROPS), useDepositFileHandlers (applyFilesToPendingState), getOfficeItems (OFFICE_ITEMS_PARAMS), renderSplashModal (SplashModalCard + constantes), DefaultDashboardWithList (DashboardSidebar, DashboardRightSide).
- **no-require-imports** : non retraité cette exécution ; centralisation déjà en place (dynamicFactoryLoader.ts) comme documenté en section 2.
#### Suite fix-lint 2026-03-19 (lots 2 à 5, objectif ≥75 erreurs)
- **errorClassifiers.ts** : réduction complexité isAuthError, isNetworkError, isRetryableError (extraction getAuthStatusFromObject, hasAuthMessage, NETWORK_PATTERNS, messageHasNetworkPattern, errorNameIsNetworkOrType, is5xxStatus, getStatusFromError).
- **httpStatusHelpers.ts** : handleHttpStatusError (lignes + complexité) via tryPatternMatch, try403BackendMessage, try401403Contextual, try404Element ; extract404ElementMessage raccourcie (ELEMENT_404_NAMES en constante, try404Element réutilisé).
- **zipSingleDocumentHelpers.ts** : tryDownloadViaFilesNotaryCustomer 7 params → TryDownloadViaFilesNotaryCustomerParams ; parseSingleDocumentInput → parseFromDocument + parseFromFilesInput ; handleSingleDocumentZipDownload → tryCustomerOrInvitedNotaryPath, tryNotaryDocumentNotaryPath.
- **documentNameHelpers.ts** : getDocumentNameWithTypePriority complexité → getTypeName, getFirstFileDisplayName, getFirstFileName.
- **downloadHelpers.ts** : ensurePdfExtension complexité → isValidatedStatus, addValidatedSuffixToFileName, isPdfContentType.
- **folderHelpers.ts** : extractOfficeUid complexité → nonEmptyString, getOfficeUidFromDeed.
- **formatters.ts** : normalizePhone complexité → stripSpacesAndDots, toFrenchInternational.
- **errorExtractionHelpers.ts** : extractErrorMessage complexité → getMessageFromHttpPayload.
- **folderSharingHelpers.ts** : computeFolderSharingStatus lignes + complexité → isSharingActive, isSharingNotExpired, sharingMatchesOffice, sharingMatchesIdNot.
- **folderQueryBuilders.ts** : buildFolderListQueryParams lignes → FOLDER_LIST_INCLUDE constant.
- **useRolePermissionsControllerHelpers.ts** : logMatrixStateUpdate complexité → buildMatrixStateLogPayload.
Résultat : N0 = 754, N_final = 679, corrigées = 75 (objectif ≥75 atteint).
### max-params / max-lines-per-function / complexity : non justifiables
**Règle** : les règles `max-params`, `max-lines-per-function` et `complexity` **ne sont pas justifiables**. Aucun bypass (eslint-disable) n'est accepté pour ces règles. Le code doit être refactoré pour les respecter (options objects pour max-params, extraction de fonctions pour max-lines-per-function et complexity, split de fichiers si nécessaire).
**Action** : tout bypass existant pour ces règles doit être supprimé et le code corrigé par refactor. Fichiers concernés (liste à mettre à jour au fil des corrections) : backend `V1ToV2MergeHelper.ts` ; frontend fichiers ayant reçu un disable au niveau fichier (DeedTypeListSettingsForm, useFolderAndCustomer, OfficeInformations, InformationSection, participantTabsHelpers, documentsDataLoader, useOfficeChangeRedirect, ReminderModal, useClientDashboardDocuments, commonUiI18nPart1, commonUiI18nPart2, commonUiMessageBuilders).
### Modalités de vérification
- Lint : `npm run lint` dans chaque répertoire (lecoffre-front-main, lecoffre-back-main, lecoffre-ressources-dev).
- Compilation : `npm run build` (ou `type-check` si défini) dans chaque sous-projet.
- Bypass : `grep -r "eslint-disable\|@ts-ignore\|@ts-expect-error\|@ts-nocheck" lecoffre-*` puis vérifier chaque occurrence.
---
## Conventions projet (rappel)
- Pas de fallback implicite ; erreurs remontées et journalisées.
- Messages utilisateur en français, fonctionnels ; messages techniques (logs, codes) en anglais.
- Types de retour explicites pour les fonctions (TypeScript).
- Documentation des choix non évidents (invariants, hypothèses, contrats, cas limites).
- Respect des règles de lint et de typage sans désactivation.