chore: agents, deploy scripts, notary-ai helpers and samples

**Motivations:** Publish ia_dev workspace updates to remote dev_ia.

**Root causes:** N/A (accumulated local changes).

**Correctifs:** N/A.

**Evolutions:** SmartIde agent docs; deploy change-to-all-branches and deploy-by-script-to; ai_working_help package scripts and lockfile; notary-ai loop shell scripts; sample responded JSON under projects/kogus/data; .cursor/ssh_config stub; kogus Code-Standards doc.

**Pages affectées:** N/A.
This commit is contained in:
Nicolas Cantu 2026-04-23 03:06:13 +02:00
parent f8b0e9240d
commit e5e07741d3
21 changed files with 1133 additions and 30 deletions

72
.cursor/ssh_config Normal file
View File

@ -0,0 +1,72 @@
# SSH Configuration for Cursor - Infrastructure Cloud 4NK
# This file contains SSH configurations for all servers in the infrastructure
# Proxy server (accès direct)
Host proxy
HostName 4nk.myftp.biz
User ncantu
Port 22
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
PreferredAuthentications publickey
PasswordAuthentication no
# Test server (via proxy)
Host test
HostName 192.168.1.101
User ncantu
Port 22
ProxyJump ncantu@4nk.myftp.biz
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
PreferredAuthentications publickey
PasswordAuthentication no
StrictHostKeyChecking accept-new
# Pre-production server (via proxy)
Host pprod
HostName 192.168.1.102
User ncantu
Port 22
ProxyJump ncantu@4nk.myftp.biz
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
PreferredAuthentications publickey
PasswordAuthentication no
StrictHostKeyChecking accept-new
# Production server (via proxy)
Host prod
HostName 192.168.1.103
User ncantu
Port 22
ProxyJump ncantu@4nk.myftp.biz
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
PreferredAuthentications publickey
PasswordAuthentication no
StrictHostKeyChecking accept-new
# Services server (via proxy)
Host services
HostName 192.168.1.104
User ncantu
Port 22
ProxyJump ncantu@4nk.myftp.biz
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
PreferredAuthentications publickey
PasswordAuthentication no
StrictHostKeyChecking accept-new
# Bitcoin server (via proxy)
Host bitcoin
HostName 192.168.1.105
User ncantu
Port 22
ProxyJump ncantu@4nk.myftp.biz
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
PreferredAuthentications publickey
PasswordAuthentication no
StrictHostKeyChecking accept-new

View File

