Étude de cas — Projet personnel

Un simulateur fiscal fait avec une IA, encadrée de bout en bout

Simulateur indépendant FR — conçu, piloté et vérifié par moi, code écrit par des agents d’IA

Statut
Bêta
Licence
MIT
Depuis
2025
Rôle
Conception et développement
  • TypeScript
  • React
  • Electron
  • Vite
  • Zod
  • Vitest
  • Playwright
  • GitHub Actions
  • SonarQube
  • MCP
Essayer la démo en ligne (lien externe)

Le point de départ

En s’installant à son compte, on tombe vite sur la question « micro-entreprise, EI, SASU ou EURL ? », et sur des calculateurs en ligne qui y répondent pour une personne seule et un chiffre d’affaires. Sauf que l’impôt sur le revenu se calcule par foyer : un conjoint salarié, des enfants, une société qui verse une rémunération puis des dividendes, et la réponse change. Un formulaire à trois champs ne voit rien de tout ça.

Le simulateur part de l’autre bout. On construit un modèle de sa situation — personnes, sociétés, micro-entreprises, les liens entre elles (président, gérant, marié, pacsé) et leurs flux mois par mois — et le moteur calcule cotisations, impôt sur les sociétés, impôt du foyer et net de chacun, sur une ou plusieurs années. Le comparateur rejoue ensuite la même activité sous chaque statut.

L’outil lui-même, sur la simulation d’exemple de la démo, fictive : le comparateur refait la même activité sous chaque statut, avec le net, l’écart et la protection sociale de chacun.

Deux contraintes dès le départ : rien ne quitte la machine, et chaque règle fiscale se rattache à un texte officiel. Ce n’est pas un logiciel de conseil — les résultats sont indicatifs, et l’outil le dit.

Fait avec une IA, encadrée

Autant le dire tout de suite, c’est le sujet de cette page : le code de ce projet est écrit par des agents de code IA. Moi, je conçois, je décide, je relis et je teste. Ce n’est ni un aveu ni un argument de vente, c’est une méthode — et elle ne tient que si le cadre est plus strict que pour une équipe humaine. Un agent ne se fatigue pas, mais il ne doute pas non plus.

  1. Moi

    Discuter, puis décider

    Chaque évolution est discutée avant d’exister. Une question reçoit une réponse et une recommandation ; rien n’est lancé sans mon accord explicite.

  2. Agents

    Répartir

    Plusieurs agents travaillent en parallèle, chacun dans son propre worktree git et sur sa branche, avec des consignes écrites.

  3. Moi

    Relire et intégrer

    Je relis chaque compte rendu. Les branches sont fusionnées dans integration, les conflits résolus, et toute la suite de tests relancée.

  4. Moi

    Recette

    J’essaie moi-même la version d’integration, et je donne mon accord — ou pas.

  5. CI

    Contrôle

    Les tests de la CI et ceux de bout en bout de l’application doivent passer sur ce commit exact, sans quoi GitHub refuse l’envoi. La branche main ne reçoit qu’une avance rapide d’integration, et un crochet git refuse tout commit direct sur main.

  6. CI

    Mise en ligne

    La démo web est recompilée, testée dans un navigateur, puis republiée.

Le trajet d’une évolution, du besoin à la mise en ligne. Les étapes encadrées sont les miennes : aucune ne se saute.

Les consignes données aux agents ne changent pas d’une tâche à l’autre : complexité plafonnée par fonction, tests unitaires et de bout en bout obligatoires, accessibilité vérifiée par axe, pas de code dupliqué, des ports de test séparés pour que deux agents ne se marchent pas dessus. Et pour toute règle fiscale, une source officielle, avec des cas de référence calculés à la main avant d’être figés en tests.

Côté GitHub, une règle de protection sur main exige que la CI et les tests de bout en bout de l’application aient réussi, interdit la suppression et la réécriture de l’historique, et ne prévoit aucune exception — y compris pour moi.

Tout laisse une trace écrite : une feuille de route tenue à jour phase par phase, un journal des modifications, et un ADR par décision de conception — le contexte, les options écartées et ce que la décision coûte. Il y en a plus de dix.

L’architecture

  • Un moteur de calcul en TypeScript pur, sans interface ni accès aux fichiers, partagé par l’application de bureau (Electron) et la démo web, où le calcul tourne dans le navigateur.
  • Les règles par année : un fichier par année, chaque paramètre avec sa source (BOFiP, service-public, Urssaf…). Un ADR fixe ce que « 2025 » veut dire — l’année de l’activité — parce que le barème de l’impôt qui frappe les revenus de 2025 est voté dans la loi de finances pour 2026.
  • Des sessions sur plusieurs années, chacune calculée avec ses propres règles : c’est ce qui permet, par exemple, de vérifier le versement libératoire d’une année avec le revenu fiscal de référence de deux ans plus tôt.
  • Des données qui ne se perdent pas : schémas Zod comme source de vérité, une passe de nettoyage à chaque lecture, des migrations entre formats de fichier. Un test parcourt chaque champ du schéma, remplit une session complète et vérifie qu’elle revient à l’identique de chaque enregistrement, export et import.
  • Une couche d’outils pour les clients d’IA, et un serveur MCP local de seize outils, dans l’application de bureau. Le principe : les chiffres viennent du moteur, jamais du modèle, et le modèle propose sans jamais modifier. Une proposition est une donnée, liée à l’empreinte de la session : si la simulation a changé entre-temps, elle est refusée. L’utilisateur la relit dans l’application, avec son effet sur le net de chaque année, et l’applique ou la refuse — une seule étape d’annulation.
