diff --git a/projects/kogus/docs/API.md b/projects/kogus/docs/API.md index 1b885ce..fcc828b 100644 --- a/projects/kogus/docs/API.md +++ b/projects/kogus/docs/API.md @@ -8,7 +8,7 @@ Ce document consolide la documentation des APIs externes utilisées par LeCoffre ### Vue d'ensemble -Le backend appelle l’API **ai_working_help** pour les opérations **ask** (legacy), **enqueue** et **getResponse**. L’URL de base est configurée via `NOTARY_AI_AGENT_URL`. Le projet et l’env sont identifiés par le token Bearer ; côté **serveur ia_dev**, l’API résout le projet en parcourant les fichiers **`projects//.secrets//ia_token`** (arborescence **ia_dev**, distincte des secrets monorepo LeCoffre sous **`/.secrets///`** — voir [README kogus — Chemins secrets](./README.md#chemins-secrets-monorepo-et-legacy)). Filtrage IP 192.168.1.* côté API. +Le backend appelle l’API **ai_working_help** pour les opérations **ask** (legacy), **enqueue** et **getResponse**. L’URL de base est configurée via `NOTARY_AI_AGENT_URL`. Le projet et l’env sont identifiés par le token Bearer ; côté dépôt **ia_dev**, l’API résout le projet via les fichiers secrets du projet (chemin typé **`projects//.secrets/...`** selon la convention du projet). Côté monorepo LeCoffre, les secrets nominaux sont sous **`.secrets///`** — voir **`docs/features/multi-site-architecture.md`**. Filtrage IP 192.168.1.* côté API. ### 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) - **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 n’est ajouté que si `NOTARY_AI_AGENT_TOKEN` est renseigné. +Implémentation : `back-common/src/services/notary/NotaryFolderAIService/NotaryFolderAIService.ts`. Le header n’est ajouté que si `NOTARY_AI_AGENT_TOKEN` est renseigné. ### 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]`. +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 L’agent ne doit jamais renvoyer RIB, coordonnées bancaires ou de paiement. Contexte envoyé : métadonnées dossier, type d’acte, 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 @@ L’agent ne doit jamais renvoyer RIB, coordonnées bancaires ou de paiement. Co ## API Annuaire V2 – Recherche offices et membres (IdNot PP) -- **Recherche offices** : route `GET .../api/v2/directory/lookup` avec paramètre **nomOffice** uniquement (recherche sur l’office ; pas de mélange notaire). Retour : offices sans liste de collaborateurs. +- **Recherche offices** : route `GET .../api/v2/directory/lookup` avec paramètre **nomOffice** d’abord, puis **nom** si aucun office (recherche sur l’office ; pas de mélange notaire côté premier passage). Le backend pagine l’annuaire 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 d’un 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). - **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 @@ L’agent 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. - **errorMessages.ts** : constantes techniques (réponses API, logique métier). -- **errorHandlers.ts** : construction des réponses d’erreur, `handlePermissionDeniedError` (message du builder 403). +- **errorHandlers.ts** : construction des réponses d’erreur, `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é. Règle : tout message destiné à l’utilisateur (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). diff --git a/projects/kogus/docs/Code-Standards.md b/projects/kogus/docs/Code-Standards.md index 117440c..c997a50 100644 --- a/projects/kogus/docs/Code-Standards.md +++ b/projects/kogus/docs/Code-Standards.md @@ -2,7 +2,7 @@ **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) : @@ -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` (5–6 params) → objet d’options ; 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). +- **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 d’options. -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) @@ -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. - **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 d’extraction 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. --- ## 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 — 1–12 en test/pprod ; 1–7 et 9–11 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. @@ -67,29 +68,30 @@ Ces vérifications alimentent les tests manuels et les scripts d’analyse (voir ## Configuration qualité et inventaire des bypass **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 -#### 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`. - **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`. - **Prettier** : `.prettierrc.json` présent. +- **Texte d’erreur 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`. - **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 @@ -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 | |----------------|------|-------------------------| -| `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). | | 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. | @@ -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 | |----------------|------|-------------------------| -| `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. | | `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 -- 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. - Bypass : `grep -r "eslint-disable\|@ts-ignore\|@ts-expect-error\|@ts-nocheck" lecoffre-*` puis vérifier chaque occurrence. diff --git a/projects/kogus/docs/Deployment.md b/projects/kogus/docs/Deployment.md index de7242f..57fd8f9 100644 --- a/projects/kogus/docs/Deployment.md +++ b/projects/kogus/docs/Deployment.md @@ -2,23 +2,6 @@ **Auteur** : Équipe 4NK -## Source de vérité multisite (dépôt LeCoffre) - -La documentation **canonique** multisite (architecture, secrets imbriqués **`.secrets///`**, **`.secrets/kogus//`**, 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) 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-.ts` (champ `textKey`) doivent être exa Chemins : -- **Multi-site (préféré)** : `.secrets///…` (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///…` (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//`** ; pour l’export local **`export-db-artifacts`**, dupliquer le connectDB **lecoffreio** → **kogus** si besoin (même doc). - **Legacy** (checkout non migré) : `.secrets//…` (ex. `.secrets/test/`). **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-.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 / l’affichage membre, **pas** le scope `site_texts`. -- **Vérification en lecture seule** (sur la base V2 de l’environnement) : 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///.env..connectDB`, orchestrateur **`.secrets/kogus//.env..connectDB`**, ou legacy `deploy/.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 l’environnement) : 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///.env..connectDB`, ou legacy orchestrateur `deploy/.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 ./scripts/verify-site-texts-thirdparty-scope-readonly.sh @@ -98,14 +81,14 @@ Liste des fichiers contenant les textes affichés à l’utilisateur (libellés, ## 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`**. -- **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. -- **Orchestration ia_dev** : depuis la racine du dépôt ia_dev, `./deploy/deploy.sh [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**). +- **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)** : [`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 [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). -- **Clé SSH déploiement (`DEPLOY_SSH_KEY`)** : définie dans `.secrets///.env.` (layout imbriqué obligatoire pour le multisite ; migration depuis l’ancien plat : `SITE_CODE=lecoffreio bash deploy/scripts_v2/sites/lecoffreio/migrate-secrets-legacy-to-nested-lecoffreio.sh …>` 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'` (l’expansion 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 ` ou les trois d’un 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 l’orchestrateur (scripts, **`import-v1`**) proviennent d’un **worktree** détaché au ref **`kogus/`** ; 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**, l’index du clone principal doit rester propre (**`local_git_require_clean_index_strict`**). +- **Clé SSH déploiement (`DEPLOY_SSH_KEY`)** : définie dans `.secrets///.env.` (layout imbriqué obligatoire pour le multisite ; migration depuis l’ancien plat : `SITE_CODE=lecoffreio bash deploy/scripts_v2/sites/lecoffreio/migrate-secrets-legacy-to-nested-lecoffreio.sh …>` ; 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'` (l’expansion 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 ` ou les trois d’un coup : `bash deploy/scripts_v2/run-verify-ssh-all-envs.sh`. +- **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 l’orchestrateur (scripts, **`import-v1`**) proviennent d’un **worktree** détaché au ref **`kogus/`** ; 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**, l’index 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. - **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/`**), 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///env-full--for-bdd-injection.txt` pour l’injection en BDD (répertoire imbriqué ; ancien plat `.secrets//` uniquement le temps d’une 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 l’agent IA notaire (voir API.md). +- **Secrets** : `.secrets///env-full--for-bdd-injection.txt` pour l’injection en BDD (répertoire imbriqué ; ancien plat `.secrets//` uniquement le temps d’une migration) ; NOTARY_AI_AGENT_URL, NOTARY_AI_AGENT_TOKEN pour l’agent 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. - **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`. diff --git a/projects/kogus/docs/README.md b/projects/kogus/docs/README.md index 9696245..0aecf17 100644 --- a/projects/kogus/docs/README.md +++ b/projects/kogus/docs/README.md @@ -1,42 +1,14 @@ # Documentation LeCoffre.io (index) -**Projet ia_dev** : **kogus** (identifiant outillage ; le site produit « LeCoffre » reste `product_code` / `sites.code` **lecoffreio** côté applicatif). -**Wiki** : https://git.4nkweb.com/4nk/lecoffre_ng/wiki +**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 (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). -## 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** l’arborescence interne des jetons **ia_dev** sous **`projects//.secrets/...`** (ex. fichier **`ia_token`** par projet), qui reste propre au dépôt **ia_dev**. - -| Rôle | Chemin canonique (scripts `deploy/scripts_v2`, `deploy-site.sh`) | -|------|------------------------------------------------------------------| -| Secrets par **ligne produit** (`SITE_CODE` / 2ᵉ argument de `deploy-site.sh`) | **`.secrets///`** avec **` ∈ { lecoffreio, enso, genealogie }`** | -| **Kogus** (orchestrateur SSH, `connectDB` partagé, précontrôle `deploy-site.sh`) | **`.secrets/kogus//`** (`.env.`, `.env..connectDB`) | - -### Fichiers d’injection 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///`** avec **` ∈ { lecoffreio, enso, genealogie }`** et **` ∈ { test, pprod, prod }`**. - -| Fichier (nom relatif, voir ``) | Rôle | -|-------------------------------------|--------| -| **`role-permissions-matrix-.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-.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///office-deed-catalog-.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-.json`** | **Configuration de la ligne** `sites` (intégrations, hôtes, drapeaux) — export/import **back-admin**. | -| **`seed-site-texts-.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 **n’affecte pas** les fichiers d’injection ci-dessus : ceux-ci ne sont **jamais** attendus sous **`projects/kogus/docs/`** ; ils sont exclusivement sous **`.secrets///`** 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 d’URL Gitea (adapter la branche) : `https://git.4nkweb.com/4nk/kogus/src/branch/test/docs/features/multi-site-architecture.md`. - -**Legacy** : arbre **plat** **`.secrets//`** 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 **``**. - -Les pages **MIGRATION**, **DATABASE_COMPLETE**, **Frontend**, **IMPORT_V1_DEPENDENCIES** (lorsqu’elles existent sur disque) peuvent encore citer **`.secrets//`** pour l’historique V1→V2 : en déploiement multisite aligné, utiliser **`SECRETS_LINE_DIR`** (typiquement **`.secrets/lecoffreio//`**) ou le **``** réel. +- **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*). +- **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`**). ## 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. | | Code-Standards.md | Code-Standards | Lint, refactors, rôles et droits, conventions. | | 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 d’ensemble technique et intégrations. | | 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 -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) - -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 d’inté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. +- **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*). +- **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).