Imported from zhounsah/kermaria-client-platform (
AGENTS.md). Install upstream withnpx skills add zhounsah/kermaria-client-platform. Copyright stays with the author.
AGENTS.md
Ce fichier s'applique a tout le depot kermaria-client-platform.
Architecture A Ne Pas Casser
- Flux obligatoire :
browser -> WEBPORTAL / BFF -> API-INTERNAL -> MariaDB. apps/webportalest le portail Next.js et le BFF public ; il ne contacte jamais MariaDB, AD, NAS, RDS, VPN ni BPCE directement.apps/api-internalest l'API ASP.NET Core privee et le seul composant autorise a parler a MariaDB, AD, BPCE, SMTP et aux integrations internes.packages/sharedcontient seulement des contrats TypeScript non sensibles ; ne pas y mettre d'URL interne, secret ou logique serveur.- L'architecture applicative reste limitee aux VM
WEBPORTALetAPI-INTERNAL; utiliser le serveur SQL existant, ne pas ajouter de VM SQL. API-INTERNALn'est pas exposee a Internet ;/internal/*exigeX-Service-AuthhorsDevelopment.
Git Et Orchestration Des Agents
- Git est la seule source de vérité du projet.
- Toute tâche commence par vérifier la racine du dépôt, la branche, l’index et le worktree.
- Ne jamais travailler en HEAD détachée.
- Une conversation ou une mémoire d’agent ne remplace pas la documentation versionnée.
- Les analyses architecture, tests, sécurité et documentation peuvent être parallélisées en lecture seule.
- Un seul agent d’écriture intervient sur un même groupe fonctionnel.
- Ne jamais lancer plusieurs agents modifiant les mêmes fichiers.
- Ne jamais restaurer globalement un snapshot, un patch ou une branche de sauvegarde.
- Restaurer les comportements groupe par groupe, avec tests et commits atomiques.
- Tout constat de revue doit être classé VALIDE, FAUX POSITIF ou INCERTAIN avant correction.
- Aucun agent ne commit, push, merge, rebase, tague ou déploie sans demande explicite.
- Avant de terminer une tâche, exécuter les validations applicables puis
examiner :
- git diff --check
- git status --short
- git diff
Toolchain
- Node.js
>=24avec npm etpackage-lock.json; utilisernpm install, pas pnpm/yarn. - .NET SDK fixe par
global.json:10.0.301avecrollForward: latestFeature; projetsnet10.0. NuGet.Configrestaure dans.nuget/packageset lit aussi.nuget-local; ne pas remplacer par une config globale.- Sous PowerShell restrictif, remplacer
npmparnpm.cmd. - Windows PowerShell 5.1 transforme chaque ligne stderr d'un executable natif en
ErrorRecord: avec$ErrorActionPreference = "Stop", un simple avertissement (le client MariaDB 12.x en emet un a chaque appel) coupe le processus en pleine execution. Dans un script, encadrer l'appel natif d'un$ErrorActionPreference = "Continue"et ne juger que sur$LASTEXITCODE.
Commandes
- Installation :
npm installpuisdotnet restore. - Dev API :
$env:ASPNETCORE_ENVIRONMENT="Development"; $env:DOTNET_ENVIRONMENT="Development"; $env:AD_INTEGRATION_MODE="disabled"; dotnet run --project apps/api-internal/Kermaria.ApiInternal.csproj --urls http://localhost:5000. - Dev web :
$env:INTERNAL_API_URL="http://localhost:5000"; $env:ALLOW_LOCAL_INTERNAL_API_URL="true"; npm run dev:web. - Verification web rapide :
npm run typecheck:webportalpuisnpm run lint:webportal; ajouternpm run typecheck:sharedsipackages/sharedchange. - Verification web complete :
npm run check:weblance typecheck shared, lint webportal, typecheck webportal, build webportal. - Builds cibles :
npm run build:webpour Next.js,npm run build:apipour ASP.NET Core. - Validation globale :
npm run validateexecutecheck:secrets, lint/typecheck/build, smoke tests API et la plupart des contrats web. - Contrats web cibles :
npm --prefix apps/webportal run test:<name>pourforms,auth,admin,operations,ux,workflow,notifications,replies,activity,commercial,ad-security,bpce,payments,subscriptions. - Attention :
paymentsetsubscriptionsexistent dansapps/webportal/package.json, pas comme scripts racine ; ne pas les lancer vianpm run test:paymentsdepuis la racine sauf sipackage.jsonchange. - Smoke API seul :
npm run test:apioudotnet test tests/api-internal/Kermaria.ApiInternal.SmokeTests.csproj -c Release; le target MSBuild lance l'executable de test avec le DLL API construit. - Health checks :
npm run check:healthattend APIhttp://127.0.0.1:5000et WEBPORTALhttp://127.0.0.1:3000, ouAPI_INTERNAL_BASE_URL/WEBPORTAL_BASE_URL.
Env, Secrets Et Modes
.env.exampleest un inventaire ; injecter les vraies valeurs hors Git.- Ne jamais introduire
NEXT_PUBLIC_INTERNAL_API_URL,PUBLIC_INTERNAL_API_URL,NEXT_PUBLIC_SERVICE_AUTH_TOKENouPUBLIC_SERVICE_AUTH_TOKEN. - Garder
apps/webportal/lib/runtime-config.ts,internal-api.ts,auth.ts,session-cookie.tsetcsrf-server.tsserver-only. - Session : token brut uniquement dans cookie
HttpOnly; jamais de token/cookie enlocalStorageousessionStorage. SERVICE_AUTH_TOKENdoit correspondre entre WEBPORTAL et API-INTERNAL ; le BFF propage aussiX-Portal-SessionetX-Correlation-Id.- Non-
Developmentrefuse placeholders,DEMO_*,SESSION_COOKIE_SECURE=false,RUN_MARIADB_TESTS=trueet SQL non MariaDB. AD_INTEGRATION_MODE=disabledpar defaut ; pas de hard delete AD, reset password, OU production ou compte Domain Admin.- En production (SRV-13),
controlled_writeest borne parAD_ALLOWED_ROOTS=OU=KoXoAdm,DC=clients,DC=home,DC=bzhetOU=Groupes_TEST,DC=clients,DC=home,DC=bzhsur le domaineclients.home.bzh. L'ancienne mentionOU=TEST_SITE_WEB,DC=home,DC=bzhetait obsolete. AD_USE_CURRENT_WINDOWS_CREDENTIALSdoit valoirfalse: atrue, le code ignoreAD_SERVICE_ACCOUNT_USERNAMEet se lie sous l'identite du service Windows, qui n'a aucune delegation. Symptome trompeur :AD_ACCESS_DENIEDalors que la delegation est correctement posee.BPCE_INTEGRATION_MODE=live,PAYPAL_MODE=liveetEMAIL_INTEGRATION_MODE=livedemandent validation explicite ; en phase de tests, pas de client reel, email externe reel ni prelevement recurrent actif.- Ne pas journaliser tokens, cookies, mots de passe, chaines de connexion,
BPCE_REFRESH_TOKEN,PAYPAL_CLIENT_SECRETni montants complets de facture.
MariaDB Et Migrations
- Le fallback mock est
Developmentseulement ; MariaDB reelle est obligatoire en staging/preprod. - Les migrations sont
apps/api-internal/Migrations/MariaDb/[0-9]*.sqlet sont separees par-- statement-break. - Les migrations ne s'executent pas au demarrage normal ; commande explicite
Development:dotnet run --project apps/api-internal/Kermaria.ApiInternal.csproj -- --apply-migrations. - Le seed fictif exige aussi
--seed-demo-dataet les variablesDEMO_PORTAL_*/DEMO_INTERNAL_ADMIN_*; il est ignore horsDevelopment. - Aucun code de requete ne doit appliquer de migration ni executer de DDL : le compte applicatif (
kermaria_api) n'a pas les droits de schema, la requete echoue enMySqlExceptionet l'API repondSQL_UNAVAILABLE. Verifier une precondition de schema en lecture seule (information_schema.tablesouschema_migrations) et remonter une erreur explicite. - Avant une migration reelle :
npm run backup:mariadb; ne jamais versionner un dump. - Tests MariaDB opt-in : fournir
SQL_*,SERVICE_AUTH_TOKEN,DEMO_*, puisnpm run validate:mariadb; le script poseRUN_MARIADB_TESTS=true.
Staging/Preprod
npm run validate:stagingexigeNODE_ENV=production,ASPNETCORE_ENVIRONMENT=Staging,DOTNET_ENVIRONMENT=Staging,SQL_PROVIDER=mariadb,AD_INTEGRATION_MODE=disabled,SESSION_COOKIE_SECURE=trueet aucunDEMO_*.npm run validate:preprodexigeASPNETCORE_ENVIRONMENT=ProductionetDOTNET_ENVIRONMENT=Productionavec les memes garde-fous.- Ces validateurs appellent
git ls-files; les lancer depuis la racine d'un clone Git, pas depuis une archive.
Exploitation — Topologie Reelle Et Pieges
Faits verifies en production, valables pour tout agent. Detail complet dans
docs/v1.1/deploy/ et docs/koxo-sync.md.
SRV-12 (webportal) — Ubuntu, pas Windows
- Ubuntu 26.04, hors domaine, SSH par cle uniquement (pas de WinRM, 445 ferme).
- Service systemd
kermaria-webportal.service;/opt/kermaria/webportalest un lien symbolique vers/opt/kermaria/releases/<horodatage>-<version>. - Ecoute sur
192.168.100.212:3000, pas surlocalhost. - Livrer en
.tar.gz, jamais en.zip: un zip fabrique sous Windows porte des separateurs\qui deviennent des noms de fichiers litteraux a l'extraction, d'ou une arborescence a plat,status=226/NAMESPACEet un 502 nginx trompeur. .next/cachen'est pas dans l'archive : le creer au deploiement, proprietairekermaria-web, sinon meme panne.sudoexige un mot de passe : les etapes privilegiees reviennent a l'exploitant.
SRV-13 (api-internal) — Windows
- Service
KermariaApiInternal, compteHOME\svc-kermaria, dossierC:\apps\api-internal, sauvegardesapi-internal-old-<yyyyMMdd-HHmmss>. - Joignable en WinRM/Kerberos depuis RDC-07 sans mot de passe. Double saut : une requete LDAP depuis une session WinRM echoue — lancer l'ADSI en local sur RDC-07.
- Le csproj porte
<UseAppHost>false</UseAppHost>: publier avec-p:UseAppHost=true, sinonKermaria.ApiInternal.exemanque et le service n'a plus d'executable. - Configuration : JSON plat
C:\ProgramData\Kermaria\api-internal.config.json, UTF-8 sans BOM, valeurs en chaines. Genere depuis<repo-parent>/kermaria-client-platform.local.env.ps1parscripts/build-api-config.ps1: corriger un reglage aux deux endroits, sinon la regeneration l'annule. - SRV-13 porte en variables Machine des reglages PROD (
SQL_*,AD_*dont le mot de passe,KOXO_SYNC_WEBHOOK_*) qui priment sur le JSON : toute seconde instance doit utiliserKERMARIA_CONFIG_AUTHORITATIVE=true. Le pare-feu Windows y est desactive par GPO (regles locales sans effet). - Journaux JSON dans
C:\apps\api-internal\logs\: ne pas filtrer surError|Exception(chaque ligne contient"Exception":null), filtrer sur"LogLevel":"(Error|Warning|Critical)". La « Reference » affichee dans l'interface est lecorrelation_id.
Environnement DEV
- Stack DEV isolee depuis le 2026-09-21 : WebPortal
192.168.100.212:3100(kermaria-webportal-dev.service), API192.168.100.213:5100(KermariaApiInternalDev), basekermaria_dev. Runbook :docs/DEV_ENVIRONMENT.md, scripts :scripts/dev-env/. APP_ENV=Developmentactive des garde-fous bloquants (code de sortie 78) : cles Stripe live, base/compte hors*_dev, provisioning sansPROVISIONING_ENABLED+ALLOW_DEV_PROVISIONING. Ne jamais les contourner ; corriger la configuration.- Secrets DEV :
<parent du depot>\kermaria-client-platform.dev.env.ps1, jamais melanges au.local.env.ps1LIVE.
Migrations en base reelle
.local.env.ps1definit aussiSQL_USERNAME/SQL_PASSWORD(comptekermaria_api, sans DDL) : le charger d'abord, surchargerkermaria_migratorensuite, sinonCREATE command denied.- Passer
--project <chemin absolu>: lance depuis une autre racine, le runner applique le mauvais checkout. - MySqlConnector materialise les colonnes
CHAR(36)enGuid, pas enstring: utiliser le helperReadIdentifier, jamaisreader.GetString. Les smoke tests tournant en persistance mock, cette classe de bug leur est structurellement invisible.
Chaine KoXo
- Le CSV fait autorite a la synchronisation : retirer une ligne desactive le compte AD correspondant. En revanche il ne porte pas les permissions — les groupes restent pilotes par l'API.
GroupeSecondairedesigne l'OU cible et KoXo la cree si elle n'existe pas.identifiantUniqueest reporte dans l'attribut ADemployeeNumber: seule cle fiable pour rattacher une identite creee par KoXo (le nom est translittere, lesAMAccountNameest derive par KoXo).KOXO_CSV_ENCODINGvaututf8bompar defaut dans le module : sans BOM, KoXo relit le CSV en ANSI etLAUMAILLÉdevientLAUMAILLÉ, puis sa mise en capitales rabote leÃenA— d'ou leLAUMAILLA‰observe dans l'annuaire. Diagnostic :scripts/koxo/Test-KoxoAccentHandling.ps1, a lancer hors session WinRM (la requete LDAP y echoue par double saut).- Aucun accent ne survit dans
sn, quoi qu'on mette dans le CSV (6 essais reels le 2026-08-04) :utf8bom,latin1etunicodedonnent tousLAUMAILLE, etLaumailléenvoye en casse normale ressort enLAUMAILLE. KoXo force la majuscule sur le champNomet desaccentue en le faisant. Ne pas rouvrir le sujet par un changement d'encodage ni par la casse de saisie : c'est mesure, c'est en aval du decodage. Seul levier : reprendresn/displayNameapres synchronisation viaemployeeNumber. - Le
sAMAccountNameest derive du nom a la creation : une resynchronisation ne le change pas, mais supprimer le compte et resynchroniser le regenere (constate le 2026-08-04 :mariececil.gouzerhle→zachary.hounsahou). KoXoAdm.exesort en code 1 meme en succes : se fier aux marqueurs de journal, pas au code de sortie.
Conventions De Code Et Docs
- Documentation utilisateur/exploitant/admin en francais ; noms techniques, routes, variables, types et classes peuvent rester en anglais.
- Quand un contrat API change, synchroniser
packages/shared/src/index.ts, les routes BFFapps/webportal/app/api/*, l'API dansProgram.cs/services/repositories et le script de verification web concerne. - Les mutations admin sensibles doivent rester bornees via le BFF et CSRF (
apps/webportal/lib/csrf-server.ts), puis revalidees/auditees dans API-INTERNAL. - Les offres catalogue se desactivent par PATCH
status: inactive; ne pas ajouter de DELETE d'offre sans changer explicitement le contrat. - Mettre a jour
docs/lorsque le comportement, les flux de securite, les variables ou le deploiement changent.
Mémoire partagée Codex / Claude Code
Ce dépôt utilise .ai/ comme mémoire durable commune à tous les agents.
Au début d'une tâche :
- Lire
.ai/MEMORY.md. - Lire uniquement les
topics/*.mdpertinents. - Si nécessaire, rechercher l'historique avec
rg -n -i "<mot-clé>" .ai/archive. - Revalider les faits dépendant de la production, des versions ou de l'infrastructure avant de les utiliser.
À la fin d'une tâche importante :
- Promouvoir dans
.ai/topics/les découvertes durables utiles aux sessions futures. - Mettre à jour
.ai/MEMORY.mdsi l'état courant ou l'index change. - Ne jamais mémoriser de secret.
- Exécuter
powershell -ExecutionPolicy Bypass -File scripts/check-memory-secrets.ps1.
La mémoire native de l'agent est secondaire : en cas de contradiction, le code / les tests / l'état live puis .ai/ priment.
