{"id":38,"date":"2026-06-28T20:46:58","date_gmt":"2026-06-28T18:46:58","guid":{"rendered":"https:\/\/missud.eu\/index.php\/2026\/06\/28\/bibliocqrs-episode-1-lia-ne-sait-pas-sarreter\/"},"modified":"2026-06-28T21:31:21","modified_gmt":"2026-06-28T19:31:21","slug":"bibliocqrs-episode-1-lia-ne-sait-pas-sarreter","status":"publish","type":"post","link":"https:\/\/missud.eu\/index.php\/2026\/06\/28\/bibliocqrs-episode-1-lia-ne-sait-pas-sarreter\/","title":{"rendered":"BiblioCQRS \u2014 \u00c9pisode 1 : L&rsquo;IA ne sait pas s&rsquo;arr\u00eater"},"content":{"rendered":"<p><em>Reportage sur la construction d&rsquo;un syst\u00e8me logiciel avec l&rsquo;intelligence artificielle \u2014 du premier prompt au premier prototype fonctionnel.<\/em><\/p>\n<p>\ud83d\udd17 <strong>Code source du prototype :<\/strong> <a href=\"https:\/\/github.com\/dmissud\/biblioCQRS\/tree\/First_IT\">github.com\/dmissud\/biblioCQRS \u2014 tag First_IT<\/a><\/p>\n<hr\/>\n<h2>Le projet, en deux phrases<\/h2>\n<p>Je forme des informaticiens depuis des ann\u00e9es \u2014 analyse m\u00e9tier, Babok, IREB, architecture logicielle. J&rsquo;ai toujours utilis\u00e9 le m\u00eame exemple pour illustrer mes cours : une biblioth\u00e8que. Simple \u00e0 comprendre, suffisamment riche pour d\u00e9montrer des principes complexes. Cette fois, j&rsquo;ai voulu aller plus loin : construire r\u00e9ellement le syst\u00e8me, en direct, avec l&rsquo;IA comme partenaire de d\u00e9veloppement. Et en documenter chaque \u00e9tape.<\/p>\n<p>BiblioCQRS est n\u00e9 de l\u00e0. Un syst\u00e8me de gestion de catalogue de biblioth\u00e8que, construit sur une architecture hexagonale, avec CQRS, Event-Driven Architecture et Apache Kafka. Le domaine est volontairement connu. Ce qui m&rsquo;int\u00e9resse, c&rsquo;est la m\u00e9thode.<\/p>\n<hr\/>\n<h2>Le cadre avant tout<\/h2>\n<p>Avant d&rsquo;\u00e9crire une seule ligne de code, j&rsquo;ai pos\u00e9 le cadre \u00e0 Gemini. Pas en lui demandant de \u00ab\u00a0faire une application de biblioth\u00e8que\u00a0\u00bb. En lui dictant les contraintes architecturales une par une :<\/p>\n<blockquote>\n<p><em>\u00ab\u00a0Nous allons commencer par poser les bases de l&rsquo;objectif et des r\u00e8gles. Tout ce que nous r\u00e9alisons doit suivre le TDD strict avec une approche via BDD. Mise en \u0153uvre d&rsquo;une approche style bo\u00eete noire sur la partie domaine\/use case et suivre les principes de l&rsquo;architecture hexagonale.\u00a0\u00bb<\/em><\/p>\n<\/blockquote>\n<p>Gemini a r\u00e9pondu positivement, a r\u00e9capitul\u00e9 les quatre principes \u2014 TDD, BDD, bo\u00eete noire, hexagonale \u2014 et a demand\u00e9 par quel cas d&rsquo;usage commencer. Bon d\u00e9but.<\/p>\n<p>J&rsquo;ai ensuite ajout\u00e9 la couche CQRS et le choix d&rsquo;infrastructure :<\/p>\n<blockquote>\n<p><em>\u00ab\u00a0Autre principe d&rsquo;architecture que je veux que tu notes. Je veux faire une architecture CQRS. [&#8230;] Je suis dans un \u00e9tat d&rsquo;esprit de d\u00e9monstration de bonne pratique, une base comme Postgres me va.\u00a0\u00bb<\/em><\/p>\n<\/blockquote>\n<p>Et l\u00e0, Gemini a fait ce que font toutes les IA : il a imm\u00e9diatement propos\u00e9 trois options pour la gestion des \u00e9v\u00e9nements \u2014 in-memory, message broker, event sourcing \u2014 avec des sous-questions sur le langage, l&rsquo;\u00e9cosyst\u00e8me, le niveau de complexit\u00e9 souhait\u00e9. Utile, mais d\u00e9j\u00e0 une l\u00e9g\u00e8re d\u00e9rive vers l&rsquo;exhaustivit\u00e9.<\/p>\n<p>J&rsquo;ai tranch\u00e9 net : Java Spring Boot, Maven multi-modules, Kafka, Docker Compose. Et on passe \u00e0 la suite.<\/p>\n<hr\/>\n<h2>Le premier pi\u00e8ge : l&rsquo;IA qui veut tout faire<\/h2>\n<p>C&rsquo;est l\u00e0 que \u00e7a devient int\u00e9ressant. J&rsquo;avais expos\u00e9 le domaine m\u00e9tier : un ouvrage d\u00e9fini par son ISBN, son titre, son auteur. Des exemplaires physiques. Chaque exemplaire avec une localisation \u2014 salle, \u00e9tag\u00e8re, position. J&rsquo;avais pr\u00e9cis\u00e9 que nous \u00e9tions dans une biblioth\u00e8que, que les exemplaires comptaient autant que les ouvrages.<\/p>\n<p>Gemini a produit son premier sc\u00e9nario BDD :<\/p>\n<blockquote>\n<p><em>Given que l&rsquo;ouvrage avec l&rsquo;ISBN \u00ab\u00a0978-2-07-036822-8\u00a0\u00bb (\u00ab\u00a01984\u00a0\u00bb, George Orwell) n&rsquo;existe pas dans notre catalogue<\/em><br \/>\n<em>When le biblioth\u00e9caire r\u00e9f\u00e9rence cet ouvrage avec 1 exemplaire situ\u00e9 en \u00ab\u00a0Salle A\u00a0\u00bb, \u00ab\u00a0\u00c9tag\u00e8re 2\u00a0\u00bb, \u00ab\u00a0Position 15\u00a0\u00bb<\/em><br \/>\n<em>Then l&rsquo;ouvrage est ajout\u00e9 au catalogue<\/em><br \/>\n<em>And 1 exemplaire est cr\u00e9\u00e9 et assign\u00e9 \u00e0 ce lieu de stockage<\/em><\/p>\n<\/blockquote>\n<p>Sc\u00e9nario propre. Bien formul\u00e9. Et pourtant, j&rsquo;ai frein\u00e9.<\/p>\n<blockquote>\n<p><em>\u00ab\u00a0Je trouve ce premier sc\u00e9nario pas mal mais tr\u00e8s riche pour une approche par baby step. Peut-\u00eatre faire des \u00e9tapes plus courtes pour une impl\u00e9mentation progressive.\u00a0\u00bb<\/em><\/p>\n<\/blockquote>\n<p>C&rsquo;est le r\u00e9flexe du formateur. Un sc\u00e9nario qui m\u00eale la cr\u00e9ation d&rsquo;un ouvrage ET l&rsquo;ajout d&rsquo;un exemplaire ET sa localisation, c&rsquo;est trop pour une premi\u00e8re it\u00e9ration TDD. Si quelque chose ne passe pas, on ne sait pas o\u00f9 chercher. Le baby step, c&rsquo;est la r\u00e8gle d&rsquo;or : <strong>une seule chose \u00e0 la fois, une seule raison d&rsquo;\u00e9chouer.<\/strong><\/p>\n<p>Gemini a imm\u00e9diatement compris et a d\u00e9coup\u00e9 en trois \u00e9tapes :<\/p>\n<ul>\n<li><strong>Baby Step 1<\/strong> : R\u00e9f\u00e9rencer un ouvrage abstrait \u2014 ISBN, titre, auteur. Rien d&rsquo;autre.<\/li>\n<li><strong>Baby Step 2<\/strong> : Refuser un doublon d&rsquo;ISBN \u2014 la r\u00e8gle m\u00e9tier d&rsquo;unicit\u00e9.<\/li>\n<li><strong>Baby Step 3<\/strong> : Ajouter un exemplaire avec son lieu de stockage \u00e0 un ouvrage existant.<\/li>\n<\/ul>\n<p>Trois sc\u00e9narios. Trois boucles TDD distinctes. Trois raisons diff\u00e9rentes d&rsquo;\u00e9chouer \u2014 et donc de comprendre.<\/p>\n<hr\/>\n<h2>Ce que \u00e7a r\u00e9v\u00e8le sur l&rsquo;IA<\/h2>\n<p>L&rsquo;IA ne r\u00e9siste pas \u00e0 l&rsquo;envie de livrer un syst\u00e8me complet. Elle confond \u00ab\u00a0montrer sa valeur\u00a0\u00bb avec \u00ab\u00a0tout faire tout de suite\u00a0\u00bb. Laiss\u00e9e sans contrainte, elle produit du code riche, fonctionnel en apparence, mais monolithique \u2014 difficile \u00e0 relire, impossible \u00e0 tester proprement, et surtout en contradiction directe avec les principes qu&rsquo;elle vient d&rsquo;accepter. Vous lui demandez du TDD, elle fait du code. Vous lui demandez des baby steps, elle vous propose une feature enti\u00e8re.<\/p>\n<p>Ce n&rsquo;est pas un d\u00e9faut de l&rsquo;IA. C&rsquo;est sa nature : elle optimise pour la compl\u00e9tude, pas pour la discipline. <strong>C&rsquo;est au d\u00e9veloppeur de l&rsquo;arr\u00eater.<\/strong><\/p>\n<p>Et pour l&rsquo;arr\u00eater, il faut savoir o\u00f9 on veut aller.<\/p>\n<hr\/>\n<h2>La documentation comme garde-fou<\/h2>\n<p>En parall\u00e8le du code, j&rsquo;ai impos\u00e9 une r\u00e8gle : chaque it\u00e9ration doit enrichir la documentation fonctionnelle et architecturale. Pas apr\u00e8s coup \u2014 en continu.<\/p>\n<p>J&rsquo;avais demand\u00e9 \u00e0 Gemini de produire une documentation structur\u00e9e selon les principes du Babok : vision produit, parties prenantes, d\u00e9composition des objectifs, use cases. Mais pas d&rsquo;un coup. \u00c9tape par \u00e9tape, en restant strictement dans le p\u00e9rim\u00e8tre de ce qui est impl\u00e9ment\u00e9.<\/p>\n<blockquote>\n<p><em>\u00ab\u00a0Notons comme une r\u00e8gle projet de toujours mettre \u00e0 jour la documentation fonctionnelle.\u00a0\u00bb<\/em><\/p>\n<\/blockquote>\n<p>La doc n&rsquo;est pas optionnelle. Elle n&rsquo;est pas un livrable de fin de projet. C&rsquo;est un miroir du code \u2014 elle doit refl\u00e9ter exactement ce qui existe, ni plus ni moins.<\/p>\n<p>R\u00e9sultat : \u00e0 la fin du premier prototype, nous avions une documentation fonctionnelle structur\u00e9e (vision, parties prenantes, arbre d&rsquo;objectifs, glossaire m\u00e9tier, use cases) et une documentation d&rsquo;architecture (hexagonale, CQRS, modules Maven, infrastructure). Les deux parfaitement align\u00e9es avec ce qui tourne r\u00e9ellement.<\/p>\n<hr\/>\n<h2>Ce qui a vraiment \u00e9t\u00e9 construit<\/h2>\n<p>En quelques heures de dialogue dirig\u00e9, voici ce que le prototype contient :<\/p>\n<p><strong>C\u00f4t\u00e9 Command (\u00e9criture) :<\/strong><br \/>\nUn domaine pur en Java \u2014 l&rsquo;agr\u00e9gat <code>Ouvrage<\/code>, ses entit\u00e9s <code>Exemplaire<\/code>, son value object <code>LieuStockage<\/code>. Trois sc\u00e9narios BDD verts. Un adaptateur PostgreSQL via Spring Data JPA. Une publication d&rsquo;\u00e9v\u00e9nements vers Kafka (<code>OuvrageReferenceEvent<\/code>, <code>ExemplaireAjouteEvent<\/code>) encapsul\u00e9e dans l&rsquo;impl\u00e9mentation du repository \u2014 le domaine ne sait pas que Kafka existe.<\/p>\n<p><strong>C\u00f4t\u00e9 Query (lecture) :<\/strong><br \/>\nUn consumer Kafka qui projette les \u00e9v\u00e9nements dans une vue d\u00e9normalis\u00e9e <code>catalogue_view<\/code> \u2014 ISBN, titre, auteur, nombre d&rsquo;exemplaires. Un endpoint REST GET pour le frontend.<\/p>\n<p><strong>Le frontend :<\/strong><br \/>\nUne application Angular 17 avec Material Design, trois facettes : consultation du catalogue en direct, r\u00e9f\u00e9rencement manuel d&rsquo;ouvrage, et un tableau de bord de test qui d\u00e9clenche une injection automatis\u00e9e de quinze requ\u00eates en rafale pour observer la propagation des \u00e9v\u00e9nements dans Kafka.<\/p>\n<p><strong>L&rsquo;infrastructure :<\/strong><br \/>\nUn <code>docker-compose.yml<\/code> qui orchestre PostgreSQL, Zookeeper et Kafka. Deux applications Spring Boot ind\u00e9pendantes \u2014 command sur le port 8082, query sur le port 8083.<\/p>\n<hr\/>\n<h2>La th\u00e8se qui \u00e9merge<\/h2>\n<p>On entend souvent que l&rsquo;IA va remplacer les d\u00e9veloppeurs. Cette exp\u00e9rience sugg\u00e8re l&rsquo;inverse : elle rend la ma\u00eetrise des cadres <strong>plus indispensable que jamais<\/strong>.<\/p>\n<p>Un d\u00e9veloppeur sans culture d&rsquo;analyse m\u00e9tier, sans r\u00e9flexe de d\u00e9coupage it\u00e9ratif, sans connaissance des principes architecturaux \u2014 ce d\u00e9veloppeur va se noyer dans ce que l&rsquo;IA lui propose. Il va accepter le premier sc\u00e9nario trop riche. Il va laisser l&rsquo;IA c\u00e2bler le Kafka dans le domaine. Il va se retrouver avec un prototype qui fonctionne et qu&rsquo;il ne comprend pas.<\/p>\n<p>L&rsquo;IA est un acc\u00e9l\u00e9rateur formidable sur les t\u00e2ches longues et r\u00e9p\u00e9titives : \u00e9crire des sc\u00e9narios BDD, g\u00e9n\u00e9rer le squelette Maven, produire les entit\u00e9s JPA, configurer Spring Kafka. Ces t\u00e2ches qui prenaient des heures se font en minutes.<\/p>\n<p>Mais l&rsquo;acc\u00e9l\u00e9rateur ne sait pas o\u00f9 aller. <strong>C&rsquo;est vous qui tenez le volant.<\/strong><\/p>\n<hr\/>\n<p><em>\u00c9pisode 2 : L&rsquo;architecture sort de terre \u2014 comment guider l&rsquo;IA pour qu&rsquo;elle respecte les fronti\u00e8res de l&rsquo;hexagone.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Reportage sur la construction d&rsquo;un syst\u00e8me logiciel avec l&rsquo;intelligence artificielle \u2014 du premier prompt au premier prototype fonctionnel. \ud83d\udd17 Code source du prototype : github.com\/dmissud\/biblioCQRS \u2014 tag First_IT Le projet, en deux phrases Je forme des informaticiens depuis des ann\u00e9es \u2014 analyse m\u00e9tier, Babok, IREB, architecture logicielle. J&rsquo;ai toujours utilis\u00e9 le m\u00eame exemple pour illustrer [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9],"tags":[10],"class_list":["post-38","post","type-post","status-publish","format-standard","hentry","category-craftsmanship","tag-first_it"],"_links":{"self":[{"href":"https:\/\/missud.eu\/index.php\/wp-json\/wp\/v2\/posts\/38","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/missud.eu\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/missud.eu\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/missud.eu\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/missud.eu\/index.php\/wp-json\/wp\/v2\/comments?post=38"}],"version-history":[{"count":1,"href":"https:\/\/missud.eu\/index.php\/wp-json\/wp\/v2\/posts\/38\/revisions"}],"predecessor-version":[{"id":40,"href":"https:\/\/missud.eu\/index.php\/wp-json\/wp\/v2\/posts\/38\/revisions\/40"}],"wp:attachment":[{"href":"https:\/\/missud.eu\/index.php\/wp-json\/wp\/v2\/media?parent=38"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/missud.eu\/index.php\/wp-json\/wp\/v2\/categories?post=38"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/missud.eu\/index.php\/wp-json\/wp\/v2\/tags?post=38"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}