[DTP-Worker] Sprint 4 · Générateur DocType porteur OTO Dossier Vente (complète hand-off workflow vente)

DocType custom cible du Workflow OTO Vente Pipeline. Cross-cohérence
workflow↔DocType : nom/champ d'état/valeurs de statut/is_submittable/permissions
tous dérivés de workflow_vente_spec.json (source unique, anti-dérive). Rôles
résolus via rbac_50_roles.json (#6). CLI build|validate · 12 invariants · 31
tests. Job CI crm-dossier-vente-tests ajouté au gate. Régression 177 tests verts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude Code DTP Worker
2026-07-30 06:09:36 +00:00
parent 34f202af40
commit c23dfc24a5
14 changed files with 1668 additions and 1 deletions
@@ -0,0 +1,80 @@
# Daily Report · 2026-07-30 · Claude Code DTP Worker (session 12)
**Session** : `20260730_055704`
## Tâche exécutée
**Sprint 4 · CRM — Générateur du DocType porteur `OTO Dossier Vente`.** Complète
le hand-off du générateur workflow vente (session 11) : le Workflow `OTO Vente
Pipeline` cible un `document_type` **custom** qui doit exister AVANT son import.
Ce module produit ce DocType porteur en-repo (fixture Frappe custom),
**cross-cohérent** avec le contrat pipeline. C'est exactement la « prochaine
tâche suggérée » de la session 11 (DocType porteur `OTO Dossier Vente`).
## Contexte / analyse
- Relu `CLAUDE.md`, `ROADMAP_8_WEEKS_OR_LESS.md`, daily report session 11, et
l'idiome des générateurs CRM/RBAC (`wflib`, `fixtures_gen` : `frappe.py` +
`builder.py` + schéma + CLI `build|validate` + tests + job CI + gate).
- Le workflow vente (session 11) référence `document_type: "OTO Dossier Vente"`
marqué `document_type_custom: true` + `custom_doctypes_a_confirmer` → il
manquait le DocType porteur. Livrable 100 % autorable sans VPS (structure
seule, zéro chiffre · #6).
## Réalisé — module `05_deliverables_mvp/crm/dossier_vente/`
- `doctype_spec.json` — structure métier (libellés + types de champ) : Prospect/
Client (`Link`), Projet (`Select` **P01..P09** ancré CLAUDE.md), Financier
(`Currency` **sans défaut** · devise USD/DOP · #10), jalons de dates, CONFOTUR,
clôture. Les champs de pilotage workflow n'y figurent PAS (injectés).
- `dvlib/frappe.py` — connaissance Frappe v15 native : types de champ légitimes,
modèle de permission (DocPerm intégré), champ `naming_series`, enveloppe
`DocType` custom.
- `dvlib/builder.py` — assemblage **déterministe** + **cross-cohérence** :
dérive du workflow le nom du DocType, le champ d'état, les valeurs de statut,
`is_submittable` et les permissions. Réutilise (`#5`) le `_UPDATE_FIELD` et le
`RoleResolver` du module `workflow_vente` (zéro duplication).
- `doctype.schema.json` — contrat de sortie draft-07 (validateur maison
Publiciste, zéro pip).
- `doctype_dossier_vente_gen.py` — CLI `build`/`validate`. **Refuse d'écrire** si
un des **12 invariants** de cross-cohérence casse.
- `out/` (commité, hand-off direct) : `doctype_oto_dossier_vente.json`,
`MANIFEST.json`.
- `tests/test_dossier_vente.py`**31 tests `unittest` (stdlib pur)**.
- **CI** : job `crm-dossier-vente-tests` ajouté au **gate** (`.gitea/workflows/ci.yml`).
## Cross-cohérence workflow ↔ DocType (le cœur du livrable)
Le DocType n'est pas rédigé indépendamment ; il **dérive** du contrat
`workflow_vente_spec.json` (source unique · anti-dérive) :
- Nom == `document_type` du workflow ; `custom` == `document_type_custom`.
- Champ `workflow_state` (Select `read_only`) : options == les 9 états, ordonnés.
- Champ `statut_pipeline` : options == les `update_value` ; nom **importé** de
`workflow_vente/wflib/builder.py::_UPDATE_FIELD` (renommage propagé).
- `is_submittable` **déduit** des `doc_status` (1/2 ⇒ soumissible).
- Permissions **déduites** des rôles du workflow (édition ⇒ write/+create si
brouillon ; transition→soumis ⇒ submit ; →annulé ⇒ cancel/amend). Noms de rôle
résolus depuis `rbac_50_roles.json` (jamais en dur · #6).
## Vérifications effectuées (en-repo, sans toucher au VPS)
- **31/31 tests verts** (validateur maison + oracle `jsonschema`) ; génération :
30 champs (23 porteurs de donnée) · 7 sections · 7 rôles · submittable=1 ;
`out/` commité == régénération bit-à-bit.
- **Gate CI local vert (exit 0)** : `guard_constraints.sh`, `validate_json.sh`,
`check_docs.sh` (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 +
31 dossier vente = **177 tests verts** au total.
## Non fait (hors périmètre worker · VPS · #8)
- Création du **module** `OTO Ventes` + import réel (`bench migrate`) du DocType,
puis du Workflow qui le cible → agent ERPNext Backend.
## Prochaine tâche suggérée
- Sprint 4 CRM : générateur des **Notification/Email Alert** par transition du
pipeline (relances lead, alerte réservation, dépôt CONFOTUR).
- Sprint 4 ERPNext Backend : barème **commissions vendeurs** (calcul traçable
façon module `finance.py` du bancable · #6) + plan e-CF DGII (Compupar).
---
**Auto-score 4Big du livrable DocType porteur : 96/100.** Réserve 4 : création
du module + import réel = côté VPS (agent ERPNext Backend, hors périmètre worker
· #8). Validé statiquement en-repo (31 tests verts + schéma conforme + 12
invariants de cross-cohérence + gate CI · 177 tests de régression au total).