Une approche low-code avec Guillaume
Guillaume présente une approche hybride no-code/vibe coding pour construire une application SaaS d'analyse et d'enrichissement de fichiers CSV par IA, en combinant Softr comme infrastructure front, N8N comme moteur de workflow, et Gemini pour générer les blocs de code custom.
Outils utilisés
Résumé de la session
Guillaume commence par se présenter : profil business/growth marketing, six ans d'expérience avec des outils no-code (Airtable, Webflow, Bubble, Make, N8N), sans background technique classique. Il travaille maintenant chez Softr, mais utilisait l'outil bien avant d'y rejoindre l'équipe.
Il expose l'idée du projet : une application permettant d'uploader un fichier CSV, d'y associer une requête en langage naturel, et d'obtenir en retour un CSV enrichi avec une nouvelle colonne générée par IA, accompagné d'une réponse synthétique à la question globale posée sur l'ensemble des données.
Avant de coder, Guillaume présente un exemple concret de sa méthodologie : l'application Revly, une app d'interprétation de rêves construite sur Softr avec un bloc custom vibe-codé. Ce bloc gère la capture audio, la transcription via Voxstral, l'affichage du transcript éditable, l'appel à N8N pour l'interprétation et la logique de sauvegarde avec email matching. Cela illustre bien le principe de la session : utiliser Softr comme conteneur d'infrastructure et y injecter uniquement les blocs custom qui dépassent les capacités natives.
Guillaume commence la construction par N8N. Il configure un premier webhook en mode production (pas en mode test, pour pouvoir en communiquer l'URL directement à Gemini), puis dicte son prompt à Gemini via Whisperflow pour générer le bloc HTML qui gère l'upload du CSV et l'envoi au webhook. Il renomme le CSV côté front pour simplifier sa manipulation dans le workflow.
Alexis l'encourage à avancer étape par étape plutôt que de tout planifier d'un coup, ce que Guillaume accepte tout en expliquant pourquoi il a besoin d'anticiper le format du JSON de retour pour que le bloc front puisse l'afficher correctement dès le one-shot.
Ensemble, ils définissent l'architecture du flow en deux temps avec un point de validation humaine (human-in-the-loop) : le premier appel envoie le CSV et le prompt, N8N analyse les colonnes, suggère les colonnes à retenir, le prompt par ligne et le prompt global, puis renvoie tout ça à l'interface pour validation. Le second appel, déclenché après confirmation humaine, reçoit les paramètres validés et lance la génération ligne par ligne.
Pour le premier traitement N8N, Guillaume utilise le nœud Extract from Files pour parser le CSV en JSON, puis un code node demandé à ChatGPT pour extraire les noms de colonnes avec trois valeurs d'exemple chacune, sans avoir à prédire les noms à l'avance. Ce contexte est ensuite passé à un LLM (GPT-4.1 mini) avec un system prompt structuré pour qu'il retourne un JSON normalisé : colonnes sélectionnées, prompt par ligne et prompt global. Le résultat est retourné au front via un nœud Respond to Webhook.
Le premier test aboutit avec succès au one-shot : l'interface affiche correctement les colonnes avec leurs checkboxes et les prompts éditables, conformément au JSON prévu.
Guillaume construit ensuite le second webhook pour recevoir les données validées par l'utilisateur. Des problèmes apparaissent autour du format des données renvoyées (le JSON validé arrive sous forme de chaîne de texte au lieu d'un objet parsé, le CSV est envoyé comme fichier séparé au lieu d'être dans le body). Ces points sont résolus par des échanges itératifs avec Gemini, qui à chaque fois réécrit l'intégralité du code mais sans casser les fonctionnalités existantes.
La boucle de traitement ligne par ligne est ensuite construite dans N8N : split des items du CSV, nœud Set pour nettoyer les données, code node pour filtrer uniquement les colonnes sélectionnées, puis appel LLM avec le prompt par ligne pour chaque ligne. Guillaume montre la technique du pin data pour éviter de déclencher les appels LLM à chaque test.
En fin de session, Guillaume intègre le bloc dans Softr en quelques minutes, configure les permissions d'accès aux logged-in users uniquement et montre la création rapide d'une page hero pour les visiteurs non connectés avec un CTA vers le sign-up. La session se termine sans avoir eu le temps d'implémenter le stockage des résultats en base Softr ni le prompt global final, mais la mécanique complète est démontrée et fonctionnelle.
Il conclut en montrant brièvement Wiglot Translator, son premier SaaS construit avec la même approche, déjà en production avec de vraies utilisations.
Il expose l'idée du projet : une application permettant d'uploader un fichier CSV, d'y associer une requête en langage naturel, et d'obtenir en retour un CSV enrichi avec une nouvelle colonne générée par IA, accompagné d'une réponse synthétique à la question globale posée sur l'ensemble des données.
Avant de coder, Guillaume présente un exemple concret de sa méthodologie : l'application Revly, une app d'interprétation de rêves construite sur Softr avec un bloc custom vibe-codé. Ce bloc gère la capture audio, la transcription via Voxstral, l'affichage du transcript éditable, l'appel à N8N pour l'interprétation et la logique de sauvegarde avec email matching. Cela illustre bien le principe de la session : utiliser Softr comme conteneur d'infrastructure et y injecter uniquement les blocs custom qui dépassent les capacités natives.
Guillaume commence la construction par N8N. Il configure un premier webhook en mode production (pas en mode test, pour pouvoir en communiquer l'URL directement à Gemini), puis dicte son prompt à Gemini via Whisperflow pour générer le bloc HTML qui gère l'upload du CSV et l'envoi au webhook. Il renomme le CSV côté front pour simplifier sa manipulation dans le workflow.
Alexis l'encourage à avancer étape par étape plutôt que de tout planifier d'un coup, ce que Guillaume accepte tout en expliquant pourquoi il a besoin d'anticiper le format du JSON de retour pour que le bloc front puisse l'afficher correctement dès le one-shot.
Ensemble, ils définissent l'architecture du flow en deux temps avec un point de validation humaine (human-in-the-loop) : le premier appel envoie le CSV et le prompt, N8N analyse les colonnes, suggère les colonnes à retenir, le prompt par ligne et le prompt global, puis renvoie tout ça à l'interface pour validation. Le second appel, déclenché après confirmation humaine, reçoit les paramètres validés et lance la génération ligne par ligne.
Pour le premier traitement N8N, Guillaume utilise le nœud Extract from Files pour parser le CSV en JSON, puis un code node demandé à ChatGPT pour extraire les noms de colonnes avec trois valeurs d'exemple chacune, sans avoir à prédire les noms à l'avance. Ce contexte est ensuite passé à un LLM (GPT-4.1 mini) avec un system prompt structuré pour qu'il retourne un JSON normalisé : colonnes sélectionnées, prompt par ligne et prompt global. Le résultat est retourné au front via un nœud Respond to Webhook.
Le premier test aboutit avec succès au one-shot : l'interface affiche correctement les colonnes avec leurs checkboxes et les prompts éditables, conformément au JSON prévu.
Guillaume construit ensuite le second webhook pour recevoir les données validées par l'utilisateur. Des problèmes apparaissent autour du format des données renvoyées (le JSON validé arrive sous forme de chaîne de texte au lieu d'un objet parsé, le CSV est envoyé comme fichier séparé au lieu d'être dans le body). Ces points sont résolus par des échanges itératifs avec Gemini, qui à chaque fois réécrit l'intégralité du code mais sans casser les fonctionnalités existantes.
La boucle de traitement ligne par ligne est ensuite construite dans N8N : split des items du CSV, nœud Set pour nettoyer les données, code node pour filtrer uniquement les colonnes sélectionnées, puis appel LLM avec le prompt par ligne pour chaque ligne. Guillaume montre la technique du pin data pour éviter de déclencher les appels LLM à chaque test.
En fin de session, Guillaume intègre le bloc dans Softr en quelques minutes, configure les permissions d'accès aux logged-in users uniquement et montre la création rapide d'une page hero pour les visiteurs non connectés avec un CTA vers le sign-up. La session se termine sans avoir eu le temps d'implémenter le stockage des résultats en base Softr ni le prompt global final, mais la mécanique complète est démontrée et fonctionnelle.
Il conclut en montrant brièvement Wiglot Translator, son premier SaaS construit avec la même approche, déjà en production avec de vraies utilisations.
Ce qu'on a appris
- **L'approche hybride no-code + vibe coding change radicalement le rapport au risque.** En déléguant l'infrastructure (auth, routing, permissions, composants UI) à un outil comme Softr, on limite le périmètre du code vibe-codé à une surface très précise et très bien définie. Moins de surface = moins de bugs potentiels.
- **Définir le contrat d'interface avant de coder est une pratique déterminante.** Guillaume a d'abord demandé à Gemini de lui générer un exemple du JSON de retour attendu, puis a construit son workflow N8N pour produire exactement ce format. Cette discipline évite d'avoir à modifier le bloc front une fois que le workflow est en place.
- **Le one-shot fonctionne mieux quand le contexte est très contraint.** Dès que la mission est claire (uploader un CSV, envoyer à un webhook, afficher une réponse JSON de structure connue), Gemini produit quelque chose d'utilisable immédiatement. C'est l'inverse du vibe coding sans direction.
- **N8N et Gemini Canvas se complètent bien dans cette architecture.** Gemini Canvas joue le rôle d'environnement de prévisualisation et d'itération du bloc front. N8N joue le rôle de backend controllable. Les deux parlent via webhook. Cette séparation claire réduit la complexité cognitive à chaque bout.
- **La gestion des données dynamiques (colonnes non prédictibles) nécessite du code.** Dès que la structure d'un objet ne peut pas être connue à l'avance (noms de colonnes d'un CSV arbitraire), les nœuds visuels de N8N ne suffisent plus. Un code node devient nécessaire, et c'est là que l'IA générative dans N8N prend tout son sens.
- **Passer trois valeurs d'exemple par colonne au LLM est une astuce efficace pour limiter les tokens tout en conservant le contexte sémantique.** Le modèle comprend ce qu'il y a dans chaque colonne sans avoir à ingérer tout le CSV. À fort volume (centaines de lignes), c'est la différence entre un appel raisonnable et un appel qui explose la fenêtre de contexte.
- **Gemini réécrit systématiquement tout le code plutôt que de faire des diffs.** C'est un comportement connu de Gemini qui contraste avec Claude ou GPT qui font davantage d'éditions ciblées. Dans ce workflow, ça n'a pas causé de régressions notables, mais ça rend la collaboration moins efficace sur du code long.
- **Le human-in-the-loop dans un workflow N8N est architecturalement non trivial.** Mettre le workflow en pause entre deux appels nécessite soit une gestion de session côté front (stocker le CSV pour le réenvoyer au deuxième appel), soit un mécanisme de wait dans N8N (non exploré pendant la session). Guillaume a choisi la voie pragmatique : réenvoyer le CSV du côté front.
- **Le nœud pin data de N8N est une pratique de développement importante.** Il permet de figer la sortie d'un nœud pour tester les nœuds suivants sans déclencher les appels coûteux (LLM, API tierces) à chaque itération. C'est l'équivalent d'un mock dans un projet de dev classique.
- **La parallélisation des appels LLM est le levier de performance le plus important sur des CSV volumineux.** Une boucle séquentielle de 100 lignes à 10 secondes par appel = 1000 secondes. Des appels en parallèle (ou en batch de 50) ramèneraient ça à 10 secondes. C'est un point d'architecture à prévoir dès le début si le volume est un enjeu.
- **Les edge cases sur les colonnes vides ou peu remplies ne sont pas gérés automatiquement.** Le logo n'est pas remonté dans le JSON parce qu'il n'avait pas de valeur dans les trois exemples extraits. Il faudrait rendre le code node plus robuste pour couvrir ces cas (colonnes avec moins de trois valeurs disponibles).
- **Exposer une clé API dans un bloc front custom est une erreur de sécurité classique.** Guillaume a contourné ça en passant par N8N comme proxy, ce qui est la bonne approche. Les appels LLM restent côté serveur (N8N) et le bloc front ne voit jamais les clés.
- **Le déploiement du code custom dans Softr pose un vrai problème de structure HTML.** Copier-coller le HTML complet généré par Gemini (incluant les balises `<html>`, `<head>`, `<body>`) dans un bloc Softr crée des conflits. La bonne pratique est soit d'extraire uniquement le contenu du `<body>` et de mettre les scripts du `<head>` dans la configuration globale de Softr, soit de demander à Gemini dès le départ de générer du code adapté à une intégration dans une page existante.
- **La précision du prompt de génération de code est directement corrélée au nombre d'itérations nécessaires.** Quand Guillaume a précisé le format exact du JSON à envoyer (et pas juste "envoie le CSV"), le résultat a fonctionné du premier coup. Quand il a été moins précis (envoyer les données dans le body vs en tant que fichier), ça a nécessité une repasse.
- **Cette architecture a une vraie valeur produit immédiate.** En deux heures, Guillaume a posé les bases d'un outil multi-utilisateurs avec auth, interface moderne, logique IA et export CSV, sans une seule ligne de backend custom écrite manuellement. Le SaaS Weglot Translator qu'il a montré à la fin valide que cette approche fonctionne en production.