[DTP-Worker] Sprint 5 · Générateur Audit 5D conformité (QA · roadmap L58)
Audit de second niveau : lit les hand-off out/ des livrables (workflow vente, Dossier Vente, commissions, e-CF DGII, CONFOTUR) et vérifie 17 contrôles en 5 dimensions (D1 Traçabilité/ISA 500 · D2 AML-UAF/Ley 155-17 · D3 Fiscal e-CF/Ley 32-23 · D4 Intégrité/IFRS · D5 Gouvernance-SoD/ISA 315). Anti-invention #6 : paramètre réglementaire non confirmé → A_CONFIRMER (open item assigné au métier), jamais fabriqué. Verdict PASS_WITH_OPEN_ITEMS (13 PASS, 0 FAIL, 4 à confirmer). Réutilise validateur Publiciste + RoleResolver CRM + roles_targeting CONFOTUR (zéro duplication). 37 tests · 15 invariants · build déterministe · régression 341 tests verts. Job CI qa-audit-5d-tests + gate. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
"""Chargement des livrables audités (sortie `out/` des modules voisins).
|
||||
|
||||
L'audit 5D est un audit de SECOND NIVEAU : sa matière première est le hand-off
|
||||
JSON déjà commité par chaque générateur. On ne relance pas les générateurs — on
|
||||
lit leur produit tel qu'il sera importé côté VPS. Chaque artefact absent lève une
|
||||
erreur explicite (un audit sur un livrable manquant serait mensonger).
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
from typing import Any
|
||||
|
||||
_HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
_DELIVERABLES = os.path.normpath(os.path.join(_HERE, "..", "..", ".."))
|
||||
|
||||
# id logique → chemin relatif au dossier 05_deliverables_mvp
|
||||
ARTIFACT_PATHS: dict[str, str] = {
|
||||
"workflow": os.path.join("crm", "workflow_vente", "out", "workflow.json"),
|
||||
"dossier": os.path.join("crm", "dossier_vente", "out",
|
||||
"doctype_oto_dossier_vente.json"),
|
||||
"commissions": os.path.join("crm", "commissions", "out",
|
||||
"commission_plan.json"),
|
||||
"ecf": os.path.join("fiscal", "ecf_dgii", "out", "ecf_plan.json"),
|
||||
"confotur": os.path.join("legal", "confotur", "out",
|
||||
"doctype_confotur_application.json"),
|
||||
}
|
||||
|
||||
|
||||
def _load(rel: str) -> Any:
|
||||
path = os.path.join(_DELIVERABLES, rel)
|
||||
if not os.path.exists(path):
|
||||
raise FileNotFoundError(
|
||||
f"Artefact audité introuvable : {rel} — le générateur amont doit "
|
||||
f"avoir écrit son `out/` avant l'audit 5D (aucun audit à vide)."
|
||||
)
|
||||
with open(path, encoding="utf-8") as fh:
|
||||
return json.load(fh)
|
||||
|
||||
|
||||
def load_artifacts() -> dict[str, Any]:
|
||||
"""Charge les 5 livrables. Le workflow est une liste ; on expose l'objet."""
|
||||
raw = {aid: _load(rel) for aid, rel in ARTIFACT_PATHS.items()}
|
||||
wf = raw["workflow"]
|
||||
if not isinstance(wf, list) or not wf:
|
||||
raise ValueError("workflow.json attendu = liste non vide de Workflow.")
|
||||
raw["workflow"] = wf[0]
|
||||
return raw
|
||||
|
||||
|
||||
def known_ids() -> frozenset[str]:
|
||||
return frozenset(ARTIFACT_PATHS)
|
||||
Reference in New Issue
Block a user