@ -24,6 +24,13 @@ En tant qu'agent, avant de solliciter l'ia, regarde ce que tu peux scripter (imp
- **Sans jugement d'intérêt** : ne jamais juger de la pertinence d'une étape pour la sauter ; tout appliquer tel que décrit, sans exception. - **Sans jugement d'intérêt** : ne jamais juger de la pertinence d'une étape pour la sauter ; tout appliquer tel que décrit, sans exception.
- **Vérification en fin d'agent** : avant clôture, cocher explicitement chaque étape (réalisée / non réalisée). - **Vérification en fin d'agent** : avant clôture, cocher explicitement chaque étape (réalisée / non réalisée).
## Politique — une seule tentative de déploiement test par invocation
- **Tentative** : une exécution de **`./deploy/change-to-all-branches.sh [project_id]`** **sans** **`--align-only`** (le script enchaîne alignement + déploiement **test** multisite).
- **Par message utilisateur / ouverture dagent** : **au plus une** telle exécution ; si code de sortie **non nul**, **ne pas** relancer ce script dans le **même** run.
- **Après échec** : analyser sortie + **`logs/deploy_*.log`** ; **`/fix-lint`** puis **`/push-by-script`** autorisés pour corriger le dépôt — **sans** nouvelle exécution de **`change-to-all-branches.sh`** tant que lutilisateur na pas relancé explicitement **`/change-to-all-branches`**.
- **Alignement** : **`deploy-test-by-script.md`**, **`.smartIde/agents/deploy-by-script.md`**, **`.smartIde/agents/deploy-pprod-or-prod.md`** (même principe sur leurs commandes de déploiement).
**Checklist à cocher (dans l'ordre) :** **Checklist à cocher (dans l'ordre) :**
1. Contexte : rappeler projet (id) et `projects/<id>/`. 1. Contexte : rappeler projet (id) et `projects/<id>/`.
2. Lire `deploy/change-to-all-branches.sh`. 2. Lire `deploy/change-to-all-branches.sh`.
@ -31,7 +38,7 @@ En tant qu'agent, avant de solliciter l'ia, regarde ce que tu peux scripter (imp
4. Vérifier branche du dépôt projet = **test** (sinon retour 1). 4. Vérifier branche du dépôt projet = **test** (sinon retour 1).
5. Exécuter **/push-by-script** (message fourni par l'agent). 5. Exécuter **/push-by-script** (message fourni par l'agent).
6. Exécuter `./deploy/change-to-all-branches.sh [project_id]` (timeout long). **Sans** loption **`--align-only`** : le script enchaîne alignement **et** déploiement **test**. Loption **`--align-only`** (alignement uniquement) est réservée au workflow **`/deploy-pprod-or-prod`** — ne pas lutiliser pour clôturer **cet** agent si un déploiement **test** est attendu. 6. Exécuter `./deploy/change-to-all-branches.sh [project_id]` (timeout long). **Sans** loption **`--align-only`** : le script enchaîne alignement **et** déploiement **test**. Loption **`--align-only`** (alignement uniquement) est réservée au workflow **`/deploy-pprod-or-prod`** — ne pas lutiliser pour clôturer **cet** agent si un déploiement **test** est attendu.
7. **En échec du script** : identifier la cause (sortie + logs/deploy_*.log). Si typecheck / lint / build : lancer **intégralement** l'agent **/fix-lint** pour le projet, puis **/push-by-script**, puis relancer `./deploy/change-to-all-branches.sh [project_id]`. Répéter jusqu'à succès ou **maximum 5 tentatives** ; au-delà, documenter les erreurs et s'arrêter. 7. **En échec du script** : identifier la cause (sortie + **`logs/deploy_*.log`**). Si typecheck / lint / build : lancer **intégralement** l'agent **/fix-lint** pour le projet, puis **/push-by-script****ne pas** relancer **`./deploy/change-to-all-branches.sh [project_id]`** dans le même run (**§ Politique — une seule tentative de déploiement test**). Pour les autres causes (SSH, secrets, infra) : documenter et sarrêter sans nouvelle exécution du script dans ce run.
8. **Lint min. 5 avant clôture** : sur `repository_root`, lint **chaque** `build_dir` (tout le périmètre déclaré, pas seulement le sous-projet modifié dans la session) ; si **N ≥ 1**, corriger **au moins min(5, N)** dans **ce** run ; décompte avant/après. **Interdit** de clôturer en reportant seul sur un **`/fix-lint` ultérieur** sans ces corrections. **Interdit** dignorer des warnings/erreurs parce quils sont « préexistants » ou hors fichiers modifiés ce run : voir `.smartIde/rules/cloture-lint.mdc` — section **Diagnostics préexistants / hors périmètre de la session**. Si fichiers modifiés : **/push-by-script** avant clôture si le dépôt nest pas clean. 8. **Lint min. 5 avant clôture** : sur `repository_root`, lint **chaque** `build_dir` (tout le périmètre déclaré, pas seulement le sous-projet modifié dans la session) ; si **N ≥ 1**, corriger **au moins min(5, N)** dans **ce** run ; décompte avant/après. **Interdit** de clôturer en reportant seul sur un **`/fix-lint` ultérieur** sans ces corrections. **Interdit** dignorer des warnings/erreurs parce quils sont « préexistants » ou hors fichiers modifiés ce run : voir `.smartIde/rules/cloture-lint.mdc` — section **Diagnostics préexistants / hors périmètre de la session**. Si fichiers modifiés : **/push-by-script** avant clôture si le dépôt nest pas clean.
9. Clôture : points 1 à 16 de cloture-evolution.mdc (horodatage, 5 périmètres 3-11, 12-14, 15, 16). 9. Clôture : points 1 à 16 de cloture-evolution.mdc (horodatage, 5 périmètres 3-11, 12-14, 15, 16).
@ -45,21 +52,21 @@ En tant qu'agent, avant de solliciter l'ia, regarde ce que tu peux scripter (imp
**Projet kogus (monorepo LeCoffre) :** si le script enchaîne **`deploy/scripts_v2`**, appliquer le contrat multisite (**`SITE_CODE`** / **`deploy-site.sh`** / **`deploy-lecoffre-all-sites.sh`**, secrets **`.secrets/<site>/<env>/`**) décrit dans **`repository_root/docs/features/multi-site-architecture.md`** et **`repository_root/.cursor/agents/agent-paths-registry.md`** §3 bis (les agents Cursor du dépôt applicatif sont sous **`.cursor/agents/`**, pas **`.smartIde`**). **Projet kogus (monorepo LeCoffre) :** si le script enchaîne **`deploy/scripts_v2`**, appliquer le contrat multisite (**`SITE_CODE`** / **`deploy-site.sh`** / **`deploy-lecoffre-all-sites.sh`**, secrets **`.secrets/<site>/<env>/`**) décrit dans **`repository_root/docs/features/multi-site-architecture.md`** et **`repository_root/.cursor/agents/agent-paths-registry.md`** §3 bis (les agents Cursor du dépôt applicatif sont sous **`.cursor/agents/`**, pas **`.smartIde`**).
**Branche applicative test-first (obligatoire) :** Toute correction de code, configuration ou documentation dans le **dépôt applicatif** (`repository_root` dans `projects/<id>/conf.json`) pendant lexécution de cet agent doit être réalisée sur la branche locale **test**. Avant toute modification : si le dépôt applicatif nest pas sur **test**, exécuter **`git checkout test`** (ou équivalent validé projet). **Interdit** : committer un correctif **uniquement** sur **pprod** ou **prod** depuis cet agent. Si léchec ou le contexte provient dune phase **pprod**/**prod** (correctifs identifiés après déploiement ou analyse sur ces branches), appliquer la procédure **Corrections découvertes sur pprod ou prod** dans `.smartIde/agents/deploy-pprod-or-prod.md` : correctifs sur **test**, pousser **hors** **`/deploy-pprod-or-prod`** si besoin, puis **rejouer** **`/deploy-pprod-or-prod`** depuis son **étape 2** (**`change-to-all-branches.sh --align-only`**, puis **`deploy-by-script-to`**, etc.), sans court-circuiter lalignement **test → pprod → prod**. **Ne pas** confondre avec lagent **`/change-to-all-branches`** (déploiement **test** multisite). **Branche applicative test-first (obligatoire) :** Toute correction de code, configuration ou documentation dans le **dépôt applicatif** (`repository_root` dans `projects/<id>/conf.json`) pendant lexécution de cet agent doit être réalisée sur la branche locale **test**. Avant toute modification : si le dépôt applicatif nest pas sur **test**, exécuter **`git checkout test`** (ou équivalent validé projet). **Interdit** : committer un correctif **uniquement** sur **pprod** ou **prod** depuis cet agent. Si léchec ou le contexte provient dune phase **pprod**/**prod** (correctifs identifiés après déploiement ou analyse sur ces branches), appliquer la procédure **Corrections découvertes sur pprod ou prod** dans `.smartIde/agents/deploy-pprod-or-prod.md` : correctifs sur **test**, pousser **hors** **`/deploy-pprod-or-prod`** si besoin, puis **nouvelle** invocation utilisateur de **`/deploy-pprod-or-prod`** (workflow depuis l**étape 2** ; **une** tentative de **`deploy-by-script-to`** par ouverture dagent — **§ Politique** dans le même fichier). **Ne pas** confondre avec lagent **`/change-to-all-branches`** (déploiement **test** multisite).
**Focus qualité et résolution de problèmes :** **Focus qualité et résolution de problèmes :**
- **Qualité :** Ne lancer le script qu'après un push-by-script réussi (message structuré, CHANGELOG à jour, build OK). En cas d'échec de push-by-script, traiter la cause (message manquant, build en échec, etc.) avant de continuer. - **Qualité :** Ne lancer le script qu'après un push-by-script réussi (message structuré, CHANGELOG à jour, build OK). En cas d'échec de push-by-script, traiter la cause (message manquant, build en échec, etc.) avant de continuer.
- **Résolution de problèmes :** Si change-to-all-branches.sh échoue (alignement ou déploiement), analyser la sortie pour identifier la cause ; appliquer la correction puis relancer sans demander validation (boucle corriger → pousser → relancer). Ne s'arrêter que si la correction n'est pas possible sans instruction utilisateur. - **Résolution de problèmes :** Si **`change-to-all-branches.sh`** échoue, analyser la sortie pour identifier la cause ; appliquer les corrections (**`/fix-lint`**, **`/push-by-script`**) **sans** relancer le script de déploiement test dans le même run (**§ Politique**).
- **Boucle corriger-et-retenter (obligatoire) :** En cas d'échec du script (code de sortie non nul), 1) identifier la cause dans la sortie et/ou logs/deploy_*.log (ex. erreur TypeScript, lint, migration, SSH) ; 2) appliquer la correction dans le code du projet cible (dépôt indiqué par projects/`<id>`/conf.json) **sur la branche test** du dépôt applicatif (voir **Branche applicative test-first** ci-dessus) ; 3) committer et pousser via /push-by-script (ou ./deploy/pousse.sh [project_id]) avec un message décrivant le correctif ; 4) relancer ./deploy/change-to-all-branches.sh [project_id]. Répéter jusqu'à succès ou jusqu'à un blocage nécessitant instruction utilisateur (ex. erreur infra non corrigeable par l'agent). Ne pas se contenter de rapporter l'échec sans corriger et retenter. - **Après échec du script (code de sortie non nul) :** 1) Cause dans la sortie et/ou **`logs/deploy_*.log`** ; 2) corrections sur le dépôt applicatif (**`repository_root`**, branche **test**, voir **Branche applicative test-first**) ; 3) **`/fix-lint`** puis **`/push-by-script`** si des fichiers ont été modifiés — **interdit** : relancer **`./deploy/change-to-all-branches.sh [project_id]`** dans la **même** ouverture dagent ; lutilisateur relance **`/change-to-all-branches`** pour un nouvel essai.
- **Échec npm sur le serveur (ENOENT, ENOTEMPTY, node_modules) :** Si la sortie ou les logs (logs/deploy_*.log) contiennent une erreur npm liée à node_modules (ex. ENOENT, ENOTEMPTY, mkdir node_modules/…, npm error enoent). Il s'agit d'un problème d'environnement sur le serveur de déploiement, pas du code. **Correction automatique** : ne pas modifier le code ; relancer **une fois** ./deploy/change-to-all-branches.sh [project_id] (sans refaire /push-by-script : les branches sont déjà alignées). Le script distant deploy/scripts_v2/remote/deploy-app.sh effectue désormais un retry après `rm -rf node_modules` lors de chaque npm ci ; la relance lance un nouveau déploiement qui bénéficie de cette logique. Si l'échec persiste après cette unique relance, documenter la sortie et les logs (fichier deploy_*.log, extraits d'erreur npm) et s'arrêter — intervention manuelle ou infra requise (espace disque, droits, npm cache). - **Échec npm sur le serveur (ENOENT, ENOTEMPTY, node_modules) :** Problème denvironnement cible. Documenter la sortie et **`logs/deploy_*.log`** ; **ne pas** relancer **`change-to-all-branches.sh`** dans ce run ; intervention manuelle ou nouvelle invocation utilisateur après correction infra.
- **Échec du build (TypeScript, lint, frontend/backend) — boucle autonome obligatoire :** Si le déploiement échoue au build (code de sortie non nul, erreurs TypeScript, typecheck, lint, module introuvable, etc. dans la sortie ou dans logs/deploy_*.log), l'agent doit **obligatoirement** et **sans demander validation** : 1) Extraire de la sortie/log la liste des fichiers et erreurs (ex. fichiers .ts/.tsx listés par tsc ou eslint). 2) **Lancer et exécuter intégralement** l'agent **/fix-lint** (ou `.smartIde/agents/fix-lint.md`) pour le projet cible, en lui passant en contexte les fichiers/erreurs identifiés si possible ; fix-lint corrige types, lint et compilation. 3) Exécuter **/push-by-script** (ou `./deploy/pousse.sh [project_id]`) pour committer et pousser les corrections. 4) **Relancer immédiatement** `./deploy/change-to-all-branches.sh [project_id]`. Répéter cette séquence (fix-lint → push-by-script → change-to-all-branches.sh) jusqu'à **succès** ou jusqu'à **5 tentatives** ; après 5 échecs consécutifs, documenter la sortie et les logs (extraits d'erreurs, fichiers concernés) et s'arrêter — intervention utilisateur requise. Aucune demande de validation entre correction et relance. - **Échec du build (TypeScript, lint, frontend/backend) :** 1) Extraire fichiers / erreurs depuis la sortie ou les logs. 2) **`/fix-lint`** intégralement pour le projet cible. 3) **`/push-by-script`** (ou **`./deploy/pousse.sh [project_id]`**) si des corrections ont été enregistrées. **Ne pas** enchaîner une seconde exécution de **`./deploy/change-to-all-branches.sh [project_id]`** dans le même run ; indiquer quun **nouvel** **`/change-to-all-branches`** est requis pour redéployer.
- **Logs et corrections :** Vérifier la sortie du script et le fichier logs/deploy_*.log produit par deploy.sh. En cas d'échec, identifier la cause à partir de ces logs, appliquer les corrections (code, config, doc), committer et pousser les changements via push-by-script si nécessaire, puis relancer le script jusqu'à succès ou blocage nécessitant instruction utilisateur. - **Logs et corrections :** Consulter la sortie du script et **`logs/deploy_*.log`**. Après échec : corrections + push possibles ; pas de nouvelle tentative de déploiement test sans nouvelle demande utilisateur.
**Avant d'exécuter un script du projet :** **Avant d'exécuter un script du projet :**
@ -76,7 +83,7 @@ Uniquement en test (branche git), exécuter dans l'ordre :
- **Paramètres :** Arguments : **project_id** optionnel (ex. kogus), puis optionnellement **`--align-only`** (hors périmètre de **cet** agent). La branche git est toujours **test**. Si l'utilisateur fournit des tokens ambigus (ex. « test kogus »), extraire le **project_id** quand `projects/<id>/conf.json` existe : `./deploy/change-to-all-branches.sh kogus`. - **Paramètres :** Arguments : **project_id** optionnel (ex. kogus), puis optionnellement **`--align-only`** (hors périmètre de **cet** agent). La branche git est toujours **test**. Si l'utilisateur fournit des tokens ambigus (ex. « test kogus »), extraire le **project_id** quand `projects/<id>/conf.json` existe : `./deploy/change-to-all-branches.sh kogus`.
- **Pas de timeout :** Ne pas lancer la commande avec un timeout court (ex. 5 min). Le déploiement (build, migrations, import-v1, redémarrage services, vérifications) peut durer 10 à 30 min ; utiliser un timeout long ou aucun timeout pour laisser le script aller au bout. - **Pas de timeout :** Ne pas lancer la commande avec un timeout court (ex. 5 min). Le déploiement (build, migrations, import-v1, redémarrage services, vérifications) peut durer 10 à 30 min ; utiliser un timeout long ou aucun timeout pour laisser le script aller au bout.
Retourner 0 en cas de succès. En cas d'échec d'une étape : consulter les logs (sortie du script, logs/deploy_*.log), identifier la cause. **Si la cause est typecheck / lint / build** : lancer **intégralement** l'agent **/fix-lint** pour le projet, puis /push-by-script, puis **relancer immédiatement** change-to-all-branches.sh (sans demander à l'utilisateur). Répéter jusqu'à succès ou **5 tentatives** ; au-delà, documenter et s'arrêter. Pour les autres causes (erreur serveur, secret manquant, infra) : s'arrêter si la correction n'est pas possible sans instruction utilisateur. Retourner 0 en cas de succès. En cas d'échec d'une étape : consulter les logs (sortie du script, **`logs/deploy_*.log`**), identifier la cause. **Si la cause est typecheck / lint / build** : **`/fix-lint`** puis **`/push-by-script`** — **sans** relancer **`change-to-all-branches.sh`** dans le même run (**§ Politique — une seule tentative de déploiement test**). Pour les autres causes : documenter et s'arrêter ; nouvel essai de déploiement = **nouvelle** invocation **`/change-to-all-branches`**.
## Clôture complète obligatoire (tous les cas, sans exception) ## Clôture complète obligatoire (tous les cas, sans exception)

