lowercase.fr
fonctionnalitéstarifsà proposnouveautésblog
se connecter

← blog

un saas satirique, de vrais choix d'architecture

· quentin guille, fondateur & chief lowercase officer

architecture
coûts
ops

lowercase.fr met des fichiers en minuscules. ce n'est pas qu'une blague.

une blague en production, avec des comptes, une api, un sdk npm et une base de données, reste un vrai service. et mon côté ingénieur se pose des questions sur ce service, alors même que personne ne l'utilisera.

la première question que je me suis posée, c'est finalement celle qu'on se pose en construisant n'importe quel saas : à quel problème je réponds, et quelle solution j'apporte ? de là, la solution se construit. il faudra optimiser, mais pas pour les mêmes raisons qu'un vrai saas : ici, on optimise pour le coût, en réutilisant au maximum ce que j'ai déjà. j'ai déjà un vps pour mon site perso alors réutilisons ça.

ne pas suroptimiser : on ne scalera pas

pas de kubernetes, pas de file de messages, pas de cdn, pas de base managée. un seul vps, celui qui héberge déjà mes autres sites. un docker compose avec trois conteneurs (l'api en go, le front en ssr, un postgres), un nginx installé sur la machine, et des ports qui n'écoutent que sur 127.0.0.1.

ce n'est pas de la paresse, c'est un budget de complexité. chaque brique en plus, c'est une chose de plus à mettre à jour, à surveiller et à comprendre à 23 h quand elle casse. pour un projet qui vit sur mon temps libre, l'architecture la plus robuste est celle que je peux tenir entière dans ma tête.

avec mon arrivée chez ovhcloud, je me suis posé la question de passer par du k3s ou du k8s pour gérer la stack applicative. ma réflexion n'étant pas mûre sur le sujet, j'ai préféré rester sur ce que je connais et maîtrise.

une blague ne doit rien coûter

le vrai risque d'un projet satirique, ce n'est pas le succès : si vous lisez ce billet, c'est déjà une réussite, et dans un futur proche j'essaierai d'ajouter des commentaires pour échanger sur ce projet farfelu.

aujourd'hui, le risque principal, c'est la facture. dans la france de macron, avoir de l'argent qui sort chaque mois pour une blague n'est pas l'idée la plus intelligente que j'aie pu avoir. un service gratuit et ouvert sur internet attire surtout des robots, et un robot ne se lasse jamais. la question n'est donc pas « combien d'utilisateurs ? » mais « qu'est-ce qui m'empêche de payer pour eux ? ».

autre chose que j'ai remarquée : les robots des ia sont déjà là. le billet précédent a déjà été lu par celui de mistral, et celui-ci le sera sûrement avant vous. mieux : des scanners de failles se font passer pour eux, et c'est sous le nom de claudebot ou de mistral qu'ils viennent réclamer mes fichiers .env.

quelques réponses concrètes :

  • aucun service payant à l'usage. pas d'api d'e-mail (c'est pour ça que lowercase.fr n'envoie toujours pas de mail de vérification), pas de captcha tiers : le nôtre vous demande de retaper en minuscules une phrase qui crie. les alertes partent par sms via l'api de notification de mon opérateur.
  • des limites partout. nginx coupe à 20 requêtes par seconde par ip, et à 10 par minute sur la connexion et l'inscription. un compte gratuit envoie 3 fichiers par heure. l'api de transformation accepte uniquement 200 caractères par appel : personne n'a de compte premium, pas même moi.
  • la mémoire mesurée, pas devinée. un test mesure ce que coûte le pire cas de chaque requête : un upload de 10 Mo, un diff, et même une transformation de 500 000 caractères, la limite d'un compte premium que personne n'aura jamais (le code la prévoit quand même, on ne sait jamais). le nombre de requêtes lourdes simultanées en découle : 3 uploads, 4 transformations, 2 diffs, sous une limite mémoire de 200 Mo pour toute l'api. au-delà, on vous demande de patienter quelques secondes plutôt que de laisser la machine tomber.
  • le disque protégé. le vps est partagé : l'api refuse les uploads dès qu'il reste moins de 2 Go libres, avant de remplir le disque de mes autres sites.
  • les données qui partent toutes seules. les documents supprimés sont purgés après 30 jours, le journal des appels à l'api aussi. ce qu'on ne garde pas ne coûte rien, ni en disque, ni en rgpd.
  • une suppression encore plus rapide, bientôt. avoir des données, c'est drôle, mais sans validation des comptes par e-mail, le risque de spam est réel. je réfléchis à une purge automatique des comptes après 3 jours d'inactivité : de quoi créer un compte, se connecter et faire quelques essais, et tout le monde est tranquille.

il reste finalement la question qui fâche : et l'argent ? la page des tarifs affiche un plan pro à 29 € par mois, et rien ne m'empêcherait de brancher stripe pour le rendre activable. le problème, c'est la blague : peut-on encore être satirique quand on encaisse ? une parodie de saas qui facture devient un saas, avec une entreprise derrière, des factures, de la tva, des conditions générales de vente et des clients qui réclament à juste titre ce qu'ils ont payé. le plan pro n'est donc qu'un décor : personne n'y a droit, pas même moi, et le bouton « essai gratuit » mène à la page de connexion, pas à un paiement.

et parfois, le meilleur serveur est celui qu'on n'appelle pas. la démo de la page fonctionnalités met votre texte en minuscules sous vos yeux, sans un seul appel à l'api : elle utilise @lowercase-fr/tolower, notre sdk, directement dans votre navigateur. même résultat que l'api, au caractère près (nous l'avons vérifié sur tout unicode), et zéro coût côté serveur.

se tirer une balle dans le pied, mais le savoir tout de suite

ne pas scaler ne veut pas dire ne pas surveiller. un vps unique, c'est aussi un point de défaillance unique, et le pire scénario n'est pas la panne : c'est la panne dont on s'aperçoit trois semaines plus tard.

ce qui tourne aujourd'hui :

  • une sauvegarde chaque nuit de la base et des documents, gardée 7 jours. si elle échoue, je reçois un sms, et l'échec s'affiche à ma prochaine connexion ssh.
  • un smoke-test après chaque déploiement : une quarantaine de vérifications sur le site en production, des en-têtes de sécurité au sitemap, en passant par une inscription, un upload et une suppression de compte jetable. si une seule échoue, je ne passe pas à autre chose.
  • fail2ban et un pare-feu devant tout ça, parce que les robots, eux, scalent très bien.

et ce qui manque encore, parce qu'un article honnête doit le dire : les sauvegardes restent sur la même machine que ce qu'elles sauvegardent, et rien ne me prévient si le site tombe en pleine journée. ce sont les deux prochaines étapes.

ce que la blague m'a forcé à faire

le plus surprenant, c'est tout ce qu'un projet « pour rire » finit par exiger. rien de tout ça n'était prévu au départ :

  • respecter le rgpd pour de vrai. des comptes, des fichiers et des adresses ip, ce sont des données personnelles, blague ou pas. il a fallu une politique de confidentialité en quatre langues, un consentement pour les deux seuls cookies optionnels (le thème et la langue), et une règle tenue jusque dans la config nginx : le texte envoyé à l'api ne touche jamais le disque, pas même dans un fichier temporaire.
  • prouver ce qu'on promet. écrire « exactement comme l'api » dans le readme du sdk m'a obligé à tester les 1 112 064 caractères d'unicode.
  • déployer avec méthode. avant chaque mise en production : une sauvegarde, l'ancienne version gardée sous le coude pour revenir en arrière en une commande, une relecture adversariale du code (j'y reviens juste après), puis le smoke-test. c'est plus de rigueur que sur certains projets qui facturent.
  • dire non. la vérification des e-mails est restée dans un tiroir : il aurait fallu confier au serveur le mot de passe d'une vraie boîte mail, ou brancher un service d'envoi tiers de plus. pour un site qui met des fichiers en minuscules, ni l'un ni l'autre ne valait le risque.
  • soigner ce que personne ne demande. sécurité des en-têtes, accessibilité, référencement, poids des pages : les audits ne savent pas que c'est une blague. ils notent pareil.

un humain, puis des ia

une précision honnête sur la façon dont tout ça est construit, parce que la question se pose forcément, surtout à l'heure de l'agentic engineering et du vibe coding.

la première version de lowercase.fr, en mars, je l'ai écrite à la main. et surtout, c'est là que se sont prises les décisions qui tiennent encore tout le reste : une api en go, un front en tanstack start rendu côté serveur pour que les moteurs de recherche voient le contenu, mui pour l'interface, postgres pour les données. ce socle, ces choix, ce sont les miens. je les ai faits un peu comme un projet de fin d'études : j'avais besoin de recul après presque cinq années de développement front, et de voir si j'étais capable de créer un saas de a à z, sans dépendre de ressources externes. dans une certaine mesure, j'ai réussi cette première version. puis j'ai changé de poste, j'ai pris de nouvelles responsabilités, et inévitablement, ce projet a pris la poussière.

quand je l'ai repris en octobre, après sept mois au placard, j'ai changé de méthode. je voulais apprendre à maîtriser les ia autrement que dans mon travail (j'en parlerai sûrement dans de futurs billets sur mon site personnel, si je le fais un jour), sur un projet réel avec de vraies contraintes plutôt que sur des exemples de démo. un saas satirique est parfait pour ça : assez sérieux pour qu'une erreur se voie en production, assez inoffensif pour qu'elle ne coûte presque rien.

une session de claude code orchestre le nouveau code, à partir de ce que je lui demande. selon que je veux garder la main ou aller vite, elle l'écrit elle-même, ou elle le répartit entre plusieurs agents qui travaillent en parallèle, comme pour l'audit de mes serveurs. une deuxième session, qui ne l'a pas écrit, le relit en adversaire avant chaque mise en production : elle cherche ce qui casse, et la version ne part pas tant qu'elle n'a pas validé. c'est elle qui a repéré, par exemple, qu'un menu chargé à la demande pouvait faire planter toute la page sur un onglet resté ouvert pendant un déploiement.

mon rôle a changé, il n'a pas disparu : je décide de ce qu'on construit et de ce qu'on refuse, je tranche les choix d'architecture, je teste dans un vrai navigateur, et rien ne part en production sans mon feu vert. les ia vont vite, et elles vont d'autant plus loin que le socle posé à la main était solide. c'est justement pour ça qu'il faut quelqu'un pour dire où aller, et quand s'arrêter.

ce que la blague m'a appris

construire quelque chose d'inutile oblige à être très précis sur ce qui est utile. quand le produit ne justifie aucune dépense, chaque choix d'architecture doit se défendre seul : est-ce que ça protège la machine ? est-ce que ça m'évite une facture ? est-ce que je le saurai quand ça cassera ?

j'en retiens quatre choses :

  1. les contraintes font l'architecture. pas de budget, pas de temps, une seule machine : ces limites ont produit plus de décisions claires que n'importe quel cahier des charges. ce qu'on ne peut pas se payer, il faut le concevoir.
  2. mesurer avant de dimensionner. chaque limite du service vient d'une mesure (mémoire, disque, temps de réponse), jamais d'une intuition. sans utilisateurs pour révéler les erreurs, c'est la seule façon de savoir.
  3. un petit système mérite un vrai soin. la taille d'un projet ne change rien à ce qu'il faut pour le faire tourner proprement : sauvegarder, surveiller, pouvoir revenir en arrière. elle change seulement le temps qu'on a pour le faire.
  4. travailler avec des ia, ça s'apprend en vrai. leur donner le contexte, exiger des preuves plutôt que des promesses (un test qui passe, une capture d'écran, une mesure), faire relire leur travail par une autre qui ne l'a pas écrit, et garder pour soi les décisions. rien de tout ça ne s'apprend sur un exemple de tutoriel : il faut un projet qui peut casser.

ce sont exactement les questions qu'on oublie de poser sur les projets sérieux, parce qu'on suppose qu'ils grandiront, et qu'il y aura un chef de produit, un chef de projet, des collègues pour relire nos pull requests, un tech lead pour orienter les choix et un architecte d'entreprise pour trancher entre une architecture event-driven ou une autre. lowercase.fr ne grandira pas. il restera petit, calme et en minuscules. et c'est un très bon terrain d'entraînement.