Une proposition envoyée par le serveur MCP, relue dans l’application sur la simulation d’exemple, fictive. L’avertissement et les montants viennent du moteur ; rien ne change avant « Appliquer ».

Ce que j’ai fait

  • Le cahier des charges, puis la feuille de route, phase par phase.
  • Chaque arbitrage de conception, tranché par moi et consigné en ADR avant que le code suive.
  • Le cadre de travail des agents : consignes, découpage des tâches, isolement par branche, et la chaîne de contrôle qui décide si un commit peut arriver sur main.
  • La relecture de chaque compte rendu, l’intégration des branches et la recette.
  • Les choix de produit, sur pièce plutôt que sur papier : pour alléger l’écran, j’ai fait construire trois propositions d’affichage, je les ai essayées, et j’en ai retiré une.

Les garde-fous

Ce sont eux qui rendent la vitesse supportable : un agent qui écrit vite écrit aussi vite ses erreurs. Chaque contrôle a un seuil chiffré, et la plupart bloquent.

Contrôles automatiques du projet, avec ce qu’ils vérifient, leur seuil et s’ils bloquent
OutilCe qu’il vérifieSeuilEffet
ESLintRègles de code, dont la complexité cyclomatique de chaque fonction, tests compris15 au plus par fonctionBloquant
TypeScriptTypes de l’interface, du moteur, des tests et du serveur MCPAucune erreurBloquant
VitestTests unitaires et de composants, cas de référence calculés à la main90 % de couverture de la logique (instructions, branches, fonctions, lignes)Bloquant
jscpdCode copié-colléBlocs de 70 jetons, 5 % au plusBloquant sur les branches de travail, où SonarQube ne tourne pas
PlaywrightParcours réels dans l’application Electron et la démo web : audit axe (WCAG 2.2 AA) en clair et en sombre, cibles de 24 et 44 px, tailles de texte, clavier, police plus largeAucune violationBloquant
SonarQube CloudFiabilité, sécurité, maintenabilité, couverture, duplication et points sensibles du nouveau codeBarrière par défaut : notes A, couverture de 80 %, duplication de 3 % au plusBloquant sur main, une fois le commit arrivé
StrykerTests de mutation du moteur : un test qui ne casse pas quand le code change ne protège rienChaque semaineSuivi, non bloquant

La couverture réelle de la logique, 99 %, dépasse nettement le seuil, les tests de mutation tuent 85 % des mutants du moteur, et le copier-coller est aujourd’hui à zéro. Les seuils, eux, sont fixés à la dizaine inférieure de ce qui est atteint : ils n’ont pas vocation à être confortables.

Les contrôles du commit f9621d0 de main, le 6 octobre 2026, sur la page publique du dépôt : tous au vert, barrière SonarQube comprise.

La limite de l’offre gratuite de SonarQube

Elle est apparue le jour où j’ai rendu la barrière SonarQube bloquante : sur la branche de recette, l’analyse a échoué avec « Organization is not allowed to access data from non main branches ». L’offre gratuite de SonarQube Cloud n’analyse que la branche principale. Sa barrière ne peut donc juger un commit qu’une fois arrivé sur main : si elle échoue, main passe au rouge et je corrige aussitôt, mais le commit est déjà là. C’est un contrôle juste après, pas juste avant.

Pour un projet personnel, ce compromis est acceptable. En production dans une entreprise, il ne l’est pas : il faut une offre payante, pour que l’analyse tourne aussi sur la branche de recette et sur chaque demande de fusion, et que la barrière devienne un contrôle exigé avant main, au même titre que les tests — ses remarques s’affichant alors directement dans la revue du code. Ici, ce qui protège main avant son arrivée, ce sont les contrôles marqués bloquants dans le tableau, et la détection de copier-coller prend le relais de SonarQube sur les branches de travail.

Le résultat

2 300+
tests unitaires et de composants
200+
tests de bout en bout, application et démo web
4
statuts comparés : micro, EI, SASU, EURL
3
systèmes visés : Windows, macOS, Linux

Un simulateur en bêta, sous licence MIT, qui modélise un foyer entier sur jusqu’à dix années, compare les statuts, arbitre entre rémunération et dividendes, exporte en CSV, Markdown et PDF, et se laisse remplir par une IA sans jamais lui laisser le dernier mot. La dernière version publiée est la 0.12.0.

La démo s’essaie dans le navigateur (lien externe), sans compte, et le code est sur GitHub (lien externe), historique, ADR et CI compris. La page de l’outil explique comment s’en servir.

Ce que ça dit du reste

Pour éprouver la couche IA, j’ai fait jouer à un agent le rôle d’un client branché sur le serveur MCP, avec des factures à saisir. Chaque outil faisait exactement ce qu’on lui demandait, chaque test passait — et le résultat était faux : les factures s’ajoutaient à l’estimation de chiffre d’affaires déjà saisie, qui doublait. Aucun test unitaire ne pouvait le voir, puisque rien n’était cassé.

La correction n’a pas consisté à interdire, mais à prévenir : une proposition signale désormais les séries du même type auxquelles elle s’ajoute, et les avertissements du moteur qu’elle fait apparaître. Les descriptions des outils, elles, disent qu’il faut retirer l’estimation que des factures remplacent.

C’est ce que je retiens : l’IA écrit vite, et c’est justement pour ça que le cadre compte. Décider avant de coder, tout faire passer par les mêmes contrôles, essayer soi-même, laisser une trace écrite — ce sont les habitudes que j’applique aussi sans IA, sur des projets clients. Ici, elles se voient, parce que tout est public.