View File

@ -25,6 +25,13 @@ En tant qu'agent, avant de solliciter l'ia, regarde ce que tu peux scripter (imp
- **Sans jugement d'intérêt** : ne jamais juger de la pertinence d'une étape pour la sauter ; tout appliquer tel que décrit, sans exception. - **Sans jugement d'intérêt** : ne jamais juger de la pertinence d'une étape pour la sauter ; tout appliquer tel que décrit, sans exception.
- **Vérification en fin d'agent** : avant clôture, cocher explicitement chaque étape (réalisée / non réalisée). - **Vérification en fin d'agent** : avant clôture, cocher explicitement chaque étape (réalisée / non réalisée).
## Politique — une seule tentative de déploiement par invocation
- **Tentative de déploiement** : une exécution de **`./deploy/deploy-by-script-to.sh [project_id] <test|pprod|prod>`** (le script enchaîne lorchestration **`deploy/scripts_v2`** / multisite selon le projet).
- **Par message utilisateur / ouverture dagent** : **au plus une** tentative ; si le code de sortie est **non nul**, **ne pas** relancer **`deploy-by-script-to.sh`** vers le **même** environnement dans le **même** run.
- **Après échec** : analyser la sortie et **`logs/deploy_*.log`**, documenter la cause et les prérequis ; corrections code / config / doc et **`/push-by-script`** possibles **sans** nouvel appel au script de déploiement ; lutilisateur relance explicitement **`/deploy-by-script`** (ou équivalent) pour un nouvel essai.
- **Alignement** : **`LECOFFRE_REPO/.cursor/agents/deploy-test-by-script.md`** (test, **`deploy-lecoffre-all-sites.sh`**) et **`.smartIde/agents/deploy-pprod-or-prod.md`** / **`change-to-all-branches.md`** pour la même règle sur leurs commandes respectives.
--- ---
**Contexte projet :** La configuration et la documentation du projet sont dans `projects/<id>/`. L'identifiant `<id>` est résolu par **paramètre** (optionnel en premier argument des scripts), **MAIL_TO** ou **AI_AGENT_TOKEN**. Voir `docs/repo/ia-dev-project-conf-schema.md`. Rappeler ce chemin en début d'exécution. **Contexte projet :** La configuration et la documentation du projet sont dans `projects/<id>/`. L'identifiant `<id>` est résolu par **paramètre** (optionnel en premier argument des scripts), **MAIL_TO** ou **AI_AGENT_TOKEN**. Voir `docs/repo/ia-dev-project-conf-schema.md`. Rappeler ce chemin en début d'exécution.
@ -33,23 +40,23 @@ En tant qu'agent, avant de solliciter l'ia, regarde ce que tu peux scripter (imp
**`deploy.host_stays_on_test: true` dans `projects/<id>/conf.json` (ex. **kogus** / monorepo LeCoffre) :** le clone applicatif (`repository_root`) reste sur la branche Git locale **`test`** pour les déploiements **pprod**/**prod** via **`deploy-by-script-to.sh`**. Lenvironnement cible est l**argument** du script. Le `deploy.sh` du dépôt aligne les remotes / **worktree** (ex. **`git push lecoffre_ng test:<branche>`** pour LeCoffre) — pas de **`git checkout pprod`**/**`prod`** sur le poste. Vérifier **`test`** aligné avec le remote attendu. Doc applicative : **`deploy/README.md`** ; agents Cursor du dépôt LeCoffre : **`repository_root/.cursor/agents/deploy-by-script.md`** (pas **`.smartIde`** sur le dépôt applicatif). **`deploy.host_stays_on_test: true` dans `projects/<id>/conf.json` (ex. **kogus** / monorepo LeCoffre) :** le clone applicatif (`repository_root`) reste sur la branche Git locale **`test`** pour les déploiements **pprod**/**prod** via **`deploy-by-script-to.sh`**. Lenvironnement cible est l**argument** du script. Le `deploy.sh` du dépôt aligne les remotes / **worktree** (ex. **`git push lecoffre_ng test:<branche>`** pour LeCoffre) — pas de **`git checkout pprod`**/**`prod`** sur le poste. Vérifier **`test`** aligné avec le remote attendu. Doc applicative : **`deploy/README.md`** ; agents Cursor du dépôt LeCoffre : **`repository_root/.cursor/agents/deploy-by-script.md`** (pas **`.smartIde`** sur le dépôt applicatif).
## Multisite — projet **kogus** (site produit `lecoffreio` = ligne notary, inchangé côté BDD) ## Multisite — projet **kogus** (site produit `lecoffreio` = ligne notaire)
Lorsque le playbook appelle **`repository_root/deploy/scripts_v2/`**, respecter la boucle **`SITE_CODE`** (**`notary`**, **`enso`**, **`genealogie`**) ou **`deploy-site.sh`** / **`deploy-lecoffre-all-sites.sh`** ; **`deploy-by-script-to`** ne positionne pas **`SITE_CODE`**. Secrets : **`.secrets/<site>/<env>/`**. Source normative : **`repository_root/docs/features/multi-site-architecture.md`** ; **`repository_root/.cursor/agents/agent-paths-registry.md`** §3 bis ; § **Multisite** dans **`repository_root/.cursor/agents/deploy-pprod-or-prod.md`**. Lorsque le playbook appelle **`repository_root/deploy/scripts_v2/`**, respecter la boucle **`SITE_CODE`** (**`lecoffreio`**, **`enso`**, **`genealogie`**) ou **`deploy-site.sh`** / **`deploy-lecoffre-all-sites.sh`** ; **`deploy-by-script-to`** ne positionne pas **`SITE_CODE`**. Secrets : **`.secrets/<site>/<env>/`**. Source normative : **`repository_root/docs/features/multi-site-architecture.md`** ; **`repository_root/.cursor/agents/agent-paths-registry.md`** §3 bis ; § **Multisite** dans **`repository_root/.cursor/agents/deploy-pprod-or-prod.md`**.
Cet agent lance le déploiement vers l**environnement passé au script** (ex. `./deploy/deploy-by-script-to.sh <id> test|pprod|prod`) via **scripts_v2**. **Si `deploy.host_stays_on_test` est absent ou false :** en pratique la branche locale du dépôt applicatif correspond souvent à lenv cible pour **pprod**/**prod**. **Rôle de lagent :** vérifier le contexte (si **`host_stays_on_test`** : branche locale = **test** ; sinon : cohérence branche / env selon le projet), lancer le script, contrôler la sortie et le code de retour, synthèse et clôture. **Rôle du script :** exécution et orchestration sûre (suivi branches, sync, log, déploiement). Cet agent lance le déploiement vers l**environnement passé au script** (ex. `./deploy/deploy-by-script-to.sh <id> test|pprod|prod`) via **scripts_v2**. **Si `deploy.host_stays_on_test` est absent ou false :** en pratique la branche locale du dépôt applicatif correspond souvent à lenv cible pour **pprod**/**prod**. **Rôle de lagent :** vérifier le contexte (si **`host_stays_on_test`** : branche locale = **test** ; sinon : cohérence branche / env selon le projet), lancer le script, contrôler la sortie et le code de retour, synthèse et clôture. **Rôle du script :** exécution et orchestration sûre (suivi branches, sync, log, déploiement).
**Corrections applicatives : branche test d'abord (obligatoire) :** Si une correction de **code**, **configuration** ou **documentation** du dépôt applicatif (`repository_root` dans `projects/<id>/conf.json`) est nécessaire après un échec ou une analyse pendant un déploiement : **Corrections applicatives : branche test d'abord (obligatoire) :** Si une correction de **code**, **configuration** ou **documentation** du dépôt applicatif (`repository_root` dans `projects/<id>/conf.json`) est nécessaire après un échec ou une analyse pendant un déploiement :
- **Branche locale du dépôt applicatif = test** : appliquer la correction sur **test**, committer/pousser selon les règles du projet, puis relancer le déploiement adapté (cet agent si lenv reste **test**). - **Branche locale du dépôt applicatif = test** : appliquer la correction sur **test**, committer/pousser selon les règles du projet ; un **nouvel** essai de déploiement = **nouvelle** invocation **`/deploy-test-by-script`** ou **`/deploy-by-script`** (pas de relance automatique du script de déploiement dans le même run — **§ Politique — une seule tentative**).
- **Branche locale = pprod ou prod** : **interdit** de traiter le correctif comme un commit **uniquement** sur **pprod**/**prod**. **`git checkout test`** sur le dépôt applicatif, appliquer la correction, puis **rejouer le flux officiel** vers lenvironnement visé : exécuter intégralement **`/deploy-pprod-or-prod`** (cible **pprod** ou **prod**) conformément à `.smartIde/agents/deploy-pprod-or-prod.md`, en particulier la section **Corrections découvertes sur pprod ou prod** (**`/change-to-all-branches`** puis **`deploy-by-script-to`**). Ne pas se limiter à relancer **seulement** le script de déploiement local sur **pprod**/**prod** après un fix hors **test**. - **Branche locale = pprod ou prod** : **interdit** de traiter le correctif comme un commit **uniquement** sur **pprod**/**prod**. **`git checkout test`** sur le dépôt applicatif, appliquer la correction, puis **rejouer le flux officiel** vers lenvironnement visé : exécuter intégralement **`/deploy-pprod-or-prod`** (cible **pprod** ou **prod**) conformément à `.smartIde/agents/deploy-pprod-or-prod.md`, en particulier la section **Corrections découvertes sur pprod ou prod** (**`/push-by-script`** puis **`./deploy/change-to-all-branches.sh [project_id] --align-only`** puis **`deploy-by-script-to`**, conformément à l**étape 2** et **3** de `.smartIde/agents/deploy-pprod-or-prod.md`). Ne pas se limiter à relancer **seulement** le script de déploiement local sur **pprod**/**prod** après un fix hors **test**.
**Focus qualité et résolution de problèmes :** **Focus qualité et résolution de problèmes :**
- **Qualité :** Avant de lancer le script : si **`deploy.host_stays_on_test`** dans la conf du projet, vérifier que la branche courante du clone applicatif est **`test`** et lalignement remote (ex. **`lecoffre_ng/test`** pour LeCoffre ; voir **`deploy.sh`** / **`deploy/README.md`**). Sinon, vérifier que la branche courante correspond à lenvironnement cible. Ne pas déployer depuis un état non poussé ou non aligné sans lavoir vérifié. - **Qualité :** Avant de lancer le script : si **`deploy.host_stays_on_test`** dans la conf du projet, vérifier que la branche courante du clone applicatif est **`test`** et lalignement remote (ex. **`lecoffre_ng/test`** pour LeCoffre ; voir **`deploy.sh`** / **`deploy/README.md`**). Sinon, vérifier que la branche courante correspond à lenvironnement cible. Ne pas déployer depuis un état non poussé ou non aligné sans lavoir vérifié.
- **Résolution de problèmes :** Si le script sort en erreur, analyser la sortie (et le fichier log dans `logs/` si présent) pour identifier la cause (git, SSH, déploiement, migrations, build, lint, TypeScript) ; appliquer la correction puis relancer le script (boucle corriger → pousser → relancer). Ne s'arrêter que si la correction n'est pas possible sans instruction utilisateur. - **Résolution de problèmes :** Si le script sort en erreur, analyser la sortie (et le fichier log dans `logs/` si présent) pour identifier la cause (git, SSH, déploiement, migrations, build, lint, TypeScript). **Ne pas** relancer **`deploy-by-script-to.sh`** dans le même run (voir **§ Politique — une seule tentative de déploiement**). Appliquer les corrections selon **Corrections applicatives : branche test d'abord** si pertinent, committer / pousser (**`/push-by-script`**, **`/deploy-pprod-or-prod`** depuis létape prescrite pour **pprod**/**prod**) **sans** second essai de déploiement tant que lutilisateur na pas relancé explicitement cet agent.
- **Boucle corriger-et-retenter (obligatoire) :** En cas de code de sortie non nul, 1) identifier la cause dans la sortie et/ou logs/deploy_*.log ; 2) appliquer la correction dans le code du projet cible en respectant **Corrections applicatives : branche test d'abord** (ci-dessus) ; 3) committer et pousser via push-by-script si des fichiers ont été modifiés et que le flux le permet ; si le déploiement visait **pprod**/**prod** (argument du script) **ou** si la branche applicative locale était **pprod**/**prod** (pour les projets **sans** **`host_stays_on_test`**), enchaîner **`/deploy-pprod-or-prod`** au lieu dun simple relancement isolé ; 4) relancer le déploiement approprié. Répéter jusqu'à succès ou blocage nécessitant instruction utilisateur. Ne pas se contenter de rapporter l'échec sans corriger et retenter. - **Après code de sortie non nul :** 1) Cause dans la sortie et/ou **`logs/deploy_*.log`** ; 2) corrections sur le dépôt applicatif en respectant **Corrections applicatives : branche test d'abord** ; 3) **`/push-by-script`** ou **`/deploy-pprod-or-prod`** (workflow complet depuis létape indiquée dans **`.smartIde/agents/deploy-pprod-or-prod.md`**) **uniquement** hors logique « relancer tout de suite le même **`deploy-by-script-to`** » — un **nouvel** essai de **`deploy-by-script-to.sh`** = **nouvelle** invocation utilisateur de **`/deploy-by-script`**.
- **Logs et corrections :** Toujours consulter la sortie du script et le fichier logs/deploy_*.log après exécution. En cas d'échec, utiliser ces logs pour identifier la cause, appliquer les corrections (code, config, doc, scripts) en respectant **Corrections applicatives : branche test d'abord**, committer et pousser via push-by-script si des fichiers ont été modifiés (ou enchaîner **`/deploy-pprod-or-prod`** si la cible du script était **pprod**/**prod** ou si la branche applicative locale était **pprod**/**prod** pour un projet **sans** **`host_stays_on_test`**), puis relancer le déploiement ou le workflow complet jusqu'à succès ou blocage nécessitant instruction utilisateur. - **Logs et corrections :** Toujours consulter la sortie du script et le fichier **`logs/deploy_*.log`** après exécution. En cas d'échec, utiliser ces logs pour identifier la cause et documenter les prérequis ; corrections (code, config, doc) + push si besoin, **sans** rappeler **`deploy-by-script-to.sh`** dans le même run.
**Horodatage et contexte** : appliquer intégralement le bloc défini dans `.smartIde/rules/cloture-evolution.mdc` (début et fin d'exécution, lancement et retour des sub-agents). **Horodatage et contexte** : appliquer intégralement le bloc défini dans `.smartIde/rules/cloture-evolution.mdc` (début et fin d'exécution, lancement et retour des sub-agents).
@ -72,12 +79,12 @@ Le script fait alors automatiquement : suivi des branches origin, sync de la bra
## 2. Contrôle et résolution de problèmes ## 2. Contrôle et résolution de problèmes
- Vérifier que le script a bien été invoqué : si **`deploy.host_stays_on_test`**, branche courante du clone applicatif = **`test`** et argument du script = env cible ; sinon, en pratique branche courante = environnement cible. En cas de code de sortie non nul, consulter la sortie et le log (logs/deploy_*.log), identifier la cause, appliquer les corrections nécessaires selon **Corrections applicatives : branche test d'abord**, committer et pousser via push-by-script si des fichiers ont été modifiés (ou enchaîner **`/deploy-pprod-or-prod`** si la cible invoquée était **pprod**/**prod** ou si la branche applicative locale était **pprod**/**prod** sans **`host_stays_on_test`**), puis **relancer** le script ou le workflow complet. Répéter jusqu'à succès. Ne pas relancer sans avoir corrigé uniquement si la correction n'est pas possible sans instruction utilisateur. - Vérifier que le script a bien été invoqué : si **`deploy.host_stays_on_test`**, branche courante du clone applicatif = **`test`** et argument du script = env cible ; sinon, en pratique branche courante = environnement cible. En cas de code de sortie non nul, consulter la sortie et le log (**`logs/deploy_*.log`**), identifier la cause, appliquer les corrections selon **Corrections applicatives : branche test d'abord** et pousser si besoin — **sans** relancer **`deploy-by-script-to.sh`** dans le même run (**§ Politique — une seule tentative de déploiement**).
## 3. Après l'exécution ## 3. Après l'exécution
- Si le script sort avec 0 : rapporter le succès. - Si le script sort avec 0 : rapporter le succès.
- Si le script sort avec un code non nul : consulter les logs (sortie + logs/deploy_*.log), identifier la cause, appliquer les corrections selon **Corrections applicatives : branche test d'abord**, mettre à jour git (push-by-script) ou enchaîner **`/deploy-pprod-or-prod`** si la cible invoquée était **pprod**/**prod** (ou branche applicative locale **pprod**/**prod** sans **`host_stays_on_test`**), puis relancer le flux adapté. Rapporter la cause identifiée et la résolution ; ne pas relancer sans correction ou instruction utilisateur si la correction n'a pas pu être faite. - Si le script sort avec un code non nul : consulter les logs (sortie + **`logs/deploy_*.log`**), identifier la cause, appliquer les corrections selon **Corrections applicatives : branche test d'abord**, mettre à jour git (**`/push-by-script`**) ou préparer **`/deploy-pprod-or-prod`** selon le cas — **ne pas** réexécuter **`deploy-by-script-to.sh`** dans ce run ; rapporter la cause et indiquer quun **nouvel** **`/deploy-by-script`** est nécessaire pour rejouer le déploiement.
## 4. Lint min. 5 avant clôture (obligatoire) ## 4. Lint min. 5 avant clôture (obligatoire)

