[DTP-Worker] Sprint 6 · Générateur Chat OTOIA embarqué par portail (Custom Block natif) (ERPNext Backend · roadmap L63)
CI / Contraintes NON-NÉGOCIABLES (CLAUDE.md) (push) Has been cancelled
CI / Validation JSON (schémas Faisabilité) (push) Has been cancelled
CI / Qualité documentaire (liens + 4Big) (push) Has been cancelled
CI / Publiciste · parser + schéma + generator (unittest) (push) Has been cancelled
CI / RBAC · 50 rôles + schéma (unittest) (push) Has been cancelled
CI / Faisabilité · générateur 4 volets + round-trip (unittest) (push) Has been cancelled
CI / RBAC · fixtures ERPNext (Role + Custom DocPerm) (push) Has been cancelled
CI / RBAC · plan User Permission (row-level) (push) Has been cancelled
CI / RBAC · Role Profile (bundles par portail) (push) Has been cancelled
CI / RBAC · run-book d'application unifié (agrégat 3 volets) (push) Has been cancelled
CI / Faisabilité · dossier bancable trilingue FR/EN/ES (push) Has been cancelled
CI / CRM · workflow vente ERPNext (lead → CONFOTUR) (push) Has been cancelled
CI / CRM · DocType porteur OTO Dossier Vente (push) Has been cancelled
CI / CRM · barème commissions vendeurs (push) Has been cancelled
CI / Fiscal · e-CF DGII (Compupar) (push) Has been cancelled
CI / Frontend · Workspaces 5 portails rôle (push) Has been cancelled
CI / Legal · DocType CONFOTUR Application (push) Has been cancelled
CI / QA · Audit 5D conformité (push) Has been cancelled
CI / SEO · mots-clés trilingues + schema.org + hreflang (push) Has been cancelled
CI / Chat OTOIA · montage par portail (Custom Block) (push) Has been cancelled
CI / E2E baseline Playwright (manuel) (push) Has been cancelled
CI / Gate qualité (agrégat) (push) Has been cancelled
CI / Contraintes NON-NÉGOCIABLES (CLAUDE.md) (push) Has been cancelled
CI / Validation JSON (schémas Faisabilité) (push) Has been cancelled
CI / Qualité documentaire (liens + 4Big) (push) Has been cancelled
CI / Publiciste · parser + schéma + generator (unittest) (push) Has been cancelled
CI / RBAC · 50 rôles + schéma (unittest) (push) Has been cancelled
CI / Faisabilité · générateur 4 volets + round-trip (unittest) (push) Has been cancelled
CI / RBAC · fixtures ERPNext (Role + Custom DocPerm) (push) Has been cancelled
CI / RBAC · plan User Permission (row-level) (push) Has been cancelled
CI / RBAC · Role Profile (bundles par portail) (push) Has been cancelled
CI / RBAC · run-book d'application unifié (agrégat 3 volets) (push) Has been cancelled
CI / Faisabilité · dossier bancable trilingue FR/EN/ES (push) Has been cancelled
CI / CRM · workflow vente ERPNext (lead → CONFOTUR) (push) Has been cancelled
CI / CRM · DocType porteur OTO Dossier Vente (push) Has been cancelled
CI / CRM · barème commissions vendeurs (push) Has been cancelled
CI / Fiscal · e-CF DGII (Compupar) (push) Has been cancelled
CI / Frontend · Workspaces 5 portails rôle (push) Has been cancelled
CI / Legal · DocType CONFOTUR Application (push) Has been cancelled
CI / QA · Audit 5D conformité (push) Has been cancelled
CI / SEO · mots-clés trilingues + schema.org + hreflang (push) Has been cancelled
CI / Chat OTOIA · montage par portail (Custom Block) (push) Has been cancelled
CI / E2E baseline Playwright (manuel) (push) Has been cancelled
CI / Gate qualité (agrégat) (push) Has been cancelled
Carrier natif ERPNext v15 (Custom Block) + config runtime par portail. Ancrage RBAC : roles_allowed/knowledge_scope = surface exacte du portail, synchronisés avec les Has Role des Workspaces. Endpoint OTOIA null (a_confirmer). Persona Amélie + capabilities + langues FR/EN/ES sourcés (anti-invention #6). 14 invariants · 31 tests · régression 408 tests verts. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
"""Dépendances partagées du générateur Chat OTOIA · réutilisation stricte (#5).
|
||||
|
||||
On NE réimplémente rien qui existe déjà dans le mandat :
|
||||
- `validator` (validateur JSON-Schema draft-07 maison) et `branding` (tokens de
|
||||
marque #4) sont importés du livrable Publiciste, source unique de vérité.
|
||||
- la résolution RBAC → (rôles / DocTypes autorisés) par portail est importée du
|
||||
builder des Workspaces (`frontend/portails/wslib/builder.py`) : le Chat s'ancre
|
||||
sur EXACTEMENT la même surface RBAC que le portail qui l'héberge — aucune
|
||||
logique dupliquée, aucune dérive possible.
|
||||
|
||||
Entrées consommées (toutes déjà validées/commitées en amont) :
|
||||
- rbac_50_roles.json (contrat RBAC · rôles + permissions_cibles)
|
||||
- frontend/portails/portails_spec.json (les 5 portails métier + libellés)
|
||||
- frontend/portails/out/workspace.json (Has Role réels des Workspaces · hand-off)
|
||||
- seo/seo_spec.json (langues trilingues FR/EN/ES · source unique)
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
|
||||
_HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
_CHAT = os.path.dirname(_HERE) # frontend/chat_otoia/
|
||||
_FRONTEND = os.path.normpath(os.path.join(_CHAT, "..")) # frontend/
|
||||
_DELIVERABLES = os.path.normpath(os.path.join(_FRONTEND, "..")) # 05_deliverables_mvp/
|
||||
_PUBLICISTE = os.path.join(_DELIVERABLES, "publiciste")
|
||||
_PORTAILS = os.path.join(_FRONTEND, "portails")
|
||||
_RBAC_DIR = os.path.join(_DELIVERABLES, "rbac")
|
||||
_SEO = os.path.join(_DELIVERABLES, "seo")
|
||||
|
||||
# Réutilisation : validateur + branding Publiciste, builder des Workspaces.
|
||||
for _p in (_PUBLICISTE, _PORTAILS):
|
||||
if _p not in sys.path:
|
||||
sys.path.insert(0, _p)
|
||||
|
||||
from lib import branding # type: ignore # noqa: E402
|
||||
from lib import validator as maison # type: ignore # noqa: E402
|
||||
from wslib import builder as portails_builder # type: ignore # noqa: E402
|
||||
|
||||
# Chemins des contrats/entrées.
|
||||
SPEC_PATH = os.path.join(_CHAT, "chat_spec.json")
|
||||
SCHEMA_PATH = os.path.join(_CHAT, "chat.schema.json")
|
||||
CONTRACT_PATH = os.path.join(_RBAC_DIR, "rbac_50_roles.json")
|
||||
PORTAILS_SPEC_PATH = os.path.join(_PORTAILS, "portails_spec.json")
|
||||
WORKSPACE_OUT_PATH = os.path.join(_PORTAILS, "out", "workspace.json")
|
||||
SEO_SPEC_PATH = os.path.join(_SEO, "seo_spec.json")
|
||||
|
||||
|
||||
def load_json(path: str) -> object:
|
||||
with open(path, encoding="utf-8") as fh:
|
||||
return json.load(fh)
|
||||
|
||||
|
||||
def load_spec() -> dict:
|
||||
return load_json(SPEC_PATH)
|
||||
|
||||
|
||||
def load_contract() -> dict:
|
||||
return load_json(CONTRACT_PATH)
|
||||
|
||||
|
||||
def load_portails_spec() -> dict:
|
||||
return load_json(PORTAILS_SPEC_PATH)
|
||||
|
||||
|
||||
def load_workspaces() -> list:
|
||||
return load_json(WORKSPACE_OUT_PATH)
|
||||
|
||||
|
||||
def load_langs() -> tuple[list[str], str]:
|
||||
"""Langues + langue par défaut DÉRIVÉES du seo_spec (source unique · #5)."""
|
||||
seo = load_json(SEO_SPEC_PATH)
|
||||
site = seo["site"]
|
||||
return list(site["langs"]), site["default_lang"]
|
||||
|
||||
|
||||
def validate(instance, schema: dict) -> list[str]:
|
||||
return list(maison.validate(instance, schema))
|
||||
|
||||
|
||||
# Réexports pour le builder (surface RBAC = celle des Workspaces).
|
||||
roles_by_portail = portails_builder.roles_by_portail
|
||||
doctypes_by_portail = portails_builder.doctypes_by_portail
|
||||
|
||||
__all__ = [
|
||||
"branding",
|
||||
"load_json",
|
||||
"load_spec",
|
||||
"load_contract",
|
||||
"load_portails_spec",
|
||||
"load_workspaces",
|
||||
"load_langs",
|
||||
"validate",
|
||||
"roles_by_portail",
|
||||
"doctypes_by_portail",
|
||||
"SPEC_PATH",
|
||||
"SCHEMA_PATH",
|
||||
"CONTRACT_PATH",
|
||||
"PORTAILS_SPEC_PATH",
|
||||
"WORKSPACE_OUT_PATH",
|
||||
"SEO_SPEC_PATH",
|
||||
]
|
||||
Reference in New Issue
Block a user