docs(kogus): sync mirror from lecoffre_ng_test/docs (API, Code-Standards, Deployment, README)

This commit is contained in:
Nicolas Cantu 2026-04-21 19:47:08 +02:00
parent 359adb6816
commit afc693b058
4 changed files with 44 additions and 84 deletions

View File

@ -8,7 +8,7 @@ Ce document consolide la documentation des APIs externes utilisées par LeCoffre
### Vue d'ensemble ### Vue d'ensemble
Le backend appelle lAPI **ai_working_help** pour les opérations **ask** (legacy), **enqueue** et **getResponse**. LURL de base est configurée via `NOTARY_AI_AGENT_URL`. Le projet et lenv sont identifiés par le token Bearer ; côté **serveur ia_dev**, lAPI résout le projet en parcourant les fichiers **`projects/<id>/.secrets/<env>/ia_token`** (arborescence **ia_dev**, distincte des secrets monorepo LeCoffre sous **`<repository_root>/.secrets/<site>/<env>/`** — voir [README kogus — Chemins secrets](./README.md#chemins-secrets-monorepo-et-legacy)). Filtrage IP 192.168.1.* côté API. Le backend appelle lAPI **ai_working_help** pour les opérations **ask** (legacy), **enqueue** et **getResponse**. LURL de base est configurée via `NOTARY_AI_AGENT_URL`. Le projet et lenv sont identifiés par le token Bearer ; côté dépôt **ia_dev**, lAPI résout le projet via les fichiers secrets du projet (chemin typé **`projects/<id>/.secrets/...`** selon la convention du projet). Côté monorepo LeCoffre, les secrets nominaux sont sous **`.secrets/<site>/<env>/`** — voir **`docs/features/multi-site-architecture.md`**. Filtrage IP 192.168.1.* côté API.
### Authentification ### Authentification
@ -24,7 +24,7 @@ Le token est de la forme **base** + **env** (ex. `nicolecoffreiotest`, `nicoleco
- **POST** `{NOTARY_AI_AGENT_URL}/enqueue` — mise en file (spooler) - **POST** `{NOTARY_AI_AGENT_URL}/enqueue` — mise en file (spooler)
- **GET** `{NOTARY_AI_AGENT_URL}/response/:request_uid` — récupération de la réponse (poll) - **GET** `{NOTARY_AI_AGENT_URL}/response/:request_uid` — récupération de la réponse (poll)
Implémentation : `lecoffre-back-main/src/services/notary/NotaryFolderAIService/NotaryFolderAIService.ts`. Le header nest ajouté que si `NOTARY_AI_AGENT_TOKEN` est renseigné. Implémentation : `back-common/src/services/notary/NotaryFolderAIService/NotaryFolderAIService.ts`. Le header nest ajouté que si `NOTARY_AI_AGENT_TOKEN` est renseigné.
### Chat IA dossier notaire (endpoints applicatifs) ### Chat IA dossier notaire (endpoints applicatifs)
@ -41,6 +41,8 @@ Implémentation : `lecoffre-back-main/src/services/notary/NotaryFolderAIService/
Flux : front → backend → ai_working_help (enqueue) ; agent (boucle Cursor) produit la réponse ; front poll GET response jusquà `status !== "pending"`. Logs backend : `[NotaryFolderAIService]`, `[FolderNotaryAIController]`. Front : `[FolderNotaryAiChat]`. Flux : front → backend → ai_working_help (enqueue) ; agent (boucle Cursor) produit la réponse ; front poll GET response jusquà `status !== "pending"`. Logs backend : `[NotaryFolderAIService]`, `[FolderNotaryAIController]`. Front : `[FolderNotaryAiChat]`.
Fiche détaillée (comportement métier, workflow, table des fichiers **front / back / ia_dev**) : **`docs/features/notary-folder-ai-workflow.md`**.
### Sécurité et restrictions ### Sécurité et restrictions
Lagent ne doit jamais renvoyer RIB, coordonnées bancaires ou de paiement. Contexte envoyé : métadonnées dossier, type dacte, types de documents, résumé membres (rôle, nom, email), résumé documents (type, déposant, statut). Pas de contenu de fichier ni donnée de paiement. Lagent ne doit jamais renvoyer RIB, coordonnées bancaires ou de paiement. Contexte envoyé : métadonnées dossier, type dacte, types de documents, résumé membres (rôle, nom, email), résumé documents (type, déposant, statut). Pas de contenu de fichier ni donnée de paiement.
@ -49,7 +51,7 @@ Lagent ne doit jamais renvoyer RIB, coordonnées bancaires ou de paiement. Co
## API Annuaire V2 Recherche offices et membres (IdNot PP) ## API Annuaire V2 Recherche offices et membres (IdNot PP)
- **Recherche offices** : route `GET .../api/v2/directory/lookup` avec paramètre **nomOffice** uniquement (recherche sur loffice ; pas de mélange notaire). Retour : offices sans liste de collaborateurs. - **Recherche offices** : route `GET .../api/v2/directory/lookup` avec paramètre **nomOffice** dabord, puis **nom** si aucun office (recherche sur loffice ; pas de mélange notaire côté premier passage). Le backend pagine lannuaire jusquà épuisement des pages (plafond de sécurité ~500 pages / pass), regroupe les offices distincts, **les trie par nom détude** (`localeCompare` `fr`, sensibilité de base), puis applique `offset` / `limit` (défaut 15) pour la réponse JSON. `hasMore` : il reste des études après la fenêtre courante.
- **Membres à la sélection** : à la sélection dun office, le front appelle `GET /api/v1/notary/search/offices/:officeIdNot/members?officeName=...` ; le backend appelle IdNot `GET /api/pp/v2/entites/:officeIdNot/personnes` et retourne les membres avec **roleLabel** (typeLien IdNot : Notaire, Collaborateur, etc.). - **Membres à la sélection** : à la sélection dun office, le front appelle `GET /api/v1/notary/search/offices/:officeIdNot/members?officeName=...` ; le backend appelle IdNot `GET /api/pp/v2/entites/:officeIdNot/personnes` et retourne les membres avec **roleLabel** (typeLien IdNot : Notaire, Collaborateur, etc.).
- **Front** : `getOfficeMembers(officeIdNot, officeName)` ; hook `useOfficeMembers(selectedOffice)` ; affichage « Chargement des membres… » puis liste « Prénom Nom (roleLabel) » (ShareFolderModal, SearchConfrereSection). - **Front** : `getOfficeMembers(officeIdNot, officeName)` ; hook `useOfficeMembers(selectedOffice)` ; affichage « Chargement des membres… » puis liste « Prénom Nom (roleLabel) » (ShareFolderModal, SearchConfrereSection).
- **Référence** : API Annuaire V2 doc § VII.iii.a (nom, nomOffice, nomNotaire) ; IdNot PP entites/:id/personnes. Conformité : `docs/compliance-annuaire-idnot-specs.md`. - **Référence** : API Annuaire V2 doc § VII.iii.a (nom, nomOffice, nomNotaire) ; IdNot PP entites/:id/personnes. Conformité : `docs/compliance-annuaire-idnot-specs.md`.
@ -66,7 +68,7 @@ Lagent ne doit jamais renvoyer RIB, coordonnées bancaires ou de paiement. Co
- **PermissionDeniedMessageBuilder.ts** : messages 403 en français (office, dossier, document) ; utilisé par FolderThirdPartiesAccessHelper, DocumentsNotaryAccessHelper. - **PermissionDeniedMessageBuilder.ts** : messages 403 en français (office, dossier, document) ; utilisé par FolderThirdPartiesAccessHelper, DocumentsNotaryAccessHelper.
- **errorMessages.ts** : constantes techniques (réponses API, logique métier). - **errorMessages.ts** : constantes techniques (réponses API, logique métier).
- **errorHandlers.ts** : construction des réponses derreur, `handlePermissionDeniedError` (message du builder 403). - **errorHandlers.ts** : construction des réponses derreur, `handlePermissionDeniedError` (message du builder 403). Les **400** émis via `handleBadRequestError` / `handleBadRequestErrorJson` ont un corps JSON `{ "message", "http_status" }` (forme unique pour toutes les routes qui passent par ces helpers).
- **FolderSharingValidationHelper.ts** : messages 400 partage dossier — invitation « même cabinet » unifiée : « Vous ne pouvez pas inviter un notaire de votre propre cabinet en tant que notaire invité. Veuillez choisir un notaire d'un autre cabinet. » (chemin même office UID et chemin même cabinet par email) ; logs `[SHARE FOLDER] Tentative d'invitation vers le même cabinet` avec email invité. - **FolderSharingValidationHelper.ts** : messages 400 partage dossier — invitation « même cabinet » unifiée : « Vous ne pouvez pas inviter un notaire de votre propre cabinet en tant que notaire invité. Veuillez choisir un notaire d'un autre cabinet. » (chemin même office UID et chemin même cabinet par email) ; logs `[SHARE FOLDER] Tentative d'invitation vers le même cabinet` avec email invité.
Règle : tout message destiné à lutilisateur (ex. corps 403/400) en français et fonctionnel ; constantes et libellés centralisés dans ces modules (ou un module dédié documenté ici). Règle : tout message destiné à lutilisateur (ex. corps 403/400) en français et fonctionnel ; constantes et libellés centralisés dans ces modules (ou un module dédié documenté ici).

View File

@ -2,7 +2,7 @@
**Auteur** : Équipe 4NK **Auteur** : Équipe 4NK
## Lint backend (lecoffre-back-main) refactors restants ## Lint backend (back-common) 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) : 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) :
@ -25,9 +25,10 @@ Après `npm run lint:fix`, les erreurs ESLint non auto-fixables sont traitées p
- `validationHelpers.ts` : `validateRequestBody`, `validateQueryParams`, `validateEntity` (56 params) → objet doptions ; mettre à jour tous les appels. - `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.). - 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). - Fonctions > 40 lignes et complexité > 10 : extraction systématique (FolderNotaryAIController, FolderNotaryAIContextBuilder, decisionHandlers, ruleMatcher, EmailBuilder, services notary/common).
- **Cartographie post-refactor (login / email / tiers)** : `docs/features/login-and-email-helpers-structure.md` — à mettre à jour si de nouveaux modules sont extraits pour le lint (back + front).
- Constructeurs et méthodes > 4 paramètres : classes @Service de dépendances ou types doptions. - 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 : `.smartIde/rules/cloture-evolution.mdc`, agent fix-lint. Vérification : `npm run lint`, `npm run lint:fix` dans back-common. Référence : `.cursor/rules/cloture-evolution.mdc`, agent fix-lint.
### Historique des correctifs lint (batches) ### Historique des correctifs lint (batches)
@ -38,16 +39,16 @@ Vérification : `npm run lint`, `npm run lint:fix` dans lecoffre-back-main. Réf
- **FolderNotaryAIController, FolderNotaryAIContextBuilder** : buildMembersSummary, buildDocumentsSummary, getDocumentTypesForDeed ; rejectIfThirdPartyUser, getUidAndQuestion, executePostAiQuestionBody, executeGetAiResponseBody, sendAiResponseResult. Backend 370 → 364. - **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. - **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 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`. - **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 back-common && 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. - **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 ## Exécution exhaustive des agents lancés
Tout agent sous `.smartIde/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. 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, git-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é. - **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 / `e2e-test`) : même logique sur les phases applicables — 112 en test/pprod ; 17 et 911 en prod (sans notaire invité). Prérequis **user-profil** documenté dans `docs/features/user-profil-and-e2e-environments.md`. - **Agent E2E** (e2e-lecoffre-notary-full / `e2e-test`) : même logique sur les phases applicables — 112 en test/pprod ; 17 et 911 en prod (sans notaire invité). Prérequis **user-profil** documenté dans `docs/features/user-profil-and-e2e-environments.md`.
Aucun déploiement applicatif ; prise en compte à la prochaine invocation des agents. Aucun déploiement applicatif ; prise en compte à la prochaine invocation des agents.
@ -67,29 +68,30 @@ Ces vérifications alimentent les tests manuels et les scripts danalyse (voir
## Configuration qualité et inventaire des bypass ## Configuration qualité et inventaire des bypass
**Date**: 2026-03-19 **Date**: 2026-03-19
**Contexte**: Agent fix-lint projet **kogus** (monorepo LeCoffre) — priorité amont (règles de qualité + bypass). **Contexte**: Agent fix-lint projet lecoffreio — priorité amont (règles de qualité + bypass).
### Règles et exigences de qualité — état par sous-projet ### Règles et exigences de qualité — état par sous-projet
#### Frontend (lecoffre-front-main) #### Frontend (front-common)
- **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. - **ESLint** : `eslint.config.mjs` (flat config). Règles en `error` (hors désactivations documentées) : `no-explicit-any`, `explicit-function-return-type`, `explicit-module-boundary-types`, `max-lines` (250), `max-lines-per-function` (40), `max-params` (4), `max-depth` (4), `complexity` (10), `max-nested-callbacks` (3), `no-console`, `react/no-unescaped-entities`, `react-hooks/rules-of-hooks`, `react-hooks/exhaustive-deps`. Plugin `unused-imports` pour variables/imports inutilisés. Exécution : `scripts/run-lint.mjs` avec **`--max-warnings 0`** (tout warning fait échouer la commande).
- **TypeScript** : `tsconfig.json` avec `strict: true`, `noImplicitAny: true`, `strictNullChecks: true`. - **TypeScript** : `tsconfig.json` avec `strict: true`, `noImplicitAny: true`, `strictNullChecks: true`.
- **Prettier** : `.prettierrc.json` présent. - **Prettier** : `.prettierrc.json` présent.
#### Backend (lecoffre-back-main) #### Backend (back-common)
- **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`. - **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`, `no-console`, `max-lines`, `max-lines-per-function`, `max-params`, `max-depth`, `complexity`, `max-nested-callbacks`. Plugin `unused-imports`. Script `npm run lint` : **`--max-warnings 0`**.
- **TypeScript** : `tsconfig.json` avec `strict: true`, `noImplicitAny: true`, `strictNullChecks: true`. - **TypeScript** : `tsconfig.json` avec `strict: true`, `noImplicitAny: true`, `strictNullChecks: true`.
- **Prettier** : `.prettierrc.json` présent. - **Prettier** : `.prettierrc.json` présent.
- **Texte derreur pour logs / interpolation** : utiliser **`coalesceThrownErrorText`** depuis `#Common/utils/coalesceThrownErrorText` à la place de `x instanceof Error ? x.message : String(x)` (y compris pour des jetables `{ message }` non-`Error`). **`back-admin`** expose la même logique dans `back-admin/src/coalesceThrownErrorText.ts` (pas de dépendance npm vers `back-common`).
#### Ressources partagées (lecoffre-ressources-dev) #### Ressources partagées (ressources-common)
- **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). - **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-console`, `max-lines`, `max-lines-per-function`, `max-params`, `max-depth`, `complexity`, `max-nested-callbacks`. Plugin **`unused-imports`** (aligné backend/front : `@typescript-eslint/no-unused-vars` désactivé au profit de `unused-imports/no-unused-imports` et `unused-imports/no-unused-vars`). Script `npm run lint` : **`--max-warnings 0`**.
- **TypeScript** : `tsconfig.json` avec `strict: true`, `noImplicitAny: true`. - **TypeScript** : `tsconfig.json` avec `strict: true`, `noImplicitAny: true`.
- **Prettier** : `.prettierrc.json` présent. - **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. Aucune config manquante ou désactivée de façon injustifiée. Exceptions locales ciblées dans `eslint.config.mjs` (fichiers précis) : voir tableau ci-dessous.
### Bypass — inventaire et justification ### Bypass — inventaire et justification
@ -97,7 +99,7 @@ Aucune config manquante ou désactivée de façon injustifiée. Les écarts (ex.
| Fichier / zone | Type | Justification ou action | | Fichier / zone | Type | Justification ou action |
|----------------|------|-------------------------| |----------------|------|-------------------------|
| `LoggerServiceClass.ts` | `/* eslint-disable no-console */` | **Justifié** : service de log dédié ; sortie console intentionnelle. | | `LoggerServiceClass.ts` | Override `eslint.config.mjs` : `no-console` **off** pour ce fichier | **Justifié** : seul point de sortie console autorisé dans le bundle navigateur. |
| `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). | | `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). | | 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. | | `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. |
@ -110,7 +112,7 @@ Aucune config manquante ou désactivée de façon injustifiée. Les écarts (ex.
| Fichier / zone | Type | Justification ou action | | Fichier / zone | Type | Justification ou action |
|----------------|------|-------------------------| |----------------|------|-------------------------|
| `LogSanitizer.ts` | `/* eslint-disable no-console */` | **Justifié** : utilitaire de sanitization des logs, sortie console désignée. | | `LogSanitizer.ts` | Override `eslint.config.mjs` : `no-console` **off** pour ce fichier | **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. | | `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. | | `import-stripe-subscriptions.ts` | `// @ts-expect-error` (x2) | **Justifié** : conflit de types Stripe.Subscription vs modèle local Subscription ; commentaire explicite sur place. |
@ -157,7 +159,7 @@ Résultat : N0 = 754, N_final = 679, corrigées = 75 (objectif ≥75 atteint).
### Modalités de vérification ### Modalités de vérification
- Lint : `npm run lint` dans chaque répertoire (lecoffre-front-main, lecoffre-back-main, lecoffre-ressources-dev). - Lint : `npm run lint` dans chaque répertoire (front-common, back-common, ressources-common). Les trois scripts passent **`--max-warnings 0`** : aucun warning ESLint ne doit rester.
- Compilation : `npm run build` (ou `type-check` si défini) dans chaque sous-projet. - 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. - Bypass : `grep -r "eslint-disable\|@ts-ignore\|@ts-expect-error\|@ts-nocheck" lecoffre-*` puis vérifier chaque occurrence.

View File

@ -2,23 +2,6 @@
**Auteur** : Équipe 4NK **Auteur** : Équipe 4NK
## Source de vérité multisite (dépôt LeCoffre)
La documentation **canonique** multisite (architecture, secrets imbriqués **`.secrets/<site>/<env>/`**, **`.secrets/kogus/<env>/`**, manifeste, runbooks, politique données LeCoffre ↔ **ia_dev**) est versionnée dans le dépôt applicatif dont `conf.json` expose **`deploy.repository_root`** (clone **LeCoffre** / **kogus** sur Gitea).
- Politique données : **`docs/features/multisite-data-policy-lecoffre-vs-ia-dev.md`** sur la branche suivie (ex. **test**).
- Checklist opérateur : **`docs/features/multisite-operator-master-checklist.md`**.
- Snippet wiki à publier : **`docs/features/wiki-deployment-multisite-snippet.md`**.
- Fichier aligné sur ce miroir : **`docs/Deployment.md`** (racine du clone LeCoffre).
URL type (adapter branche) : `https://git.4nkweb.com/4nk/kogus/src/branch/test/docs/features/multisite-data-policy-lecoffre-vs-ia-dev.md`.
Les sections suivantes reprennent le contenu de **`docs/Deployment.md`** du clone LeCoffre. Les chemins **`.md`** et répertoires **`.secrets/...`** ci-dessous sont relatifs à **la racine Git du dépôt LeCoffre** (`repository_root`), pas à la racine du dépôt **ia_dev**.
En cas de divergence entre ce fichier et le dépôt LeCoffre, **priorité au dépôt LeCoffre**.
---
## Vérification site_texts (seeds, env, boot) ## Vérification site_texts (seeds, env, boot)
Objectif : aligner les clés site_texts entre seeds, env et boot (test, pprod, prod). Objectif : aligner les clés site_texts entre seeds, env et boot (test, pprod, prod).
@ -29,7 +12,7 @@ Les clés du seed `seed-site-texts-<env>.ts` (champ `textKey`) doivent être exa
Chemins : Chemins :
- **Multi-site (préféré)** : `.secrets/<site_dir>/<env>/…` (ligne notaire : **`.secrets/lecoffreio/test/`** avec **`SITE_CODE=lecoffreio`** côté processus / BDD ; voir **`docs/features/secrets-multisite-kogus-and-sites.md`**). - **Multi-site (préféré)** : `.secrets/<site_dir>/<env>/…` (ligne notaire : **`.secrets/lecoffreio/test/`** avec **`SITE_CODE=lecoffreio`** côté processus / BDD ; voir **`docs/features/secrets-multisite-kogus-and-sites.md`**). **connectDB** orchestrateur : **`.secrets/kogus/<env>/`** ; pour lexport local **`export-db-artifacts`**, dupliquer le connectDB **lecoffreio****kogus** si besoin (même doc).
- **Legacy** (checkout non migré) : `.secrets/<env>/…` (ex. `.secrets/test/`). - **Legacy** (checkout non migré) : `.secrets/<env>/…` (ex. `.secrets/test/`).
**Commandes** : **Commandes** :
@ -57,7 +40,7 @@ Mêmes clés site_texts sur les trois environnements ; seuls les contenus peuven
- **Cible** : pour les clés dont le `textKey` commence par `thirdParty.` (ex. `thirdParty.roleLabel.courtier`), le champ **`scope`** en base et dans `seed-site-texts-<env>.ts` doit être exactement **`thirdParty`** (camelCase), comme dans `defaultSiteTextFallbacks.ts`. Le préfixe API publique utilise ce même identifiant : `GET .../site-texts?scope=thirdParty,...`. - **Cible** : pour les clés dont le `textKey` commence par `thirdParty.` (ex. `thirdParty.roleLabel.courtier`), le champ **`scope`** en base et dans `seed-site-texts-<env>.ts` doit être exactement **`thirdParty`** (camelCase), comme dans `defaultSiteTextFallbacks.ts`. Le préfixe API publique utilise ce même identifiant : `GET .../site-texts?scope=thirdParty,...`.
- **À ne pas confondre** : les clés **`forms.thirdParty.*`** (formulaire édition tiers) restent en scope **`forms`**. La variante UI `THIRD_PARTY_UI_VARIANT = "third-party"` (tiret) concerne le parcours / laffichage membre, **pas** le scope `site_texts`. - **À ne pas confondre** : les clés **`forms.thirdParty.*`** (formulaire édition tiers) restent en scope **`forms`**. La variante UI `THIRD_PARTY_UI_VARIANT = "third-party"` (tiret) concerne le parcours / laffichage membre, **pas** le scope `site_texts`.
- **Vérification en lecture seule** (sur la base V2 de lenvironnement) : le script **ne se connecte pas à une base locale** ; il copie le SQL et un runner sur le **serveur de déploiement** (SSH, même mécanisme que `scripts/e2e-verify-db-env.sh`), puis exécute `psql` **sur la cible** en utilisant le fichier connectDB résolu sur la cible (canonique imbriqué `.secrets/<site_code>/<env>/.env.<env>.connectDB`, orchestrateur **`.secrets/kogus/<env>/.env.<env>.connectDB`**, ou legacy `deploy/.env.<env>.connectDB`, comme `resolve_connect_db_path_on_target` / `import-v1.sh`) **présent sur ce serveur** (`DATABASE_HOST=db``127.0.0.1` côté cible). - **Vérification en lecture seule** (sur la base V2 de lenvironnement) : le script **ne se connecte pas à une base locale** ; il copie le SQL et un runner sur le **serveur de déploiement** (SSH, même mécanisme que `scripts/e2e-verify-db-env.sh`), puis exécute `psql` **sur la cible** en utilisant le fichier connectDB résolu sur la cible (canonique imbriqué `.secrets/<site_code>/<env>/.env.<env>.connectDB`, ou legacy orchestrateur `deploy/.env.<env>.connectDB`, comme `resolve_connect_db_path_on_target` / `import-v1.sh`) **présent sur ce serveur** (`DATABASE_HOST=db``127.0.0.1` côté cible).
```bash ```bash
./scripts/verify-site-texts-thirdparty-scope-readonly.sh <test|pprod|prod> ./scripts/verify-site-texts-thirdparty-scope-readonly.sh <test|pprod|prod>
@ -98,14 +81,14 @@ Liste des fichiers contenant les textes affichés à lutilisateur (libellés,
## Déploiement applicatif ## Déploiement applicatif
- **Multi-site (runbook)** : ordre **test** → préparation **pprod/prod**, migrations Prisma, smoke `site-config`**`docs/features/multi-site-deploy-runbook.md`** ; snippet wiki **`docs/features/wiki-deployment-multisite-snippet.md`**. - **Multi-site (runbook)** : ordre **test** → préparation **pprod/prod**, migrations Prisma, smoke `site-config`[`features/multi-site-deploy-runbook.md`](./features/multi-site-deploy-runbook.md). Snippet à intégrer à la page wiki **Deployment** : [`features/wiki-deployment-multisite-snippet.md`](./features/wiki-deployment-multisite-snippet.md).
- **Admin local (exports / imports secrets par site, sans déploiement)** : **`docs/features/secrets-devai-kogus-sites-and-imports.md`** — couches dev_ai / kogus / site, API `back-admin`, UI `front-admin`, fichiers matrice et catalogues actes. - **Admin local (exports / imports secrets par site, sans déploiement)** : [`features/secrets-devai-kogus-sites-and-imports.md`](./features/secrets-devai-kogus-sites-and-imports.md) — couches dev_ai / kogus / site, API `back-admin`, UI `front-admin`, fichiers matrice et catalogues actes.
- **Orchestration ia_dev** : depuis la racine du dépôt ia_dev, `./deploy/deploy.sh <project_id> <env> [options]` exporte `IA_PROJECT_ID` puis exécute `orchestrator.sh`. Celui-ci enchaîne les scripts listés dans `deploy.hooks.phases` du `conf.json` du projet (chemins relatifs à `repository_root`), ou exécute `deploy.deploy_script_path` si `phases` est vide. `run-project-hooks.sh` délègue à `orchestrator.sh` (compatibilité). Cadrage : `deploy/DEPLOY_ORCHESTRATION_IA_DEV.md` (fichier dans le dépôt **ia_dev**). - **Orchestration ia_dev** : depuis la racine du dépôt ia_dev, `./deploy/deploy.sh <project_id> <env> [options]` exporte `IA_PROJECT_ID` puis exécute `orchestrator.sh`. Celui-ci enchaîne les scripts listés dans `deploy.hooks.phases` du `conf.json` du projet (chemins relatifs à `repository_root`), ou exécute `deploy.deploy_script_path` si `phases` est vide. `run-project-hooks.sh` délègue à `orchestrator.sh` (compatibilité). Cadrage : `deploy/DEPLOY_ORCHESTRATION_IA_DEV.md`.
- **Scripts** : `deploy/scripts_v2/` ; chemin projet dans ia_dev `projects/kogus/conf.json` (project_path, build_dirs, deploy.deploy_script_path, deploy.secrets_path). - **Scripts** : `deploy/scripts_v2/` ; chemin projet dans ia_dev `projects/kogus/conf.json` (project_path, build_dirs, deploy.deploy_script_path, deploy.secrets_path).
- **Clé SSH déploiement (`DEPLOY_SSH_KEY`)** : définie dans `.secrets/<site_code>/<env>/.env.<env>` (layout imbriqué obligatoire pour le multisite ; migration depuis lancien plat : `SITE_CODE=lecoffreio bash deploy/scripts_v2/sites/lecoffreio/migrate-secrets-legacy-to-nested-lecoffreio.sh <env>…>` depuis la racine du monorepo LeCoffre ; gabarits locaux optionnels : `node deploy/scripts_v2/nested-secrets-tool.mjs materialize` — alias : `materialize-nested-secrets-mandatory.mjs`). Utiliser un chemin **portable** : par ex. `DEPLOY_SSH_KEY='$HOME/.ssh/id_ed25519_4nk'` (lexpansion de `$HOME`, `${HOME}` et un préfixe `~/` est appliquée par `lecoffre_deploy_resolve_deploy_ssh_key` après `load_dotenv_file_strict`, qui ne fait pas d`eval`). Ne pas figer un autre compte système (`/home/desk/...`). Ordre de repli si la clé indiquée est absente : `$HOME/.ssh/id_ed25519_4nk`, puis `$HOME/.ssh/id_ed25519`. Avant toute connexion SSH, la clé retenue est validée avec `ssh-keygen -y`. Vérification réseau : `bash deploy/scripts_v2/run-verify-ssh.sh <env>` ou les trois dun coup : `bash deploy/scripts_v2/run-verify-ssh-all-envs.sh`. - **Clé SSH déploiement (`DEPLOY_SSH_KEY`)** : définie dans `.secrets/<site_code>/<env>/.env.<env>` (layout imbriqué obligatoire pour le multisite ; migration depuis lancien plat : `SITE_CODE=lecoffreio bash deploy/scripts_v2/sites/lecoffreio/migrate-secrets-legacy-to-nested-lecoffreio.sh <env>…>` ; gabarits locaux optionnels : `node deploy/scripts_v2/nested-secrets-tool.mjs materialize` — alias : `materialize-nested-secrets-mandatory.mjs`). Utiliser un chemin **portable** : par ex. `DEPLOY_SSH_KEY='$HOME/.ssh/id_ed25519_4nk'` (lexpansion de `$HOME`, `${HOME}` et un préfixe `~/` est appliquée par `lecoffre_deploy_resolve_deploy_ssh_key` après `load_dotenv_file_strict`, qui ne fait pas d`eval`). Ne pas figer un autre compte système (`/home/desk/...`). Ordre de repli si la clé indiquée est absente : `$HOME/.ssh/id_ed25519_4nk`, puis `$HOME/.ssh/id_ed25519`. Avant toute connexion SSH, la clé retenue est validée avec `ssh-keygen -y`. Vérification réseau : `bash deploy/scripts_v2/run-verify-ssh.sh <env>` ou les trois dun coup : `bash deploy/scripts_v2/run-verify-ssh-all-envs.sh`.
- **Modifications locales** : **`deploy.sh`** (LeCoffre) ne modifie pas la branche locale **`test`** (pas de **`git pull`** ni **`git stash`** sur **`test`** avec **`--sync-origin`**). Les fichiers déployés depuis lorchestrateur (scripts, **`import-v1`**) proviennent dun **worktree** détaché au ref **`kogus/<branche denv>`** ; le working tree du clone principal peut donc contenir du WIP non poussé sans être écrasé — seul le tip **`kogus/test`** (ou branche alignée pour **pprod**/**prod**) part sur la cible après **`git push`**. Pour **pprod**/**prod**, lindex du clone principal doit rester propre (**`local_git_require_clean_index_strict`**). - **Modifications locales** : **`deploy.sh`** ne modifie pas la branche locale **`test`** (pas de **`git pull`** ni **`git stash`** sur **`test`** avec **`--sync-origin`**). Les fichiers déployés depuis lorchestrateur (scripts, **`import-v1`**) proviennent dun **worktree** détaché au ref **`kogus/<branche denv>`** ; le working tree du clone principal peut donc contenir du WIP non poussé sans être écrasé — seul le tip **`kogus/test`** (ou branche alignée pour **pprod**/**prod**) part sur la cible après **`git push`**. Pour **pprod**/**prod**, lindex du clone principal doit rester propre (**`local_git_require_clean_index_strict`**).
- **Versions** : version.package_json_paths (backend, frontend) ; splash_app_name pour la notice. - **Versions** : version.package_json_paths (backend, frontend) ; splash_app_name pour la notice.
- **Dépendances npm (fiabilité avant phases distantes)** : `deploy.sh` exécute `hooks/verify-npm-lockfiles.sh` sur la racine du **worktree** de déploiement (ref **`kogus/<branche>`**), après préparation de ce worktree et après le hook de concurrence. Pour chaque `build_dir` (ressources-common, back-common, front-common) : présence de `package-lock.json`, JSON valide, `npm install --package-lock-only --dry-run` (cohérence `package.json` ↔ lockfile), puis `npm audit --audit-level=high`. Sur la cible, `deploy/scripts_v2/remote/deploy-app.sh` exécute `npm_ci_strict` (suppression de `node_modules` puis `npm ci` sans repli `npm install`) pour les trois mêmes répertoires. Contournements documentés : `DEPLOY_SKIP_NPM_LOCKFILE_VERIFY=1`, `DEPLOY_SKIP_NPM_AUDIT=1`. - **Dépendances npm (fiabilité avant phases distantes)** : `deploy.sh` exécute `hooks/verify-npm-lockfiles.sh` sur la racine du **worktree** de déploiement (ref **`kogus/<branche>`**), après préparation de ce worktree et après le hook de concurrence. Pour chaque `build_dir` (ressources-common, back-common, front-common) : présence de `package-lock.json`, JSON valide, `npm install --package-lock-only --dry-run` (cohérence `package.json` ↔ lockfile), puis `npm audit --audit-level=high`. Sur la cible, `deploy/scripts_v2/remote/deploy-app.sh` exécute `npm_ci_strict` (suppression de `node_modules` puis `npm ci` sans repli `npm install`) pour les trois mêmes répertoires. Contournements documentés : `DEPLOY_SKIP_NPM_LOCKFILE_VERIFY=1`, `DEPLOY_SKIP_NPM_AUDIT=1`.
- **Secrets / injection BDD** : `.secrets/<site_code>/<env>/env-full-<env>-for-bdd-injection.txt` pour linjection en BDD (répertoire imbriqué ; ancien plat `.secrets/<env>/` uniquement le temps dune migration). Super-admins systématiques après déploiement : clé **`SUPERADMIN_IDNOTS`** (liste `users.idNot`, virgules) — succède à **`SUPERADMIN_EMAILS`** ; voir `deploy/scripts_v2/remote/sql/list-lecoffreio-users-by-office-name-pattern-readonly.sql` et `deploy/scripts_v2/remote/promote-super-admins.sh`. NOTARY_AI_AGENT_URL, NOTARY_AI_AGENT_TOKEN pour lagent IA notaire (voir API.md). - **Secrets** : `.secrets/<site_code>/<env>/env-full-<env>-for-bdd-injection.txt` pour linjection en BDD (répertoire imbriqué ; ancien plat `.secrets/<env>/` uniquement le temps dune migration) ; NOTARY_AI_AGENT_URL, NOTARY_AI_AGENT_TOKEN pour lagent IA notaire (voir API.md).
- **Cartographie des checks de déploiement** : référence unique dans la doc projet (ex. projects/kogus/docs ou doc dédiée) ; ne pas dupliquer ici. - **Cartographie des checks de déploiement** : référence unique dans la doc projet (ex. projects/kogus/docs ou doc dédiée) ; ne pas dupliquer ici.
- **ShellCheck** : `npm run lint:shell` exécute `scripts/run-shellcheck.sh` sur `deploy/**/*.sh`, `scripts/*.sh` et `back-common/scripts/**/*.sh` (options : `--external-sources`, `--source-path=SCRIPTDIR`, `--severity=warning`). Helpers déploiement : `_lib/deploy-export-ssh-from-infos-json.sh` (chargement `infos.json`), `_lib/ssh-run-app-script.sh` (`lecoffre_ssh_run_remote_deploy_script`, `lecoffre_ssh_run_remote_mkdir_p`, etc.). Détail : `deploy/scripts_v2/hooks/README.md`. - **ShellCheck** : `npm run lint:shell` exécute `scripts/run-shellcheck.sh` sur `deploy/**/*.sh`, `scripts/*.sh` et `back-common/scripts/**/*.sh` (options : `--external-sources`, `--source-path=SCRIPTDIR`, `--severity=warning`). Helpers déploiement : `_lib/deploy-export-ssh-from-infos-json.sh` (chargement `infos.json`), `_lib/ssh-run-app-script.sh` (`lecoffre_ssh_run_remote_deploy_script`, `lecoffre_ssh_run_remote_mkdir_p`, etc.). Détail : `deploy/scripts_v2/hooks/README.md`.

View File

@ -1,42 +1,14 @@
# Documentation LeCoffre.io (index) # Documentation LeCoffre.io (index)
**Projet ia_dev** : **kogus** (identifiant outillage ; le site produit « LeCoffre » reste `product_code` / `sites.code` **lecoffreio** côté applicatif). **Projet ia_dev** : **kogus** (orchestration de ce monorepo). Le site notaire en production reste **`lecoffreio`** (FQDN `*.lecoffreio.*`, unités systemd `lecoffreio-*`, `sites.code` en base).
**Wiki** : https://git.4nkweb.com/4nk/lecoffre_ng/wiki **Wiki (miroir optionnel)** : https://git.4nkweb.com/4nk/kogus/wiki
**Correspondance fichier → page wiki** : nom du fichier sans `.md`, `_``-`, title-case par segment (ex. `README.md` → Readme, `Operations.md` → Operations). **Correspondance fichier → page wiki** : nom du fichier sans `.md`, `_``-`, title-case par segment (ex. `README.md` → Readme, `Operations.md` → Operations).
## Chemins secrets (monorepo et legacy) ## Statut de cette documentation
Cette section évite de dupliquer les tableaux détaillés dans chaque page de ce dossier. Elle vise le clone **LeCoffre** (`deploy.repository_root` dans `projects/kogus/conf.json`). Elle ne décrit **pas** larborescence interne des jetons **ia_dev** sous **`projects/<id>/.secrets/...`** (ex. fichier **`ia_token`** par projet), qui reste propre au dépôt **ia_dev**. - **Référence canonique** : dans ce monorepo, **`docs/` est versionné** et sert de documentation technique de référence (ainsi que `docs/features/` pour les fiches ciblées).
- **Miroir wiki** : si le projet maintient un miroir sur le wiki Gitea, il est alimenté à partir de ces fichiers (voir § *Mise à jour du wiki*).
| Rôle | Chemin canonique (scripts `deploy/scripts_v2`, `deploy-site.sh`) | - **Numéro de version publié** : fichier **`VERSION`** à la racine du monorepo, **`front-common/src/front/version.json`** (`"version": "v"` + valeur exacte de **`VERSION`**), et entrées **`CHANGELOG.md`**. Incrément patch : depuis la racine **`IADEV_REPO`**, **`./deploy/pousse.sh kogus --bump-version`** (build `build_dirs` puis commit/push sur la branche courante du dépôt applicatif ; message multi-lignes sur stdin, voir **`IADEV_REPO/.smartIde/agents/push-by-script.md`**).
|------|------------------------------------------------------------------|
| Secrets par **ligne produit** (`SITE_CODE` / 2ᵉ argument de `deploy-site.sh`) | **`.secrets/<site>/<env>/`** avec **`<site> ∈ { lecoffreio, enso, genealogie }`** |
| **Kogus** (orchestrateur SSH, `connectDB` partagé, précontrôle `deploy-site.sh`) | **`.secrets/kogus/<env>/`** (`.env.<env>`, `.env.<env>.connectDB`) |
### Fichiers dinjection métier (matrices, actes, site, textes / tiers)
Ces fichiers **ne sont pas** dans **`projects/kogus/docs/`** (ni dans le wiki) : ils vivent **uniquement** sur le disque du clone **LeCoffre**, **par site et par environnement**, sous :
**`.secrets/<site>/<env>/`** avec **`<site> ∈ { lecoffreio, enso, genealogie }`** et **`<env> ∈ { test, pprod, prod }`**.
| Fichier (nom relatif, voir `<env>`) | Rôle |
|-------------------------------------|--------|
| **`role-permissions-matrix-<env>.json`** | Injection / export-import de la **matrice des droits** (`role_permissions_matrix`) — API **back-admin**, voir `docs/features/secrets-devai-kogus-sites-and-imports.md`. |
| **`office-deed-catalog-<env>.json`** | **Catalogue actes** — obligatoire pour **`deploy-site.sh`** (manifeste `site_env_required`). Export depuis la base : **back-admin** `POST /api/office-deed-catalog/export-to-secrets` ou lot **`POST /api/site-mandatory-artifacts/export-to-secrets`**. Chemin : **`.secrets/<site>/<env>/office-deed-catalog-<env>.json`** (ex. `.secrets/lecoffreio/test/office-deed-catalog-test.json`). Dossier disque **`lecoffreio`** (plus de segment **`notary`** côté **ia_dev** pour les symlinks secrets : voir **`ia_dev/deploy/lib/deploy-conf-handling.sh`**). Vérification : **GET** `/api/site-config/file-status?env=&site=`. |
| **`site-config-<env>.json`** | **Configuration de la ligne** `sites` (intégrations, hôtes, drapeaux) — export/import **back-admin**. |
| **`seed-site-texts-<env>.ts`** | **Textes i18n** publiés via `site_texts` ; **y compris les libellés et listes liés aux tiers** (clés `thirdParty.*`, `forms.thirdParty.*`, etc., selon `docs/Deployment.md` / seeds LeCoffre). |
Liste normative des noms : **`deploy/secrets-layout-manifest.json`** (bloc **`site_env_optional`**). Contrôle **SHA-256** inter-env (fichiers identiques) pour **enso** / **genealogie** : entrée **`inter_env_sha256_identical`** du même manifeste. Détail API (**`file-status`**, exports, garde-fous **lecoffreio**) : **`docs/features/secrets-devai-kogus-sites-and-imports.md`**.
### Wiki `projects/kogus/docs/*.md` vs dépôt Git **ia_dev**
Le **`.gitignore`** à la racine **ia_dev** contient **`**/docs/**`** : les fichiers **`.md`** sous **`projects/kogus/docs/`** sont en général **des copies de travail / wiki** et **ne sont pas tous suivis** par Git (seuls certains fichiers déjà indexés le restent, ex. ce **README**, **MIGRATION**, **Deployment**). Cela **naffecte pas** les fichiers dinjection ci-dessus : ceux-ci ne sont **jamais** attendus sous **`projects/kogus/docs/`** ; ils sont exclusivement sous **`.secrets/<site>/<env>/`** sur le monorepo LeCoffre.
**Documentation canonique (dépôt LeCoffre, branche suivie)** : `docs/features/multi-site-architecture.md`, `docs/features/secrets-multisite-kogus-and-sites.md`, `docs/features/secrets-devai-kogus-sites-and-imports.md`, `docs/features/multisite-data-policy-lecoffre-vs-ia-dev.md`, manifeste `deploy/secrets-layout-manifest.json`. Exemple dURL Gitea (adapter la branche) : `https://git.4nkweb.com/4nk/kogus/src/branch/test/docs/features/multi-site-architecture.md`.
**Legacy** : arbre **plat** **`.secrets/<env>/`** uniquement en phase de migration ; pont **symlinks** documenté avec **`LECOFFRE_LEGACY_FLAT_SECRETS_SYMLINKS=1`** côté orchestration **ia_dev** — état cible = répertoires **réels** par **`<site>`**.
Les pages **MIGRATION**, **DATABASE_COMPLETE**, **Frontend**, **IMPORT_V1_DEPENDENCIES** (lorsquelles existent sur disque) peuvent encore citer **`.secrets/<env>/`** pour lhistorique V1→V2 : en déploiement multisite aligné, utiliser **`SECRETS_LINE_DIR`** (typiquement **`.secrets/lecoffreio/<env>/`**) ou le **`<site>`** réel.
## Pages disponibles (docs/ racine) ## Pages disponibles (docs/ racine)
@ -48,15 +20,16 @@ Les pages **MIGRATION**, **DATABASE_COMPLETE**, **Frontend**, **IMPORT_V1_DEPEND
| Frontend.md | Frontend | Toasters, messages 403, sources de textes front, paramétrage, parcours UI. | | Frontend.md | Frontend | Toasters, messages 403, sources de textes front, paramétrage, parcours UI. |
| Code-Standards.md | Code-Standards | Lint, refactors, rôles et droits, conventions. | | Code-Standards.md | Code-Standards | Lint, refactors, rôles et droits, conventions. |
| Deployment.md | Deployment | Env, seeds, site-texts, vérifications boot, déploiement. | | Deployment.md | Deployment | Env, seeds, site-texts, vérifications boot, déploiement. |
| `scripts/verify-site-texts-thirdparty-scope-readonly.sh` | Ops | Lecture seule : scopes `site_texts` pour clés `thirdParty.%` via SSH sur la cible (voir Deployment.md §3.1). |
| Architecture.md | Architecture | Vue densemble technique et intégrations. | | Architecture.md | Architecture | Vue densemble technique et intégrations. |
| compliance-annuaire-idnot-specs.md | Compliance-Annuaire-Idnot-Specs | Conformité API Annuaire V2 et ID.NOT (lookup, PP). | | compliance-annuaire-idnot-specs.md | Compliance-Annuaire-Idnot-Specs | Conformité API Annuaire V2 et ID.NOT (lookup, PP). |
Contenu des anciens dossiers `docs/features/` et `docs/fixKnowledge/` : ventilé dans les pages ci-dessus (pas de page dédiée FEATURES ni FIXKNOWLEDGE). Contenu des anciens dossiers `docs/features/` et `docs/fixKnowledge/` : en grande partie ventilé dans les pages ci-dessus ; certaines **fiches techniques** restent sous `docs/features/` (ex. notaire office actif / IdNot : `notary-active-office-idnot-subscriptions.md`, liée depuis `Architecture.md` ; **structure login / email / helpers** après refactors ESLint : `login-and-email-helpers-structure.md`, liée depuis `Architecture.md` et `Frontend.md` ; **IA dossier notaire** (workflow, spooler ia_dev, emplacements des composants) : `notary-folder-ai-workflow.md`, liée depuis `API.md` ; **stockage fichiers chiffrés / rétrocompat IPFS** : `local-encrypted-file-storage.md`, liée depuis `Architecture.md` ; **archivage long dossier** : `long-term-folder-archive.md`, liée depuis `local-encrypted-file-storage.md` et `Architecture.md`). **Multi-site** : runbook opérateur `features/multi-site-deploy-runbook.md` (ordre test → pprod/prod, migrate, déploiement) ; architecture `features/multi-site-architecture.md` ; secrets disque **`lecoffreio` / `kogus` / `enso` / `genealogie`** : `features/secrets-multisite-kogus-and-sites.md` ; inventaire SQL `features/multi-site-sql-site-code-inventory.md` ; courriel `features/multi-site-mail-transactional-coverage.md` ; Stripe `features/multi-site-stripe-billing-edge.md`.
## Mise à jour du wiki ## Mise à jour du wiki
Depuis la racine du dépôt qui contient `docs/` : exécuter le script de migration (si disponible depuis ia_dev) pour pousser `docs/*.md` vers le wiki. Correspondance détaillée : `projects/ia_dev/docs/GIT_ISSUES_SCRIPTS_AGENTS.md` (section Migration docs/ → wiki). Ne pas committer `docs/` (hors versionnement). Depuis la racine de ce dépôt (qui contient `docs/`) :
## Dépôt applicatif `lecoffre_ng_test` (référence versionnée) - **Préparer / synchroniser** : mettre à jour les fichiers `docs/*.md` et, si nécessaire, `docs/features/*.md` (ces derniers peuvent être référencés depuis les pages wiki, sans duplication de contenu).
- **Pousser vers le wiki (si activé)** : utiliser le script `IADEV_REPO/git-issues/wiki-migrate-docs.sh`. Détails (correspondance fichier → page, conventions, périmètre) : `IADEV_REPO/projects/ia_dev/docs/GIT_ISSUES_SCRIPTS_AGENTS.md` (section *Migration docs/ → wiki*).
Le monorepo applicatif (`deploy.repository_root` dans `projects/kogus/conf.json`) versionne **`docs/`** à sa racine : index **`docs/README.md`**, fiches **`docs/features/`**. Ce répertoire **`projects/kogus/docs/`** sous ia_dev reste un miroir / notes dintégration agents ; en cas décart, le dépôt Git du code fait foi. Alignement **`VERSION`** / **`front-common/src/front/version.json`** / **`CHANGELOG.md`** : voir la même section *Numéro de version publié* dans le **`docs/README.md`** du monorepo. - **Changement de slug Gitea ou de chemin du clone local** : `docs/operations/gitea-repo-and-local-path-rename.md` (wiki, tickets, CI, remotes, chemins ia_dev et agents).