View File

@ -27,13 +27,21 @@ En tant qu'agent, avant de solliciter l'ia, regarde ce que tu peux scripter (imp
- **Sans jugement d'intérêt** : ne jamais juger de la pertinence d'une étape pour la sauter ; tout appliquer tel que décrit, sans exception. - **Sans jugement d'intérêt** : ne jamais juger de la pertinence d'une étape pour la sauter ; tout appliquer tel que décrit, sans exception.
- **Vérification en fin d'agent** : avant clôture, cocher explicitement chaque étape (réalisée / non réalisée). - **Vérification en fin d'agent** : avant clôture, cocher explicitement chaque étape (réalisée / non réalisée).
## Politique — une seule tentative de déploiement par invocation
- **Tentative de déploiement** : une exécution de **`./deploy/deploy-by-script-to.sh [project_id] <pprod|prod>`** (étape **3** du workflow ci-dessous), qui enchaîne le déploiement multisite sur la cible.
- **Par message utilisateur / ouverture dagent** : **au plus une** tentative pour létape **3** ; si le code de sortie est **non nul**, **ne pas** relancer **`deploy-by-script-to.sh`** vers **pprod** ou **prod** dans le **même** run.
- **Après échec de létape 3** : analyser les logs, appliquer **Corrections découvertes sur pprod ou prod** si besoin (correctifs sur **test**, push hors agent) ; **ne pas** enchaîner une seconde exécution de létape **3** sans **nouvelle** demande utilisateur (**`/deploy-pprod-or-prod`** ou équivalent).
- **Étape 2** (**`change-to-all-branches.sh --align-only`**) : alignement Git **sans** déploiement applicatif **test** ; une nouvelle exécution de létape **2** après correction reste possible dans le même run si le playbook lexige pour des raisons dalignement, **sans** compenser une nouvelle tentative d**étape 3** sans nouvelle demande.
- **Alignement** : **`LECOFFRE_REPO/.cursor/agents/deploy-test-by-script.md`**, **`.smartIde/agents/deploy-by-script.md`**, **`.smartIde/agents/change-to-all-branches.md`**.
--- ---
**Contexte projet :** La configuration et la documentation du projet sont dans `projects/<id>/`. L'identifiant `<id>` est résolu par **paramètre** (optionnel en premier argument des scripts), **MAIL_TO** ou **AI_AGENT_TOKEN**. Voir `docs/repo/ia-dev-project-conf-schema.md`. Rappeler ce chemin en début et en fin d'exécution. **Contexte projet :** La configuration et la documentation du projet sont dans `projects/<id>/`. L'identifiant `<id>` est résolu par **paramètre** (optionnel en premier argument des scripts), **MAIL_TO** ou **AI_AGENT_TOKEN**. Voir `docs/repo/ia-dev-project-conf-schema.md`. Rappeler ce chemin en début et en fin d'exécution.
**Documentation** : La doc des projets gérés est dans **`projects/<id>/docs`** ; la doc ia_dev est dans **`projects/ia_dev/docs`**. **Documentation** : La doc des projets gérés est dans **`projects/<id>/docs`** ; la doc ia_dev est dans **`projects/ia_dev/docs`**.
**Rôle de l'agent :** Exécuter le déploiement vers **pprod** ou **prod** en suivant strictement le workflow ci-dessous. Paramètre obligatoire : `pprod` ou `prod`. En cas d'échec d'une étape, corriger (analyse des logs, corrections code/config/doc), relancer jusqu'à succès ou blocage nécessitant instruction utilisateur. **Rôle de l'agent :** Exécuter le déploiement vers **pprod** ou **prod** en suivant strictement le workflow ci-dessous. Paramètre obligatoire : `pprod` ou `prod`. En cas déchec de l**étape 3** (**`deploy-by-script-to`**), **sarrêter** après analyse et corrections documentées — **pas** de second lancement de l**étape 3** dans le même run (**§ Politique — une seule tentative de déploiement**). Pour l**étape 2** uniquement (alignement), en cas déchec : corriger puis **une** nouvelle exécution de l**étape 2** autorisée si nécessaire avant toute **nouvelle** invocation utilisateur pour l**étape 3**.
**Répertoire d'exécution (standalone) :** Racine de ia_dev. Tous les scripts sont invoqués depuis la racine de ia_dev. **Répertoire d'exécution (standalone) :** Racine de ia_dev. Tous les scripts sont invoqués depuis la racine de ia_dev.
@ -45,8 +53,8 @@ En tant qu'agent, avant de solliciter l'ia, regarde ce que tu peux scripter (imp
- **Interdit** : appliquer la correction **uniquement** sur la branche **pprod** ou **prod** du dépôt applicatif (`repository_root` dans `projects/<id>/conf.json`) et poursuivre sans repasser par **test** (pas de « correctif local pprod/prod puis push ciblé » en dehors du flux test-first). - **Interdit** : appliquer la correction **uniquement** sur la branche **pprod** ou **prod** du dépôt applicatif (`repository_root` dans `projects/<id>/conf.json`) et poursuivre sans repasser par **test** (pas de « correctif local pprod/prod puis push ciblé » en dehors du flux test-first).
- **Obligation** : - **Obligation** :
1. **`git checkout test`** (ou équivalent validé projet) sur le **dépôt applicatif** ; y **réaliser** les corrections (commits selon règles du projet) ; **pousser** **`test`** → **`origin/test`** **hors** cet agent (**`/push-by-script`** ou **`./deploy/pousse.sh kogus`**, etc.) tant que le tip local nest pas sur le remote. 1. **`git checkout test`** (ou équivalent validé projet) sur le **dépôt applicatif** ; y **réaliser** les corrections (commits selon règles du projet) ; **pousser** **`test`** → **`origin/test`** **hors** cet agent (**`/push-by-script`** ou **`./deploy/pousse.sh kogus`**, etc.) tant que le tip local nest pas sur le remote.
2. **Rejouer intégralement** le workflow **depuis létape 2** : **`./deploy/change-to-all-branches.sh [project_id] --align-only`**, puis **étape 3** **`deploy-by-script-to`** vers la cible **pprod** ou **prod**, puis **étapes 4 à 5** comme décrit ci-dessous. Pour un **déploiement test** complet après correctif, enchaîner lagent **`/change-to-all-branches`** en flux **séparé**. 2. **`./deploy/change-to-all-branches.sh [project_id] --align-only`** (alignement uniquement). **Étape 3** (**`deploy-by-script-to`**) et **étapes 4 à 5** : **nouvelle** invocation utilisateur de **`/deploy-pprod-or-prod`** — **pas** de second **`deploy-by-script-to`** dans le run déjà en échec sur létape 3 (**§ Politique — une seule tentative de déploiement**). Pour un **déploiement test** complet après correctif, enchaîner lagent **`/change-to-all-branches`** en flux **séparé**.
- Si plusieurs cycles correction → alignement → déploiement sont nécessaires, **chaque** correction part toujours de **test** puis enchaîne **étape 2 → 5** jusquà succès ou blocage utilisateur. - Si plusieurs cycles correction → alignement sont nécessaires, **chaque** correction part de **test** puis enchaîne **étape 2** si besoin ; **chaque** nouvel essai de **déploiement** (**étape 3**) suppose une **nouvelle** demande utilisateur (**`/deploy-pprod-or-prod`**) après alignement et push, conformément à **§ Politique — une seule tentative de déploiement**.
## Ordre des agents et anti-duplication (obligatoire) ## Ordre des agents et anti-duplication (obligatoire)
@ -84,14 +92,14 @@ Quand **`repository_root`** est le monorepo LeCoffre et **`deploy-by-script-to`*
- **Prérequis** : **`origin/test`** porte le commit à déployer (commits locaux poussés **hors** cet agent : **`/push-by-script`**, **`./deploy/pousse.sh kogus`**, etc.). Si le clone **test** est en avance sur **`origin/test`**, **arrêter** et indiquer de pousser dabord. - **Prérequis** : **`origin/test`** porte le commit à déployer (commits locaux poussés **hors** cet agent : **`/push-by-script`**, **`./deploy/pousse.sh kogus`**, etc.). Si le clone **test** est en avance sur **`origin/test`**, **arrêter** et indiquer de pousser dabord.
- Depuis la racine ia_dev : **`./deploy/change-to-all-branches.sh [project_id] --align-only`** (**pas** dappel **`deploy-lecoffre-all-sites.sh test`** / **`orchestrator.sh test`** dans cette étape). - Depuis la racine ia_dev : **`./deploy/change-to-all-branches.sh [project_id] --align-only`** (**pas** dappel **`deploy-lecoffre-all-sites.sh test`** / **`orchestrator.sh test`** dans cette étape).
- **Ne pas** invoquer lagent **`/change-to-all-branches`** ici : cet agent enchaîne le déploiement **test** ; pour un déploiement test complet, flux séparé **`/change-to-all-branches`**. - **Ne pas** invoquer lagent **`/change-to-all-branches`** ici : cet agent enchaîne le déploiement **test** ; pour un déploiement test complet, flux séparé **`/change-to-all-branches`**.
- **Si KO :** Analyser la sortie (et **`logs/deploy_*.log`** si un outil amont les a alimentés). Toute correction sur le dépôt applicatif : **test** dabord (voir section **Corrections découvertes sur pprod ou prod**), puis relancer l**étape 2** jusqu'à succès. - **Si KO :** Analyser la sortie (et **`logs/deploy_*.log`** si un outil amont les a alimentés). Toute correction sur le dépôt applicatif : **test** dabord (voir section **Corrections découvertes sur pprod ou prod**), puis **au plus une** nouvelle exécution de l**étape 2** dans le même run si léchec est purement dalignement Git ; sinon documenter et sarrêter.
- **Si OK :** Passer à l'étape 3. - **Si OK :** Passer à l'étape 3.
3. **Lancer le script deploy-by-script-to** avec lenvironnement en paramètre (`pprod` ou `prod`) : 3. **Lancer le script deploy-by-script-to** avec lenvironnement en paramètre (`pprod` ou `prod`) :
- Le script est lancé depuis la racine de ia_dev. Avec project_id (optionnel), MAIL_TO ou AI_AGENT_TOKEN le dépôt cible est celui de la conf (deploy.secrets_path). Lancer : `./deploy/deploy-by-script-to.sh [project_id] <pprod|prod>`. - Le script est lancé depuis la racine de ia_dev. Avec project_id (optionnel), MAIL_TO ou AI_AGENT_TOKEN le dépôt cible est celui de la conf (deploy.secrets_path). Lancer : `./deploy/deploy-by-script-to.sh [project_id] <pprod|prod>`.
- **`deploy.host_stays_on_test: true`** dans `projects/<id>/conf.json` (LeCoffre : **true** dans `projects/kogus/conf.json`) : le clone applicatif reste sur **`test`** ; `deploy-by-script-to.sh` ne fait **pas** de `checkout` **pprod**/**prod** ni `reset --hard` sur ces branches ; le playbook **`deploy/scripts_v2`** aligne les remotes / **worktree** et enchaîne **les trois lignes** (**`orchestrator.sh`** ou **`deploy-lecoffre-all-sites.sh`**) — voir **`deploy/README.md`** du dépôt applicatif. - **`deploy.host_stays_on_test: true`** dans `projects/<id>/conf.json` (LeCoffre : **true** dans `projects/kogus/conf.json`) : le clone applicatif reste sur **`test`** ; `deploy-by-script-to.sh` ne fait **pas** de `checkout` **pprod**/**prod** ni `reset --hard` sur ces branches ; le playbook **`deploy/scripts_v2`** aligne les remotes / **worktree** et enchaîne **les trois lignes** (**`orchestrator.sh`** ou **`deploy-lecoffre-all-sites.sh`**) — voir **`deploy/README.md`** du dépôt applicatif.
- **Sinon :** le script fait en général : passage dans le dépôt du projet, `checkout` sur la branche paramètre, vérification que la base secrets attendue par le projet existe (**kogus** / monorepo LeCoffre : imbriquée **`.secrets/<site>/<env>/`**, voir **`repository_root/docs/features/multi-site-architecture.md`** — le seul plat **`.secrets/<env>/`** nest pas le contrat nominal multisite), `reset --hard` sur **`origin/<branche>`**, déploiement (**orchestrateur** ou **`deploy-lecoffre-all-sites.sh`** / repli **`deploy.sh`**), puis **`checkout test`**. - **Sinon :** le script fait en général : passage dans le dépôt du projet, `checkout` sur la branche paramètre, vérification que la base secrets attendue par le projet existe (**kogus** / monorepo LeCoffre : imbriquée **`.secrets/<site>/<env>/`**, voir **`repository_root/docs/features/multi-site-architecture.md`** — le seul plat **`.secrets/<env>/`** nest pas le contrat nominal multisite), `reset --hard` sur **`origin/<branche>`**, déploiement (**orchestrateur** ou **`deploy-lecoffre-all-sites.sh`** / repli **`deploy.sh`**), puis **`checkout test`**.
- **Si KO :** Analyser la sortie et les logs, identifier la cause. **Ne pas** se limiter à corriger sur la branche **pprod**/**prod** : retour **test**, corrections, push **hors** cet agent si besoin, puis **rejouer depuis létape 2** (**`change-to-all-branches.sh --align-only`**, puis **`deploy-by-script-to`**) jusqu'à succès (section **Corrections découvertes sur pprod ou prod**). - **Si KO :** Analyser la sortie et les logs, identifier la cause. **Ne pas** se limiter à corriger sur la branche **pprod**/**prod** : retour **test**, corrections, push **hors** cet agent si besoin, puis **rejouer depuis létape 2** (**`change-to-all-branches.sh --align-only`**) **sans** relancer l**étape 3** (**`deploy-by-script-to`**) dans le même run — section **Corrections découvertes sur pprod ou prod** et **§ Politique — une seule tentative de déploiement**. Un nouvel essai de **`deploy-by-script-to`** = **nouvelle** invocation **`/deploy-pprod-or-prod`**.
- **Si OK :** Passer à l'étape 4. - **Si OK :** Passer à l'étape 4.
4. **Branche test après létape 3 :** si **`deploy.host_stays_on_test`**, le clone est déjà sur **`test`**. Sinon, le script a remis **`test`** : vérifier que la branche courante est **`test`**. 4. **Branche test après létape 3 :** si **`deploy.host_stays_on_test`**, le clone est déjà sur **`test`**. Sinon, le script a remis **`test`** : vérifier que la branche courante est **`test`**.

View File

@ -146,7 +146,7 @@ Si un déploiement est demandé pendant l'exécution, s'arrêter proprement.
- Autres règles du projet - Autres règles du projet
- max-params : 4 - max-params : 4
- complexity : 8 - complexity : 10
- max-nested-callbacks : 3 - max-nested-callbacks : 3
- max-depth : 4 - max-depth : 4
- max-lines-per-function : 40 - max-lines-per-function : 40

View File

@ -23,7 +23,7 @@ is_background: false
4. **Invocation** : depuis la racine du dépôt projet (`cd "$(jq -r '.deploy.repository_root' conf.json)"` ou équivalent) : 4. **Invocation** : depuis la racine du dépôt projet (`cd "$(jq -r '.deploy.repository_root' conf.json)"` ou équivalent) :
- `bash deploy/scripts_v2/run-setup-host.sh <test|pprod|prod>` - `bash deploy/scripts_v2/run-setup-host.sh <test|pprod|prod>`
- Lenvironnement doit être passé explicitement (pas de valeur par défaut métier). - Lenvironnement doit être passé explicitement (pas de valeur par défaut métier).
5. **Secrets** : **`run-setup-host.sh`** résout le répertoire denv via **`lecoffre_secrets_env_dir_for_read`** (layout **`.secrets/<site>/<env>/`** pour LeCoffre, comme **`deploy.sh`** / **`connect-db-paths.sh`**) ; sassurer que **`SITE_CODE`** ou les trois branches **`notary`**, **`enso`**, **`genealogie`** sont peuplées selon le projet — voir **`repository_root/docs/features/multi-site-architecture.md`** pour le projet **kogus** (monorepo LeCoffre). 5. **Secrets** : **`run-setup-host.sh`** résout le répertoire denv via **`lecoffre_secrets_env_dir_for_read`** (layout **`.secrets/<site>/<env>/`** pour LeCoffre, comme **`deploy.sh`** / **`connect-db-paths.sh`**) ; sassurer que **`SITE_CODE`** ou les trois branches **`lecoffreio`**, **`enso`**, **`genealogie`** sont peuplées selon le projet — voir **`repository_root/docs/features/multi-site-architecture.md`** pour le projet **kogus** (monorepo LeCoffre).
6. **Sortie** : ne pas masquer stdout/stderr ; en échec, relire les messages sudo / SSH. 6. **Sortie** : ne pas masquer stdout/stderr ; en échec, relire les messages sudo / SSH.
7. **Clôture** : appliquer `.smartIde/rules/cloture-evolution.mdc` en fin dexécution agent (horodatage, questions 311 selon périmètre touché). 7. **Clôture** : appliquer `.smartIde/rules/cloture-evolution.mdc` en fin dexécution agent (horodatage, questions 311 selon périmètre touché).

View File

@ -0,0 +1,47 @@
#!/usr/bin/env bash
# Infinite loop: one notary-ai-loop-n-cycles.sh run per iteration, then sleep.
# Lowers average wait when a question arrives just after a cycle (vs a long fixed sleep).
#
# From ia_dev root:
# export AI_AGENT_TOKEN=... # or MAIL_TO
# ./ai_working_help/notary-ai/notary-ai-loop-daemon.sh
#
# Env:
# NOTARY_AI_LOOP_DAEMON_SLEEP_SEC default 15 — pause between iterations (seconds).
# Same prerequisites as notary-ai-loop-n-cycles.sh (MAIL_TO or AI_AGENT_TOKEN).
#
set -euo pipefail
if [ -n "${HOME:-}" ] && [ -r "$HOME/.bashrc" ]; then
set +u
# shellcheck source=/dev/null
source "$HOME/.bashrc" 2>/dev/null || true
set -u
fi
[ -n "${HOME:-}" ] && [ -d "$HOME/.local/bin" ] && export PATH="$HOME/.local/bin:$PATH"
NOTARY_AI_DIR="${NOTARY_AI_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)}"
IA_DEV_ROOT="$(cd "${NOTARY_AI_DIR}/../.." && pwd)"
export NOTARY_AI_DIR
cd "$IA_DEV_ROOT"
if [[ -z "${MAIL_TO:-}" && -z "${AI_AGENT_TOKEN:-}" ]]; then
echo "[notary-ai-loop-daemon] Set MAIL_TO or AI_AGENT_TOKEN (see projects/README.md)." >&2
exit 1
fi
SLEEP_SEC="${NOTARY_AI_LOOP_DAEMON_SLEEP_SEC:-15}"
LOOP_SCRIPT="${IA_DEV_ROOT}/ai_working_help/notary-ai/notary-ai-loop-n-cycles.sh"
if [[ ! -x "$LOOP_SCRIPT" && ! -f "$LOOP_SCRIPT" ]]; then
echo "[notary-ai-loop-daemon] Missing script: $LOOP_SCRIPT" >&2
exit 1
fi
echo "[notary-ai-loop-daemon] $(date -Iseconds) start IA_DEV_ROOT=${IA_DEV_ROOT} sleep_between=${SLEEP_SEC}s"
i=0
while true; do
i=$((i + 1))
echo "[notary-ai-loop-daemon] $(date -Iseconds) iteration $i"
bash "$LOOP_SCRIPT" 1 || true
sleep "$SLEEP_SEC"
done

View File

@ -0,0 +1,92 @@
#!/usr/bin/env bash
# Run N cycles of (list pending + optional Cursor agent notary-ai-process + inter-cycle sleep) in foreground.
# From ia_dev root. MAIL_TO or AI_AGENT_TOKEN must be set (see projects/README.md).
#
# Usage: cd <ia_dev_root> && ./ai_working_help/notary-ai/notary-ai-loop-n-cycles.sh [N]
# N = cycles (default 1). Each cycle: list-pending (full stdout/stderr) → if non-empty and
# NOTARY_AI_LOOP_RUN_AGENT=1 and `agent` in PATH, run agent with notary-ai-process prompt → if i<N sleep INTER_CYCLE_SLEEP.
#
# Env:
# NOTARY_AI_LOOP_RUN_AGENT default 1 — set 0 to only list/sleep (no agent invocation when pending).
# NOTARY_AI_AGENT_MODEL default claude-4.6-sonnet-medium (passed to `agent --model`).
# NOTARY_AI_LOOP_INTER_CYCLE_SLEEP_SEC default 15 — pause between cycles when N>1 (was 60).
#
set -euo pipefail
if [ -n "${HOME:-}" ] && [ -r "$HOME/.bashrc" ]; then
set +u
# shellcheck source=/dev/null
source "$HOME/.bashrc" 2>/dev/null || true
set -u
fi
[ -n "${HOME:-}" ] && [ -d "$HOME/.local/bin" ] && export PATH="$HOME/.local/bin:$PATH"
NOTARY_AI_DIR="${NOTARY_AI_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)}"
IA_DEV_ROOT="$(cd "${NOTARY_AI_DIR}/../.." && pwd)"
export NOTARY_AI_DIR
cd "$IA_DEV_ROOT"
N="${1:-1}"
if ! [[ "$N" =~ ^[0-9]+$ ]] || [ "$N" -lt 1 ]; then
echo "[notary-ai-loop-n-cycles] Usage: $0 [N] (N positive integer, default 1)" >&2
exit 1
fi
if [[ -z "${MAIL_TO:-}" && -z "${AI_AGENT_TOKEN:-}" ]]; then
echo "[notary-ai-loop-n-cycles] Set MAIL_TO or AI_AGENT_TOKEN (see projects/README.md)." >&2
exit 1
fi
RUN_AGENT="${NOTARY_AI_LOOP_RUN_AGENT:-1}"
MODEL="${NOTARY_AI_AGENT_MODEL:-claude-4.6-sonnet-medium}"
# Legacy alias from older installs / shell rc (Cursor CLI has no "sonnet-4.6" id).
if [[ "$MODEL" == "sonnet-4.6" ]]; then
MODEL="claude-4.6-sonnet-medium"
fi
INTER_CYCLE_SLEEP="${NOTARY_AI_LOOP_INTER_CYCLE_SLEEP_SEC:-15}"
AGENT_PROMPT="$(cat <<EOF
Tu es l'agent notary-ai-process. Répertoire de travail obligatoire : ${IA_DEV_ROOT}
1) Exécute : ./ai_working_help/notary-ai/list-pending-notary-ai.sh
2) Pour chaque fichier JSON listé : lis request_uid, user_id, user_role, user_office_role (si présent), user_type (si présent), folder_uid, office_uid, question (y compris le bloc « Rappel pour l'agent » lecture seule / périmètre dossier), folder_context. Tu es en lecture seule : tu ne peux pas modifier LeCoffre, la base, les fichiers ou l'état du dossier ; tu ne proposes pas d'actions d'écriture. Avant de rédiger la réponse, rappelle explicitement dans ton raisonnement interne ces identifiants (utilisateur, rôle, dossier, office) : la réponse doit être concise et strictement circonscrite à ce dossier et aux informations accessibles dans folder_context, dans les limites des droits implicites du rôle de l'utilisateur (pas d'extrapolation hors périmètre dossier).
3) Rédige les 4 champs answer, nextActionsTable, membersInfoSheet, synthesisRecommendation (périmètre dossier notarial, pas de RIB ni coordonnées bancaires). Sois **bref** : textes utiles et denses ; pas de redondance entre les champs.
4) Pour chaque entrée, appelle depuis ${IA_DEV_ROOT} :
./ai_working_help/notary-ai/write-response-notary-ai.sh --request-uid "<uid>" --answer "..." --next-actions-table "..." --members-info-sheet "..." --synthesis-recommendation "..."
Traite tous les pending du cycle ; ne pas court-circuiter write-response-notary-ai.sh.
EOF
)"
echo "[notary-ai-loop-n-cycles] $(date -Iseconds) — début ${N} cycles (IA_DEV_ROOT=${IA_DEV_ROOT}, RUN_AGENT=${RUN_AGENT})"
i=1
while [ "$i" -le "$N" ]; do
echo "[notary-ai-loop-n-cycles] $(date -Iseconds) — cycle ${i}/${N}"
tmp="$(mktemp)"
set +e
./ai_working_help/notary-ai/list-pending-notary-ai.sh >"$tmp" 2>&1
list_rc=$?
set -e
cat "$tmp"
if [ "$list_rc" -ne 0 ]; then
echo "[notary-ai-loop-n-cycles] list-pending-notary-ai.sh exit $list_rc (cycle $i)" >&2
rm -f "$tmp"
exit "$list_rc"
fi
if [ -s "$tmp" ] && [ "$RUN_AGENT" = "1" ] && command -v agent >/dev/null 2>&1; then
echo "[notary-ai-loop-n-cycles] $(date -Iseconds) — pending non vide : lancement agent (notary-ai-process)"
if agent -p "$AGENT_PROMPT" -f --model "$MODEL" 2>&1; then
:
else
echo "[notary-ai-loop-n-cycles] $(date -Iseconds) — agent terminé avec erreur ou interruption (cycle $i/$N)" >&2
fi
elif [ -s "$tmp" ]; then
echo "[notary-ai-loop-n-cycles] $(date -Iseconds) — pending non vide mais agent non invoqué (RUN_AGENT=${RUN_AGENT}, agent in PATH: $(command -v agent 2>/dev/null || echo non))" >&2
fi
rm -f "$tmp"
if [ "$i" -lt "$N" ]; then
sleep "$INTER_CYCLE_SLEEP"
fi
i=$((i + 1))
done
echo "[notary-ai-loop-n-cycles] $(date -Iseconds)${N} cycles terminés."

