mirror of
https://github.com/JMP-MS/ASPIC.git
synced 2026-10-27 16:07:10 +00:00
V1.14.15 Mise en plce des consignes et premiers tests
This commit is contained in:
@@ -57,10 +57,11 @@ Pour les trois documents de ce projet (ce journal — résumé/index —, les R
|
||||
- 27. Pilotage vocal
|
||||
- 28. Écran de fond
|
||||
- 29. Interprétation vocale des contacts par LLM
|
||||
- 30. Chantier des consignes — moteur générique
|
||||
|
||||
*(Numérotation et titres repris du découpage fait par Jean-Marc le 31 août 2026, légèrement reformulés par lui à cette occasion — se référer aux fichiers eux-mêmes pour le libellé exact. Section 27 (Pilotage vocal) validée de bout en bout et son fichier définitif déposé dans `/journal` le 2 septembre 2026. Section 28 (Écran de fond) ouverte le 2 septembre 2026, toujours **en cours** — passée d'une maquette graphique exploratoire à un premier essai fonctionnel réel, puis (soirée du 2 au 3 septembre) à une pastille de comptage sur le classeur Contacts et à un premier affichage réel des post-its personnels sur le tableau de liège. Section 29 (Interprétation vocale des contacts par LLM) ouverte et son fichier définitif déposé le 4 septembre 2026 après validation de bout en bout sur un premier corpus réel ; fichiers de section à déposer par Jean-Marc, voir Statut actuel.)*
|
||||
*(Numérotation et titres repris du découpage fait par Jean-Marc le 31 août 2026, légèrement reformulés par lui à cette occasion — se référer aux fichiers eux-mêmes pour le libellé exact. Section 27 (Pilotage vocal) validée de bout en bout et son fichier définitif déposé dans `/journal` le 2 septembre 2026. Section 28 (Écran de fond) ouverte le 2 septembre 2026, toujours **en cours** — passée d'une maquette graphique exploratoire à un premier essai fonctionnel réel, puis (soirée du 2 au 3 septembre) à une pastille de comptage sur le classeur Contacts et à un premier affichage réel des post-its personnels sur le tableau de liège. Section 29 (Interprétation vocale des contacts par LLM) ouverte et son fichier définitif déposé le 4 septembre 2026 après validation de bout en bout sur un premier corpus réel ; fichiers de section à déposer par Jean-Marc, voir Statut actuel. Section 30 (Chantier des consignes — moteur générique) ouverte le 6 septembre 2026, fichier définitif rédigé le soir même après validation de bout en bout du mécanisme sur des cas réels ; fichier de section à déposer par Jean-Marc, voir Statut actuel.)*
|
||||
|
||||
## Statut actuel (2-4 septembre 2026)
|
||||
## Statut actuel (2-6 septembre 2026)
|
||||
|
||||
**Écrans "Identification" et "Liste des contacts"** (avec panneau détail intégré) : aboutis depuis le 25 août 2026, testés en production. **Prospection** (formulaire externe, vérification mail, envoi de doc) : livrée et testée en conditions réelles le 26 août 2026 (section 18). **Dépôt Git** en place depuis le 27-28 août (section 20), avec circuit de livraison FileZilla → SSH VPS → `git push` (section 23) — l'écriture directe par Claude reste bloquée côté proxy Anthropic, contournement adopté sans gêne. **MIRADOR** (authentification centralisée multi-bases, identifiant = email) branché et validé à deux utilisateurs le 30 août 2026, déployé sur `aspic.mvl-tls.fr` (développement) et `crm.aspic.bzh` (test), chacun avec son propre environnement Docker (sections 21, 24, 25).
|
||||
|
||||
@@ -98,6 +99,8 @@ Version incrémentée une seule fois pour l'ensemble de cette session (pastille
|
||||
|
||||
**4 septembre 2026 : interprétation vocale des contacts par un LLM à sortie structurée (V1.012).** Détail complet en section 29 du journal. Résumé : premier outil réel d'interprétation, dans le prolongement de la banque de dictées "Gestion des Contacts" — `contact_ia_interprete.php` (appel OpenAI `gpt-5.6-luna`, JSON Schema strict construit à partir des tables réelles ASP_Statuts/ASP_Professions/ASP_Agents/ASP_Actions, re-validation défensive après réponse), `contact_ia_valide.php` (seul point d'écriture, table à part `ASP_PropositionsContact` — ne crée jamais de contact ni de profession réels), `contact_ia_panel.js` (panneau flottant sur le micro de l'écran de fond, remplace `micro_test.js`). Décision architecturale actée : l'attribution d'un assistant par défaut quand aucun n'est nommé relève d'un futur traitement n8n, pas de cette couche d'interprétation qui doit rester un enregistreur honnête de ce qui est réellement dit. Détection de l'action "ajouter le contact" (libellé fixe, toujours classée en premier) confirmée comme une vraie décision du LLM porté par le prompt, pas un cas codé en dur — vérifié avec Jean-Marc. Zone actions simplifiée en 3 champs de texte libre (au lieu d'un motif dynamique existant/nouveau par ligne, jugé trop lourd pour cet essai). Nombreuses itérations d'ergonomie du panneau : dimensionnement immédiat à la taille maximale disponible avec défilement unique, lisibilité des listes déroulantes, arrêt automatique du micro après 3,5s de silence, redémarrage automatique du micro et panneau qui reste ouvert après validation (pour dicter plusieurs contacts à la suite), bouton "Abandonner" retiré au profit d'Échap seul. Relecture d'un premier corpus réel (11 essais) : résultats globalement encourageants, un bug d'extraction identifié (adresse mail non nettoyée d'un mot d'appel et d'un accent) et une possible troncature de fin de dictée par le minuteur de silence restent des points ouverts, non corrigés à la clôture. Jean-Marc a par ailleurs formulé une réflexion pour une prochaine session : séparer formellement les actions utilisables par l'utilisateur humain (menu/clavier) de celles utilisables par le LLM vocal, avec un vocabulaire d'actions unique et cohérent entre les deux voies d'accès. Version incrémentée une seule fois pour l'ensemble de cette session : **V1.012**.
|
||||
|
||||
**6 septembre 2026 : chantier des consignes — un moteur générique pour sortir du code en dur (V1.14.15).** Détail complet en section 30 du journal, fil conceptuel complet en Réflexions stratégiques, section 15. Résumé : reprise le soir même, sous forme concrète, de la distinction règles/consignes esquissée le matin — première mise en œuvre volontairement circonscrite à la fiche Contacts (création/modification). Deux tables créées par Jean-Marc (`ASP_Fonctions` : catalogue de fonctions génériques ; `ASP_Consignes` : instructions actives par contexte/champ), un moteur générique unique (`moteur_consignes.php`, fonction `appliquerConsignes()`) qui lit ces tables à l'exécution et applique traitements (mise en forme silencieuse) puis tests (validation, avec message d'erreur personnalisé), et une bibliothèque de fonctions du catalogue (`consignes_fonctions.php` : `MAJUSCULE`, `NON_VIDE`, `PREMIERE_LETTRE_MAJUSCULE`). `contacts.php` réduit à un seul appel au moteur, plus aucun contrôle de champ écrit en dur. Détour initial corrigé par Jean-Marc (Claude avait d'abord codé en dur un contrôle par champ au lieu du moteur générique demandé), puis abandon délibéré de la validation en temps réel côté écran au profit de la robustesse — révélant au passage un bug préexistant (message d'erreur générique affiché au lieu du message réel du serveur), corrigé. Ajustements d'interface demandés en cours de test : toast d'erreur centré et rouge sur le panneau de saisie, rendu correct des retours à la ligne saisis dans un message d'erreur. Preuve de concept validée par Jean-Marc en fin de session : ajout de nouvelles consignes (`NON_VIDE` sur Prénom et Ville) sans la moindre modification de fichier PHP/JS, comportement immédiatement actif avec les fichiers déjà livrés. Version incrémentée une seule fois pour l'ensemble de cette session, sur les deux compteurs anticipés dès le début (code et conception) : **V1.14.15**.
|
||||
|
||||
**Reste à faire, noté au passage :**
|
||||
- Décider s'il faut renforcer le prompt d'extraction pour neutraliser les mots parasites/formules de politesse dictés autour d'une adresse mail (bug identifié le 4 septembre sur le corpus réel, correction non encore actée par Jean-Marc).
|
||||
- Clarifier l'origine de la coupure de fin de dictée observée sur un essai du 4 septembre (minuteur de silence à 3,5s vs interruption réelle) avant de décider si `DUREE_SILENCE_ARRET_MS` (`contact_ia_panel.js`) doit être allongée.
|
||||
@@ -113,7 +116,7 @@ Version incrémentée une seule fois pour l'ensemble de cette session (pastille
|
||||
- Reconnecter `micro.js` (vrai pilotage) sur le micro de l'écran de fond une fois la phase de mise au point terminée — une ligne à changer dans `ecran_fond.html`.
|
||||
- Étendre `MARQUEUR_FIN_LIGNE` dans `micro.js` pour accepter "puis" en plus de "ensuite" (retour d'usage de Jean-Marc, 3 septembre) — sans urgence.
|
||||
- Continuer à observer les agents actifs (Viktor, Matilda, Léon, Nikita) en usage réel ; ajuster `AGN_Variantes` en base si de nouvelles confusions apparaissent.
|
||||
- Documentation utilisateur : le panneau de détail du contact, la ToDoList et le pilotage vocal restent à documenter (mise à jour du 3 septembre limitée à l'écran d'accueil et à la liste des contacts) — l'outil de banque de dictées n'a volontairement pas vocation à y figurer, ce n'est pas un module utilisateur.
|
||||
- Documentation utilisateur : le panneau de détail du contact, la ToDoList et le pilotage vocal restent à documenter (mise à jour du 3 septembre limitée à l'écran d'accueil et à la liste des contacts) — l'outil de banque de dictées et le chantier des consignes n'ont volontairement pas vocation à y figurer pour l'instant, ce sont des chantiers internes, pas des modules utilisateur finalisés.
|
||||
- Écran de fond : reconfirmer l'état de la "tranche du bureau" après le recadrage du 3 septembre (a pu déplacer le problème sans que ce soit son objet) ; décider si les autres objets photographiés (carnet, téléphone) doivent devenir cliquables ; trancher un jour le sort de la piste "maquette liège + post-its par agent" (Claude Design, mise de côté pour cet essai, pas explicitement abandonnée).
|
||||
- Concevoir les deux signes graphiques distincts pour les post-its "à corriger"/"à valider" (réflexions stratégiques, section 12) — le premier acté (point d'interrogation), le second encore à choisir.
|
||||
- Tableau de liège : coder la répartition dynamique des 70% entre assistants par charge de tâches (formule actée, voir Statut actuel) — bloqué tant que la ToDoList des assistants n'existe pas réellement.
|
||||
@@ -122,3 +125,9 @@ Version incrémentée une seule fois pour l'ensemble de cette session (pastille
|
||||
- Revoir les règles de calcul des pastilles rouge/orange/vert (`calculerGroupe()`) pour éviter un tableau trop chargé en rouge/orange maintenant que le vert quitte le tableau immédiatement.
|
||||
- Décider du comportement du clic sur un post-it (aujourd'hui inerte) : ouvrir `liste_todolist.html` sur la tâche précise, ou afficher un détail directement sur l'écran de fond.
|
||||
- Capacité du tableau (20) et taille de la grille (4×5) dans `ecran_fond.html`/`todolist.php` sont des valeurs provisoires posées avant d'avoir les vrais pixels de la version finale — à ajuster ensemble après usage réel prolongé.
|
||||
- Concevoir un nouveau type de consigne pour les cas nécessitant un appel IA en cours de traitement (ex. retrouver le code postal d'une ville saisie sans code postal) — contrat de retour plus riche que Traitement/Test actuel (silencieux / besoin de précision / question à poser), gestion d'échec réseau, coût et latence d'un appel externe (chantier des consignes, section 30) — session dédiée à prévoir.
|
||||
- Écran de gestion des consignes par le boss (au lieu d'`INSERT`/`UPDATE` SQL à la main) — à construire après stabilisation du contrat ci-dessus, pour ne pas le refaire (chantier des consignes, section 30).
|
||||
- Réflexion sur un catalogue restreint de consignes/fonctions avancées à proposer aux futurs utilisateurs de l'agence, sans leur ouvrir la création libre de A à Z — argument commercial identifié par Jean-Marc le 6 septembre (voir réflexions stratégiques, section 15).
|
||||
- Accumulation de plusieurs messages d'erreur à la fois dans le moteur de consignes (aujourd'hui, seul le premier test en échec est remonté).
|
||||
- Gestion des consignes transverses à toute la fiche (`CNS_Champ` NULL, ex. contrôle de doublon) — non traitée par le moteur de consignes actuel.
|
||||
- Distinction Saisie/Validation réellement exploitée un jour dans le moteur de consignes (temps réel), si le besoin redevient assez fort pour justifier la complexité écartée le 6 septembre.
|
||||
|
||||
@@ -205,3 +205,28 @@ Point explicitement acté avec Jean-Marc : **aucune solution, gratuite ou payant
|
||||
- Un corpus de consignes commun aux quatre assistants, ou un livret propre à chacun selon son `AGN_Fonction`.
|
||||
- Le périmètre exact du journalier (actions des assistants seulement, ou humain + assistants comme envisagé initialement le 4 septembre pour l'écran journalier du journal de développement).
|
||||
- La fréquence d'alimentation du journalier par n8n (par demi-journée évoquée par Jean-Marc, ou calée sur le rythme réel de l'agent de veille dont le réglage reste, comme noté en section 12, à choisir plus tard) — non encore décidée par Jean-Marc au 6 septembre.
|
||||
|
||||
## 15. Sortir du code en dur : règles et consignes comme mécanisme générique, premier cas construit sur la fiche Contacts (6 septembre 2026)
|
||||
|
||||
**Origine — le prolongement naturel de la session de réflexion du matin même.** Dans la continuité directe de la section 14 (le pilotage vocal comme deuxième mode de fonctionnement, consignes en langage naturel plutôt que règles programmées), Jean-Marc a voulu, le soir du même jour, poser une première brique concrète et volontairement modeste de cette philosophie — pas encore le pipeline vocal à quatre phases de la section 14, mais son fondement le plus basique : une fiche (Contacts, en création/modification) dont le comportement de validation et de mise en forme n'est plus écrit dans le code, mais lu dans des données.
|
||||
|
||||
**La distinction posée en ouverture de session : règles vs consignes.** Une **règle** est intrinsèque à l'application, non modifiable par l'utilisateur, parfois visible et parfois totalement transparente pour lui (ex. un contrôle d'intégrité que Jean-Marc seul déciderait d'activer). Une **consigne** est éditable par l'utilisateur, en langage naturel dans son intitulé, à l'image d'une instruction donnée à une véritable assistante — ce que Jean-Marc a nommé, en cours de session, "Mathilda" pour parler concrètement de cette couche. Deux natures pour une consigne : **Traitement** (transformation silencieuse d'une valeur, ex. mise en majuscules) et **Test** (validation, avec un message d'erreur si elle échoue). Cette distinction règles/consignes, et celle Traitement/Test, sont directement héritées de la réflexion du matin (section 14) mais franchissent ici, pour la première fois, le seuil du code réel.
|
||||
|
||||
**Le principe non négociable, formulé sans ambiguïté par Jean-Marc après une première tentative manquée de Claude (voir plus bas) : "sortir du code en dur".** L'objectif explicite n'était pas de coder telle ou telle validation, aussi propre soit-elle, mais de construire un **moteur générique** qui lit deux tables (le catalogue de fonctions disponibles, et les consignes actives qui s'appuient dessus) et qui exécute ce qu'il y trouve — de sorte qu'ajouter, modifier ou désactiver une consigne change le comportement réel de l'application **sans qu'aucune ligne de code ne soit retouchée**, sauf dans deux cas seulement assumés comme limites naturelles du système : l'écriture d'une fonction réellement nouvelle dans le catalogue, ou la correction d'un bug. Dans les mots de Jean-Marc, précisant ce qu'il ne demandait pas : *"Je n'ai aucun doute sur la capacité à programmer les tests et fonctions que tu as mis en place. Ce n'est pas cela que je souhaite tester, c'est bien toute la mécanique [...] : brancher des consignes, des règles sur la mise à jour des contacts [...] en sortant du code en dur !"*
|
||||
|
||||
**Un détour instructif, corrigé en cours de route.** Face à la première demande de Jean-Marc (rendre le Nom obligatoire, le mettre en majuscules), Claude a d'abord câblé ces deux comportements directement dans `contacts.php`, en se disant que le cas concret viendrait avant la généralisation. Erreur de lecture du besoin, corrigée fermement par Jean-Marc : ce n'était pas la complexité de la règle qui était en jeu, mais l'endroit où elle devait vivre. Reconstruction immédiate autour d'un moteur générique unique lisant les deux tables à l'exécution, sans plus aucune référence à un champ ou une consigne précise dans le code (voir journal de développement, section 30, pour le détail technique). Ce détour, bien que corrigé rapidement, mérite d'être consigné ici : il illustre concrètement la différence entre "avoir compris l'objectif en théorie" et "construire le bon niveau d'abstraction du premier coup" — un risque qui se représentera à chaque nouvelle brique de cette philosophie plus large.
|
||||
|
||||
**Un arbitrage assumé : la robustesse plutôt que le temps réel.** Une fois le moteur générique posé, restait la question du moment d'exécution : au clavier, au fil de la saisie (retour immédiat, "Saisie"), ou seulement à l'enregistrement ("Validation"). Jean-Marc, dépourvu selon ses propres mots de la compétence pour juger du coût réel d'un contrôle en temps réel, a choisi de trancher sur le critère qui compte le plus pour lui à ce stade du projet plutôt que sur l'exhaustivité fonctionnelle : *"je cherche aussi à ce que l'exécution soit fluide et que le code ne soit pas propice à des plantages"*. Décision : abandonner, pour cette première version du moteur, toute distinction Saisie/Validation et toute réaction en temps réel — une consigne active s'applique uniquement à l'enregistrement, quel que soit son moment déclaré en base. Ce choix a eu un effet inattendu et bienvenu : en retirant l'ancien contrôle client codé en dur, il a révélé un bug préexistant et jusque-là invisible (le message d'erreur affiché à l'écran était toujours générique, jamais celui réellement renvoyé par le serveur) — une illustration concrète du principe déjà éprouvé sur ce projet : simplifier expose parfois des défauts que la complexité précédente masquait, plutôt que d'en créer de nouveaux.
|
||||
|
||||
**L'enseignement retenu pour l'avenir, au-delà du cas des contacts : mécanisme générique et données propres à un client ne doivent jamais se mélanger.** En discutant de l'extension possible du catalogue de fonctions à des cas plus élaborés (ex. une liste de préfixes de codes postaux propre à une zone géographique), le principe suivant a été posé comme garde-fou pour la suite : le catalogue de fonctions (`ASP_Fonctions`) ne doit contenir que des primitives **génériques et paramétrables** (ex. "la valeur appartient à telle liste"), jamais une valeur métier figée pour un client donné — celle-ci doit toujours vivre comme une donnée de consigne (`CNS_Parametres`), jamais comme du code nouveau. Ce point prend une importance particulière à la lumière du modèle SaaS envisagé pour ASPIC (section 5) : le jour où plusieurs clients partageront le même catalogue de fonctions, ce catalogue devra rester strictement neutre vis-à-vis de chacun d'eux — toute valeur propre à un client doit résider dans ses propres consignes, jamais s'infiltrer dans le mécanisme commun.
|
||||
|
||||
**Validation par la pratique, sans qu'aucun code ne soit retouché après livraison.** Une fois le moteur et le catalogue de premières fonctions (mise en majuscule, non-vide, première lettre en majuscule) livrés, Jean-Marc a lui-même ajouté deux nouvelles consignes en base (non-vide sur le Prénom, puis sur la Ville) — comportement immédiatement actif, aucun fichier applicatif retouché. Conclusion de Jean-Marc, dans ses mots : *"On peut dire qu'on n'est pas mauvais !"* — première preuve concrète, à petite échelle, que la philosophie de la section 14 (des consignes plutôt que des écrans à embranchements) est réalisable techniquement, pas seulement séduisante sur le papier.
|
||||
|
||||
**Une extension entrevue mais explicitement mise de côté pour ce soir : l'appel à l'IA au sein même d'une consigne.** Jean-Marc a proposé, en fin de session, une consigne bien plus élaborée que celles construites jusqu'ici : si une ville est saisie sans code postal, aller chercher ce code postal via un appel à l'IA. Contrairement aux consignes du soir (Traitement pur ou Test pur, réponse immédiate et locale), ce cas suppose un contrat de retour plus riche (le résultat peut être silencieux, réclamer une clarification, ou poser une question), une latence et un risque d'échec réseau inédits pour ce mécanisme. Claude a recommandé de ne pas la traiter comme un simple ajout au catalogue existant, mais comme un chantier à part entière justifiant une session dédiée — recommandation implicitement acceptée par Jean-Marc, qui a préféré clore la soirée plutôt que de se lancer dans cette extension à une heure tardive.
|
||||
|
||||
**Trois pistes proposées par Jean-Marc pour les prochaines sessions, actées ici pour mémoire :**
|
||||
1. Concevoir des consignes plus élaborées faisant réellement appel à l'IA (le cas du code postal ci-dessus en étant le premier exemple concret) — préalable : définir le nouveau contrat de retour évoqué plus haut.
|
||||
2. Commencer à construire un écran de gestion des consignes pour le "boss" (Jean-Marc, puis un futur client), en remplacement de la saisie SQL directe utilisée ce soir — Claude a suggéré de séquencer cet écran **après** la stabilisation du contrat de retour enrichi du point 1, pour ne pas le concevoir deux fois.
|
||||
3. Réfléchir à un **catalogue restreint et curaté** de consignes et de fonctions avancées, à proposer aux futurs clients de l'agence — Jean-Marc a été explicite sur le fait qu'il n'envisage pas d'ouvrir à ses futurs utilisateurs une création libre de consignes avancées "de A à Z" ; il y voit au contraire un argument commercial pour de futures mises à jour payantes ("Possibilité de nouvelles consignes pour vos assistants"). Ce point rejoint directement la distinction actée plus haut entre mécanisme générique (partagé, neutre) et catalogue de fonctions (à curater soigneusement, puisqu'il devient potentiellement un produit en soi).
|
||||
|
||||
**Statut : premier cas concret bâti et validé, philosophie plus large confirmée par la pratique.** Le moteur générique de consignes existe, fonctionne, et a déjà changé de comportement une fois sans code — scellant, à l'échelle d'un cas modeste, l'intuition posée le matin même en section 14. Trois directions ouvertes pour la suite (consignes IA, écran de gestion, catalogue commercial), aucune engagée à ce stade au-delà de la discussion.
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
## 30. Chantier des consignes — moteur générique (6 septembre 2026)
|
||||
|
||||
**Origine.** Reprise le soir même de la réflexion stratégique de la nuit précédente (Réflexions stratégiques, section 14) sur le pilotage vocal comme deuxième mode de fonctionnement, et de la session de réflexion du matin du 6 septembre sur la distinction entre règles intrinsèques (non modifiables) et consignes personnelles (modifiables par l'utilisateur) — voir Réflexions stratégiques, section 15, pour le fil conceptuel complet. Ce chantier est le premier cas concret construit sur cette distinction, volontairement circonscrit à la fiche contact (création/modification) pour commencer.
|
||||
|
||||
**Nouvelle numérotation de version actée en tout début de session.** Format à trois niveaux `V<majeur>.<code>.<conception>` (voir `version.php`, en-tête). Départ de la session : `V1.13.14`. `<code>` et `<conception>` anticipés dès le début de session (Jean-Marc savait déjà que les deux évolueraient) : `V1.14.15`.
|
||||
|
||||
**Deux tables créées par Jean-Marc lui-même (convention habituelle) :**
|
||||
|
||||
```sql
|
||||
CREATE TABLE `ASP_Fonctions` (
|
||||
`FON_Incr` int NOT NULL AUTO_INCREMENT,
|
||||
`FON_Nom` varchar(30) NOT NULL,
|
||||
`FON_Nature` varchar(12) NOT NULL,
|
||||
`FON_Description` varchar(200) NOT NULL,
|
||||
`FON_ParametresAttendus` varchar(200) NULL,
|
||||
`FON_NomPHP` varchar(50) NOT NULL,
|
||||
`FON_Active` varchar(1) NOT NULL DEFAULT 'O',
|
||||
PRIMARY KEY (`FON_Incr`),
|
||||
UNIQUE KEY (`FON_Nom`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
CREATE TABLE `ASP_Consignes` (
|
||||
`CNS_Incr` int NOT NULL AUTO_INCREMENT,
|
||||
`CNS_Contexte` varchar(40) NOT NULL,
|
||||
`CNS_Portee` varchar(60) NOT NULL,
|
||||
`CNS_Champ` varchar(40) NULL,
|
||||
`CNS_Type` varchar(10) NOT NULL,
|
||||
`CNS_Nature` varchar(12) NOT NULL,
|
||||
`CNS_Moment` varchar(15) NULL,
|
||||
`CNS_Visible` varchar(1) NOT NULL DEFAULT 'O',
|
||||
`CNS_Modifiable` varchar(1) NOT NULL DEFAULT 'O',
|
||||
`CNS_Agent` varchar(20) NULL,
|
||||
`CNS_LibelleCourt` varchar(60) NOT NULL,
|
||||
`CNS_TexteDefinition` TEXT NOT NULL,
|
||||
`CNS_TexteAffiche` varchar(300) NOT NULL,
|
||||
`CNS_Fonction` varchar(30) NULL,
|
||||
`CNS_Parametres` JSON NULL,
|
||||
`CNS_MessageErreur` varchar(200) NULL,
|
||||
`CNS_Active` varchar(1) NOT NULL DEFAULT 'O',
|
||||
`CNS_DateCreation` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`CNS_Utilisateur` varchar(3) NULL,
|
||||
PRIMARY KEY (`CNS_Incr`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
```
|
||||
|
||||
Conventions retenues pour les valeurs de colonnes (choisies par Jean-Marc, différentes du style sans accent utilisé ailleurs comme `CVX_Type`) : `CNS_Type` = `Règle`/`Consigne`, `CNS_Nature` = `Traitement`/`Test`, `CNS_Moment` = `Saisie`/`Validation`, booléens en `O`/`N`. `CNS_Portee` = `'Mise à jour'` est traité comme un mot-clé signifiant "Création et Modification" par le moteur (voir plus bas), à côté de valeurs plus précises possibles plus tard (`'Création'` ou `'Modification'` seules, pour une future règle d'immuabilité). `CNS_Fonction` référence `ASP_Fonctions.FON_Nom` (texte, pas la clé technique `FON_Incr`) — plus lisible pour une inspection directe en base.
|
||||
|
||||
**`moteur_consignes.php` — le moteur générique.** Fonction unique `appliquerConsignes(PDO $pdo, string $contexte, string $portee, array &$data): ?string`. Lit `ASP_Consignes` (jointure `ASP_Fonctions` sur `FON_Nom = CNS_Fonction` et `FON_Active='O'`) pour le contexte/portée donnés, applique tous les Traitements actifs (silencieux, mutent `$data` par référence, dans l'ordre de `CNS_Incr`) puis tous les Tests actifs sur les valeurs déjà transformées ; retourne le message du premier test en échec (`CNS_MessageErreur`), ou `null` si tout passe. Aucune référence à un champ ou une consigne précise dans ce fichier — tout vient de la base. Limites assumées pour cette première version (documentées en en-tête du fichier) :
|
||||
- pas de distinction Saisie/Validation à l'exécution (voir plus bas, décision de Jean-Marc) ;
|
||||
- les consignes transverses à toute la fiche (`CNS_Champ` NULL, ex. futur contrôle de doublon) sont ignorées, à reprendre le jour d'un vrai cas ;
|
||||
- un seul message d'erreur renvoyé (le premier test en échec), pas d'accumulation.
|
||||
|
||||
**`consignes_fonctions.php` — le catalogue de fonctions.** Bibliothèque sans dépendance (pas de session, pas de base), une fonction par entrée de `ASP_Fonctions.FON_NomPHP`. Convention : un Traitement a la signature `(string $valeur): string`, un Test `(string $valeur): bool`. Trois fonctions écrites ce soir :
|
||||
- `consigne_majuscule` (`MAJUSCULE`, Traitement) — `mb_strtoupper` avec encodage explicite (un `strtoupper()` simple laisserait les accents français inchangés selon la locale serveur).
|
||||
- `consigne_non_vide` (`NON_VIDE`, Test) — `trim($valeur) !== ''`.
|
||||
- `consigne_premiere_lettre_majuscule` (`PREMIERE_LETTRE_MAJUSCULE`, Traitement) — "georges"→"Georges", "JOSEPH"→"Joseph", "jean-marc"→"Jean-Marc". Écrite à la main plutôt qu'avec `ucwords()` : cette fonction native PHP raisonne en octets, pas en caractères, et corromprait un prénom commençant par une lettre accentuée (ex. "Éric"). Implémentation par `preg_replace_callback` avec `\p{L}` (Unicode) après minuscule globale.
|
||||
|
||||
**`contacts.php` débarrassé de tout contrôle en dur.** Avant ce soir : `$nom = trim($data['CNT_Nom'] ?? ''); if ($nom === '') { ... 400 ... }` dupliqué en POST et PUT, aucun traitement de mise en forme. Après : un seul appel, `appliquerConsignes($pdo, 'Contacts', 'Création'|'Modification', $data)`, suivi d'un retour 400 avec le message tel quel si non-null. Objectif explicite de Jean-Marc, vérifié en fin de session : ajouter ou modifier une ligne dans `ASP_Consignes`/`ASP_Fonctions` change le comportement réel de l'application sans qu'aucun fichier PHP ne soit retouché, sauf écriture d'une fonction nouvelle ou bug.
|
||||
|
||||
**Détour et correction en cours de route : le temps réel, tenté puis abandonné.** Premier réflexe de Claude (avant clarification par Jean-Marc) : coder en dur un contrôle "nom obligatoire" réactif au `blur` du champ côté écran, en plus du contrôle serveur — mauvaise cible, Jean-Marc voulait tester le moteur générique, pas un nouveau code écrit à la main par champ. Après clarification, Jean-Marc a lui-même arbitré l'abandon du temps réel pour cette version (latence non significative pour un seul champ, mais complexité de construction jugée disproportionnée par rapport au gain — priorité donnée à la robustesse). Tout le code de validation côté client (`liste_contacts.html`) a été retiré ; `validerFormulaireContact()` se contente d'envoyer et d'afficher tel quel le message renvoyé par le serveur.
|
||||
|
||||
**Bug découvert (et corrigé) précisément à cause de ce retrait.** En enlevant l'ancien contrôle client ("Le nom est obligatoire.", codé en dur avant ce chantier), on a révélé que le gestionnaire d'erreur de `validerFormulaireContact()` affichait déjà, de longue date, un message générique fixe ("Erreur : impossible de créer ce contact.") au lieu du message précis renvoyé par le serveur (`data.error` était lu pour la console, jamais pour le toast). Corrigé dans les trois points d'échec (PUT, POST, catch réseau) : `afficherToast((data && data.error) || <message générique>, true)`.
|
||||
|
||||
**Ajustements d'interface demandés par Jean-Marc après premiers tests réels :**
|
||||
- Toast d'erreur centré sur le panneau de saisie (`top:50%`, comme `#panneau-detail`) et en rouge (`var(--rouge-suppression)`, déjà utilisée pour le mode suppression) — nouvelle classe `.toast-erreur`, activée via un deuxième paramètre de `afficherToast(message, erreur)`. Limité aux erreurs de `validerFormulaireContact` (PUT/POST/catch), les autres toasts du fichier restent inchangés.
|
||||
- `white-space:pre-line` ajouté à `#toast` (tous les toasts, pas seulement l'erreur) : un `CNS_MessageErreur` contenant des retours à la ligne saisis en base ne s'affichait pas correctement (HTML fond les retours à la ligne en un espace par défaut).
|
||||
|
||||
**Test réel réussi en fin de session, sans aucune modification de code :** Jean-Marc a ajouté trois nouvelles lignes dans `ASP_Consignes` (`NON_VIDE` sur `CNT_Prenom` et `CNT_AdrVille`, réutilisant la fonction déjà cataloguée) — comportement immédiatement actif après dépôt des fichiers déjà livrés, aucun fichier PHP/JS retouché. Preuve de concept validée par Jean-Marc : *"On peut dire qu'on n'est pas mauvais !"*
|
||||
|
||||
**Reste à faire, noté en fin de session :**
|
||||
- Concevoir un nouveau type de consigne pour les cas nécessitant un appel IA en cours de traitement (ex. retrouver le code postal d'une ville saisie sans code postal) — contrat de retour plus riche que Traitement/Test actuel (silencieux / besoin de précision / question à poser), gestion d'échec réseau, coût et latence d'un appel externe. Session dédiée à prévoir, pas un ajout mineur au catalogue existant.
|
||||
- Écran de gestion des consignes par le boss (au lieu de `INSERT`/`UPDATE` SQL à la main) — à construire après stabilisation du contrat ci-dessus, pour ne pas le refaire.
|
||||
- Réflexion sur un catalogue restreint de consignes/fonctions avancées à proposer aux futurs utilisateurs de l'agence, sans leur ouvrir la création libre de A à Z — argument commercial identifié par Jean-Marc ("Possibilité de nouvelles consignes pour vos assistants").
|
||||
- Accumulation de plusieurs messages d'erreur à la fois (le moteur ne remonte aujourd'hui que le premier test en échec).
|
||||
- Gestion des consignes transverses à toute la fiche (`CNS_Champ` NULL, ex. contrôle de doublon) — non traitée par le moteur actuel.
|
||||
- Distinction Saisie/Validation réellement exploitée un jour (temps réel), si le besoin redevient assez fort pour justifier la complexité écartée ce soir.
|
||||
Reference in New Issue
Block a user