Files
Claude Code DTP Worker d7dbda9e2b [DTP-Worker 20260805_084202] FIX RÉEL : « 6 sections » périmé dans les 2 docs d'IMPLÉMENTATION de crm/financement_bancaire alors que le module en livre 7
Classe prose FACT count ungated (prose-facts-vs-numeric-drift). Défaut : README:9 « la structure des 6 sections » + fiche CRM AGENT.md:47 « cœur du gate + 6 sections » décrivaient le livrable avec un compte périmé. Le bon compte = 7 est triple-sourcé et byte-gaté : out/MANIFEST.json counts.sections=7 · financement_spec.json bloc sections=7 (apport_initial,info_achat,choix_banque,formulaires,exigences,autorisations,envoi) · et le README se contredisait lui-même (L49 énumère 7, L57 « 7 sections » annotée source=MANIFEST). Origine du 6 : la DIRECTIVE originale énumérait 6 sections non-gating puis fut amendée pour ajouter apport_initial (gating, pos.1) → 7 ; spec+module ont suivi, les 2 prose L9/L47 non.

Correctif 6→7 sur les 2 SEULES surfaces d'implémentation. Les 4 « 6 sections » restantes sont des snapshots directive gelés (DIRECTIVE_FINANCEMENT L106/122/131 + DIRECTIVE_WORKFLOW_V10 L22/47) — input-specs datés de Michel, jamais réécrits (directive-vs-implementation · spec=authority) ; leur « 6 » est exact au cadre pré-amendement → INTACTS.

