911f70b9ab
Générateur brief JSON → data_room/PXX/ (template canonique v1.0) :
- genlib/{model,scorer,renderer}.py : params canoniques imposés (#9/#10),
barème 4Big §7, rendu aligné sur le parser Publiciste (round-trip garanti)
- faisabilite_gen.py : CLI score/scaffold/generate/batch ; axe machine-lisible
PROUVÉ (re-parse Publiciste + validation version.json), jamais auto-décerné
- Anti-invention #6 : champ 🔴 absent → placeholder + champs_manquants +
rétrogradation statut ; prix manquant → {{…}} (jamais 0)
- 16 tests unittest (stdlib, réutilise parser+validateur Publiciste · #5) +
oracle jsonschema ; job CI faisabilite-gen-tests dans le gate (Gitea only #2)
- brief.schema.json + fixtures synthétiques ; README ; GAP §2 mis à jour
Boucle de valeur fermée : generator → data_room → Publiciste → projets_master.json
Auto-score 4Big : 96/100.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
238 lines
22 KiB
Markdown
238 lines
22 KiB
Markdown
# Daily Report · 2026-07-30 · Claude Code DTP Worker
|
||
|
||
**Session** : `20260730_002624`
|
||
|
||
## Tâche exécutée
|
||
**Sprint 1 · Livrable DevOps « CI/CD Gitea Actions »**
|
||
(roadmap `04_roadmap/ROADMAP_8_WEEKS_OR_LESS.md` §Sprint 1 · GAP_ANALYSIS_SPRINT1 §7 = `☐ à faire`).
|
||
|
||
## Contexte / analyse
|
||
- Relu `CLAUDE.md`, `ROADMAP_8_WEEKS_OR_LESS.md`, `GAP_ANALYSIS_SPRINT1.md`, daily report 2026-07-29, AGENT.md DevOps + QA.
|
||
- **Sprint 1 non terminé.** Critères de sortie restants (§7) authorables **dans ce repo sans toucher au VPS** :
|
||
1. **CI/CD Gitea Actions** (DevOps · marqué *PRIORITÉ S1* · gate qualité qui conditionne tous les sprints).
|
||
2. Baseline Playwright (QA) — dépend des endpoints VPS pour s'exécuter réellement.
|
||
- Priorité évidente : **CI/CD Gitea Actions** — 100 % authorable en-repo, débloque le gate qualité 4Big, déjà signalé comme prochaine tâche par la session précédente.
|
||
|
||
## Réalisé
|
||
- Créé `.gitea/workflows/ci.yml` : pipeline Gitea Actions (push/PR `main` + `workflow_dispatch`), 4 jobs → `constraints-guard`, `validate-json`, `check-docs`, `gate` agrégat. Zéro dépendance marketplace hors `actions/checkout`. **Gitea Actions uniquement** (contrainte #2, jamais GitHub).
|
||
- Créé `ci/guard_constraints.sh` : enforce les contraintes NON-NÉGOCIABLES de CLAUDE.md — GitHub/GitLab/Bitbucket (#2), EspoCRM/HubSpot (#3), Stripe (#10), écriture `/var/www/html/static/`, `git clean`, remote git non-Gitea. **Heuristique zéro faux positif** : ignore les lignes portant un marqueur de prohibition (`jamais`/`❌`/`only`/`interdit`…) + escape hatch `ci-allow`.
|
||
- Créé `ci/validate_json.sh` : parse strict de tous les `*.json` suivis (contrat Faisabilité↔Publiciste).
|
||
- Créé `ci/check_docs.sh` : liens Markdown internes cassés [HARD] + présence auto-score 4Big [SOFT].
|
||
- Créé `ci/README.md` : doc pipeline + exécution locale + **procédure d'enregistrement du runner Gitea** (act_runner, à exécuter côté VPS par DevOps).
|
||
- Mis à jour `GAP_ANALYSIS_SPRINT1.md` §7 : critère « CI/CD Gitea Actions » → ✅ (runner VPS restant à confirmer).
|
||
|
||
## Vérifications effectuées (dans le repo, sans toucher au VPS)
|
||
- Les 3 scripts passent au **vert (exit 0)** sur l'état actuel du repo — aucun faux positif sur le texte de politique de CLAUDE.md/AGENT.md.
|
||
- **Test négatif** : fichier de violation temporaire (`hubspot` + `github.com`) → guard retourne **exit 1** et pointe les 2 violations, en ignorant correctement les lignes de prohibition. Fichier de test retiré (repo propre). <!-- ci-allow : cette ligne décrit le test négatif du guard lui-même -->
|
||
|
||
- `git remote -v` = Gitea (`gitea.otov7.com`) → conforme #2.
|
||
|
||
## Non fait (hors périmètre worker · touche au VPS)
|
||
- Enregistrement de l'`act_runner` Gitea (label `ubuntu-latest`) → DevOps sur VPS (procédure dans `ci/README.md` §4).
|
||
- Activation de Gitea Actions au niveau instance + repo → DevOps.
|
||
- Baseline Playwright QA (`/crm`, `/waf-home`, `/qa`, `/choisir-mon-unite`) → nécessite endpoints VPS.
|
||
|
||
## Note de convention
|
||
Rapport écrit dans `05_deliverables_mvp/daily_reports/` (chemin canonique fixé roadmap l.92 + session précédente) plutôt que `05_activity_log/`, pour éviter un doublon (workflow #5).
|
||
|
||
## Prochaine tâche suggérée
|
||
- QA S1 : fichiers Playwright baseline (`tests/e2e/`) — authorables en-repo, exécution différée VPS.
|
||
- Ou Faisabilité S2/S3 : scaffold doc du générateur 4 volets automatique consommant le template v1.0.
|
||
- Ou Publiciste S2 : scaffold doc `otoia/capabilities/publiciste.py` (seul module net-neuf, chemin critique).
|
||
|
||
---
|
||
|
||
**Auto-score 4Big du livrable CI/CD : 96/100.** Réserve −4 : runner Gitea à enregistrer sur VPS (DevOps) avant exécution serveur ; scripts validés localement.
|
||
|
||
---
|
||
|
||
# Daily Report · 2026-07-30 · Claude Code DTP Worker (session 2)
|
||
|
||
**Session** : `20260730_005632`
|
||
|
||
## Tâche exécutée
|
||
**Sprint 1 · Livrable QA « Baseline Playwright »**
|
||
(roadmap §Sprint 1 · `GAP_ANALYSIS_SPRINT1` §7 = `☐ à faire` · suggérée par la session 1).
|
||
|
||
## Contexte / analyse
|
||
- Relu `CLAUDE.md`, `ROADMAP_8_WEEKS_OR_LESS.md`, `GAP_ANALYSIS_SPRINT1.md`, daily report session 1, `AGENT.md` QA, spec `CHOISIR_MON_UNITE`, `ci/ci.yml`.
|
||
- **2 critères de sortie Sprint 1 restants** (§7) : (a) **Baseline Playwright** — 100 % authorable en-repo, exécution différée VPS ; (b) Cartographie DocTypes `otov7_platform` — **nécessite le VPS → hors périmètre worker**.
|
||
- Priorité évidente : **Baseline Playwright** (seul critère S1 restant autorable sans toucher la prod).
|
||
|
||
## Réalisé
|
||
- Projet Playwright **auto-contenu** sous `tests/` :
|
||
- `tests/e2e/routes.json` — data-contract des 4 endpoints Sprint 1 (`/waf-home`, `/crm`, `/qa`, `/choisir-mon-unite`) avec flag `gated`.
|
||
- `tests/e2e/smoke.spec.ts` — **data-driven** : 4 contrôles/route → status < 400 · HTML titré + `<html lang>` · **brand luxury** (`#0a0a12`/`#f0b429` + Fraunces/Cormorant dans le CSS servi) · zéro erreur JS/5xx.
|
||
- `tests/e2e/_shared/contract.ts` — tokens de marque (CLAUDE.md #4) + helpers (reachable, détection mur de login, collecte surface CSS).
|
||
- `tests/playwright.config.ts` — **cible via `DTP_BASE_URL`** (aucune URL codée en dur) · chromium + mobile-safari (acheteurs mobiles) · reporters list/html/junit.
|
||
- `tests/package.json`, `tests/tsconfig.json`, `tests/.gitignore`, `tests/README.md`.
|
||
- **CI** : ajout d'un job `e2e-baseline` **manuel** (`workflow_dispatch`) dans `.gitea/workflows/ci.yml` — hors du gate push/PR (exige serveur live + navigateurs), upload artefact rapport. Reste **Gitea Actions uniquement** (contrainte #2).
|
||
- **Zéro invention (#6)** : aucun prix/superficie/dispo asserté — santé + brand uniquement. Routes `gated` non authentifiées : brand annoté + sauté, pas échoué (baseline tolérante).
|
||
|
||
## Bug corrigé (gate rouge sur `main`)
|
||
- Constat : le gate CI **échouait déjà sur HEAD** (exit 1) — le daily report session 1 (l.26) citait les deux plateformes interdites en prose pour décrire le test négatif du guard, sans marqueur de prohibition reconnu par l'heuristique → **faux positif du guard sur sa propre doc**. <!-- ci-allow : méta-description du correctif, aucun usage réel -->
|
||
|
||
- Correctif : escape hatch documenté `ci-allow` ajouté sur la ligne concernée (mécanisme prévu à cet effet). Gate **repassé au vert**.
|
||
|
||
## Vérifications effectuées (en-repo, sans toucher au VPS)
|
||
- `routes.json` : JSON valide (parse strict).
|
||
- `ci.yml` : YAML valide.
|
||
- **Les 3 scripts du gate** (`guard_constraints.sh`, `validate_json.sh`, `check_docs.sh`) → **exit 0** (vert) après correctif.
|
||
- Confirmé que le gate rouge **préexistait** à mes changements (`git stash` → guard exit 1 sur HEAD).
|
||
|
||
## Non fait (hors périmètre worker · touche au VPS)
|
||
- Exécution réelle de la baseline (`npm install` + `playwright install` + `npm test`) → runner Gitea + `DTP_BASE_URL` sur VPS (DevOps · `ci/README.md §4`).
|
||
- Cartographie DocTypes `otov7_platform` (dernier critère S1) → ERPNext Backend sur VPS.
|
||
|
||
## Prochaine tâche suggérée
|
||
- **Sprint 1 quasi bouclé** : ne reste que la cartographie DocTypes (VPS · ERPNext) + confirmation runner/endpoints (VPS · DevOps/QA).
|
||
- Sinon démarrer S2 en-repo : scaffold doc `otoia/capabilities/publiciste.py` (seul module net-neuf, chemin critique) **ou** spec RBAC 50 rôles (ERPNext S2).
|
||
|
||
---
|
||
|
||
**Auto-score 4Big du livrable Baseline QA : 95/100.** Réserve −5 : exécution serveur différée (runner + `DTP_BASE_URL` VPS, hors périmètre) ; specs validées statiquement en-repo (JSON + YAML + gate vert).
|
||
|
||
---
|
||
|
||
# Daily Report · 2026-07-30 · Claude Code DTP Worker (session 3)
|
||
|
||
**Session** : `20260730_012632`
|
||
|
||
## Tâche exécutée
|
||
**Sprint 2 · Livrable Publiciste « Setup base + parser faisabilité → JSON »**
|
||
(roadmap §Sprint 2 · AGENT.md Publiciste §Livrable Sprint · Semaine 2 · suggérée par session 2).
|
||
|
||
## Contexte / analyse
|
||
- Relu `CLAUDE.md`, `ROADMAP_8_WEEKS_OR_LESS.md`, `GAP_ANALYSIS_SPRINT1.md`, daily reports sessions 1-2, `AGENT.md` Publiciste, template canonique v1.0 + les 2 schémas (`projets_master.schema.json`, `version.schema.json`), `ci.yml`, `guard_constraints.sh`.
|
||
- **Sprint 1 bouclé côté repo** ; les 2 critères restants (cartographie DocTypes, runner/endpoints) touchent le VPS → hors périmètre worker.
|
||
- Priorité évidente : **Publiciste** — seul module net-neuf (`GAP_ANALYSIS §3.13`), chemin critique, démarre S2, contrat de données déjà défini au S1. 100 % autorable en-repo (parser + validateur + generator, zéro API externe, zéro VPS).
|
||
|
||
## Réalisé — module `05_deliverables_mvp/publiciste/` (cible portage : `otoia/capabilities/publiciste.py`)
|
||
- `lib/parser.py` — **cœur du sprint** : `data_room/PXX/` (template v1.0) → dict projet conforme au schéma. Mapping colonnes **par en-tête** (résilient), parsing robuste des montants (USD/DOP, séparateurs FR/US), extraction localisation/services/positionnement FR/rendus.
|
||
- **Anti-invention #6 (défensif)** : statut dérivé de `_META/version.json` ; **rétrogradation** en « en_developpement » si un prix USD manque (jamais publier de prix douteux) ; cellule vide/`{{…}}`/« non défini » → `null` (jamais `0`).
|
||
- `lib/validator.py` — validateur **JSON-Schema draft-07 (sous-ensemble)** **zéro dépendance pip** (le runner Gitea n'a pas `pip`). Couvre type/enum/pattern/required/additionalProperties/items/allOf/if-then/const/min-max… Oracle `jsonschema` utilisé en test **s'il est présent**.
|
||
- `lib/generator.py` + `templates/site_public.html.tmpl` + `lib/branding.py` — rendu HTML **luxury #4** (dark `#0a0a12` + doré `#f0b429`, Fraunces + Cormorant Garamond). Projet sans prix → « Prochainement · Détails à venir » (aucun prix inventé).
|
||
- `publiciste.py` — orchestrateur CLI : `parse` / `validate` / `generate` / `run`.
|
||
- `fixtures/` — données **synthétiques** de test (P01 complète, P02 incomplète) clairement marquées « ne jamais publier » (respect #6).
|
||
- `tests/test_publiciste.py` — **23 tests `unittest`** (stdlib pur) : parsing, extraction, rétrogradation défensive, conformité schéma (maison + oracle), rendu marque + zéro prix inventé.
|
||
- **CI** : job `publiciste-tests` ajouté au **gate** de `.gitea/workflows/ci.yml` (Gitea Actions uniquement · #2) → `unittest` sans installation pip.
|
||
- `README.md` module + `.gitignore` (artefacts `build/`).
|
||
|
||
## Vérifications effectuées (en-repo, sans toucher au VPS)
|
||
- **23/23 tests `unittest` verts.**
|
||
- Pipeline CLI complet sur fixtures : `run` → `projets_master.json` **conforme au schéma** + `index.html` (2 projets ; P01 « disponible » avec prix, P02 « en développement » sans prix).
|
||
- **Gate CI local vert (exit 0)** : `guard_constraints.sh`, `validate_json.sh` (inclut les 2 `version.json` fixtures), `check_docs.sh` (0 lien cassé ; ⚠ 4Big = SOFT sur fixtures uniquement).
|
||
- Aucun terme interdit introduit (guard #2/#3/#10 vert).
|
||
|
||
## Non fait (hors périmètre worker · touche au VPS ou calendrier ultérieur)
|
||
- Exécution contre les **données réelles** `data_room/` (VPS · ERPNext/Faisabilité).
|
||
- Triggers systemd `otoia-publiciste.timer` + watch inotify (Semaine 4 · VPS).
|
||
- Notifications WhatsApp Michel (Semaine 5 · VPS).
|
||
- Génération copy **EN/ES** automatique (Semaine 6 ; seul le FR est extrait aujourd'hui).
|
||
- DocType Frappe `Publiciste Log` (VPS · ERPNext).
|
||
|
||
## Prochaine tâche suggérée
|
||
- Publiciste S3 : brancher le generator sur un layout proche de `/waf-home` (Frontend) + intégrer les 6 vues/projet (dépend Rendu S3).
|
||
- Ou ERPNext S2 : spec **RBAC 50 rôles** (autorable en-repo comme document de conception).
|
||
- Ou Faisabilité S2 : générateur 4 volets auto consommant le template v1.0 (produit les `data_room/PXX/` que le parser Publiciste consomme).
|
||
|
||
---
|
||
|
||
**Auto-score 4Big du livrable Publiciste (parser) : 95/100.** Réserve −5 : exécution contre `data_room/` réel différée (VPS) ; triggers/notifications/EN-ES = livrables Semaines 4-6 ; validé statiquement en-repo (23 tests verts + gate CI vert + schéma conforme).
|
||
|
||
---
|
||
|
||
# Daily Report · 2026-07-30 · Claude Code DTP Worker (session 4)
|
||
|
||
**Session** : `20260730_015634`
|
||
|
||
## Tâche exécutée
|
||
**Sprint 2 · Livrable ERPNext Backend « RBAC 50 rôles »**
|
||
(roadmap `04_roadmap/ROADMAP_8_WEEKS_OR_LESS.md` §Sprint 2 l.38 · `GAP_ANALYSIS_SPRINT1` §3.4 · suggérée par session 3).
|
||
|
||
## Contexte / analyse
|
||
- Relu `CLAUDE.md`, `ROADMAP_8_WEEKS_OR_LESS.md`, `GAP_ANALYSIS_SPRINT1.md`, daily reports sessions 1-3, `AGENT.md` ERPNext Backend + Frontend Console, `AGENTS_EXISTING_ASSETS.md` §4-6, `projets_master.schema.json`, `validator.py`, `ci.yml`.
|
||
- **Sprint 1 bouclé côté repo** ; Sprint 2 : 3 deliverables. Frontend (clone 5 entités) + CRM (pipeline) dépendent des layouts LIVE `/waf-home` / `/crm.html` (VPS). **RBAC 50 rôles = seul deliverable S2 100 % autorable en-repo** comme spec de conception machine-lisible → priorité évidente. Dépendance amont des 5 portails rôle (S4) et du workflow vente.
|
||
|
||
## Réalisé — module `05_deliverables_mvp/rbac/`
|
||
- `rbac.schema.json` — contrat JSON-Schema draft-07 (sous-ensemble supporté par le validateur maison, **zéro pip**) : 50 rôles, `id` kebab, `erpnext_role_name` préfixe `OTO `, `permissions_cibles[]` (DocType + verbes Frappe), `scope_donnees` (own/equipe/entite/groupe), `cible_rbac_roles` const 50.
|
||
- `rbac_50_roles.json` — **50 rôles** répartis sur 5 portails métier (roadmap S4) + 1 console technique (`plateforme`), mappés aux **entités CLAUDE.md** (WAF/WA SRL/AC Arias Cuevas/Consortium ECR DR/Helios RD/Ploutos/9060 QC/Groupe). Permissions ciblant des **DocTypes ERPNext v15 natifs** (Lead/Opportunity/Quotation/Sales Order/Purchase Order/Journal Entry/Salary Slip…) + DocTypes DTP marqués `custom: true` (à confirmer VPS).
|
||
- `RBAC_50_ROLES_SPEC.md` — design : modèle RBAC 3 niveaux (Role · DocPerm · User Permission), cartographie portails/familles/entités, conformité contraintes #1/#3/#6/#8, **séparation des pouvoirs** (`set_user_permissions` réservé au RBAC Admin), procédure d'application VPS (fixtures `bench`, hors périmètre worker).
|
||
- `tests/test_rbac.py` — **10 tests `unittest` (stdlib)** : **réutilise le validateur Publiciste** (pas de duplication · workflow #5) + oracle `jsonschema` si présent ; vérifie exactement 50 rôles, unicité `id`/nom Frappe, couverture des 5 portails, anti-élévation de privilège.
|
||
- **CI** : job `rbac-tests` ajouté au **gate** de `.gitea/workflows/ci.yml` (Gitea Actions uniquement · #2).
|
||
- `GAP_ANALYSIS_SPRINT1.md` §3.4 mis à jour (RBAC design livré S2).
|
||
|
||
## Anti-invention (#6) appliqué
|
||
- **Aucun chiffre/plafond monétaire inventé** : seuls rôles, entités et DocTypes natifs. Plafonds d'approbation volontairement non chiffrés (à définir avec la Direction sur pièces).
|
||
- DocTypes non natifs marqués `custom: true` → **existence à confirmer VPS** avant application (respect de l'interdit « documenter code sans vérifier existence courante »).
|
||
|
||
## Vérifications effectuées (en-repo, sans toucher au VPS)
|
||
- **10/10 tests RBAC verts** (schéma maison **+** oracle `jsonschema` installé → concordance draft-07 confirmée).
|
||
- **Gate CI local vert (exit 0)** : `guard_constraints.sh`, `validate_json.sh` (inclut `rbac_50_roles.json`), `check_docs.sh` (0 lien cassé ; spec RBAC porte son auto-score 4Big).
|
||
- **Régression** : 23/23 tests Publiciste toujours verts (réutilisation du validateur sans effet de bord).
|
||
|
||
## Non fait (hors périmètre worker · touche au VPS)
|
||
- Génération + application des **fixtures `Role`/`Custom DocPerm`** sur `erpnext-backend-1` (`bench migrate`) → agent ERPNext Backend.
|
||
- Création des DocTypes DTP `custom` (`Faisabilité`, `Publiciste Log`, `CONFOTUR Application`, `API Access`) après confirmation VPS.
|
||
- Mapping `scope_donnees` → `User Permission` par utilisateur → VPS.
|
||
- Cartographie DocTypes réels `otov7_platform` (dernier critère S1) → ERPNext sur VPS.
|
||
|
||
## Prochaine tâche suggérée
|
||
- ERPNext S2 : **générateur de fixtures** `rbac_50_roles.json → fixtures/` (même patron que le Publiciste, autorable en-repo).
|
||
- Ou Faisabilité S2 : générateur 4 volets auto consommant le template v1.0 (produit les `data_room/PXX/` consommés par le parser Publiciste).
|
||
- Ou Frontend/CRM S2 : nécessite les layouts LIVE (VPS) → hors périmètre worker.
|
||
|
||
---
|
||
|
||
**Auto-score 4Big du livrable RBAC 50 rôles : 95/100.** Réserve −5 : application fixtures + DocTypes `custom` + `User Permission` = côté VPS (agent ERPNext, hors périmètre) ; plafonds monétaires non chiffrés (anti-invention #6). Validé statiquement en-repo (10 tests verts + schéma conforme + gate CI vert).
|
||
|
||
---
|
||
|
||
# Daily Report · 2026-07-30 · Claude Code DTP Worker (session 5)
|
||
|
||
**Session** : `20260730_022639`
|
||
|
||
## Tâche exécutée
|
||
**Sprint 2 · Livrable Faisabilité « Générateur 4 volets automatique »**
|
||
(roadmap `04_roadmap/ROADMAP_8_WEEKS_OR_LESS.md` §Sprint 2/3 · `03_agents/faisabilite/AGENT.md` §Livrable S2 · `GAP_ANALYSIS_SPRINT1` §2 · suggérée par sessions 3-4).
|
||
|
||
## Contexte / analyse
|
||
- Relu `CLAUDE.md`, `ROADMAP_8_WEEKS_OR_LESS.md`, `GAP_ANALYSIS_SPRINT1.md`, daily reports sessions 1-4, `AGENT.md` Faisabilité, template canonique v1.0 + `version.schema.json`, **parser Publiciste** (`lib/parser.py`) + `publiciste.py`.
|
||
- **Sprint 1 bouclé côté repo** ; Sprint 2 : RBAC (session 4) + Publiciste parser (session 3) livrés. Frontend/CRM dépendent des layouts LIVE (VPS · hors périmètre).
|
||
- Priorité évidente : **Générateur Faisabilité 4 volets** — sur le **chemin critique**, produit les `data_room/PXX/` que le parser Publiciste (déjà livré) consomme. **Ferme la boucle de valeur** et 100 % autorable en-repo (zéro API, zéro VPS). Vérifiable end-to-end : générateur → parser → schéma.
|
||
|
||
## Réalisé — module `05_deliverables_mvp/faisabilite/generator/`
|
||
- `genlib/model.py` — constantes **canoniques** (3 %/8.5 %/52 % · USD+DOP · Cardnet · Letter US · #9/#10, **imposées, jamais issues du brief**) + tables des champs 🔴 par volet + `is_filled()` (détecte placeholders/absences).
|
||
- `genlib/scorer.py` — **barème 4Big §7** (5 axes × 20) : complétude, anti-gap prix (§3.2), traçabilité (`sources[]` + taux daté/sourcé), paramètres canoniques, machine-lisible. Dérive `statut_faisabilite` / `volets_complets` / `champs_manquants` cohérents avec la contrainte `allOf` de `version.schema.json`.
|
||
- `genlib/renderer.py` — rend les 4 volets + brief + commercial + manifeste photos + `_META/version.json`, avec **en-têtes/colonnes exactement alignés sur le parser Publiciste** (garantit le round-trip). Champ absent → placeholder `{{…}}` (**jamais de chiffre inventé · #6**).
|
||
- `faisabilite_gen.py` — CLI `score` / `scaffold` / `generate` / `batch`. L'axe machine-lisible n'est **pas auto-décerné** : après génération, le CLI **re-parse** le projet avec le parser Publiciste + **valide** `version.json` → en cas d'échec, retire les 20 pts, réécrit `version.json`, sort en erreur.
|
||
- `brief.schema.json` (contrat d'entrée) + `fixtures/` **synthétiques** (`brief_complete.json` → complete 100/100 ; `brief_incomplete.json` → prix absents → rétrogradation `en_developpement`, prix restés placeholders).
|
||
- `tests/test_generator.py` — **16 tests `unittest` (stdlib pur, zéro pip)** : scoring, rétrogradation défensive, paramètres canoniques, et **round-trip end-to-end** generator → parser Publiciste → `projets_master.json` validé contre le schéma. **Réutilise** parser + validateur Publiciste (aucune duplication · workflow #5) + oracle `jsonschema` si présent.
|
||
- **CI** : job `faisabilite-gen-tests` ajouté au **gate** de `.gitea/workflows/ci.yml` (Gitea Actions uniquement · #2).
|
||
- `README.md` + `.gitignore` ; `GAP_ANALYSIS_SPRINT1.md §2` mis à jour (générateur livré S2).
|
||
|
||
## Anti-invention (#6) appliqué
|
||
- Paramètres canoniques émis par le générateur (jamais du brief) → impossibles à fausser projet par projet.
|
||
- Tout 🔴 absent → placeholder + `champs_manquants` + rétrogradation ; prix manquant → `{{…}}` (jamais `0`).
|
||
- Fixtures **clairement synthétiques** (`"synthetique": true` + bannière « ne jamais publier »).
|
||
|
||
## Vérifications effectuées (en-repo, sans toucher au VPS)
|
||
- **16/16 tests verts** (schéma maison **+** oracle `jsonschema` → concordance draft-07 confirmée).
|
||
- **Pipeline complet démontré en CLI** : `batch fixtures` → `data_room/{P01,P02}/` → **Publiciste `run`** → `projets_master.json` (2 projets : P01 `disponible`/3 typo, P02 `en_developpement`/2 typo) + `index.html`. Round-trip cohérent de bout en bout.
|
||
- **Gate CI local vert (exit 0)** : `guard_constraints.sh`, `validate_json.sh` (inclut `brief.schema.json` + fixtures), `check_docs.sh` (0 lien cassé), YAML `ci.yml` valide.
|
||
- **Régression** : 23/23 tests Publiciste + 10/10 tests RBAC toujours verts (réutilisation sans effet de bord).
|
||
|
||
## Non fait (hors périmètre worker · VPS ou calendrier ultérieur)
|
||
- Génération contre les **briefs réels** P01-P09 (VPS · Faisabilité) — régénération batch des 7 faisabilités = **S4**.
|
||
- `40_llm_outputs/` marché/directeur/fiscal/juridique + rapports bancables FR/EN/ES + archives auto `_ARCHIVES/` (S3+).
|
||
- Trigger `otoia-faisabilite.timer` + notification Publiciste/WhatsApp (S6 · VPS).
|
||
|
||
## Prochaine tâche suggérée
|
||
- Faisabilité S3 : générer les `40_llm_outputs/` + rapports bancables FR/EN/ES depuis le brief (étend le renderer).
|
||
- Ou ERPNext S2 : générateur de fixtures `rbac_50_roles.json → fixtures/` (même patron, autorable en-repo).
|
||
- Ou Publiciste S3 : brancher le generator HTML sur un layout proche de `/waf-home` (dépend layout LIVE · VPS).
|
||
|
||
---
|
||
|
||
**Auto-score 4Big du livrable Générateur Faisabilité : 96/100.** Réserve −4 : exécution contre les briefs réels P01-P09 différée (VPS · S4) ; `40_llm_outputs`/bancables/archives = livrables S3+. Validé statiquement en-repo (16 tests verts + round-trip end-to-end démontré + gate CI vert).
|