Retour aux projets

VisualMind

VisualMind

Une application web de brainstorming visuel qui transforme des sujets, des articles et des vidéos YouTube en cartes mentales interactives — en ligne sur visualideas.app, avec des abonnés payants et un appel de modèle derrière chaque génération. J’ai rejoint le projet en décembre 2024 et j’ai participé au développement du front-end jusqu’en août 2026 : une SPA React dont le travail consiste à garder fluide un canevas de 43 nœuds tout en demandant le moins possible au serveur. Les rafales de modifications sont regroupées en une seule écriture, une carte non enregistrée n’est créée qu’une fois quelle que soit la vitesse des clics, et huit formats d’export sont générés dans le navigateur — un export ne coûte donc rien à l’API.

Résultats

Nœuds par carte, révélés en une seule mise à jour groupée
43Nœuds par carte, révélés en une seule mise à jour groupée
Temporisation qui transforme une rafale de modifications en une écriture
600 msTemporisation qui transforme une rafale de modifications en une écriture
Formats d’export générés dans le navigateur
8Formats d’export générés dans le navigateur
Aller-retour serveur que coûte un export
0Aller-retour serveur que coûte un export

Chiffres relevés dans le front-end que j’ai développé chez VisualMind — les valeurs par défaut livrées du canevas de carte, en août 2026.

Démonstration

L’application web en train de construire une carte sur « The Neuroscience of Decision Making » : les branches se déploient en sous-thèmes à la demande, et le champ de relance en bas prolonge la carte depuis la même conversation.
L’application web en train de construire une carte sur « The Neuroscience of Decision Making » : les branches se déploient en sous-thèmes à la demande, et le champ de relance en bas prolonge la carte depuis la même conversation.

Conçu pour tenir la charge

  • Une écriture par rafale, pas par image

    Éditions, déplacements et changements de disposition sont temporisés à 600 ms en un seul PATCH du document de la carte — des centaines d’événements de position deviennent une écriture.

  • Une carte créée exactement une fois

    Une promesse unique en vol garde la première sauvegarde : ni un double clic ni une connexion instable ne peuvent laisser des doublons dans le compte d’un client.

  • Révélations groupées, une seule remise en page

    Une branche s’ouvre en une mise à jour : le moteur de mise en page tourne une fois au lieu d’une fois par nœud, et la caméra reste fluide sur 43 nœuds.

  • Une sortie de modèle défectueuse se dégrade, elle ne casse pas

    Un adaptateur défensif normalise le JSON du modèle et comble les branches manquantes — une réponse malformée donne une carte plus maigre, jamais un écran blanc.

  • Des exports qui ne coûtent rien au serveur

    PNG, PDF, Word, Excel, PowerPoint, OPML, Markdown et un format .vimap maison, tous générés dans le navigateur — la charge d’export n’atteint jamais l’API.

  • Quatre dispositions, un seul chemin de code

    Radiale, arbre à gauche, miroir en haut et radiale horizontale sortent d’un même constructeur d’arbre, en palettes claire et sombre — une chose à corriger, pas quatre.

Comment ça marche

On donne à VisualMind un sujet, l’URL d’un article ou un lien YouTube, et il répond par une carte mentale interactive plutôt que par un mur de texte. Chaque branche se déploie en sous-thèmes à la demande, et un champ de relance prolonge la carte depuis la même conversation — une session ressemble à un tableau blanc qui se remplit tout seul. Derrière, il y a un produit en ligne avec des abonnés payants, où chaque carte générée est un appel de modèle facturé : le travail du front-end n’est donc pas seulement d’avoir l’air juste, mais de garder borné et prévisible le travail que chaque utilisateur crée pour le serveur.

J’ai rejoint le projet en décembre 2024 et participé au développement du front-end jusqu’en août 2026 — une SPA React 18 construite avec Vite. Son cœur est le canevas de la carte : vis-network dessine un graphe à trois niveaux — un sujet central, six branches colorées, puis trois sous-thèmes et trois cartes d’idées derrière chacune, 43 nœuds en tout — positionnés par un moteur de mise en page offrant quatre dispositions réglées à la main (radiale, arbre à gauche, miroir en haut, radiale horizontale). Les quatre sortent d’un même constructeur d’arbre, en palettes claire et sombre assorties : c’est la version économique d’une décision qui compte plus tard — un seul chemin de code à corriger plutôt que quatre qui divergent.

