Retour aux projetsÉtude de casDéveloppement produit SaaS

Atoly

Les prestataires de services -- ateliers de poterie, praticiens du bien-être, consultants -- jonglaient entre tableurs, appels téléphoniques et outils déconnectés. J'ai construit Atoly pour leur offrir une plateforme unique qui gère réservations, paiements et relation client, pendant que leurs propres clients profitent d'une expérience de réservation simple et fiable.

Étude de casPRJ/ATOLY
Développement produit SaaS

Atoly est une plateforme de réservation et de gestion d'activité pour les prestataires de services, avec planning, paiements, opérations clients et delivery multi-plateforme.

Système en ligne

atoly.co

Type
Produit SaaS
Stack
React, Node, SQLite
Plateformes
Web, Mobile, API
Statut
En ligne sur atoly.co

Le problème

Les petites structures de services -- imaginez un atelier de poterie à Lyon ou un consultant indépendant à Paris -- n'ont pas accès aux mêmes outils qu'une entreprise SaaS ou qu'un cabinet médical. La plupart des solutions de réservation proposent soit un simple lien de prise de rendez-vous, à la Calendly, soit une suite tout-en-un lourde pensée pour les grandes organisations. Ce dont ces activités ont réellement besoin se situe entre les deux : un site de réservation personnalisé, un moyen de gérer les clients, des paiements intégrés et des rappels automatiques, sans devoir assembler cinq services différents.

C'est l'espace qu'Atoly occupe. Pas seulement un lien de réservation, mais une véritable présence web pour chaque entreprise, avec un tableau de bord qui gère le quotidien d'une activité de service.

Ce que j'ai construit

Atoly est une plateforme complète de planning et de gestion d'activité. Chaque entreprise qui s'inscrit obtient un site public de réservation, pas seulement un lien, un back-office pour gérer événements, clients et commandes, ainsi qu'une application mobile pour piloter l'activité en déplacement. Sous le capot, la plateforme se connecte à Google Calendar, Microsoft Outlook, Stripe, et envoie automatiquement des emails transactionnels et des SMS.

Le périmètre était important. J'ai livré cinq applications distinctes à partir d'un seul codebase : l'application web principale, les pages publiques de réservation, une application mobile React Native, un site marketing et un outil d'administration. L'ensemble partage la logique métier au sein d'un monorepo composé de 18 packages internes.

Les décisions d'architecture qui ont compté

Très tôt, j'ai pris quelques paris d'architecture qui ont modelé tout le reste. Le premier concernait la multi-tenance avec une isolation réelle des bases de données. Plutôt qu'une base partagée avec des colonnes de tenant, solution plus simple, chaque organisation dispose de sa propre base SQLite synchronisée dans le cloud via Turso. Cela élimine tout risque de fuite de données entre tenants et permet de faire évoluer chaque organisation indépendamment. Une base centrale de plateforme gère utilisateurs, organisations et appartenances.

La deuxième décision a été d'adopter une approche domain-driven dès le premier jour. Le codebase est organisé en contextes délimités -- @atoly/booking, @atoly/sales, @atoly/notifications, @atoly/organization -- chacun avec ses entités, ses repositories et ses cas d'usage. Cela a gardé le code navigable alors que les fonctionnalités s'accumulaient et a permis à différentes parties du système d'évoluer indépendamment.

# Structure du monorepo
apps/
  atoly-webapp         # Application web full-stack (React Router + Hono)
  atoly-mobile         # React Native + Expo
  atoly-frontends      # Pages publiques de reservation
  marketing            # atoly.co
packages/
  @atoly/core          # Modeles de domaine, value objects
  @atoly/booking       # Moteur de reservation
  @atoly/sales         # Paiements, commandes, pricing
  @atoly/notifications # Pipelines email et SMS
  @atoly/infrastructure # Base, couche API, repositories
  @atoly/ui            # Bibliotheque de composants partages
  # ...et 12 autres

Le troisième pari a été l'utilisation de workflows événementiels avec Inngest pour tout ce qui est asynchrone. Lorsqu'une réservation est créée, un événement de domaine est émis. Cet événement déclenche les emails de confirmation, les synchronisations calendrier, les captures de paiement et le suivi analytique, le tout en étapes séparées et rejouables. Cela garde la logique coeur de réservation propre et rend la couche notifications et intégrations facile à étendre sans toucher au moteur de planning.

La stack technique

J'ai choisi chaque outil délibérément, en optimisant pour la sûreté de type, la vitesse de développement et la maintenabilité sur le long terme.

Frontend

React 19, React Router 7, Tailwind CSS 4, Radix UI, Jotai pour l'état, React Hook Form plus Zod pour les formulaires, et Vite 7.

Backend

