
- rôle
- Produit, règles métier, specs, design, développement.
- période
- Octobre 2026 · construit en deux jours, 11–12 oct.
- plateforme
- Web, installable sur téléphone, un seul utilisateur
- stack
- Next.js 16, Tailwind v4, shadcn/ui · Drizzle, Neon · Better Auth · Vercel Blob, Resend, react-pdf · API Claude
- en chiffres
- 42 commits, ~25 000 lignes de TypeScript, 306 tests unitaires, 84 parcours de bout en bout, 47 décisions notées
01 · contexte
Un outil plutôt que cinq
En octobre 2026, j’ai quitté mon poste de lead front-end pour devenir ingénieur front-end freelance, en micro-entreprise, au moment de partir un an en Amérique latine. Il me fallait un endroit unique pour savoir où j’en suis, utilisable depuis un ordinateur comme depuis un téléphone, avec du réseau ou presque pas.
Ce que je voulais tenir : le chiffre d’affaires encaissé et ce qu’il reste sous les plafonds, les cotisations à mettre de côté, les échéances URSSAF et fiscales rappelées dans mon agenda, des factures propres faites à partir de ce que j’ai réellement livré, les prospects arrivés par le formulaire de mon site, un lien suivi avec mes clients, et mes documents au même endroit.
Quatre principes
- Calculer plutôt que saisir.
Le livre des recettes vient des paiements, les cotisations du livre des recettes, les échéances de mon statut, les tâches de règles.
- Proposer, ne pas décider.
Relances, montants à déclarer, suggestions aux clients : l’app prépare, je valide.
- Le chiffre exact, la règle visible.
Chaque montant calculé montre sa base et son taux.
- Sobriété.
Ma charte, sans exception : une police, un accent, pas de rouge. Une alerte s’écrit en gras.
Je ne suis pas comptable, et lotus ne remplace pas un conseil. Les taux et les seuils qu’il applique sont datés, sourcés, et les points incertains restent modifiables dans l’interface.
02 · produit
Ce que fait l’app
Sept écrans, une barre latérale qui devient un tiroir sur téléphone, un mode jour et un mode nuit.
- tableau de bord
- Chiffre d’affaires encaissé, ce qui reste à encaisser, ce qu’il faut mettre de côté pour l’URSSAF, les tâches du moment, les derniers prospects.
- comptabilité
- Livre des recettes, plafond du régime micro, franchise de TVA, cotisations détaillées ligne par ligne, exports CSV et PDF, archive annuelle.
- échéances
- Calendrier du mois, déclarations à venir, tâches, synchronisation avec Google Calendar.
- clients
- Fiche, prestations à facturer, abonnements de maintenance, historique des e-mails, suggestions du mois.
- factures
- Générateur à partir des prestations, aperçu fidèle au PDF, envoi, paiements, relances, avoirs et devis.
- leads
- Les demandes du formulaire de mon site, en pipeline, jusqu’à la conversion en client.
- documents
- Présentations, propositions, audits, contrats et PDF générés, rangés et partageables par lien qui expire.



03 · architecture
L’architecture
Le principe « calculer plutôt que saisir » dessine toute l’app. Je ne saisis presque qu’une chose à la main : la date et le montant d’un encaissement. Le reste en découle.