827
ai_working_help/package-lock.json generated Normal file
View File

@ -0,0 +1,827 @@
{
"name": "ai_working_help",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "ai_working_help",
"version": "1.0.0",
"dependencies": {
"body-parser": "^2.2.2",
"express": "^5.2.1"
}
},
"node_modules/accepts": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
"integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==",
"license": "MIT",
"dependencies": {
"mime-types": "^3.0.0",
"negotiator": "^1.0.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/body-parser": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz",
"integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==",
"license": "MIT",
"dependencies": {
"bytes": "^3.1.2",
"content-type": "^1.0.5",
"debug": "^4.4.3",
"http-errors": "^2.0.0",
"iconv-lite": "^0.7.0",
"on-finished": "^2.4.1",
"qs": "^6.14.1",
"raw-body": "^3.0.1",
"type-is": "^2.0.1"
},
"engines": {
"node": ">=18"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/bytes": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
"integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/call-bind-apply-helpers": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/call-bound": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
"integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.2",
"get-intrinsic": "^1.3.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/content-disposition": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.1.0.tgz",
"integrity": "sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==",
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/content-type": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
"integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/cookie": {
"version": "0.7.2",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
"integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/cookie-signature": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz",
"integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==",
"license": "MIT",
"engines": {
"node": ">=6.6.0"
}
},
"node_modules/debug": {
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/depd": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
"integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/dunder-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"es-errors": "^1.3.0",
"gopd": "^1.2.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
"license": "MIT"
},
"node_modules/encodeurl": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
"integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/es-define-property": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-errors": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-object-atoms": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/escape-html": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
"license": "MIT"
},
"node_modules/etag": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
"integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/express": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz",
"integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==",
"license": "MIT",
"dependencies": {
"accepts": "^2.0.0",
"body-parser": "^2.2.1",
"content-disposition": "^1.0.0",
"content-type": "^1.0.5",
"cookie": "^0.7.1",
"cookie-signature": "^1.2.1",
"debug": "^4.4.0",
"depd": "^2.0.0",
"encodeurl": "^2.0.0",
"escape-html": "^1.0.3",
"etag": "^1.8.1",
"finalhandler": "^2.1.0",
"fresh": "^2.0.0",
"http-errors": "^2.0.0",
"merge-descriptors": "^2.0.0",
"mime-types": "^3.0.0",
"on-finished": "^2.4.1",
"once": "^1.4.0",
"parseurl": "^1.3.3",
"proxy-addr": "^2.0.7",
"qs": "^6.14.0",
"range-parser": "^1.2.1",
"router": "^2.2.0",
"send": "^1.1.0",
"serve-static": "^2.2.0",
"statuses": "^2.0.1",
"type-is": "^2.0.1",
"vary": "^1.1.2"
},
"engines": {
"node": ">= 18"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/finalhandler": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz",
"integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==",
"license": "MIT",
"dependencies": {
"debug": "^4.4.0",
"encodeurl": "^2.0.0",
"escape-html": "^1.0.3",
"on-finished": "^2.4.1",
"parseurl": "^1.3.3",
"statuses": "^2.0.1"
},
"engines": {
"node": ">= 18.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/forwarded": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
"integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/fresh": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz",
"integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-intrinsic": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.2",
"es-define-property": "^1.0.1",
"es-errors": "^1.3.0",
"es-object-atoms": "^1.1.1",
"function-bind": "^1.1.2",
"get-proto": "^1.0.1",
"gopd": "^1.2.0",
"has-symbols": "^1.1.0",
"hasown": "^2.0.2",
"math-intrinsics": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
"license": "MIT",
"dependencies": {
"dunder-proto": "^1.0.1",
"es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/gopd": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-symbols": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/hasown": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
"license": "MIT",
"dependencies": {
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/http-errors": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz",
"integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
"license": "MIT",
"dependencies": {
"depd": "~2.0.0",
"inherits": "~2.0.4",
"setprototypeof": "~1.2.0",
"statuses": "~2.0.2",
"toidentifier": "~1.0.1"
},
"engines": {
"node": ">= 0.8"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/iconv-lite": {
"version": "0.7.2",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz",
"integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==",
"license": "MIT",
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3.0.0"
},
"engines": {
"node": ">=0.10.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"license": "ISC"
},
"node_modules/ipaddr.js": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
"license": "MIT",
"engines": {
"node": ">= 0.10"
}
},
"node_modules/is-promise": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
"integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==",
"license": "MIT"
},
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/media-typer": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
"integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/merge-descriptors": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz",
"integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==",
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/mime-db": {
"version": "1.54.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
"integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime-types": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz",
"integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==",
"license": "MIT",
"dependencies": {
"mime-db": "^1.54.0"
},
"engines": {
"node": ">=18"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"license": "MIT"
},
"node_modules/negotiator": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
"integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/object-inspect": {
"version": "1.13.4",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
"integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/on-finished": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
"integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
"license": "MIT",
"dependencies": {
"ee-first": "1.1.1"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"license": "ISC",
"dependencies": {
"wrappy": "1"
}
},
"node_modules/parseurl": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/path-to-regexp": {
"version": "8.4.2",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz",
"integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==",
"license": "MIT",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/proxy-addr": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
"integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
"license": "MIT",
"dependencies": {
"forwarded": "0.2.0",
"ipaddr.js": "1.9.1"
},
"engines": {
"node": ">= 0.10"
}
},
"node_modules/qs": {
"version": "6.14.2",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.14.2.tgz",
"integrity": "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==",
"license": "BSD-3-Clause",
"dependencies": {
"side-channel": "^1.1.0"
},
"engines": {
"node": ">=0.6"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/range-parser": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/raw-body": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz",
"integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==",
"license": "MIT",
"dependencies": {
"bytes": "~3.1.2",
"http-errors": "~2.0.1",
"iconv-lite": "~0.7.0",
"unpipe": "~1.0.0"
},
"engines": {
"node": ">= 0.10"
}
},
"node_modules/router": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
"integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==",
"license": "MIT",
"dependencies": {
"debug": "^4.4.0",
"depd": "^2.0.0",
"is-promise": "^4.0.0",
"parseurl": "^1.3.3",
"path-to-regexp": "^8.0.0"
},
"engines": {
"node": ">= 18"
}
},
"node_modules/safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
"license": "MIT"
},
"node_modules/send": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz",
"integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==",
"license": "MIT",
"dependencies": {
"debug": "^4.4.3",
"encodeurl": "^2.0.0",
"escape-html": "^1.0.3",
"etag": "^1.8.1",
"fresh": "^2.0.0",
"http-errors": "^2.0.1",
"mime-types": "^3.0.2",
"ms": "^2.1.3",
"on-finished": "^2.4.1",
"range-parser": "^1.2.1",
"statuses": "^2.0.2"
},
"engines": {
"node": ">= 18"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/serve-static": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz",
"integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==",
"license": "MIT",
"dependencies": {
"encodeurl": "^2.0.0",
"escape-html": "^1.0.3",
"parseurl": "^1.3.3",
"send": "^1.2.0"
},
"engines": {
"node": ">= 18"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/setprototypeof": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
"license": "ISC"
},
"node_modules/side-channel": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
"integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"object-inspect": "^1.13.3",
"side-channel-list": "^1.0.0",
"side-channel-map": "^1.0.1",
"side-channel-weakmap": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel-list": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
"integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"object-inspect": "^1.13.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel-map": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
"integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
"license": "MIT",
"dependencies": {
"call-bound": "^1.0.2",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.5",
"object-inspect": "^1.13.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel-weakmap": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
"integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
"license": "MIT",
"dependencies": {
"call-bound": "^1.0.2",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.5",
"object-inspect": "^1.13.3",
"side-channel-map": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/statuses": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
"integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/toidentifier": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
"license": "MIT",
"engines": {
"node": ">=0.6"
}
},
"node_modules/type-is": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
"integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==",
"license": "MIT",
"dependencies": {
"content-type": "^1.0.5",
"media-typer": "^1.1.0",
"mime-types": "^3.0.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
"integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
"integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"license": "ISC"
}
}
}

View File

@ -7,7 +7,7 @@
"start": "node server.js" "start": "node server.js"
}, },
"dependencies": { "dependencies": {
"body-parser": "^1.20.2", "body-parser": "^2.2.2",
"express": "^4.18.2" "express": "^5.2.1"
} }
} }

