# Rapport de session · 2026-07-30 · session 19 (`20260730_092724`) ## Tâche **Sprint 6 · ERPNext Backend** — Générateur du **Chat OTOIA embarqué par portail** (roadmap `04_roadmap/ROADMAP_8_WEEKS_OR_LESS.md` l.63 : « ERPNext Backend : **Chat OTOIA embedded dans chaque portail** »). C'est le **deuxième volet réalisable en repo** de Sprint 6, après le SEO trilingue (session 18). Le troisième volet Sprint 6 — **OTOIA voice Amélie pilote AEC complet** (BIM/Faisabilité) — dépend d'API externes / desk VPS et reste hors périmètre worker (#8). Le volet « chat embarqué » a en revanche une **tranche repo nette** : le **carrier natif** et sa **config de montage** par portail, indépendants du backend conversationnel réel. ## Décision d'architecture (#1 ERPNext natif) Dans ERPNext v15, un bloc de contenu réutilisable inséré dans un `Workspace` **EST** le DocType `Custom Block` (`frappe/desk/doctype/custom_block`). On ne fabrique donc **aucun** framework de chat externe : on livre **un `Custom Block` par portail** (un `
` de montage vide et déterministe) + la **config runtime** (`chat_mount.json`) que le web-component OTOIA consommera. Chaque `Custom Block` s'ancre sur le `Workspace` du portail produit par le hand-off Sprint 4 (`frontend/portails`). ## Fichiers créés — `05_deliverables_mvp/frontend/chat_otoia/` - `chat_spec.json` — présentation + persona seules (persona Amélie sourcée, capabilities OTOIA sourcées, `ui_label` FR/EN/ES générique, `endpoint: null`, tokens de marque). - `chatlib/{__init__,deps,frappe,knowledge,builder}.py` : - `deps` **réutilise** (#5) le validateur + `branding` Publiciste **et** le builder RBAC↔Workspaces (`frontend/portails/wslib/builder.py`) → même surface RBAC, zéro duplication ; dérive les langues du `seo_spec.json` (source unique). - `frappe` : connaissance du DocType natif `Custom Block` (`block_name` + `html`). - `knowledge` : `roles_allowed` / `knowledge_scope` par portail, dérivés du CONTRAT. - `builder` : assemblage déterministe du bundle. - `chat_otoia_gen.py` — CLI `build`/`validate` · **14 invariants**. - `chat.schema.json` — contrat de sortie draft-07. - `out/{custom_block,chat_mount,MANIFEST}.json` — hand-off. - `tests/test_chat_otoia.py` (**31 tests** dont 11 injections négatives) · `README.md` · `.gitignore`. ## Fichiers modifiés - `.gitea/workflows/ci.yml` : job `chat-otoia-tests` + ajout au `gate`. ## Anti-invention (cœur · #6) Le générateur ne fabrique **aucun fait** : - **endpoint OTOIA = `null` (`a_confirmer`)** — jamais fabriqué ; un invariant refuse tout endpoint non-null et refuse toute URL (`http(s)://`) dans le HTML de montage. - **portée de connaissance = surface RBAC EXACTE du portail** (`permissions_cibles`) : l'assistant ne peut ni prétendre ni exposer un DocType hors du périmètre du portail. Ajouter/retirer un DocType est rejeté par invariant. - **rôles autorisés = rôles du portail**, et un invariant vérifie qu'ils sont **synchronisés avec les Has Role réels des Workspaces** (`portails/out/workspace.json`) → cohérence inter-livrables prouvée. - persona (`Amélie`/`multilingual_v2`), capabilities (`aec/knowledge/prompt_engine/chat.py`) et langues (FR/EN/ES) repris de sources **sourcées** (CLAUDE.md, seo_spec), jamais inventés ; le HTML de montage ne contient **aucun chiffre**. ## Résultat 5 portails métier (`plateforme` exclu comme les Workspaces) · 5 `Custom Block` · **44 rôles couverts** (= total restreint des Workspaces) · **35 DocTypes de connaissance uniques** · endpoint `a_confirmer`. ## Vérifs - **31/31** tests du livrable ; `validate` = schéma + 14 invariants verts ; build déterministe. - Gate CI local vert : guard des contraintes · docs (liens OK) · JSON bien formés. - **Régression : 408 tests verts au total** (377 → +31). ## Hors périmètre worker (VPS · #8) Import des fixtures `Custom Block` (bench) · insertion d'un bloc `custom_block` dans le `content` de chaque Workspace (payload editor.js `a_confirmer` selon patch v15) · renseignement de l'endpoint OTOIA + chargement du web-component via le thème desk · application des tokens dark+doré → agents ERPNext Backend / Frontend. ## Auto-score 4Big : 96/100.