Une app Next.js, un dossier par fonctionnalité
Server Components par défaut, Server Actions pour écrire. Chaque fonctionnalité a son dossier : les lectures, les actions, leurs schémas Zod, ses composants. Chaque action suit le même chemin : session vérifiée, entrée validée, transaction si plusieurs tables sont touchées, journal d’audit pour tout ce qui est comptable, résultat typé.
src/
├─ app/(app)/ écrans protégés : /, /comptabilite, /factures…
├─ app/api/ webhook des leads, crons, pdf, ics, exports
├─ features/ clients, invoices, accounting, obligations,
│ calendar, leads, nurturing, documents…
├─ lib/fiscal/ taux et seuils datés, cotisations, échéances
├─ components/ui/ shadcn/ui, retouché selon ma charte
└─ components/pdf/ factures, devis, livre des recettes
| sujet | retenu | pourquoi |
|---|---|---|
| Base | Neon en production, PGlite partout ailleurs | Un vrai Postgres compilé en WebAssembly : le développement, les tests et la CI tournent sans Docker ni compte Neon, avec le même code. |
| Connexion | Better Auth, Google, un seul compte | Pas d’inscription publique ; le même compte Google donne accès à l’agenda. |
| Interface | shadcn/ui, thème réécrit | Des composants accessibles dont je possède le code, ramenés à ma charte : rayon 2 px, aucune ombre, des glyphes plutôt que des icônes. |
| Fichiers | Vercel Blob en mode privé | Aucune adresse de fichier n’atteint le navigateur ; tout passe par une route qui vérifie la session. |
| Tâches de fond | Trois crons : jour, semaine, mois | Chaque étape est rejouable sans doublon, grâce à une clé de déduplication par élément. |
04 · factures
Facturer sans se tromper
Une facture est un document légal : un numéro qui se suit sans trou, des mentions obligatoires, des montants qui ne bougent plus une fois envoyés. C’est la partie où une erreur coûte le plus, et celle où le code est le plus strict.

- L’argent en centimes entiers.
Jamais de nombre à virgule flottante. Arrondi au centime, demi vers le haut, ligne par ligne.
- Un numéro sans trou ni doublon.
Attribué à l’émission, dans une transaction qui verrouille le compteur de l’année. Un test lance deux émissions simultanées et vérifie qu’elles reçoivent deux numéros consécutifs.
- Tout est figé à l’émission.
Mon identité, celle du client, mes coordonnées bancaires et les mentions légales sont copiées dans la facture : changer d’adresse demain ne réécrit pas les factures d’hier.
- Ce que je vois est ce que reçoit le client.
Un seul modèle d’affichage produit toutes les chaînes ; l’aperçu HTML et le PDF ne font que les placer.
- Les relances sont des tâches.
À J+1, J+15 et J+30 après l’échéance, une tâche « Relancer » apparaît, et se ferme seule quand la facture est soldée.
La micro-typographie française veut une espace fine insécable dans « 1 200,00 € ». Geist n’a pas ce glyphe : dans les PDF, elle est remplacée par une espace insécable ordinaire. Le genre de détail qu’on ne découvre qu’en imprimant.
05 · échéances
L’URSSAF dans mon agenda
La règle de travail la plus importante du projet tient en une ligne : ne jamais deviner une règle fiscale. Les taux et les seuils vivent dans un seul fichier, chacun avec sa date de validité, et sont testés. Une année non couverte réutilise la dernière version connue et l’écrit : « taux 2026 · à confirmer pour 2027 ».
Ne jamais deviner une règle fiscale.
Chaque nuit, un cron génère les obligations des quinze prochains mois à partir de mes paramètres : déclarations URSSAF trimestrielles, impôt sur le revenu, CFE. Le montant estimé d’une déclaration est recalculé depuis le livre des recettes tant qu’elle n’est pas faite. Une obligation déclarée ne bouge plus.
Elle ne suit pas le rythme des suivantes. Pour une activité démarrée le 15 octobre 2026, la spec calcule une première période jusqu’au 31 mars 2027, à déclarer avant le 30 avril. Les deux dates restent modifiables : c’est l’URSSAF qui a le dernier mot.
Ces échéances, les dates limites des factures et mes tâches datées partent dans un agenda « lotus » de mon Google Calendar, avec la portée la plus étroite possible : l’app ne voit que l’agenda qu’elle a créé. Un flux ICS à jeton, régénérable, fait la même chose pour n’importe quel autre agenda.
Côté plafonds, le générateur de facture montre l’effet du montant avant que je l’émette : part du plafond du régime micro, et alerte si la facture ferait dépasser le seuil de franchise de TVA.

