Odin

Comment j’ai construit un SaaS de planification pour les entreprises Bookeo

Yo ! Il y a quelques heures, j’ai mis en ligne Odin, un outil de planification hebdomadaire conçu pour les entreprises qui gèrent leurs réservations via Bookeo. L’objectif n’était pas de créer un énième calendrier, mais de résoudre un problème très spécifique que j’ai observé de manière répétée : la reconstruction manuelle des plannings, semaine après semaine.

Disponible sur https://odin.dyosis.com, Odin est aujourd’hui en production avec un socle fonctionnel complet. Dans cet article, je détaille le problème initial, les choix de conception, et les décisions techniques qui ont réellement structuré le produit.

Le problème : un rituel manuel difficile à scaler

Dans beaucoup de structures (escape games, studios photo, salles de sport, activités de loisirs), le planning hebdomadaire repose encore sur des outils génériques comme Google Sheets.

Le processus est souvent le même :

  • dupliquer la semaine précédente
  • ajuster les créneaux
  • croiser les disponibilités des employés
  • vérifier les réservations clients dans Bookeo
  • corriger les incohérences

Ce fonctionnement tient tant que l’équipe est petite. Mais dès que le volume augmente, il devient fragile :

  • erreurs humaines fréquentes
  • perte de temps récurrente
  • absence de vision consolidée

Ce n’est pas un problème technique complexe, mais c’est un problème opérationnel constant.

L’approche : arrêter de manipuler des créneaux, définir un modèle

Le point de départ d’Odin repose sur un changement de modèle mental : au lieu de reconstruire un planning, on définit une semaine type.

Une semaine type contient :

  • des créneaux
  • des horaires
  • des affectations d’employés

Une fois définie, elle peut être appliquée à n’importe quelle période. Le planning n’est plus édité manuellement, il est généré.

Ce choix paraît simple, mais il structure toute l’application.

Le produit : un calendrier opérationnel, pas un simple affichage

La vue principale est un calendrier hebdomadaire (7 jours × 24h) qui affiche à la fois les créneaux internes et les réservations clients Bookeo. Plus besoin de jongler entre deux outils : tout est au même endroit, avec la possibilité de filtrer par employé ou de masquer les réservations clients.

Interactions directes sur le planning

L’interface principale est un calendrier hebdomadaire (7 jours × 24h) qui regroupe deux types d’informations :

  • les créneaux internes
  • les réservations clients synchronisées depuis Bookeo

L’objectif n’est pas seulement d’afficher des données, mais de permettre une manipulation directe :

  • déplacement des créneaux en drag & drop
  • ajustement de la durée par redimensionnement
  • édition rapide sans quitter le calendrier
  • navigation complète au clavier
  • mise à disposition d’informations pertinentes (disponibilités des employés, réservations clientes)

Ce point est important : l’outil doit remplacer un tableur. Donc il doit être au moins aussi rapide à manipuler.

Intégration Bookeo : contrainte externe, logique interne

Bookeo est au cœur du produit, mais c’est aussi une contrainte.

L’API n’est pas toujours fiable, et il faut gérer :

  • les nouvelles réservations
  • les modifications
  • les suppressions

Le choix fait a été de combiner deux approches :

  • une synchronisation régulière (toutes les heures)
  • des webhooks pour les mises à jour en temps réel

En parallèle, l’application reste utilisable même si Bookeo est indisponible. On accepte donc une cohérence eventual consistency plutôt qu’une dépendance forte au temps réel.

Les décisions techniques qui ont réellement structuré le projet

Un calendrier entièrement custom

J’ai volontairement évité les bibliothèques comme FullCalendar. Elles sont efficaces pour des cas génériques, mais deviennent rapidement contraignantes dès qu’on sort du standard :

  • difficulté à gérer une navigation clavier complète
  • limitations sur le comportement du drag & drop
  • rigidité sur la représentation métier

Le choix a donc été de construire un calendrier sur mesure.

Conséquence directe :

  • un contrôle total du comportement
  • un coût de développement nettement plus élevé
  • une responsabilité complète sur la maintenance

C’est un choix qui ne se justifie que si le calendrier est central dans le produit. Ici, c’est le cas.

Une isolation multi-tenant systémique

Le produit est multi-tenant : chaque entreprise doit être totalement isolée.

Plutôt que de filtrer manuellement les requêtes, j’ai intégré cette contrainte directement dans l’ORM via un filtre Doctrine.

Concrètement :

  • toutes les requêtes sont automatiquement scoppées par tenant
  • aucun développeur ne peut “oublier” ce filtre

C’est une décision qui augmente la complexité interne, mais qui réduit drastiquement les risques de fuite de données.

Une architecture orientée métier (DDD)

Le backend est structuré en contextes métier distincts (Planning, Calendar, Bookeo, User, etc.) avec une séparation claire :

  • Domain
  • Application
  • Infrastructure

Ce choix n’est pas anodin :

  • il permet d’isoler les règles métier
  • il facilite les évolutions
  • il rend le code plus explicite

En contrepartie, il introduit plus de structure et de discipline.

Gérer l’incertitude des systèmes externes

L’intégration Bookeo m’a imposé de traiter des cas non idéaux :

  • API temporairement indisponible
  • données incohérentes
  • délais de propagation
  • absence de sandbox/espace développeur

J’ai donc intégré :

  • un retry exponentiel
  • une logique de tolérance aux pannes
  • une séparation claire entre données internes et externes
  • le développement d’une librairie dédiée basé sur des comptes de production « test »

Le système n’est pas strictement synchrone. Il privilégie la robustesse.

Accessibilité dès la conception

Le calendrier respecte les standards ARIA et est utilisable entièrement au clavier.

Ce n’est pas un ajout tardif. C’est un choix initial :

  • rôles ARIA (grid, row, cell)
  • navigation clavier complète
  • tests automatisés

C’est plus coûteux au départ, mais ça évite une refonte ultérieure.

Stack technique

Plutôt qu’une simple liste, voici les rôles :

Frontend

  • React 19 + TypeScript
  • TanStack Query : synchronisation avec le backend
  • Zustand : état local
  • Tailwind + Shadcn/ui : interface

Backend

  • Symfony 7.4 (PHP 8.4)
  • Doctrine ORM + PostgreSQL
  • JWT (tokens courts + refresh)

Infrastructure

  • Docker
  • Redis (cache, sessions)
  • Sentry (monitoring)

État actuel

Odin est aujourd’hui :

  • fonctionnel en production
  • capable de générer et manipuler des plannings complets
  • connecté à Bookeo
  • multi-tenant
  • prêt pour la monétisation (Stripe intégré)

Limites et compromis

Certains choix ont un coût :

  • le calendrier custom est plus difficile à faire évoluer
  • la synchronisation externe implique une cohérence non instantanée
  • l’architecture DDD demande de la rigueur

Ces compromis sont assumés, car ils servent les contraintes du produit.

Ce que ce projet démontre

Ce projet ne montre pas uniquement une stack technique. Il met en évidence :

  • la capacité à partir d’un problème opérationnel réel
  • la conception d’un produit cohérent
  • des choix techniques structurants, avec leurs compromis
  • la gestion de contraintes concrètes (multi-tenant, API externe, UX complexe)

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Retour en haut