[DTP-Worker] Sprint 4 · Générateur workflow vente ERPNext (lead → CONFOTUR)

Contrat pipeline commercial CRM natif (lead → visite → devis → réservation →
contrat → CONFOTUR) → fixtures Frappe/ERPNext v15 : Workflow (9 états / 11
transitions) + Workflow State + Workflow Action Master + MANIFEST.

Rôles gardant états/transitions résolus depuis rbac_50_roles.json (réutilisation,
zéro duplication · #6) : le contrat ne cite qu'un id de rôle, jamais un nom
Frappe en dur. CLI build/validate refuse d'écrire si l'un des 9 invariants de
graphe casse (monotonie doc_status, atteignabilité, séparation des pouvoirs sur
les étapes engageant de l'argent / clôturant).

25 tests (stdlib pur + oracle jsonschema) · job CI crm-workflow-vente-tests ajouté
au gate · 146 tests de régression verts au total. Application VPS (DocType porteur
OTO Dossier Vente + bench migrate) = agent ERPNext Backend, hors périmètre worker.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude Code DTP Worker
2026-07-30 05:36:27 +00:00
parent 915fc5194a
commit 34f202af40
17 changed files with 1797 additions and 1 deletions
@@ -0,0 +1,95 @@
# Daily Report · 2026-07-30 · Claude Code DTP Worker (session 11)
**Session** : `20260730_052701`
## Tâche exécutée
**Sprint 4 · CRM — Générateur de workflow vente ERPNext** (roadmap
`04_roadmap/ROADMAP_8_WEEKS_OR_LESS.md` §Sprint 4 : « workflow complet **lead →
visite → devis → réservation → contrat → CONFOTUR** »). Prochaine tâche
prioritaire **in-scope worker** après la clôture de la Faisabilité S3 (bancable,
session 10) : premier livrable Sprint 4 100 % autorable sans VPS.
## Contexte / analyse
- Relu `CLAUDE.md`, `ROADMAP_8_WEEKS_OR_LESS.md`, daily report session 10,
l'AGENT.md CRM, le contrat `rbac_50_roles.json` (rôles portails
ventes/direction/compta) et l'idiome des générateurs RBAC (`fixtures_gen` :
`frappe.py`/`builder.py`/`schema`/CLI `build|validate`/tests + job CI + gate).
- État : RBAC **clos** (4 générateurs + run-book), Faisabilité **close**
(4 volets + bancable trilingue). Sprint 4 non entamé en-repo. Le deliverable
CRM « workflow lead→CONFOTUR » est **structurel** (états + rôles), donc sans
aucun chiffre à inventer (#6) et sans dépendance VPS → cible idéale.
- Contrainte #3 (CRM = ERPNext natif) : on produit les DocTypes **natifs du
moteur Workflow de Frappe**, jamais un moteur externe.
## Réalisé — module `05_deliverables_mvp/crm/workflow_vente/`
- `workflow_vente_spec.json` — contrat pipeline canonique : **9 états**
(Lead → Visite planifiée → Devis émis → Réservation confirmée → Contrat signé →
CONFOTUR déposé → CONFOTUR approuvé + Abandonné/Perdu terminaux) · **11
transitions**. Chaque état/transition référence un **`id` de rôle RBAC**
(jamais un nom Frappe en dur).
- `wflib/rbac.py`**réutilisation (workflow #5, zéro duplication)** de
`rbac_50_roles.json` : résout `role_id → erpnext_role_name`. `id` absent ⇒
erreur (aucun rôle inventé · #6) ; renommage RBAC propagé automatiquement.
- `wflib/erpnext.py` — connaissance Frappe v15 native : DocTypes `Workflow`,
`Workflow Document State`, `Workflow Transition`, `Workflow State`,
`Workflow Action Master` ; `doc_status` (0/1/2) + styles de badge natifs.
- `wflib/builder.py` — assemblage **déterministe** (tri stable, aucun
horodatage) : table `states[]`, table `transitions[]` (triées état→action),
maîtres États/Actions uniques, manifeste de traçabilité (rôles RBAC utilisés +
DocType porteur `custom` à confirmer VPS).
- `workflow.schema.json` — contrat de sortie draft-07 (sous-ensemble validateur
maison Publiciste).
- `workflow_vente_gen.py` — CLI `build` / `validate`. **Refuse d'écrire** si un
des **9 invariants de graphe** casse.
- `out/` (commité, hand-off direct) : `workflow.json`, `workflow_state.json`,
`workflow_action_master.json`, `MANIFEST.json`.
- `tests/test_workflow_vente.py`**25 tests `unittest` (stdlib pur)**.
- **CI** : job `crm-workflow-vente-tests` ajouté au **gate**
(`.gitea/workflows/ci.yml`, Gitea Actions uniquement · #2).
## 9 invariants de graphe (le CLI refuse d'écrire si l'un casse)
1. Conformité au schéma de sortie. 2. Unicité des noms d'état. 3. Transitions
vers/depuis états déclarés. 4. **Monotonie `doc_status`** (pas de saut 0→2 ni
retour arrière — natif Frappe). 5. Unicité (état, action). 6. **Atteignabilité**
de tous les états depuis `Lead`. 7. ≥1 état terminal de succès (soumis, sans
sortie) + terminaux sans transition sortante. 8. **Séparation des pouvoirs** :
confirmer réservation / signer contrat / approuver CONFOTUR / annuler = pas
d'auto-approbation. 9. Maîtres États/Actions == graphe + comptes manifeste
cohérents.
## Anti-invention (#6) + séparation des pouvoirs appliqués
- Aucun nom de rôle en dur : tous résolus depuis le contrat RBAC (source unique).
- Aucun chiffre inventé (workflow purement structurel) ; `condition` de
transition laissée `null` (le métier ne documente pas de seuil chiffré).
- Étapes engageant de l'argent / clôturant ⇒ `allow_self_approval = 0`
(quatre-yeux), vérifié par test + CLI.
## Vérifications effectuées (en-repo, sans toucher au VPS)
- **25/25 tests verts** (schéma maison + oracle `jsonschema`) ; génération réelle :
9 états / 11 transitions / 9 maîtres États / 9 maîtres Actions ; `out/` commité
== régénération bit-à-bit.
- **Gate CI local vert (exit 0)** : `guard_constraints.sh`, `validate_json.sh`
(nouveaux JSON valides), `check_docs.sh` (README score présent, 0 lien cassé),
YAML `ci.yml` valide.
- **Régression** : 23 Publiciste + 10 RBAC + 16 Faisabilité + 11 fixtures + 12
userperm + 11 roleprofile + 16 apply_plan + 22 bancable + 25 workflow vente =
**146 tests verts** au total.
## Non fait (hors périmètre worker · VPS)
- Création du DocType porteur `OTO Dossier Vente` + import des fixtures
(`bench migrate`) → agent ERPNext Backend (contrainte #8).
## Prochaine tâche suggérée
- Sprint 4 CRM : générateur des **Notification/Email Alert** par transition, ou
du **DocType porteur `OTO Dossier Vente`** (fixture DocType) pour compléter le
hand-off workflow.
- Sprint 4 ERPNext Backend : plan e-CF DGII (Compupar) + barème commissions
vendeurs (calcul traçable façon module `finance.py` du bancable · #6).
---
**Auto-score 4Big du livrable Générateur workflow vente : 96/100.**
Réserve 4 : création du DocType porteur + import des fixtures = côté VPS (agent
ERPNext Backend, hors périmètre worker · #8) ; `condition` de transition non
peuplée (anti-invention #6). Validé statiquement en-repo (25 tests verts + schéma
conforme + 9 invariants de graphe + gate CI · 146 tests de régression au total).