06 · leads
Du formulaire au client fidèle
Le formulaire de contact de mon site et lotus sont deux applications distinctes. Le contrat entre elles est écrit une fois, dans un document qui fait foi pour les deux dépôts. La règle de départ : un prospect n’est jamais perdu parce que lotus est indisponible.

La requête est signée en HMAC SHA-256 sur l’horodatage et le corps exact ; lotus refuse un écart de plus de cinq minutes, compare la signature à temps constant et ne dit jamais pourquoi il refuse. Un identifiant fourni par le site sert de clé d’idempotence : un renvoi ne crée jamais de doublon. Le lead arrive avec une tâche « Répondre à… ».
Puis, une fois par mois, le nurturing
Le 1er du mois, lotus passe les sites de mes clients dans PageSpeed Insights. Trente règles transforment les résultats en suggestions chiffrées à mon taux journalier : optimiser les images, mettre à jour un framework, corriger un parcours au clavier. L’API Claude rédige l’e-mail du mois à partir de ces suggestions. J’en retire, j’en ajoute, je relis, j’envoie.
Ne sortent de l’app que la société, l’adresse du site, le secteur, la stack et les résultats du scan : ni nom de contact, ni e-mail. Une suggestion acceptée devient une prestation, qui deviendra une ligne de facture. La boucle est fermée.


07 · sécurité
Une app privée sur Internet
Coordonnées bancaires, chiffre d’affaires, données de prospects : une app pour une seule personne, mais exposée au monde.
- Une surface publique listée, exhaustive.
Connexion, pages légales, webhook signé, crons à secret, flux ICS à jeton, liens de partage. Tout le reste exige une session vérifiée côté serveur, et un test le contrôle module par module.
- Des liens de partage qui ne racontent rien.
Jeton de 32 octets dont seule l’empreinte est stockée ; expiré, révoqué ou inconnu, la réponse est la même : « Ce lien a expiré. »
- Invisible des moteurs de recherche.
En-têtes stricts sur toutes les routes, et rien d’indexable.
- Une sauvegarde par mois.
Deux ans conservés, en plus de la restauration à un instant donné de Neon.
Un compromis est assumé et écrit : la politique de sécurité du contenu n’utilise pas de nonce, parce qu’un nonce force le rendu dynamique de chaque page et casse le prérendu partiel de Next.js 16. Le reste de la politique est strict.
08 · méthode
Construit en douze phases
lotus est le premier projet que j’ai mené de cette façon, juste avant pensee. Un dossier de spécification complet d’abord : vision, architecture, modèle de données, règles métier de la micro-entreprise, charte appliquée à shadcn/ui, douze fonctionnalités avec leurs critères d’acceptation, un schéma Drizzle et des règles fiscales de référence, et les maquettes des écrans. Puis le développement, phase par phase.
Chaque phase se termine par un build, un lint et des tests verts, et un commit. Deux fichiers tiennent la mémoire du projet : l’état d’avancement, pour reprendre après une coupure, et un journal de décisions, où chaque écart à la spec est noté avec sa raison. Il en compte quarante-sept.
- 2 jours
- 42
- ~25 000
- 390
- 47
Les tests tournent sur PGlite, sans service réel : Vitest pour les règles métier (cotisations, plafonds, numérotation, échéances), Playwright pour les parcours, et axe pour l’accessibilité, en mode jour comme en mode nuit. Une connexion simulée, réservée aux tests, évite de passer par Google.

09 · bilan
Ce que j’en retiens
- Une règle fiscale ne se devine pas.
Elle se date, se teste, et reste modifiable quand elle est incertaine.
- Calculer plutôt que saisir
supprime une classe entière d’erreurs : celles de recopie.
- Un journal de décisions vaut une revue de code.
Quarante-sept écarts expliqués, c’est ce qui permet de revenir sur un choix des mois plus tard sans le refaire.
- Deux apps qui se parlent par un contrat écrit.
Le site et lotus évoluent chacun de leur côté, sans jamais se casser l’un l’autre.