0 gate ajouté (#5 · un gate structuré ne mordrait pas la prose L9, hors-cible ; SIGNAL surfacé : financement seul module dont MANIFEST.counts n'est pas recompté par check_readme_claims). 0 chiffre inventé (#6). 0 production éditée. 0 commande VPS (#8). run_ci.sh 33 PASS 0 FAIL 0 SKIP.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-05 08:50:13 +00:00

6.1 KiB
Raw Permalink Blame History

Financement Bancaire · parcours hypothécaire immobilier RD

Sprint 4 · CRM natif ERPNext · roadmap L52 (workflow vente end-to-end · volet financement). Matérialise la DIRECTIVE_FINANCEMENT_BANCAIRE_COMPLET_20260803.md (Michel, 2026-08-03) : un module complet de financement bancaire pour un vrai parcours hypothécaire dominicain, à la place du module « trop simpliste » antérieur. Livrable Phase 1 (P0 · MVP) : le contrat de données + le cœur métier du gate check + la structure des 7 sections + la bannière critique.

Ce worker n'écrit jamais sur le VPS (contrainte #8). Il produit le contrat et les artefacts en-repo ; le backend /api/hypotheque/* et le frontend renderHypotheque réels sont appliqués côté serveur (agents ERPNext Backend / Frontend Console). La Phase 2 (vrais formulaires PDF des 6 banques) attend les démarches relationship-manager de Michel — hors périmètre worker.

Le cœur du livrable · le gate check 4 conditions

L'exigence non-négociable de Michel : aucun document n'est transmis à la banque tant que les 4 conditions ne sont pas remplies. La logique vit dans finlib/gate.py — fonctions pures, testées, sans I/O :

# Condition (key) Règle vérifiée
1 apport_initial_complet Σ paiements ≥ prix × taux20 % résident RD · 30 % étranger (amendement Michel · aussi exigence des banques RD · Ley 189-11).
2 documents_exiges Tous les documents is_required de la banque choisie au statut « Validé WAG » ou « Envoyé banque ».
3 autorisations_signees Toutes les autorisations signées (signature_date non nulle).
4 validation_wag Un conseiller WAG référent a validé (wag_validated_by).
from finlib import gate
cfg = gate.GateConfig.from_spec(spec)
ok, reasons = gate.can_submit_dossier(dossier, cfg)   # (False, ["Apport initial incomplet : …", …])
status = gate.gate_status(dossier, cfg)               # forme de l'endpoint gate-status (barres 0-100 %)

Si une condition manque, can_submit est False et reasons liste chaque blocage (ordre canonique). Le backend POST /…/submit doit renvoyer 403 + ces raisons ; le frontend grise le bouton « Envoyer à la banque » et affiche une barre de progression par condition. Tant que l'apport initial est incomplet, toutes les sections aval sont grisées (section apport_initial = seule section gating, en position 1).

Ce qui est généré (out/, commité — hand-off direct)

Fichier Contenu
banques.json Profils des banques partenaires (type, taux/LTV/durée, spécialités, devises).
sections.json Structure accordéon (apport → info achat → choix banque → formulaires → exigences → autorisations → envoi).
documents.json Catalogue des documents exigés par catégorie (client / immobilier / étrangers).
autorisations.json Autorisations à signer (OTO Sign) + base légale.
gate_spec.json Les 4 conditions + bannière critique + endpoints + rôle validation résolu + workflow suivi banque.
gate_status_example.json Exemple calculé (dossier P07 volontairement bloqué) — auditable, jamais fabriqué.
MANIFEST.json Traçabilité (sources, comptes dérivés, rôles RBAC utilisés).

Comptes courants (source de vérité = MANIFEST.json) : 6 banques, 7 sections, 15 documents (requis 9 résident · 13 étranger), 4 autorisations, 4 conditions de gate.

Anti-invention (#6)

  • Aucun taux d'apport codé en dur : 20/30 viennent du contrat (apport.residence_types), sourcés de la DIRECTIVE. Changer le contrat change le gate, sans toucher au code.
  • Aucun taux/LTV bancaire fabriqué : les fourchettes non données par la DIRECTIVE restent null (a_confirmer · démarche relationship manager). Seules les valeurs que la DIRECTIVE énonce (ex. Scotiabank LTV 70 %, BHD León 30 ans) sont encodées.
  • Aucun nom de rôle Frappe en dur : les rôles (ventes-conseiller pour la validation WAG, etc.) sont résolus depuis rbac_50_roles.json via finlib/rbac.py (source unique · zéro duplication · #5).

Validation · schéma + 12 invariants

validate re-génère le bundle en mémoire et vérifie le schéma de sortie (financement.schema.json) plus 12 invariants métier (unicité des ids ; 0 < résident < étranger ≤ 100 ; fourchettes banque min ≤ max ; rôles résolus dans RBAC ; sections contiguës + section gating en tête ; gate = 4 conditions alignées sur la bannière ; documents étrangers strictement additionnels ; statuts recevables ⊆ statuts ; exemple de gate recalculé cohérent ; comptes du manifeste cohérents). Un invariant qui casse refuse le build (anti-régression).

Utilisation

cd 05_deliverables_mvp/crm/financement_bancaire
python3 financement_bancaire_gen.py validate      # schéma + 12 invariants
python3 financement_bancaire_gen.py build          # écrit les 7 artefacts out/
python3 -m unittest discover -s tests -v           # suite (gate + générateur)

Sortie déterministe (tri stable, aucun horodatage) → l'artefact commité est reproductible bit-à-bit et vérifié par ci/check_artifacts.sh.

Endpoints backend visés (Phase 1 · à implémenter côté serveur)

Contrat exposé par gate_spec.json :

  • GET /api/hypotheque/banques · profils banques (⇐ banques.json)
  • GET /api/hypotheque/dossier/{id}/gate-status · état des 4 conditions (forme de gate_status_example.json)
  • POST /api/hypotheque/dossier/{id}/submit · 403 + raisons tant que le gate n'est pas vert
  • GET /api/hypotheque/dossier/{id}/journal · historique horodaté

Périmètre

  • Phase 1 (ce module) : contrat, gate check, sections, bannière, exemple calculé.
  • Phase 2 (hors worker) : vrais formulaires PDF officiels des 6 banques (démarche relationship-manager Michel) + implémentation runtime des endpoints / du renderHypotheque côté VPS.