Bizleen Orbit
En ligne · app.bizleen.comBizleen Orbit (anciennement StaffClock) est l'espace de travail connecté de Bizleen : pointage, pourboires, salaires estimés, congés, planning, événements, notifications et documents, servi sur la tablette partagée de l'établissement et sur le téléphone de chaque salarié. Né pour un restaurant, il sert aujourd'hui onze verticales avec neuf modules livrés, un moteur de réservation par couverts, et un moteur de rendez-vous en construction. Un Worker Cloudflare unique : Hono 4, React 19, Drizzle, D1, R2, trois Durable Objects. En ligne sur app.bizleen.com ; le domaine historique staffclock.app reste servi.
Pourquoi j'ai construit ça
Un restaurant comptait ses heures sur une application lente, avec un sélecteur d'heure impossible à manier en plein coup de feu ; les pourboires par carte étaient répartis à la main et les salaires estimés au doigt mouillé. J'ai construit l'outil le 3 juin 2026 pour ce besoin précis, sous son premier nom : pointage à gros boutons, répartition automatique au centime près, salaires estimés, clôtures formelles. Une fois l'outil en place pour un établissement, je l'ai ouvert à plusieurs (superadmin, établissements, administrateurs invités par courriel), puis à onze verticales servies par des axes de comportement plutôt que par le nom du métier. Par-dessus le pointage sont venus les congés, le planning de quarts, l'événementiel, les notifications, les documents et la paie estimée : neuf modules livrés. En août 2026, le raccordement au site public Bizleen a commencé, parce qu'un mini-site sait afficher une grille de prestations mais pas dire si le créneau de mardi 15 heures est libre, et que cette information vit dans l'outil qui tient déjà le planning. L'outil est devenu Bizleen Orbit sur toutes les surfaces que le client voit : application, manifeste, courriels, logos, et le domaine app.bizleen.com. Le pont entre le site public et l'espace connecté est construit et testé des deux côtés ; sa mise en service commerciale est en cours. Le tout tourne dans un Worker Cloudflare unique, avec 252 814 lignes de test pour 211 451 lignes de production.
Décisions techniques structurantes
Dans un restaurant, l'appareil qui pointe n'appartient à personne : c'est une tablette posée au passe, que tout le monde touche. Les rôles d'Orbit partent de cette réalité au lieu de la contourner. La tablette est un poste de consultation partagé ; un PIN serveur ou manager élève les droits le temps d'un geste, et cette élévation est tracée. Le téléphone de chaque salarié est son espace privé : ses heures, ses pourboires, ses congés, rien d'autre. Côté données, 74 tables sur 84 sont cloisonnées par établissement, et l'entrée du superadmin dans un établissement est tracée dans l'audit.
Orbit ne teste jamais « si restaurant alors ». Chaque métier est décrit par des axes purs : traceur privé, primes médicales, pourboires, relevé solo, organisateur d'événements. Une verticale est une combinaison de ces axes, et ouvrir un douzième métier est un travail de configuration, pas une duplication de code. C'est ce qui a permis de passer d'un restaurant à onze verticales sans forker le moteur.
Le serveur est découpé pour que la séparation se vérifie, pas seulement se déclare : 45 fichiers de routes (21 304 lignes) qui ne portent que la validation et l'autorisation, 85 fichiers de services (47 303 lignes), 79 fichiers de domaine pur sans effet de bord, 53 repositories, et aucun repository n'importe un service. Sous cette pile, un socle d'intégration : outbox transactionnel avec bail et lettre morte, inbox de consommation, registre d'idempotence capable de rejouer la réponse d'origine, projections en lecture du catalogue publié par Bizleen. Et 52 fichiers de test rejouent les migrations SQL jusqu'à vérifier la présence des déclencheurs dans sqlite_master.
Un coordinateur de réservation par établissement, qui sérialise les demandes sur une date ; un debounce des notifications de pourboires, qui regroupe les rafales avant l'envoi push ; et une garde qui refuse toute commande adressée à la mauvaise instance. Le fan-out des notifications est borné par établissement et par fenêtre de temps, pour qu'une rafale de saisies ne devienne jamais une rafale de push.
48 écrans chargés à la demande le long des frontières de rôle, aucun gestionnaire d'état, aucune bibliothèque de composants, et un seul appel à fetch dans tout le client : toutes les requêtes passent par la même porte. Le SPA est servi en Static Assets à côté de l'API, dans le même Worker.
Le challenge non-trivial
C'est le plus gros bloc du parc : 45 657 lignes serveur, 14 807 lignes client, 20 tables dédiées, 167 contraintes CHECK nommées, 69 déclencheurs SQL. Il empile trois moteurs. Un moteur de règles décrit une prestation en étapes ordonnées, avec des marges et, pour chaque étape, des exigences de ressource (nature, compétence, niveau, quantité). Un moteur d'allocation pose des retenues dont la durée de vie est lue à l'horloge de la base, et les résout par un solveur déterministe et borné. Un orchestrateur de commandes tourne sous un Durable Object coordinateur, une instance par établissement, et une garde refuse toute commande adressée à la mauvaise instance. Le moteur couverts, plus simple (capacité par service), est livré et sert déjà les réservations de restaurant. Le moteur de rendez-vous, lui, reste un chantier : il se présente comme tel, sans date.
Leçon retenue
Un outil construit pour un seul restaurant peut devenir l'espace connecté de onze métiers, à deux conditions que j'ai apprises ici. D'abord, les moteurs ne doivent jamais connaître le nom du métier : chaque verticale est une combinaison d'axes de comportement, et un métier de plus est de la configuration. Ensuite, une architecture en couches ne vaut que si elle se vérifie : des routes qui ne font que valider et autoriser, un domaine sans effet de bord, des repositories qui n'importent jamais un service, et des tests qui rejouent les migrations jusqu'aux déclencheurs. C'est ce qui permet d'écrire plus de lignes de test que de lignes de production (252 814 contre 211 451). Dernière leçon, plus simple : un chantier se dit comme un chantier. Le moteur de rendez-vous est en construction, et cette fiche le dit.
Fonctionnalités
Tablette de consultation partagée en salle, PIN serveur et PIN manager, entrées journalières, lieux de travail. Les gros boutons viennent du premier restaurant : il faut pouvoir pointer en plein coup de feu.
Trois modes de répartition mémorisés jour par jour, un axe distinct pour les espèces, règlements hebdomadaires idempotents : un règlement rejoué ne paie jamais deux fois.
Calcul, exports, envois de paie programmés, clôtures mensuelles : chaque salarié voit son estimation, l'établissement clôture son mois.
Demandes, validateurs désignés par établissement, rappels automatiques quand une demande attend.
Disponibilités, échanges de quarts entre salariés, patrons de repos : 7 465 lignes pour ce seul module.
34 points d'entrée, pointage par QR à secret régénérable, facturation au taux horaire ou au forfait.
Push web, Durable Object de debounce, abonnements d'appareils ; fan-out borné par établissement et par fenêtre de temps.
Registre déclaratif, audit métier opposable, purge de compte à la demande.
33 points d'entrée, impersonation tracée, 74 tables sur 84 cloisonnées par établissement.
Capacité par service, sérialisation par établissement et par date : c'est lui que sert le widget de réservation partenaire de Bizleen.
45 657 lignes serveur, 20 tables, trois moteurs empilés (règles, allocation, orchestration). Un chantier ouvert, présenté comme tel, sans date.