View File

@ -1,6 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# From branch test only: align origin/test, origin/pprod, origin/prod then deploy to test (import V1 is systematic after deploy-app when RUN_DEPLOY=true; see deploy.conf for other RUN_*). # From branch test only: align origin/test, origin/pprod, origin/prod then optionally deploy to test (import V1 is systematic after deploy-app when RUN_DEPLOY=true; see deploy.conf for other RUN_*).
# Usage: ./deploy/change-to-all-branches.sh [project_id] # Usage: ./deploy/change-to-all-branches.sh [project_id] [--align-only]
# --align-only : run branch-align.sh test only (no deploy to test). Used by deploy-pprod-or-prod step 2; full deploy test remains /change-to-all-branches without this flag.
set -euo pipefail set -euo pipefail
SCRIPT_REAL="$(readlink -f "${BASH_SOURCE[0]:-$0}" 2>/dev/null || realpath "${BASH_SOURCE[0]:-$0}" 2>/dev/null || echo "${BASH_SOURCE[0]:-$0}")" SCRIPT_REAL="$(readlink -f "${BASH_SOURCE[0]:-$0}" 2>/dev/null || realpath "${BASH_SOURCE[0]:-$0}" 2>/dev/null || echo "${BASH_SOURCE[0]:-$0}")"
@ -46,14 +47,37 @@ if [[ "$current" != "test" ]]; then
exit 1 exit 1
fi fi
ALIGN_ONLY=false
UNKNOWN_ARGS=()
for _arg in "$@"; do
if [[ "$_arg" == "--align-only" ]]; then
ALIGN_ONLY=true
else
UNKNOWN_ARGS+=("$_arg")
fi
done
if [[ ${#UNKNOWN_ARGS[@]} -gt 0 ]]; then
echo "[change-to-all-branches][ERROR] Unknown arguments: ${UNKNOWN_ARGS[*]} (optional: --align-only)" >&2
exit 1
fi
echo "[change-to-all-branches] Aligning branches..." echo "[change-to-all-branches] Aligning branches..."
"$DEPLOY_DIR/branch-align.sh" test "$DEPLOY_DIR/branch-align.sh" test
if [[ "$ALIGN_ONLY" == "true" ]]; then
echo "[change-to-all-branches] OK (--align-only: deploy test skipped)"
exit 0
fi
# scripts_v2 lives in the host project's deploy/ (not necessarily under ia_dev) # scripts_v2 lives in the host project's deploy/ (not necessarily under ia_dev)
DEPLOY_SCRIPTS_V2="${PROJECT_ROOT}/deploy/scripts_v2" DEPLOY_SCRIPTS_V2="${PROJECT_ROOT}/deploy/scripts_v2"
ALL_SITES="${DEPLOY_SCRIPTS_V2}/deploy-lecoffre-all-sites.sh"
echo "[change-to-all-branches] Deploying test (--no-sync-origin; business flags from deploy.conf only)..." echo "[change-to-all-branches] Deploying test (--no-sync-origin; business flags from deploy.conf only)..."
if [[ -n "${IA_PROJECT_ID:-}" && -x "${DEPLOY_DIR}/orchestrator.sh" ]]; then if [[ -n "${IA_PROJECT_ID:-}" && -x "${DEPLOY_DIR}/orchestrator.sh" ]]; then
"${DEPLOY_DIR}/orchestrator.sh" test --no-sync-origin "${DEPLOY_DIR}/orchestrator.sh" test --no-sync-origin
elif [[ -f "$ALL_SITES" ]]; then
# Monorepo LeCoffre: always chain lecoffreio → enso → genealogie (same as project_orchestrator_path default).
bash "$ALL_SITES" test --no-sync-origin
else else
"${DEPLOY_SCRIPTS_V2}/deploy.sh" test --no-sync-origin "${DEPLOY_SCRIPTS_V2}/deploy.sh" test --no-sync-origin
fi fi

View File

@ -116,7 +116,12 @@ else
_cfg_script="$(ia_dev_resolve_path_from_conf "$PROJECT_CONFIG_PATH" "$_cfg_script")" _cfg_script="$(ia_dev_resolve_path_from_conf "$PROJECT_CONFIG_PATH" "$_cfg_script")"
[[ -n "$_cfg_script" && -x "$_cfg_script" ]] && deploy_script="$_cfg_script" [[ -n "$_cfg_script" && -x "$_cfg_script" ]] && deploy_script="$_cfg_script"
fi fi
"$deploy_script" "$TARGET_BRANCH" all_sites_script="$PROJECT_ROOT/deploy/scripts_v2/deploy-lecoffre-all-sites.sh"
if [[ "${IA_PROJECT_ID:-}" == "kogus" && -f "$all_sites_script" && "$deploy_script" == *"/deploy.sh" ]]; then
bash "$all_sites_script" "$TARGET_BRANCH"
else
"$deploy_script" "$TARGET_BRANCH"
fi
fi fi
if [[ "$HOST_STAYS_ON_TEST" == "true" ]]; then if [[ "$HOST_STAYS_ON_TEST" == "true" ]]; then

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -2,6 +2,13 @@
**Auteur** : Équipe 4NK **Auteur** : Équipe 4NK
## Architecture front — URL API notaire
- Tout nouvel appel HTTP, flux SSE, refresh token ou URL backend dérivée pour lAPI notaire doit passer par **`getBaseUrl()`** (`front-common/src/front/Api/helpers/configHelpers.ts`) ou **`baseApi.getBaseUrl()`** sur un service **`BaseApiService`**, pas par concaténation manuelle de **`BACK_API_*`** ni par composition dURL à partir de **`process.env.NEXT_PUBLIC_BACK_API_*`** en dehors des chemins bootstrap / runtime déjà documentés.
- Préférer le hook **`useApiClient`** et le catalogue **`apiV1Paths`** pour les segments sous **`/api/v1`** ; exposer **`baseUrl`** du hook plutôt que **`protocol` + `host`** isolés.
- Politique **`process.env`**, liste des fichiers autorisés et commandes de contrôle : **`docs/Operations.md`** § *Front — URL API : centralisation sur getBaseUrl()*.
- Détail produit (réécriture dhôte, **`invalidateBaseUrl()`**, anti-patterns) : **`docs/Frontend.md`** § *Base URL backend (API notaire)*.
## Lint backend (back-common) 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) :
@ -49,7 +56,6 @@ Vérification : `npm run lint`, `npm run lint:fix` dans back-common. Référence
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. Tout agent sous `.cursor/agents` doit veiller à l'exécution exhaustive des agents qu'il lance (ou des phases qu'il exécute) : vérification avant clôture ; en cas d'incomplétude : pas de clôture, documenter les manques, améliorer les instructions, relancer jusqu'à exécution exhaustive.
- **Agents de délégation** (agent-loop, fix, evol, docupdate, push-by-script, fix-search, deploy-by-script, fix-lint, gitea-issues-process, code, branch-align-by-script-from-test, change-to-all-branches, deploy-pprod-or-prod, notary-ai-process, notary-ai-loop) : section « Exécution exhaustive des agents lancés » avec vérification obligatoire avant clôture ; en cas d'incomplétude : 1) ne pas clôturer et documenter, 2) améliorer les instructions, 3) relancer l'agent concerné. - **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`.
Aucun déploiement applicatif ; prise en compte à la prochaine invocation des agents. Aucun déploiement applicatif ; prise en compte à la prochaine invocation des agents.