Node.js 22, Hono, Drizzle ORM, TypeScript de bout en bout, et Neverthrow pour la gestion d'erreurs.

Base de données

SQLite plus Turso avec replicas embarqués, Drizzle Kit pour les migrations, et une architecture à double base.

Mobile

React Native avec Expo 54, Expo Router, TanStack Query, et packages de domaine partagés depuis le monorepo.

Intégrations

Stripe Connect, Google Calendar API, Microsoft Graph, Resend pour les emails, Twilio pour les SMS, et Giftup pour les cartes-cadeaux.

Infrastructure

Fly.io, Docker, Turborepo, Sentry, GrowthBook pour les feature flags, PostHog pour l'analytics, et Playwright pour les tests end-to-end.

Pourquoi Hono plutôt qu'Express ou Fastify ?

Hono est léger, s'exécute partout, des workers à Node jusqu'à l'edge, et démarre quasiment instantanément. Pour une plateforme qui devait faire cohabiter pages server-rendered et routes API dans le même processus, c'était le bon choix : rapide à développer et rapide en production.

Les défis que j'ai résolus

La synchronisation calendrier est plus difficile qu'elle n'en a l'air. Google Calendar et Microsoft Outlook ont des API, des modèles de webhooks et des garanties de fiabilité très différents. Google utilise des notifications push qui expirent et doivent être renouvelées. Outlook fonctionne avec des subscriptions ayant leur propre cycle de vie. J'ai construit un package @atoly/external-calendars qui abstrait les deux derrière une interface unifiée, renouvelle automatiquement les webhooks et gère les cas limites : événements supprimés, problèmes de fuseaux horaires, et événements à la journée qui franchissent minuit différemment selon le fournisseur.

Les paiements dans un modèle de marketplace. Atoly utilise Stripe Connect pour que chaque entreprise reçoive les paiements directement sur son propre compte Stripe tandis que la plateforme prélève sa commission. Cela implique la gestion des parcours d'onboarding, de la vérification des comptes, des webhooks pour payment intents, des remboursements et de la facturation d'abonnement, le tout avec une gestion d'erreur propre et des retries via les workflows Inngest.

Partager du code entre web et mobile sans compromis. L'architecture monorepo permet à l'application web et à l'application mobile de partager logique métier, schémas de validation et définitions de types via des packages internes. Mais j'ai fait attention à ne pas laisser du code spécifique au web contaminer le mobile, et inversement. Le package @atoly/core ne contient que du TypeScript pur : pas d'import React et pas d'API Node, donc il s'exécute partout.

Ce que j'ai livré

Le résultat est un SaaS en production avec de vrais utilisateurs, de vraies réservations et de vrais paiements. Les chiffres racontent une partie de l'histoire : 1 500+ commits, 18 packages de workspace, 15+ intégrations tierces, et 5 applications livrées depuis un seul monorepo. Mais ce qui compte davantage, c'est que je suis parti d'un dépôt vide pour arriver à une plateforme multi-tenant en ligne, avec application mobile, tout en gardant une architecture propre et une couverture de test sérieuse avec Vitest pour l'unitaire et l'intégration, et Playwright pour l'end-to-end.

La plateforme gère l'internationalisation en anglais et en français, fonctionne comme Progressive Web App, utilise des feature flags pour des rollouts contrôlés, et dispose d'une observabilité complète grâce au suivi d'erreurs Sentry et aux analytics PostHog.

Atoly montre ce qu'un développeur seul peut livrer lorsque l'architecture est juste dès le départ. Pas de rewrite, pas d'opération sauvetage après dette technique, juste une livraison itérative et régulière depuis le premier jour.

Ce que cela signifie pour votre projet

Construire Atoly m'a confronté aux mêmes décisions que celles qui reviennent dans tout projet logiciel sérieux : comment structurer un codebase qui grandit, comment isoler les données de chaque tenant, comment intégrer des API tierces capricieuses, et comment partager du code entre plateformes sans fabriquer un monstre. Pour moi, ce ne sont pas des problèmes théoriques. Ce sont des sujets déjà résolus en production.

Si vous envisagez de construire un SaaS, une plateforme de réservation, ou toute application qui a besoin de multi-tenance, de traitement des paiements ou d'un delivery cross-platform, je l'ai déjà fait et je peux le faire pour vous.

Construire avec Basaltbytes

Vous avez une idée produit ? Parlons-en.

Je conçois des SaaS, des applications web et des apps mobiles avec des stacks modernes et une architecture propre.

Réserver un appel de cadrage

Parlons de votre logiciel

Réservez un appel de cadrage de 30 minutes, sans engagement.

À propos de Basaltbytes

Basaltbytes est le cabinet de CTO externalisé de Philippe L'ATTENTION : un diagnostic technique indépendant, à prix fixe, pour reprendre la main sur votre logiciel.