L'appel de cotisations URSSAF 2026 (PDF officiel du 09/07) a permis de qualifier l'imputation, restée explicitement ouverte dans le runbook. La réponse contredit ce qui y était écrit. Le compte 646 est réservé à l'entreprise individuelle et aux sociétés à l'IR : il ne s'applique pas à une SARL à l'IS. La prise en charge par la société des cotisations de son gérant majoritaire est un complément de rémunération — compte 641, sous-compte dédié, déductible. 645 et 631/633 restent vides : aucun salarié, l'opérateur n'est pas employeur. Piège corrigé au passage : la mention « CSG déductible fiscalement » de l'appel vise l'IR personnel du gérant (art. 62 CGI), pas l'IS de la société. Pour la SARL la CSG/CRDS est intégralement déductible — la réintégration annoncée dans un premier temps était un raisonnement d'entreprise individuelle mal transposé. Le runbook affirmait aussi que le type de charge Dolibarr pilotait le compte. Faux : la colonne « Code comptable » du dictionnaire est vide pour tous les types, TAXSSI compris (vérifié cellule par cellule), et le module comptabilité n'est pas déployé. La carte affiche « Code comptable: Inconnu ». L'ERP porte les faits, pas les écritures. Deux corrections de fond sur les dates et les montants : - les dates de l'échéancier sont des dates d'ÉCHÉANCE (le 5 du mois), pas de débit bancaire — 05/05 et non 22/05, ce qui rend visible le retard de 17 jours ; - les 3 041 EUR sont PROVISOIRES, assis sur un forfait début d'activité, et seront régularisés. L'assiette est la rémunération du gérant, jamais le CA. Enfin, découvert en tentant la correction de date : aucune charge sociale n'est modifiable sur ce déploiement. Toute édition, même du seul montant, échoue sur « multiple assignments to same column fk_user_modif » — ChargeSociales::update() génère un UPDATE que PostgreSQL rejette (42601) là où MySQL passe. Le défaut est propre à cet objet ; la mise à jour d'un tiers via REST fonctionne. La date doit donc être juste à la création. updateSocialCharge.ts conserve le cas de reproduction et diagnostique l'erreur au lieu de la subir. Le justificatif officiel est attaché aux trois charges de production. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
test — Dolibarr UI automation (Deno + Playwright)
A small Deno + Playwright POC that drives the Dolibarr admin UI in the fr-FR
locale. Playwright fills the same forms a human admin would, so the automation
works even where the REST API can't (e.g. generating an API key, which is
encrypted with the instance's own DOLI_INSTANCE_UNIQUE_ID).
Layout
main.ts— original entrypoint (first install, company/display/module setup).provisionSandbox.ts— entrypoint that provisions theerp-sandboxinstance for the AI agent (enable REST API, create a write-scoped user, generate its API key).scripts/login.ts— admin login / logout / whoami helpers.scripts/forms.ts—fillForm,toggleOnOff, CKEditor/ACE helpers.scripts/admin/moduleSetup.ts—configureModule,enableApiModule.scripts/admin/userSetup.ts—createUser,assignRights,generateApiKey.
Configure
Copy .env.example to .env and fill it in. .env, *.key, and
.ai_agent_sandbox.key are gitignored — never commit secrets.
cp .env.example .env
Lock the installer (after a fresh install via main.ts)
Dolibarr keeps its web installer reachable until an install.lock file exists.
After a fresh install (the main.ts flow), create it in the target pod — for the
sandbox:
kubectl -n erp-sandbox exec \
"$(kubectl get pod -n erp-sandbox -l app.kubernetes.io/instance=erp-sandbox -o name)" -- \
/bin/sh -c 'touch /var/www/documents/install.lock && chown www-data:www-data /var/www/documents/install.lock'
The path is the Dolibarr data root (/var/www/documents, a PVC) — that's where
Dolibarr checks, and being on the PVC the lock persists across pod restarts. For
prod, swap to -n erp -l app.kubernetes.io/instance=erp. A sandbox seeded from
prod still needs this: the seed (see ../ops/sandbox/) copies the DB +
documents/mycompany, not install.lock.
Provision the sandbox
Provisions erp-sandbox.arcodange.lab: enables the REST API module, creates the
write-scoped ai_agent_sandbox user, grants it its write rights, and has
Dolibarr generate the user's API key. The key is written to
test/.ai_agent_sandbox.key (gitignored) — it is never printed.
cd test
deno run --allow-all provisionSandbox.ts
Populate .env from the erp-sandbox namespace secrets first. secretkv
carries the app env (including DOLI_ADMIN_PASSWORD); vso-db-credentials
carries the database password:
# Admin password (key DOLI_ADMIN_PASSWORD inside the secretkv secret)
kubectl get secret secretkv -n erp-sandbox \
-o jsonpath='{.data.DOLI_ADMIN_PASSWORD}' | base64 -d
# Database password (key `password` inside vso-db-credentials)
kubectl get secret vso-db-credentials -n erp-sandbox \
-o jsonpath='{.data.password}' | base64 -d
Set in .env:
DOLIBARR_ADDRESS=https://erp-sandbox.arcodange.lab
DOLI_ADMIN_LOGIN=admin
DOLI_ADMIN_PASSWORD="<from secretkv above>"
DOLI_DB_PASSWORD="<from vso-db-credentials above>"
# Optional — otherwise a random password is generated and only the API key emitted:
# AI_AGENT_SANDBOX_PASSWORD="<choose one>"
After it runs
The generated API key lands in test/.ai_agent_sandbox.key. Next step (not
automated by this POC): load it into the dolibarr skill's sandbox config /
Vault at kvv2/erp-sandbox/ai_agent.
Important
The sandbox Dolibarr is not installed/provisioned yet (empty DB, fresh install wizard). Until the install wizard has been completed against the sandbox,
provisionSandbox.tswill not have a UI to drive, and the selectors inmoduleSetup.ts/userSetup.tsare best-effort (Dolibarr 22 conventions, not verified live). Confirm them on the first real run.
Write rights granted
The ai_agent_sandbox user is created non-admin and granted (the authoritative
list is WRITE_IDS in provisionSandbox.ts):
| Module | rights ids |
|---|---|
| facture | lire=11, creer=12 |
| societe | lire=121, creer=122, client voir=262 |
| societe contact | lire=281, creer=282 |
| fournisseur | lire=1181, facture lire=1231, facture creer=1232 |
| produit | lire=31, creer=32 |
| banque | lire=111 |
| user | lire=251 — requis par le probe armé GET /users/info (checkpoint status/relink-env) |