C’est au rendu du graphe qu’un canevas devient lent : les révélations sont donc groupées. Les branches restent cachées et pulsent doucement jusqu’au premier appui ; un appui ajoute toute la branche en une seule mise à jour, si bien que le moteur de mise en page tourne une fois au lieu d’une fois par nœud, et le déplacement de la caméra ne saccade jamais. Les cartes s’éditent sur place et se déplacent librement — deux interactions qui émettent un événement par image, c’est-à-dire exactement ce qu’on n’envoie pas à un serveur au fil de l’eau.

Tout converge donc vers un seul chemin de sauvegarde. Éditions, déplacements et changements de disposition sont temporisés à 600 ms puis envoyés en PATCH à l’API sous forme du document JSON de la carte : un déplacement qui produirait autrement des centaines de mises à jour de position par minute ne coûte à l’API qu’une seule écriture. La première modification d’une carte non enregistrée doit la créer exactement une fois — une promesse unique en vol le garantit, puis réécrit l’URL pour que rafraîchir et partager fonctionnent tels quels — et dupliquer, renommer et supprimer passent par les mêmes routes : l’écran et MySQL ne divergent jamais. Se tromper sur cette garde ne se voit pas comme une page lente, mais comme des lignes dupliquées dans le compte d’un client payant.

Le passage de relais avec l’IA est un contrat JSON, écrit pour se dégrader plutôt que pour casser. L’écran de conversation envoie l’échange en cours à l’API, le modèle répond avec la carte en JSON structuré, et un adaptateur défensif la normalise en comblant toute branche ou carte manquante : une réponse malformée venue d’un service que personne ne contrôle donne une carte plus maigre, pas un écran blanc. La carte fraîche est mise en cache dans sessionStorage pour s’afficher instantanément à l’arrivée plutôt que d’être récupérée deux fois, et le client s’appuie sur les états d’échec du serveur — un 402 contenant subscription_paused emmène toute l’application vers l’écran d’abonnement suspendu, tandis que le canevas traite un 401 comme un « connectez-vous pour enregistrer » plutôt que de perdre la modification. Autour de tout cela, l’API TypeScript du produit gère la génération GPT-4o, l’extraction d’articles et de YouTube, l’authentification par cookie JWT, les abonnements PayPal et les tables MySQL derrière le tout.

C’est en appelant cette API depuis chaque écran que m’est venue l’envie de la reconstruire de l’intérieur — puis de savoir si ma reconstruction tiendrait un vrai trafic. Au départ, non : aucune limitation de débit, aucun plafond de dépense, un fil de requête immobilisé pendant toute la durée de chaque génération, et des listes plafonnées à 200 lignes sans moyen d’atteindre la 201e. Corriger ces neuf plafonds est le projet compagnon présenté sur ce site, « VisualMind : un front-end, un back-end reconstruit en Java et en Python ».

Le pipeline front-end

Schéma du front-end de VisualMind : la conversation part vers l’API generate-map, le JSON renvoyé est normalisé par un adaptateur défensif, positionné par le moteur de mise en page, rendu sur un canevas interactif, édité sur place, et chaque changement est sauvegardé automatiquement vers l’API et MySQL.

Le pipeline front-end que j’ai construit — de la conversation à la carte rendue, chaque modification resauvegardée vers l’API. Cliquer sur le schéma pour l’ouvrir en taille réelle.

Architecture

Schéma d’architecture de VisualMind : une application monopage qui appelle une API back-end, laquelle passe par l’authentification, le contrôle d’accès et la couche de persistance vers une base relationnelle, et sort vers un fournisseur LLM, un service de paiement, des sources de contenu externes et un service d’e-mail.

Comment les pièces s’assemblent — la SPA, les routes d’API, les services externes et les tables MySQL derrière. Cliquer sur le schéma pour l’ouvrir en taille réelle.

Stack technique

ReactTypeScriptNext.jsMySQLJWT
Dépôt privéEn ligne